From b558a091b6b5a05a69c9e804ab162cace03d7744 Mon Sep 17 00:00:00 2001 From: joeolson42 Date: Tue, 28 Feb 2023 22:10:37 +0000 Subject: [PATCH 01/19] MYNN updates --- physics/module_bl_mynn.F90 | 2956 ++++++++++++++++----------------- physics/mynnedmf_wrapper.F90 | 279 ++-- physics/mynnedmf_wrapper.meta | 46 +- physics/sgscloud_radpre.F90 | 135 +- physics/sgscloud_radpre.meta | 38 + 5 files changed, 1793 insertions(+), 1661 deletions(-) diff --git a/physics/module_bl_mynn.F90 b/physics/module_bl_mynn.F90 index ffb4b5696..b95f401c4 100644 --- a/physics/module_bl_mynn.F90 +++ b/physics/module_bl_mynn.F90 @@ -121,7 +121,7 @@ ! Hybrid PBL height diagnostic, which blends a theta-v-based ! definition in neutral/convective BL and a TKE-based definition ! in stable conditions. -! TKE budget output option (bl_mynn_tkebudget) +! TKE budget output option ! v3.5.0: TKE advection option (bl_mynn_tkeadvect) ! v3.5.1: Fog deposition related changes. ! v3.6.0: Removed fog deposition from the calculation of tendencies @@ -216,14 +216,14 @@ ! Misc small-impact bugfixes: ! 1) dz was incorrectly indexed in mym_condensation ! 2) configurations with icloud_bl = 0 were using uninitialized arrays -! v4.4 / CCPP +! v4.5 / CCPP ! This version includes many modifications that proved valuable in the global ! framework and removes some key lingering bugs in the mixing of chemical species. ! TKE Budget output fixed (Puhales, 2020-12) ! New option for stability function: (Puhales, 2020-12) ! bl_mynn_stfunc = 0 (original, Kansas-type function, Paulson, 1970 ) ! bl_mynn_stfunc = 1 (expanded range, same as used for Jimenez et al (MWR) -! see the Technical Note for this implementation. +! see the Technical Note for this implementation (small impact). ! Improved conservation of momentum and higher-order moments. ! Important bug fixes for mixing of chemical species. ! Addition of pressure-gradient effects on updraft momentum transport. @@ -248,21 +248,11 @@ MODULE module_bl_mynn xlvcp , tv0 , tv1 , tref , & zero , half , one , two , & onethird , twothirds , tkmin , t0c , & - tice + tice , kind_phys IMPLICIT NONE -!get rid - INTEGER , PARAMETER :: param_first_scalar = 1, & - & p_qc = 2, & - & p_qr = 0, & - & p_qi = 2, & - & p_qs = 0, & - & p_qg = 0, & - & p_qnc= 0, & - & p_qni= 0 - !=================================================================== ! From here on, these are MYNN-specific parameters: ! The parameters below depend on stability functions of module_sf_mynn. @@ -301,6 +291,7 @@ MODULE module_bl_mynn ! &cns=3.5, alp1=0.23, alp2=0.3, alp3=3.0, alp4=10.0, alp5=0.2 REAL, PARAMETER :: gpw=5./3., qcgmin=1.e-8, qkemin=1.e-12 + REAL, PARAMETER :: tliq = 269. !all hydrometeors are liquid when T > tliq ! Constants for cloud PDF (mym_condensation) REAL, PARAMETER :: rr2=0.7071068, rrp=0.3989423 @@ -340,32 +331,6 @@ MODULE module_bl_mynn LOGICAL, PARAMETER :: debug_code = .false. INTEGER, PARAMETER :: idbg = 23 !specific i-point to write out -! JAYMES- -!> Constants used for empirical calculations of saturation -!! vapor pressures (in function "esat") and saturation mixing ratios -!! (in function "qsat"), reproduced from module_mp_thompson.F, -!! v3.6 - REAL, PARAMETER:: J0= .611583699E03 - REAL, PARAMETER:: J1= .444606896E02 - REAL, PARAMETER:: J2= .143177157E01 - REAL, PARAMETER:: J3= .264224321E-1 - REAL, PARAMETER:: J4= .299291081E-3 - REAL, PARAMETER:: J5= .203154182E-5 - REAL, PARAMETER:: J6= .702620698E-8 - REAL, PARAMETER:: J7= .379534310E-11 - REAL, PARAMETER:: J8=-.321582393E-13 - - REAL, PARAMETER:: K0= .609868993E03 - REAL, PARAMETER:: K1= .499320233E02 - REAL, PARAMETER:: K2= .184672631E01 - REAL, PARAMETER:: K3= .402737184E-1 - REAL, PARAMETER:: K4= .565392987E-3 - REAL, PARAMETER:: K5= .521693933E-5 - REAL, PARAMETER:: K6= .307839583E-7 - REAL, PARAMETER:: K7= .105785160E-9 - REAL, PARAMETER:: K8= .161444444E-12 -! end- - ! Used in WRF-ARW module_physics_init.F INTEGER :: mynn_level @@ -373,7 +338,7 @@ MODULE module_bl_mynn CONTAINS ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine is the GSD MYNN-EDNF PBL driver routine,which !! encompassed the majority of the subroutines that comprise the !! procedures that ultimately solve for tendencies of @@ -383,35 +348,32 @@ MODULE module_bl_mynn SUBROUTINE mynn_bl_driver( & &initflag,restart,cycling, & &delt,dz,dx,znt, & - &u,v,w,th,sqv3D,sqc3D,sqi3D, & - &qnc,qni, & - &qnwfa,qnifa,ozone, & - &p,exner,rho,T3D, & + &u,v,w,th,sqv3d,sqc3d,sqi3d, & + &sqs3d,qnc,qni, & + &qnwfa,qnifa,qnbca,ozone, & + &p,exner,rho,t3d, & &xland,ts,qsfc,ps, & &ust,ch,hfx,qfx,rmol,wspd, & &uoce,voce, & !ocean current - &vdfg, & !Katata-added for fog dep - &Qke,qke_adv, & + &qke,qke_adv, & &sh3d,sm3d, & - &nchem,kdvel,ndvel, & !Smoke/Chem variables - &chem3d, vdep, & - &frp,EMIS_ANT_NO, & ! JLS/RAR to adjust exchange coeffs - &mix_chem,fire_turb,rrfs_smoke, & ! end smoke/chem variables - - &Tsq,Qsq,Cov, & - &RUBLTEN,RVBLTEN,RTHBLTEN, & - &RQVBLTEN,RQCBLTEN,RQIBLTEN, & - &RQNCBLTEN,RQNIBLTEN, & - &RQNWFABLTEN,RQNIFABLTEN, & - &DOZONE, & + &chem3d,vdep,smoke_dbg, & + &frp,emis_ant_no, & ! JLS/RAR to adjust exchange coeffs + &mix_chem,enh_mix,rrfs_sd, & ! end smoke/chem variables + &tsq,qsq,cov, & + &rublten,rvblten,rthblten, & + &rqvblten,rqcblten,rqiblten, & + &rqncblten,rqniblten,rqsblten, & + &rqnwfablten,rqnifablten, & + &rqnbcablten,dozone, & &exch_h,exch_m, & - &Pblh,kpbl, & + &pblh,kpbl, & &el_pbl, & - &dqke,qWT,qSHEAR,qBUOY,qDISS, & + &dqke,qwt,qshear,qbuoy,qdiss, & &qc_bl,qi_bl,cldfra_bl, & &bl_mynn_tkeadvect, & - &bl_mynn_tkebudget, & + &tke_budget, & &bl_mynn_cloudpdf, & &bl_mynn_mixlength, & &icloud_bl, & @@ -428,20 +390,21 @@ SUBROUTINE mynn_bl_driver( & &det_thl3D,det_sqv3D, & &nupdraft,maxMF,ktop_plume, & &spp_pbl,pattern_spp_pbl, & - &RTHRATEN, & + &rthraten, & &FLAG_QC,FLAG_QI,FLAG_QNC, & - &FLAG_QNI,FLAG_QNWFA,FLAG_QNIFA, & - &FLAG_OZONE & - &,IDS,IDE,JDS,JDE,KDS,KDE & - &,IMS,IME,JMS,JME,KMS,KME & - &,ITS,ITE,JTS,JTE,KTS,KTE) + &FLAG_QNI,FLAG_QS, & + &FLAG_QNWFA,FLAG_QNIFA, & + &FLAG_QNBCA,FLAG_OZONE, & + &IDS,IDE,JDS,JDE,KDS,KDE, & + &IMS,IME,JMS,JME,KMS,KME, & + &ITS,ITE,JTS,JTE,KTS,KTE ) !------------------------------------------------------------------- INTEGER, INTENT(in) :: initflag !INPUT NAMELIST OPTIONS: - LOGICAL, INTENT(IN) :: restart,cycling - LOGICAL, INTENT(in) :: bl_mynn_tkebudget + LOGICAL, INTENT(in) :: restart,cycling + INTEGER, INTENT(in) :: tke_budget INTEGER, INTENT(in) :: bl_mynn_cloudpdf INTEGER, INTENT(in) :: bl_mynn_mixlength INTEGER, INTENT(in) :: bl_mynn_edmf @@ -453,17 +416,18 @@ SUBROUTINE mynn_bl_driver( & INTEGER, INTENT(in) :: bl_mynn_cloudmix INTEGER, INTENT(in) :: bl_mynn_mixqt INTEGER, INTENT(in) :: icloud_bl - REAL, INTENT(in) :: closure + REAL(kind=kind_phys), INTENT(in) :: closure LOGICAL, INTENT(in) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QNC,& - FLAG_QNWFA,FLAG_QNIFA,FLAG_OZONE + FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & + FLAG_OZONE,FLAG_QS - LOGICAL, INTENT(IN) :: mix_chem,fire_turb,rrfs_smoke + LOGICAL, INTENT(IN) :: mix_chem,enh_mix,rrfs_sd,smoke_dbg - INTEGER, INTENT(in) :: & - & IDS,IDE,JDS,JDE,KDS,KDE & - &,IMS,IME,JMS,JME,KMS,KME & - &,ITS,ITE,JTS,JTE,KTS,KTE + INTEGER, INTENT(in) :: & + & IDS,IDE,JDS,JDE,KDS,KDE & + &,IMS,IME,JMS,JME,KMS,KME & + &,ITS,ITE,JTS,JTE,KTS,KTE #ifdef HARDCODE_VERTICAL # define kts 1 @@ -480,71 +444,67 @@ SUBROUTINE mynn_bl_driver( & ! to prevent a crash on Cheyenne. Do not change it back without testing if the code runs ! on Cheyenne with the GNU compiler. - REAL, INTENT(in) :: delt - REAL, DIMENSION(:), INTENT(in) :: dx - REAL, DIMENSION(:,:), INTENT(in) :: dz, & + REAL(kind=kind_phys), INTENT(in) :: delt + REAL(kind=kind_phys), DIMENSION(:), INTENT(in) :: dx + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: dz, & &u,v,w,th,sqv3D,p,exner,rho,T3D - REAL, DIMENSION(:,:), INTENT(in):: & - &sqc3D,sqi3D,qni,qnc,qnwfa,qnifa - REAL, DIMENSION(:,:), INTENT(in):: ozone - REAL, DIMENSION(:), INTENT(in) :: xland,ust, & - &ch,ts,qsfc,ps,hfx,qfx,wspd,uoce,voce,vdfg,znt - - REAL, DIMENSION(:,:), INTENT(inout) :: & + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: & + &sqc3D,sqi3D,sqs3D,qni,qnc,qnwfa,qnifa,qnbca + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in):: ozone + REAL(kind=kind_phys), DIMENSION(:), INTENT(in):: ust, & + &ch,qsfc,ps,wspd + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & &Qke,Tsq,Qsq,Cov,qke_adv + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & + &rublten,rvblten,rthblten,rqvblten,rqcblten, & + &rqiblten,rqsblten,rqniblten,rqncblten, & + &rqnwfablten,rqnifablten,rqnbcablten + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: dozone + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: rthraten - REAL, DIMENSION(:,:), INTENT(inout) :: & - &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN,RQCBLTEN, & - &RQIBLTEN,RQNIBLTEN,RQNCBLTEN, & - &RQNWFABLTEN,RQNIFABLTEN - REAL, DIMENSION(:,:), INTENT(inout) :: DOZONE - - REAL, DIMENSION(:,:), INTENT(in) :: RTHRATEN - - REAL, DIMENSION(:,:), INTENT(out) :: & - &exch_h,exch_m + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(out) :: exch_h,exch_m + REAL, DIMENSION(:), INTENT(in) :: xland,ts,znt,hfx,qfx, & + &uoce,voce !These 10 arrays are only allocated when bl_mynn_output > 0 - REAL, DIMENSION(:,:), INTENT(inout) :: & - & edmf_a,edmf_w,edmf_qt,edmf_thl,edmf_ent,edmf_qc, & + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & + & edmf_a,edmf_w,edmf_qt,edmf_thl,edmf_ent,edmf_qc, & & sub_thl3D,sub_sqv3D,det_thl3D,det_sqv3D ! REAL, DIMENSION(IMS:IME,KMS:KME) :: & ! & edmf_a_dd,edmf_w_dd,edmf_qt_dd,edmf_thl_dd,edmf_ent_dd,edmf_qc_dd - REAL, DIMENSION(:), INTENT(inout) :: Pblh,rmol + REAL(kind=kind_phys), DIMENSION(:), INTENT(inout) :: Pblh + REAL, DIMENSION(:), INTENT(inout) :: rmol - REAL, DIMENSION(IMS:IME) :: Psig_bl,Psig_shcu + REAL, DIMENSION(IMS:IME) :: psig_bl,psig_shcu - INTEGER,DIMENSION(:),INTENT(INOUT) :: & + INTEGER,DIMENSION(:),INTENT(INOUT) :: & &KPBL,nupdraft,ktop_plume - REAL, DIMENSION(:), INTENT(OUT) :: & - &maxmf + REAL(kind=kind_phys), DIMENSION(:), INTENT(out) :: maxmf - REAL, DIMENSION(:,:), INTENT(inout) :: & - &el_pbl + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: el_pbl - REAL, DIMENSION(:,:), INTENT(out) :: & + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(out) :: & &qWT,qSHEAR,qBUOY,qDISS,dqke - ! 3D budget arrays are not allocated when bl_mynn_tkebudget == .false. + ! 3D budget arrays are not allocated when tke_budget == 0 ! 1D (local) budget arrays are used for passing between subroutines. - REAL, DIMENSION(kts:kte) :: qWT1,qSHEAR1,qBUOY1,qDISS1,dqke1,diss_heat + REAL, DIMENSION(kts:kte) :: qwt1,qshear1,qbuoy1,qdiss1, & + &dqke1,diss_heat - REAL, DIMENSION(:,:), intent(out) :: Sh3D,Sm3D + REAL(kind=kind_phys), DIMENSION(:,:), intent(out) :: Sh3D,Sm3D - REAL, DIMENSION(:,:), INTENT(inout) :: & + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & &qc_bl,qi_bl,cldfra_bl - REAL, DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D,cldfra_bl1D,& + REAL, DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D,cldfra_bl1D, & qc_bl1D_old,qi_bl1D_old,cldfra_bl1D_old ! smoke/chemical arrays INTEGER, INTENT(IN ) :: nchem, kdvel, ndvel -! REAL, DIMENSION( ims:ime, kms:kme, nchem ), INTENT(INOUT), optional :: chem3d -! REAL, DIMENSION( ims:ime, kdvel, ndvel ), INTENT(IN), optional :: vdep - REAL, DIMENSION(:, :, :), INTENT(INOUT) :: chem3d - REAL, DIMENSION(:, :), INTENT(IN) :: vdep - REAL, DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO + REAL(kind=kind_phys), DIMENSION(:,:,:), INTENT(INOUT) :: chem3d + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(IN) :: vdep + REAL(kind=kind_phys), DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO !local REAL, DIMENSION(kts:kte ,nchem) :: chem1 REAL, DIMENSION(kts:kte+1,nchem) :: s_awchem1 @@ -553,15 +513,16 @@ SUBROUTINE mynn_bl_driver( & !local vars INTEGER :: ITF,JTF,KTF, IMD,JMD - INTEGER :: i,j,k - REAL, DIMENSION(KTS:KTE) :: thl,thvl,tl,qv1,qc1,qi1,sqw,& - &El, Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, & - &Vt, Vq, sgm, thlsg, sqwsg + INTEGER :: i,j,k,kproblem + REAL, DIMENSION(KTS:KTE) :: thl,tl,qv1,qc1,qi1,qs1,sqw, & + &el, dfm, dfh, dfq, tcd, qcd, pdk, pdt, pdq, pdc, & + &vt, vq, sgm REAL, DIMENSION(KTS:KTE) :: thetav,sh,sm,u1,v1,w1,p1, & &ex1,dz1,th1,tk1,rho1,qke1,tsq1,qsq1,cov1, & - &sqv,sqi,sqc,du1,dv1,dth1,dqv1,dqc1,dqi1,ozone1, & + &sqv,sqi,sqc,sqs, & + &du1,dv1,dth1,dqv1,dqc1,dqi1,dqs1,ozone1, & &k_m1,k_h1,qni1,dqni1,qnc1,dqnc1,qnwfa1,qnifa1, & - &dqnwfa1,dqnifa1,dozone1 + &qnbca1,dqnwfa1,dqnifa1,dqnbca1,dozone1 !mass-flux variables REAL, DIMENSION(KTS:KTE) :: dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf @@ -574,52 +535,67 @@ SUBROUTINE mynn_bl_driver( & det_thl,det_sqv,det_sqc,det_u,det_v REAL,DIMENSION(KTS:KTE+1) :: s_aw1,s_awthl1,s_awqt1, & s_awqv1,s_awqc1,s_awu1,s_awv1,s_awqke1, & - s_awqnc1,s_awqni1,s_awqnwfa1,s_awqnifa1 + s_awqnc1,s_awqni1,s_awqnwfa1,s_awqnifa1, & + s_awqnbca1 REAL,DIMENSION(KTS:KTE+1) :: sd_aw1,sd_awthl1,sd_awqt1, & sd_awqv1,sd_awqc1,sd_awu1,sd_awv1,sd_awqke1 REAL, DIMENSION(KTS:KTE+1) :: zw REAL :: cpm,sqcg,flt,fltv,flq,flqv,flqc,pmz,phh,exnerg,zet,phi_m,& & afk,abk,ts_decay, qc_bl2, qi_bl2, & - & th_sfc,ztop_plume,sqc9,sqi9 + & th_sfc,ztop_plume,wsp !top-down diffusion REAL, DIMENSION(ITS:ITE) :: maxKHtopdown - REAL,DIMENSION(KTS:KTE) :: KHtopdown,TKEprodTD + REAL, DIMENSION(KTS:KTE) :: KHtopdown,TKEprodTD - LOGICAL :: INITIALIZE_QKE + LOGICAL :: INITIALIZE_QKE,problem ! Stochastic fields - INTEGER, INTENT(IN) ::spp_pbl - REAL, DIMENSION( :, :), INTENT(IN) ::pattern_spp_pbl - REAL, DIMENSION(KTS:KTE) ::rstoch_col + INTEGER, INTENT(IN) :: spp_pbl + REAL(kind=kind_phys), DIMENSION( :, :), INTENT(IN) :: pattern_spp_pbl + REAL, DIMENSION(KTS:KTE) :: rstoch_col ! Substepping TKE INTEGER :: nsub - real :: delt2 - - IF ( debug_code ) THEN - if (idbg .lt. ime) then - print*,'in MYNN driver; at beginning' - print*," th(1:5)=",th(idbg,1:5) - print*," u(1:5)=",u(idbg,1:5) - print*," v(1:5)=",v(idbg,1:5) - print*," w(1:5)=",w(idbg,1:5) - print*," sqv(1:5)=",sqv3D(idbg,1:5) - print*," p(1:5)=",p(idbg,1:5) - print*," rho(1:5)=",rho(idbg,1:5) - print*," xland=",xland(idbg)," u*=",ust(idbg), & - &" ts=",ts(idbg)," qsfc=",qsfc(idbg), & - &" z/L=",0.5*dz(idbg,1)*rmol(idbg)," ps=",ps(idbg),& - &" hfx=",hfx(idbg)," qfx=",qfx(idbg), & - &" wspd=",wspd(idbg)," znt=",znt(idbg) - endif - ENDIF + real(kind=kind_phys) :: delt2 + + + if (debug_code) then !check incoming values + do i=its,ite + problem = .false. + do k=kts,kte + wsp = sqrt(u(i,k)**2 + v(i,k)**2) + if (abs(hfx(i)) > 1200. .or. abs(qfx(i)) > 0.001 .or. & + wsp > 200. .or. t3d(i,k) > 360. .or. t3d(i,k) < 160. .or. & + sqv3d(i,k)< 0.0 .or. sqc3d(i,k)< 0.0 ) then + kproblem = k + problem = .true. + print*,"Incoming problem at: i=",i," k=1" + print*," QFX=",qfx(i)," HFX=",hfx(i) + print*," wsp=",wsp," T=",t3d(i,k) + print*," qv=",sqv3d(i,k)," qc=",sqc3d(i,k) + print*," u*=",ust(i)," wspd=",wspd(i) + print*," xland=",xland(i)," ts=",ts(i) + print*," z/L=",0.5*dz(i,1)*rmol(i)," ps=",ps(i) + print*," znt=",znt(i)," dx=",dx(i) + endif + enddo + if (problem) then + print*,"===tk:",t3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qv:",sqv3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qc:",sqc3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qi:",sqi3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====u:",u(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====v:",v(i,max(kproblem-3,1):min(kproblem+3,kte)) + endif + enddo + endif !*** Begin debugging IMD=(IMS+IME)/2 JMD=(JMS+JME)/2 -!*** End debugging +!*** End debugging JTF=JTE ITF=ITE @@ -691,6 +667,7 @@ SUBROUTINE mynn_bl_driver( & dqnc1(kts:kte)=0.0 dqnwfa1(kts:kte)=0.0 dqnifa1(kts:kte)=0.0 + dqnbca1(kts:kte)=0.0 dozone1(kts:kte)=0.0 qc_bl1D_old(kts:kte)=0.0 cldfra_bl1D_old(kts:kte)=0.0 @@ -711,7 +688,7 @@ SUBROUTINE mynn_bl_driver( & ENDDO ENDDO - IF ( bl_mynn_tkebudget ) THEN + IF (tke_budget .eq. 1) THEN DO k=KTS,KTE DO i=ITS,ITF qWT(i,k)=0. @@ -724,7 +701,23 @@ SUBROUTINE mynn_bl_driver( & ENDIF DO i=ITS,ITF - DO k=KTS,KTE !KTF + if (FLAG_QI ) then + sqi(:)=sqi3D(i,:) + else + sqi = 0.0 + endif + if (FLAG_QS ) then + sqs(:)=sqs3D(i,:) + else + sqs = 0.0 + endif + if (icloud_bl > 0) then + cldfra_bl1d(:)=cldfra_bl(i,:) + qc_bl1d(:)=qc_bl(i,:) + qi_bl1d(:)=qi_bl(i,:) + endif + + do k=KTS,KTE !KTF dz1(k)=dz(i,k) u1(k) = u(i,k) v1(k) = v(i,k) @@ -736,51 +729,14 @@ SUBROUTINE mynn_bl_driver( & sqc(k)=sqc3D(i,k) !/(1.+qv(i,k)) sqv(k)=sqv3D(i,k) !/(1.+qv(i,k)) thetav(k)=th(i,k)*(1.+0.608*sqv(k)) - IF (icloud_bl > 0) THEN - CLDFRA_BL1D(k)=CLDFRA_BL(i,k) - QC_BL1D(k)=QC_BL(i,k) - QI_BL1D(k)=QI_BL(i,k) - ENDIF - IF (FLAG_QI ) THEN - sqi(k)=sqi3D(i,k) !/(1.+qv(i,k)) - sqw(k)=sqv(k)+sqc(k)+sqi(k) - thl(k)=th1(k) - xlvcp/ex1(k)*sqc(k) & - & - xlscp/ex1(k)*sqi(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & - ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. sqi(k)<1e-8 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=QI_BL1D(k)*CLDFRA_BL1D(k) - ELSE - sqc9=sqc(k) - sqi9=sqi(k) - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - sqwsg(k)=sqv(k)+sqc9+sqi9 - ELSE - sqi(k)=0.0 - sqw(k)=sqv(k)+sqc(k) - thl(k)=th1(k)-xlvcp/ex1(k)*sqc(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=0.0 - ELSE - sqc9=sqc(k) - sqi9=0.0 - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - sqwsg(k)=sqv(k)+sqc9+sqi9 - ENDIF - thvl(k)=thlsg(k)*(1.+0.61*sqv(k)) + !keep snow out for now - increases ceiling bias + sqw(k)=sqv(k)+sqc(k)+sqi(k)!+sqs(k) + thl(k)=th1(k) - xlvcp/ex1(k)*sqc(k) & + & - xlscp/ex1(k)*(sqi(k)+sqs(k)) + !Use form from Tripoli and Cotton (1981) with their + !suggested min temperature to improve accuracy. + !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & + ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) IF (k==kts) THEN zw(k)=0. @@ -811,9 +767,8 @@ SUBROUTINE mynn_bl_driver( & zw(kte+1)=zw(kte)+dz(i,kte) -!> - Call get_pblh() to calculate hybrid (\f$\theta_{vli}-TKE\f$) PBL height. -! CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& - CALL GET_PBLH(KTS,KTE,PBLH(i),thvl, & +!> - Call get_pblh() to calculate hybrid (\f$\theta_{v}-TKE\f$) PBL height. + CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& & Qke1,zw,dz1,xland(i),KPBL(i)) !> - Call scale_aware() to calculate similarity functions for scale-adaptive control @@ -831,18 +786,17 @@ SUBROUTINE mynn_bl_driver( & !! obtaining prerequisite variables by calling the following subroutines from !! within mym_initialize(): mym_level2() and mym_length(). CALL mym_initialize ( & - &kts,kte, & + &kts,kte,xland(i), & &dz1, dx(i), zw, & &u1, v1, thl, sqv, & - &thlsg, sqwsg, & &PBLH(i), th1, thetav, sh, sm, & &ust(i), rmol(i), & &el, Qke1, Tsq1, Qsq1, Cov1, & &Psig_bl(i), cldfra_bl1D, & &bl_mynn_mixlength, & - &edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf,& + &edmf_w1,edmf_a1, & &INITIALIZE_QKE, & - &spp_pbl,rstoch_col ) + &spp_pbl,rstoch_col ) IF (.not.restart) THEN !UPDATE 3D VARIABLES @@ -885,654 +839,582 @@ SUBROUTINE mynn_bl_driver( & ENDIF DO i=ITS,ITF - DO k=KTS,KTE !KTF - !JOE-TKE BUDGET - IF ( bl_mynn_tkebudget ) THEN - dqke(i,k)=qke(i,k) - END IF - IF (icloud_bl > 0) THEN - CLDFRA_BL1D(k)=CLDFRA_BL(i,k) - QC_BL1D(k)=QC_BL(i,k) - QI_BL1D(k)=QI_BL(i,k) - cldfra_bl1D_old(k)=cldfra_bl(i,k) - qc_bl1D_old(k)=qc_bl(i,k) - qi_bl1D_old(k)=qi_bl(i,k) - else - CLDFRA_BL1D(k)=0.0 - QC_BL1D(k)=0.0 - QI_BL1D(k)=0.0 - cldfra_bl1D_old(k)=0.0 - qc_bl1D_old(k)=0.0 - qi_bl1D_old(k)=0.0 - ENDIF - dz1(k)= dz(i,k) - u1(k) = u(i,k) - v1(k) = v(i,k) - w1(k) = w(i,k) - th1(k)= th(i,k) - tk1(k)=T3D(i,k) - p1(k) = p(i,k) - ex1(k)= exner(i,k) - rho1(k)=rho(i,k) - sqv(k)= sqv3D(i,k) !/(1.+qv(i,k)) - sqc(k)= sqc3D(i,k) !/(1.+qv(i,k)) - qv1(k)= sqv(k)/(1.-sqv(k)) - qc1(k)= sqc(k)/(1.-sqv(k)) - dqc1(k)=0.0 - dqi1(k)=0.0 - dqni1(k)=0.0 - dqnc1(k)=0.0 - dqnwfa1(k)=0.0 - dqnifa1(k)=0.0 - dozone1(k)=0.0 - IF(FLAG_QI)THEN - sqi(k)= sqi3D(i,k) !/(1.+qv(i,k)) - qi1(k)= sqi(k)/(1.-sqv(k)) - sqw(k)= sqv(k)+sqc(k)+sqi(k) - thl(k)= th1(k) - xlvcp/ex1(k)*sqc(k) & - & - xlscp/ex1(k)*sqi(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & - ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. sqi(k)<1e-8 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=QI_BL1D(k)*CLDFRA_BL1D(k) - ELSE - sqc9=sqc(k) - sqi9=sqi(k) - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - sqwsg(k)=sqv(k)+sqc9+sqi9 - ELSE - qi1(k)=0.0 - sqi(k)=0.0 - sqw(k)= sqv(k)+sqc(k) - thl(k)= th1(k)-xlvcp/ex1(k)*sqc(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=QI_BL1D(k)*CLDFRA_BL1D(k) - ELSE - sqc9=sqc(k) - sqi9=0.0 - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - ENDIF - thetav(k)=th1(k)*(1.+0.608*sqv(k)) - thvl(k) =thlsg(k) *(1.+0.608*sqv(k)) - - IF (FLAG_QNI ) THEN - qni1(k)=qni(i,k) - ELSE - qni1(k)=0.0 - ENDIF - IF (FLAG_QNC ) THEN - qnc1(k)=qnc(i,k) - ELSE - qnc1(k)=0.0 - ENDIF - IF (FLAG_QNWFA ) THEN - qnwfa1(k)=qnwfa(i,k) - ELSE - qnwfa1(k)=0.0 - ENDIF - IF (FLAG_QNIFA ) THEN - qnifa1(k)=qnifa(i,k) - ELSE - qnifa1(k)=0.0 - ENDIF - IF (FLAG_OZONE) THEN - ozone1(k)=ozone(i,k) - ELSE - ozone1(k)=0.0 - ENDIF - el(k) = el_pbl(i,k) - qke1(k)=qke(i,k) - sh(k) =sh3d(i,k) - sm(k) =sm3d(i,k) - tsq1(k)=tsq(i,k) - qsq1(k)=qsq(i,k) - cov1(k)=cov(i,k) - if (spp_pbl==1) then - rstoch_col(k)=pattern_spp_pbl(i,k) - else - rstoch_col(k)=0.0 - endif - - !edmf - edmf_a1(k)=0.0 - edmf_w1(k)=0.0 - edmf_qc1(k)=0.0 - s_aw1(k)=0. - s_awthl1(k)=0. - s_awqt1(k)=0. - s_awqv1(k)=0. - s_awqc1(k)=0. - s_awu1(k)=0. - s_awv1(k)=0. - s_awqke1(k)=0. - s_awqnc1(k)=0. - s_awqni1(k)=0. - s_awqnwfa1(k)=0. - s_awqnifa1(k)=0. - ![EWDD] - edmf_a_dd1(k)=0.0 - edmf_w_dd1(k)=0.0 - edmf_qc_dd1(k)=0.0 - sd_aw1(k)=0. - sd_awthl1(k)=0. - sd_awqt1(k)=0. - sd_awqv1(k)=0. - sd_awqc1(k)=0. - sd_awu1(k)=0. - sd_awv1(k)=0. - sd_awqke1(k)=0. - sub_thl(k)=0. - sub_sqv(k)=0. - sub_u(k)=0. - sub_v(k)=0. - det_thl(k)=0. - det_sqv(k)=0. - det_sqc(k)=0. - det_u(k)=0. - det_v(k)=0. - - IF (k==kts) THEN - zw(k)=0. - ELSE - zw(k)=zw(k-1)+dz(i,k-1) - ENDIF - ENDDO ! end k - - !initialize smoke/chem arrays (if used): - IF ( rrfs_smoke .and. mix_chem ) then - do ic = 1,ndvel - vd1(ic) = vdep(i,ic) !is this correct???? - chem1(kts,ic) = chem3d(i,kts,ic) - s_awchem1(kts,ic)=0. - enddo - do k = kts+1,kte - DO ic = 1,nchem - chem1(k,ic) = chem3d(i,k,ic) - s_awchem1(k,ic)=0. - ENDDO - enddo - ELSE - do ic = 1,ndvel - vd1(ic) = 0. !is this correct??? (ite) or (ndvel) - chem1(kts,ic) = 0. - s_awchem1(kts,ic)=0. - enddo - do k = kts+1,kte - do ic = 1,nchem - chem1(k,ic) = 0. - s_awchem1(k,ic)=0. - enddo - enddo - ENDIF - - zw(kte+1)=zw(kte)+dz(i,kte) - !EDMF - s_aw1(kte+1)=0. - s_awthl1(kte+1)=0. - s_awqt1(kte+1)=0. - s_awqv1(kte+1)=0. - s_awqc1(kte+1)=0. - s_awu1(kte+1)=0. - s_awv1(kte+1)=0. - s_awqke1(kte+1)=0. - s_awqnc1(kte+1)=0. - s_awqni1(kte+1)=0. - s_awqnwfa1(kte+1)=0. - s_awqnifa1(kte+1)=0. - sd_aw1(kte+1)=0. - sd_awthl1(kte+1)=0. - sd_awqt1(kte+1)=0. - sd_awqv1(kte+1)=0. - sd_awqc1(kte+1)=0. - sd_awu1(kte+1)=0. - sd_awv1(kte+1)=0. - sd_awqke1(kte+1)=0. - IF ( mix_chem ) THEN - DO ic = 1,nchem - s_awchem1(kte+1,ic)=0. - ENDDO - ENDIF + !Initialize some arrays + if (tke_budget .eq. 1) then + dqke(i,:)=qke(i,:) + endif + if (FLAG_QI ) then + sqi(:)=sqi3D(i,:) + else + sqi = 0.0 + endif + if (FLAG_QS ) then + sqs(:)=sqs3D(i,:) + else + sqs = 0.0 + endif + if (icloud_bl > 0) then + CLDFRA_BL1D(:)=CLDFRA_BL(i,:) + QC_BL1D(:) =QC_BL(i,:) + QI_BL1D(:) =QI_BL(i,:) + cldfra_bl1D_old(:)=cldfra_bl(i,:) + qc_bl1D_old(:)=qc_bl(i,:) + qi_bl1D_old(:)=qi_bl(i,:) + else + CLDFRA_BL1D =0.0 + QC_BL1D =0.0 + QI_BL1D =0.0 + cldfra_bl1D_old=0.0 + qc_bl1D_old =0.0 + qi_bl1D_old =0.0 + endif + dz1(kts:kte) =dz(i,kts:kte) + u1(kts:kte) =u(i,kts:kte) + v1(kts:kte) =v(i,kts:kte) + w1(kts:kte) =w(i,kts:kte) + th1(kts:kte) =th(i,kts:kte) + tk1(kts:kte) =T3D(i,kts:kte) + p1(kts:kte) =p(i,kts:kte) + ex1(kts:kte) =exner(i,kts:kte) + rho1(kts:kte) =rho(i,kts:kte) + sqv(kts:kte) =sqv3D(i,kts:kte) !/(1.+qv(i,kts:kte)) + sqc(kts:kte) =sqc3D(i,kts:kte) !/(1.+qv(i,kts:kte)) + qv1(kts:kte) =sqv(kts:kte)/(1.-sqv(kts:kte)) + qc1(kts:kte) =sqc(kts:kte)/(1.-sqv(kts:kte)) + qi1(kts:kte) =sqi(kts:kte)/(1.-sqv(kts:kte)) + qs1(kts:kte) =sqs(kts:kte)/(1.-sqv(kts:kte)) + dqc1(kts:kte) =0.0 + dqi1(kts:kte) =0.0 + dqs1(kts:kte) =0.0 + dqni1(kts:kte) =0.0 + dqnc1(kts:kte) =0.0 + dqnwfa1(kts:kte)=0.0 + dqnifa1(kts:kte)=0.0 + dqnbca1(kts:kte)=0.0 + dozone1(kts:kte)=0.0 + IF (FLAG_QNI ) THEN + qni1(kts:kte)=qni(i,kts:kte) + ELSE + qni1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNC ) THEN + qnc1(kts:kte)=qnc(i,kts:kte) + ELSE + qnc1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNWFA ) THEN + qnwfa1(kts:kte)=qnwfa(i,kts:kte) + ELSE + qnwfa1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNIFA ) THEN + qnifa1(kts:kte)=qnifa(i,kts:kte) + ELSE + qnifa1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNBCA ) THEN + qnbca1(kts:kte)=qnbca(i,kts:kte) + ELSE + qnbca1(kts:kte)=0.0 + ENDIF + IF (FLAG_OZONE ) THEN + ozone1(kts:kte)=ozone(i,kts:kte) + ELSE + ozone1(kts:kte)=0.0 + ENDIF + el(kts:kte) =el_pbl(i,kts:kte) + qke1(kts:kte)=qke(i,kts:kte) + sh(kts:kte) =sh3d(i,kts:kte) + sm(kts:kte) =sm3d(i,kts:kte) + tsq1(kts:kte)=tsq(i,kts:kte) + qsq1(kts:kte)=qsq(i,kts:kte) + cov1(kts:kte)=cov(i,kts:kte) + if (spp_pbl==1) then + rstoch_col(kts:kte)=pattern_spp_pbl(i,kts:kte) + else + rstoch_col(kts:kte)=0.0 + endif + !edmf + edmf_a1 =0.0 + edmf_w1 =0.0 + edmf_qc1 =0.0 + s_aw1 =0.0 + s_awthl1 =0.0 + s_awqt1 =0.0 + s_awqv1 =0.0 + s_awqc1 =0.0 + s_awu1 =0.0 + s_awv1 =0.0 + s_awqke1 =0.0 + s_awqnc1 =0.0 + s_awqni1 =0.0 + s_awqnwfa1 =0.0 + s_awqnifa1 =0.0 + s_awqnbca1 =0.0 + ![EWDD] + edmf_a_dd1 =0.0 + edmf_w_dd1 =0.0 + edmf_qc_dd1=0.0 + sd_aw1 =0.0 + sd_awthl1 =0.0 + sd_awqt1 =0.0 + sd_awqv1 =0.0 + sd_awqc1 =0.0 + sd_awu1 =0.0 + sd_awv1 =0.0 + sd_awqke1 =0.0 + sub_thl =0.0 + sub_sqv =0.0 + sub_u =0.0 + sub_v =0.0 + det_thl =0.0 + det_sqv =0.0 + det_sqc =0.0 + det_u =0.0 + det_v =0.0 + + do k = kts,kte + if (k==kts) then + zw(k)=0. + else + zw(k)=zw(k-1)+dz(i,k-1) + endif + !keep snow out for now - increases ceiling bias + sqw(k)= sqv(k)+sqc(k)+sqi(k)!+sqs(k) + thl(k)= th1(k) - xlvcp/ex1(k)*sqc(k) & + & - xlscp/ex1(k)*(sqi(k)+sqs(k)) + !Use form from Tripoli and Cotton (1981) with their + !suggested min temperature to improve accuracy. + !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & + ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) + thetav(k)=th1(k)*(1.+0.608*sqv(k)) + enddo ! end k + zw(kte+1)=zw(kte)+dz(i,kte) + + !initialize smoke/chem arrays (if used): + if ( mix_chem ) then + do ic = 1,ndvel + vd1(ic) = vdep(i,ic) ! dry deposition velocity + chem1(kts,ic) = chem3d(i,kts,ic) + enddo + do k = kts+1,kte + do ic = 1,nchem + chem1(k,ic) = chem3d(i,k,ic) + enddo + enddo + else + do ic = 1,ndvel + vd1(ic) = 0. ! dry deposition velocity + chem1(kts,ic) = 0. + enddo + do k = kts+1,kte + do ic = 1,nchem + chem1(k,ic) = 0. + enddo + enddo + endif + s_awchem1 = 0.0 !> - Call get_pblh() to calculate the hybrid \f$\theta_{vli}-TKE\f$ !! PBL height diagnostic. -! CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& - CALL GET_PBLH(KTS,KTE,PBLH(i),thvl,& - & Qke1,zw,dz1,xland(i),KPBL(i)) + CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& + & Qke1,zw,dz1,xland(i),KPBL(i)) !> - Call scale_aware() to calculate the similarity functions, !! \f$P_{\sigma-PBL}\f$ and \f$P_{\sigma-shcu}\f$, to control !! the scale-adaptive behaviour for the local and nonlocal !! components, respectively. - IF (scaleaware > 0.) THEN - CALL SCALE_AWARE(dx(i),PBLH(i),Psig_bl(i),Psig_shcu(i)) - ELSE - Psig_bl(i)=1.0 - Psig_shcu(i)=1.0 - ENDIF + if (scaleaware > 0.) then + call SCALE_AWARE(dx(i),PBLH(i),Psig_bl(i),Psig_shcu(i)) + else + Psig_bl(i)=1.0 + Psig_shcu(i)=1.0 + endif - sqcg= 0.0 !ill-defined variable; qcg has been removed - cpm=cp*(1.+0.84*qv1(kts)) - exnerg=(ps(i)/p1000mb)**rcp - - !----------------------------------------------------- - !ORIGINAL CODE - !flt = hfx(i)/( rho(i,kts)*cpm ) & - ! +xlvcp*ch(i)*(sqc(kts)/exner(i,kts) -sqcg/exnerg) - !flq = qfx(i)/ rho(i,kts) & - ! -ch(i)*(sqc(kts) -sqcg ) - !----------------------------------------------------- - ! Katata-added - The deposition velocity of cloud (fog) - ! water is used instead of CH. - !flt = hfx(i)/( rho(i,kts)*cpm ) & - ! & +xlvcp*vdfg(i)*(sqc(kts)/exner(i,kts)- sqcg/exnerg) - !flq = qfx(i)/ rho(i,kts) & - ! & -vdfg(i)*(sqc(kts) - sqcg ) - !----------------------------------------------------- - flqv = qfx(i)/rho1(kts) - flqc = -vdfg(i)*(sqc(kts) - sqcg ) - th_sfc = ts(i)/ex1(kts) - - ! TURBULENT FLUX FOR TKE BOUNDARY CONDITIONS - flq =flqv+flqc !! LATENT - flt =hfx(i)/(rho1(kts)*cpm )-xlvcp*flqc/ex1(kts) !! Temperature flux - fltv=flt + flqv*p608*th_sfc !! Virtual temperature flux - - ! Update 1/L using updated sfc heat flux and friction velocity - rmol(i) = -karman*gtr*fltv/max(ust(i)**3,1.0e-6) - zet = 0.5*dz(i,kts)*rmol(i) - zet = MAX(zet, -20.) - zet = MIN(zet, 20.) - !if(i.eq.idbg)print*,"updated z/L=",zet - if (bl_mynn_stfunc == 0) then - !Original Kansas-type stability functions - if ( zet >= 0.0 ) then - pmz = 1.0 + (cphm_st-1.0) * zet - phh = 1.0 + cphh_st * zet - else - pmz = 1.0/ (1.0-cphm_unst*zet)**0.25 - zet - phh = 1.0/SQRT(1.0-cphh_unst*zet) - end if + sqcg= 0.0 !ill-defined variable; qcg has been removed + cpm=cp*(1.+0.84*qv1(kts)) + exnerg=(ps(i)/p1000mb)**rcp + + !----------------------------------------------------- + !ORIGINAL CODE + !flt = hfx(i)/( rho(i,kts)*cpm ) & + ! +xlvcp*ch(i)*(sqc(kts)/exner(i,kts) -sqcg/exnerg) + !flq = qfx(i)/ rho(i,kts) & + ! -ch(i)*(sqc(kts) -sqcg ) + !----------------------------------------------------- + flqv = qfx(i)/rho1(kts) + flqc = 0.0 !currently no sea-spray fluxes, fog settling handled elsewhere + th_sfc = ts(i)/ex1(kts) + + ! TURBULENT FLUX FOR TKE BOUNDARY CONDITIONS + flq =flqv+flqc !! LATENT + flt =hfx(i)/(rho1(kts)*cpm )-xlvcp*flqc/ex1(kts) !! Temperature flux + fltv=flt + flqv*p608*th_sfc !! Virtual temperature flux + + ! Update 1/L using updated sfc heat flux and friction velocity + rmol(i) = -karman*gtr*fltv/max(ust(i)**3,1.0e-6) + zet = 0.5*dz(i,kts)*rmol(i) + zet = MAX(zet, -20.) + zet = MIN(zet, 20.) + !if(i.eq.idbg)print*,"updated z/L=",zet + if (bl_mynn_stfunc == 0) then + !Original Kansas-type stability functions + if ( zet >= 0.0 ) then + pmz = 1.0 + (cphm_st-1.0) * zet + phh = 1.0 + cphh_st * zet else - !Updated stability functions (Puhales, 2020) - phi_m = phim(zet) - pmz = phi_m - zet - phh = phih(zet) + pmz = 1.0/ (1.0-cphm_unst*zet)**0.25 - zet + phh = 1.0/SQRT(1.0-cphh_unst*zet) end if + else + !Updated stability functions (Puhales, 2020) + phi_m = phim(zet) + pmz = phi_m - zet + phh = phih(zet) + end if !> - Call mym_condensation() to calculate the nonconvective component !! of the subgrid cloud fraction and mixing ratio as well as the functions !! used to calculate the buoyancy flux. Different cloud PDFs can be !! selected by use of the namelist parameter \p bl_mynn_cloudpdf. - CALL mym_condensation ( kts,kte, & - &dx(i),dz1,zw,thl,sqw,sqv,sqc,sqi,& - &p1,ex1,tsq1,qsq1,cov1, & - &Sh,el,bl_mynn_cloudpdf, & - &qc_bl1D,qi_bl1D,cldfra_bl1D, & - &PBLH(i),HFX(i), & - &Vt, Vq, th1, sgm, rmol(i), & - &spp_pbl, rstoch_col ) + call mym_condensation (kts,kte, & + &dx(i),dz1,zw,xland(i), & + &thl,sqw,sqv,sqc,sqi,sqs, & + &p1,ex1,tsq1,qsq1,cov1, & + &Sh,el,bl_mynn_cloudpdf, & + &qc_bl1D,qi_bl1D,cldfra_bl1D, & + &PBLH(i),HFX(i), & + &Vt, Vq, th1, sgm, rmol(i), & + &spp_pbl, rstoch_col ) !> - Add TKE source driven by cloud top cooling !! Calculate the buoyancy production of TKE from cloud-top cooling when !! \p bl_mynn_topdown =1. - IF (bl_mynn_topdown.eq.1)then - CALL topdown_cloudrad(kts,kte,dz1,zw, & - &xland(i),kpbl(i),PBLH(i), & - &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & - &cldfra_bl1D,rthraten, & - &maxKHtopdown(i),KHtopdown,TKEprodTD ) - ELSE - maxKHtopdown(i) = 0.0 - KHtopdown(kts:kte) = 0.0 - TKEprodTD(kts:kte) = 0.0 - ENDIF + if (bl_mynn_topdown.eq.1) then + call topdown_cloudrad(kts,kte,dz1,zw, & + &xland(i),kpbl(i),PBLH(i), & + &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & + &cldfra_bl1D,rthraten(i,:), & + &maxKHtopdown(i),KHtopdown,TKEprodTD ) + else + maxKHtopdown(i) = 0.0 + KHtopdown(kts:kte) = 0.0 + TKEprodTD(kts:kte) = 0.0 + endif - IF (bl_mynn_edmf > 0) THEN - !PRINT*,"Calling DMP Mass-Flux: i= ",i - CALL DMP_mf( & - &kts,kte,delt,zw,dz1,p1,rho1, & - &bl_mynn_edmf_mom, & - &bl_mynn_edmf_tke, & - &bl_mynn_mixscalars, & - &u1,v1,w1,th1,thl,thetav,tk1, & - &sqw,sqv,sqc,qke1, & - &qnc1,qni1,qnwfa1,qnifa1, & - &ex1,Vt,Vq,sgm, & - &ust(i),flt,fltv,flq,flqv, & - &PBLH(i),KPBL(i),DX(i), & - &xland(i),th_sfc, & + if (bl_mynn_edmf > 0) then + !PRINT*,"Calling DMP Mass-Flux: i= ",i + call DMP_mf( & + &kts,kte,delt,zw,dz1,p1,rho1, & + &bl_mynn_edmf_mom, & + &bl_mynn_edmf_tke, & + &bl_mynn_mixscalars, & + &u1,v1,w1,th1,thl,thetav,tk1, & + &sqw,sqv,sqc,qke1, & + &qnc1,qni1,qnwfa1,qnifa1,qnbca1, & + &ex1,Vt,Vq,sgm, & + &ust(i),flt,fltv,flq,flqv, & + &PBLH(i),KPBL(i),DX(i), & + &xland(i),th_sfc, & ! now outputs - tendencies - ! &,dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf & + ! &,dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf & ! outputs - updraft properties - & edmf_a1,edmf_w1,edmf_qt1, & - & edmf_thl1,edmf_ent1,edmf_qc1, & + &edmf_a1,edmf_w1,edmf_qt1, & + &edmf_thl1,edmf_ent1,edmf_qc1, & ! for the solver - & s_aw1,s_awthl1,s_awqt1, & - & s_awqv1,s_awqc1, & - & s_awu1,s_awv1,s_awqke1, & - & s_awqnc1,s_awqni1, & - & s_awqnwfa1,s_awqnifa1, & - & sub_thl,sub_sqv, & - & sub_u,sub_v, & - & det_thl,det_sqv,det_sqc, & - & det_u,det_v, & + &s_aw1,s_awthl1,s_awqt1, & + &s_awqv1,s_awqc1, & + &s_awu1,s_awv1,s_awqke1, & + &s_awqnc1,s_awqni1, & + &s_awqnwfa1,s_awqnifa1,s_awqnbca1, & + &sub_thl,sub_sqv, & + &sub_u,sub_v, & + &det_thl,det_sqv,det_sqc, & + &det_u,det_v, & ! chem/smoke mixing - & nchem,chem1,s_awchem1, & - & mix_chem, & - & qc_bl1D,cldfra_bl1D, & - & qc_bl1D_old,cldfra_bl1D_old, & - & FLAG_QC,FLAG_QI, & - & FLAG_QNC,FLAG_QNI, & - & FLAG_QNWFA,FLAG_QNIFA, & - & Psig_shcu(i), & - & nupdraft(i),ktop_plume(i), & - & maxmf(i),ztop_plume, & - & spp_pbl,rstoch_col ) - ENDIF + &nchem,chem1,s_awchem1, & + &mix_chem, & + &qc_bl1D,cldfra_bl1D, & + &qc_bl1D_old,cldfra_bl1D_old, & + &FLAG_QC,FLAG_QI, & + &FLAG_QNC,FLAG_QNI, & + &FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & + &Psig_shcu(i), & + &nupdraft(i),ktop_plume(i), & + &maxmf(i),ztop_plume, & + &spp_pbl,rstoch_col ) + endif - IF (bl_mynn_edmf_dd == 1) THEN - CALL DDMF_JPL(kts,kte,delt,zw,dz1,p1, & - &u1,v1,th1,thl,thetav,tk1, & - sqw,sqv,sqc,rho1,ex1, & - &ust(i),flt,flq, & - &PBLH(i),KPBL(i), & - &edmf_a_dd1,edmf_w_dd1,edmf_qt_dd1, & - &edmf_thl_dd1,edmf_ent_dd1, & - &edmf_qc_dd1, & - &sd_aw1,sd_awthl1,sd_awqt1, & - &sd_awqv1,sd_awqc1,sd_awu1,sd_awv1, & - &sd_awqke1, & - &qc_bl1d,cldfra_bl1d, & - &rthraten(i,:) ) - ENDIF + if (bl_mynn_edmf_dd == 1) then + call DDMF_JPL(kts,kte,delt,zw,dz1,p1, & + &u1,v1,th1,thl,thetav,tk1, & + &sqw,sqv,sqc,rho1,ex1, & + &ust(i),flt,flq, & + &PBLH(i),KPBL(i), & + &edmf_a_dd1,edmf_w_dd1,edmf_qt_dd1, & + &edmf_thl_dd1,edmf_ent_dd1, & + &edmf_qc_dd1, & + &sd_aw1,sd_awthl1,sd_awqt1, & + &sd_awqv1,sd_awqc1,sd_awu1,sd_awv1, & + &sd_awqke1, & + &qc_bl1d,cldfra_bl1d, & + &rthraten(i,:) ) + endif - !Capability to substep the eddy-diffusivity portion - !do nsub = 1,2 - delt2 = delt !*0.5 !only works if topdown=0 - - CALL mym_turbulence ( & - &kts,kte,closure, & - &dz1, DX(i), zw, & - &u1, v1, thl, thetav, sqc, sqw, & - &thlsg, sqwsg, & - &qke1, tsq1, qsq1, cov1, & - &vt, vq, & - &rmol(i), flt, flq, & - &PBLH(i),th1, & - &Sh,Sm,el, & - &Dfm,Dfh,Dfq, & - &Tcd,Qcd,Pdk, & - &Pdt,Pdq,Pdc, & - &qWT1,qSHEAR1,qBUOY1,qDISS1, & - &bl_mynn_tkebudget, & - &Psig_bl(i),Psig_shcu(i), & - &cldfra_bl1D,bl_mynn_mixlength, & - &edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & - &TKEprodTD, & - &spp_pbl,rstoch_col) + !Capability to substep the eddy-diffusivity portion + !do nsub = 1,2 + delt2 = delt !*0.5 !only works if topdown=0 + + call mym_turbulence( & + &kts,kte,xland(i),closure, & + &dz1, DX(i), zw, & + &u1, v1, thl, thetav, sqc, sqw, & + &qke1, tsq1, qsq1, cov1, & + &vt, vq, & + &rmol(i), flt, fltv, flq, & + &PBLH(i),th1, & + &Sh,Sm,el, & + &Dfm,Dfh,Dfq, & + &Tcd,Qcd,Pdk, & + &Pdt,Pdq,Pdc, & + &qWT1,qSHEAR1,qBUOY1,qDISS1, & + &tke_budget, & + &Psig_bl(i),Psig_shcu(i), & + &cldfra_bl1D,bl_mynn_mixlength, & + &edmf_w1,edmf_a1, & + &TKEprodTD, & + &spp_pbl,rstoch_col ) !> - Call mym_predict() to solve TKE and !! \f$\theta^{'2}, q^{'2}, and \theta^{'}q^{'}\f$ !! for the following time step. - CALL mym_predict (kts,kte,closure, & - &delt2, dz1, & - &ust(i), flt, flq, pmz, phh, & - &el, dfq, rho1, pdk, pdt, pdq, pdc,& - &Qke1, Tsq1, Qsq1, Cov1, & - &s_aw1, s_awqke1, bl_mynn_edmf_tke,& - &qWT1, qDISS1,bl_mynn_tkebudget) !! TKE budget (Puhales, 2020) - - if (dheat_opt > 0) then - DO k=kts,kte-1 - ! Set max dissipative heating rate to 7.2 K per hour - diss_heat(k) = MIN(MAX(1.0*(qke1(k)**1.5)/(b1*MAX(0.5*(el(k)+el(k+1)),1.))/cp, 0.0),0.002) - ! Limit heating above 100 mb: - diss_heat(k) = diss_heat(k) * exp(-10000./MAX(p1(k),1.)) - ENDDO - diss_heat(kte) = 0. - else - diss_heat(1:kte) = 0. - endif + call mym_predict(kts,kte,closure, & + &delt2, dz1, & + &ust(i), flt, flq, pmz, phh, & + &el, dfq, rho1, pdk, pdt, pdq, pdc, & + &Qke1, Tsq1, Qsq1, Cov1, & + &s_aw1, s_awqke1, bl_mynn_edmf_tke, & + &qWT1, qDISS1, tke_budget ) + + if (dheat_opt > 0) then + do k=kts,kte-1 + ! Set max dissipative heating rate to 7.2 K per hour + diss_heat(k) = MIN(MAX(1.0*(qke1(k)**1.5)/(b1*MAX(0.5*(el(k)+el(k+1)),1.))/cp, 0.0),0.002) + ! Limit heating above 100 mb: + diss_heat(k) = diss_heat(k) * exp(-10000./MAX(p1(k),1.)) + enddo + diss_heat(kte) = 0. + else + diss_heat(1:kte) = 0. + endif !> - Call mynn_tendencies() to solve for tendencies of !! \f$U, V, \theta, q_{v}, q_{c}, and q_{i}\f$. - CALL mynn_tendencies(kts,kte,i, & - &closure, & - &delt, dz1, rho1, & - &u1, v1, th1, tk1, qv1, & - &qc1, qi1, qnc1, qni1, & - &ps(i), p1, ex1, thl, & - &sqv, sqc, sqi, sqw, & - &qnwfa1, qnifa1, ozone1, & - &ust(i),flt,flq,flqv,flqc, & - &wspd(i),uoce(i),voce(i), & - &tsq1, qsq1, cov1, & - &tcd, qcd, & - &dfm, dfh, dfq, & - &Du1, Dv1, Dth1, Dqv1, & - &Dqc1, Dqi1, Dqnc1, Dqni1, & - &Dqnwfa1, Dqnifa1, Dozone1, & - &vdfg(i), diss_heat, & + call mynn_tendencies(kts,kte,i, & + &delt, dz1, rho1, & + &u1, v1, th1, tk1, qv1, & + &qc1, qi1, qs1, qnc1, qni1, & + &ps(i), p1, ex1, thl, & + &sqv, sqc, sqi, sqs, sqw, & + &qnwfa1, qnifa1, qnbca1, ozone1, & + &ust(i),flt,flq,flqv,flqc, & + &wspd(i),uoce(i),voce(i), & + &tsq1, qsq1, cov1, & + &tcd, qcd, & + &dfm, dfh, dfq, & + &Du1, Dv1, Dth1, Dqv1, & + &Dqc1, Dqi1, Dqs1, Dqnc1, Dqni1, & + &Dqnwfa1, Dqnifa1, Dqnbca1, & + &Dozone1, & + &diss_heat, & ! mass flux components - &s_aw1,s_awthl1,s_awqt1, & - &s_awqv1,s_awqc1,s_awu1,s_awv1, & - &s_awqnc1,s_awqni1, & - &s_awqnwfa1,s_awqnifa1, & - &sd_aw1,sd_awthl1,sd_awqt1, & - &sd_awqv1,sd_awqc1, & - sd_awu1,sd_awv1, & - &sub_thl,sub_sqv, & - &sub_u,sub_v, & - &det_thl,det_sqv,det_sqc, & - &det_u,det_v, & - &FLAG_QC,FLAG_QI,FLAG_QNC, & - &FLAG_QNI,FLAG_QNWFA,FLAG_QNIFA, & - &cldfra_bl1d, & - &bl_mynn_cloudmix, & - &bl_mynn_mixqt, & - &bl_mynn_edmf, & - &bl_mynn_edmf_mom, & - &bl_mynn_mixscalars ) - - - IF ( rrfs_smoke .and. mix_chem ) THEN - CALL mynn_mix_chem(kts,kte,i, & - &delt, dz1, pblh(i), & - &nchem, kdvel, ndvel, & - &chem1, vd1, & - &rho1,flt, & - &tcd, qcd, & - &dfh, & - &s_aw1,s_awchem1, & - &emis_ant_no(i), & - &frp(i), & - &fire_turb ) - - DO ic = 1,nchem - DO k = kts,kte - chem3d(i,k,ic) = chem1(k,ic) - ENDDO - ENDDO - ENDIF + &s_aw1,s_awthl1,s_awqt1, & + &s_awqv1,s_awqc1,s_awu1,s_awv1, & + &s_awqnc1,s_awqni1, & + &s_awqnwfa1,s_awqnifa1,s_awqnbca1, & + &sd_aw1,sd_awthl1,sd_awqt1, & + &sd_awqv1,sd_awqc1, & + &sd_awu1,sd_awv1, & + &sub_thl,sub_sqv, & + &sub_u,sub_v, & + &det_thl,det_sqv,det_sqc, & + &det_u,det_v, & + &FLAG_QC,FLAG_QI,FLAG_QNC, & + &FLAG_QNI,FLAG_QS, & + &FLAG_QNWFA,FLAG_QNIFA, & + &FLAG_QNBCA, & + &cldfra_bl1d, & + &bl_mynn_cloudmix, & + &bl_mynn_mixqt, & + &bl_mynn_edmf, & + &bl_mynn_edmf_mom, & + &bl_mynn_mixscalars ) + + + if ( mix_chem ) then + if ( rrfs_sd ) then + call mynn_mix_chem(kts,kte,i, & + &delt, dz1, pblh(i), & + &nchem, kdvel, ndvel, & + &chem1, vd1, & + &rho1,flt, & + &tcd, qcd, & + &dfh, & + &s_aw1,s_awchem1, & + &emis_ant_no(i), & + &frp(i), rrfs_sd, & + &enh_mix, smoke_dbg ) + else + call mynn_mix_chem(kts,kte,i, & + &delt, dz1, pblh(i), & + &nchem, kdvel, ndvel, & + &chem1, vd1, & + &rho1,flt, & + &tcd, qcd, & + &dfh, & + &s_aw1,s_awchem1, & + &zero, & + &zero, rrfs_sd, & + &enh_mix, smoke_dbg ) + endif + do ic = 1,nchem + do k = kts,kte + chem3d(i,k,ic) = max(1.e-12, chem1(k,ic)) + enddo + enddo + endif - CALL retrieve_exchange_coeffs(kts,kte,& - &dfm, dfh, dz1, K_m1, K_h1) - - !UPDATE 3D ARRAYS - DO k=KTS,KTE !KTF - exch_m(i,k)=K_m1(k) - exch_h(i,k)=K_h1(k) - RUBLTEN(i,k)=du1(k) - RVBLTEN(i,k)=dv1(k) - RTHBLTEN(i,k)=dth1(k) - RQVBLTEN(i,k)=dqv1(k) - IF(bl_mynn_cloudmix > 0)THEN - IF (FLAG_QC) RQCBLTEN(i,k)=dqc1(k) - IF (FLAG_QI) RQIBLTEN(i,k)=dqi1(k) - ELSE - IF (FLAG_QC) RQCBLTEN(i,k)=0. - IF (FLAG_QI) RQIBLTEN(i,k)=0. - ENDIF - IF(bl_mynn_cloudmix > 0 .AND. bl_mynn_mixscalars > 0)THEN - IF (FLAG_QNC) RQNCBLTEN(i,k)=dqnc1(k) - IF (FLAG_QNI) RQNIBLTEN(i,k)=dqni1(k) - IF (FLAG_QNWFA) RQNWFABLTEN(i,k)=dqnwfa1(k) - IF (FLAG_QNIFA) RQNIFABLTEN(i,k)=dqnifa1(k) - ELSE - IF (FLAG_QNC) RQNCBLTEN(i,k)=0. - IF (FLAG_QNI) RQNIBLTEN(i,k)=0. - IF (FLAG_QNWFA) RQNWFABLTEN(i,k)=0. - IF (FLAG_QNIFA) RQNIFABLTEN(i,k)=0. - ENDIF - DOZONE(i,k)=DOZONE1(k) - - IF(icloud_bl > 0)THEN - !DIAGNOSTIC-DECAY FOR SUBGRID-SCALE CLOUDS - IF (CLDFRA_BL1D(k) < cldfra_bl1D_old(k)) THEN - !DECAY TIMESCALE FOR CALM CONDITION IS THE EDDY TURNOVER - !TIMESCALE, BUT FOR WINDY CONDITIONS, IT IS THE ADVECTIVE - !TIMESCALE. USE THE MINIMUM OF THE TWO. - ts_decay = MIN( 1800., 2.*dx(i)/MAX(SQRT(u1(k)**2 + v1(k)**2),1.0) ) - cldfra_bl(i,k)= MAX(cldfra_bl1D(k),cldfra_bl1D_old(k)-(0.25*delt/ts_decay)) - ! qc_bl2 and qi_bl2 are linked to decay rates - qc_bl2 = MAX(qc_bl1D(k),qc_bl1D_old(k)) - qi_bl2 = MAX(qi_bl1D(k),qi_bl1D_old(k)) - qc_bl(i,k) = MAX(qc_bl1D(k),qc_bl1D_old(k)-(MIN(qc_bl2,1.0E-5) * delt/ts_decay)) - qi_bl(i,k) = MAX(qi_bl1D(k),qi_bl1D_old(k)-(MIN(qi_bl2,1.0E-6) * delt/ts_decay)) - IF (cldfra_bl(i,k) < 0.005 .OR. & - (qc_bl(i,k) + qi_bl(i,k)) < 1E-9) THEN - CLDFRA_BL(i,k)= 0. - QC_BL(i,k) = 0. - QI_BL(i,k) = 0. - ENDIF - ELSE - qc_bl(i,k)=qc_bl1D(k) - qi_bl(i,k)=qi_bl1D(k) - cldfra_bl(i,k)=cldfra_bl1D(k) - ENDIF - ENDIF - - el_pbl(i,k)=el(k) - qke(i,k)=qke1(k) - tsq(i,k)=tsq1(k) - qsq(i,k)=qsq1(k) - cov(i,k)=cov1(k) - sh3d(i,k)=sh(k) - sm3d(i,k)=sm(k) - ENDDO !end-k - - IF ( bl_mynn_tkebudget ) THEN - !! TKE budget is now given in m**2/s**-3 (Puhales, 2020) - !! Lower boundary condtions (using similarity relationships such as the prognostic equation for Qke) - k=kts - qSHEAR1(k)=4.*(ust(i)**3*phi_m/(karman*dz(i,k)))-qSHEAR1(k+1) !! staggered - qBUOY1(k)=4.*(-ust(i)**3*zet/(karman*dz(i,k)))-qBUOY1(k+1) !! staggered - !! unstaggering SHEAR and BUOY and trasfering all TKE budget to 3D array - DO k = kts,kte-1 - qSHEAR(i,k)=0.5*(qSHEAR1(k)+qSHEAR1(k+1)) !!! unstaggering in z - qBUOY(i,k)=0.5*(qBUOY1(k)+qBUOY1(k+1)) !!! unstaggering in z - qWT(i,k)=qWT1(k) - qDISS(i,k)=qDISS1(k) - dqke(i,k)=(qke1(k)-dqke(i,k))*0.5/delt - ENDDO - !! Upper boundary conditions - k=kte - qSHEAR(i,k)=0. - qBUOY(i,k)=0. - qWT(i,k)=0. - qDISS(i,k)=0. - dqke(i,k)=0. - ENDIF + call retrieve_exchange_coeffs(kts,kte, & + &dfm, dfh, dz1, K_m1, K_h1 ) + + !UPDATE 3D ARRAYS + exch_m(i,:) =k_m1(:) + exch_h(i,:) =k_h1(:) + rublten(i,:) =du1(:) + rvblten(i,:) =dv1(:) + rthblten(i,:)=dth1(:) + rqvblten(i,:)=dqv1(:) + if (bl_mynn_cloudmix > 0) then + if (flag_qc) rqcblten(i,:)=dqc1(:) + if (flag_qi) rqiblten(i,:)=dqi1(:) + if (flag_qs) rqsblten(i,:)=dqs1(:) + else + if (flag_qc) rqcblten(i,:)=0. + if (flag_qi) rqiblten(i,:)=0. + if (flag_qs) rqsblten(i,:)=0. + endif + if (bl_mynn_cloudmix > 0 .and. bl_mynn_mixscalars > 0) then + if (flag_qnc) rqncblten(i,:) =dqnc1(:) + if (flag_qni) rqniblten(i,:) =dqni1(:) + if (flag_qnwfa) rqnwfablten(i,:)=dqnwfa1(:) + if (flag_qnifa) rqnifablten(i,:)=dqnifa1(:) + if (flag_qnbca) rqnbcablten(i,:)=dqnbca1(:) + else + if (flag_qnc) rqncblten(i,:) =0. + if (flag_qni) rqniblten(i,:) =0. + if (flag_qnwfa) rqnwfablten(i,:)=0. + if (flag_qnifa) rqnifablten(i,:)=0. + if (flag_qnbca) rqnbcablten(i,:)=0. + endif + dozone(i,:)=dozone1(:) + if (icloud_bl > 0) then + qc_bl(i,:) =qc_bl1D(:) + qi_bl(i,:) =qi_bl1D(:) + cldfra_bl(i,:)=cldfra_bl1D(:) + endif + el_pbl(i,:)=el(:) + qke(i,:) =qke1(:) + tsq(i,:) =tsq1(:) + qsq(i,:) =qsq1(:) + cov(i,:) =cov1(:) + sh3d(i,:) =sh(:) + sm3d(i,:) =sm(:) + + if (tke_budget .eq. 1) then + !! TKE budget is now given in m**2/s**-3 (Puhales, 2020) + !! Lower boundary condtions (using similarity relationships such as the prognostic equation for Qke) + k=kts + qSHEAR1(k) =4.*(ust(i)**3*phi_m/(karman*dz(i,k)))-qSHEAR1(k+1) !! staggered + qBUOY1(k) =4.*(-ust(i)**3*zet/(karman*dz(i,k)))-qBUOY1(k+1) !! staggered + !! unstaggering SHEAR and BUOY and trasfering all TKE budget to 3D array + do k = kts,kte-1 + qSHEAR(i,k)=0.5*(qSHEAR1(k)+qSHEAR1(k+1)) !!! unstaggering in z + qBUOY(i,k) =0.5*(qBUOY1(k)+qBUOY1(k+1)) !!! unstaggering in z + qWT(i,k) =qWT1(k) + qDISS(i,k) =qDISS1(k) + dqke(i,k) =(qke1(k)-dqke(i,k))*0.5/delt + enddo + !! Upper boundary conditions + k=kte + qSHEAR(i,k) =0. + qBUOY(i,k) =0. + qWT(i,k) =0. + qDISS(i,k) =0. + dqke(i,k) =0. + endif - !update updraft/downdraft properties - if (bl_mynn_output > 0) THEN !research mode == 1 - if (bl_mynn_edmf > 0) THEN - DO k = kts,kte - edmf_a(i,k)=edmf_a1(k) - edmf_w(i,k)=edmf_w1(k) - edmf_qt(i,k)=edmf_qt1(k) - edmf_thl(i,k)=edmf_thl1(k) - edmf_ent(i,k)=edmf_ent1(k) - edmf_qc(i,k)=edmf_qc1(k) - sub_thl3D(i,k)=sub_thl(k) - sub_sqv3D(i,k)=sub_sqv(k) - det_thl3D(i,k)=det_thl(k) - det_sqv3D(i,k)=det_sqv(k) - ENDDO - endif -! if (bl_mynn_edmf_dd > 0) THEN -! DO k = kts,kte -! edmf_a_dd(i,k)=edmf_a_dd1(k) -! edmf_w_dd(i,k)=edmf_w_dd1(k) -! edmf_qt_dd(i,k)=edmf_qt_dd1(k) -! edmf_thl_dd(i,k)=edmf_thl_dd1(k) -! edmf_ent_dd(i,k)=edmf_ent_dd1(k) -! edmf_qc_dd(i,k)=edmf_qc_dd1(k) -! ENDDO -! ENDIF - ENDIF + !update updraft/downdraft properties + if (bl_mynn_output > 0) then !research mode == 1 + if (bl_mynn_edmf > 0) then + edmf_a(i,:) =edmf_a1(:) + edmf_w(i,:) =edmf_w1(:) + edmf_qt(i,:) =edmf_qt1(:) + edmf_thl(i,:) =edmf_thl1(:) + edmf_ent(i,:) =edmf_ent1(:) + edmf_qc(i,:) =edmf_qc1(:) + sub_thl3D(i,:)=sub_thl(:) + sub_sqv3D(i,:)=sub_sqv(:) + det_thl3D(i,:)=det_thl(:) + det_sqv3D(i,:)=det_sqv(:) + endif + !if (bl_mynn_edmf_dd > 0) THEN + ! edmf_a_dd(i,:) =edmf_a_dd1(:) + ! edmf_w_dd(i,:) =edmf_w_dd1(:) + ! edmf_qt_dd(i,:) =edmf_qt_dd1(:) + ! edmf_thl_dd(i,:)=edmf_thl_dd1(:) + ! edmf_ent_dd(i,:)=edmf_ent_dd1(:) + ! edmf_qc_dd(i,:) =edmf_qc_dd1(:) + !endif + endif - !*** Begin debug prints - IF ( debug_code .and. (i .eq. idbg)) THEN - IF ( ABS(QFX(i))>.001)print*,& - "SUSPICIOUS VALUES AT: i=",i," QFX=",QFX(i) - IF ( ABS(HFX(i))>1100.)print*,& - "SUSPICIOUS VALUES AT: i=",i," HFX=",HFX(i) - DO k = kts,kte - IF ( sh(k) < 0. .OR. sh(k)> 200.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," sh=",sh(k) - IF ( ABS(vt(k)) > 0.9 )print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," vt=",vt(k) - IF ( ABS(vq(k)) > 6000.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," vq=",vq(k) - IF ( qke(i,k) < -1. .OR. qke(i,k)> 200.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," qke=",qke(i,k) - IF ( el_pbl(i,k) < 0. .OR. el_pbl(i,k)> 1500.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," el_pbl=",el_pbl(i,k) - IF ( exch_m(i,k) < 0. .OR. exch_m(i,k)> 2000.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," exxch_m=",exch_m(i,k) - IF (icloud_bl > 0) then - IF( cldfra_bl(i,k) < 0.0 .OR. cldfra_bl(i,k)> 1.)THEN - PRINT*,"SUSPICIOUS VALUES: CLDFRA_BL=",cldfra_bl(i,k)," qc_bl=",QC_BL(i,k) - ENDIF - ENDIF - - !IF (I==IMD .AND. J==JMD) THEN - ! PRINT*,"MYNN DRIVER END: k=",k," sh=",sh(k) - ! PRINT*," sqw=",sqw(k)," thl=",thl(k)," exch_m=",exch_m(i,k) - ! PRINT*," xland=",xland(i)," rmol=",rmol(i)," ust=",ust(i) - ! PRINT*," qke=",qke(i,k)," el=",el_pbl(i,k)," tsq=",tsq(i,k) - ! PRINT*," PBLH=",PBLH(i)," u=",u(i,k)," v=",v(i,k) - ! PRINT*," vq=",vq(k)," vt=",vt(k)," vdfg=",vdfg(i) - !ENDIF - ENDDO !end-k - ENDIF - !*** End debug prints + !*** Begin debug prints + if ( debug_code .and. (i .eq. idbg)) THEN + if ( ABS(QFX(i))>.001)print*,& + "SUSPICIOUS VALUES AT: i=",i," QFX=",QFX(i) + if ( ABS(HFX(i))>1100.)print*,& + "SUSPICIOUS VALUES AT: i=",i," HFX=",HFX(i) + do k = kts,kte + IF ( sh(k) < 0. .OR. sh(k)> 200.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," sh=",sh(k) + IF ( ABS(vt(k)) > 2.0 )print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," vt=",vt(k) + IF ( ABS(vq(k)) > 7000.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," vq=",vq(k) + IF ( qke(i,k) < -1. .OR. qke(i,k)> 200.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," qke=",qke(i,k) + IF ( el_pbl(i,k) < 0. .OR. el_pbl(i,k)> 1500.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," el_pbl=",el_pbl(i,k) + IF ( exch_m(i,k) < 0. .OR. exch_m(i,k)> 2000.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," exxch_m=",exch_m(i,k) + IF (icloud_bl > 0) then + IF ( cldfra_bl(i,k) < 0.0 .OR. cldfra_bl(i,k)> 1.)THEN + PRINT*,"SUSPICIOUS VALUES: CLDFRA_BL=",cldfra_bl(i,k)," qc_bl=",QC_BL(i,k) + ENDIF + ENDIF - !JOE-add tke_pbl for coupling w/shallow-cu schemes (TKE_PBL = QKE/2.) - ! TKE_PBL is defined on interfaces, while QKE is at middle of layer. - !tke_pbl(i,kts) = 0.5*MAX(qke(i,kts),1.0e-10) - !DO k = kts+1,kte - ! afk = dz1(k)/( dz1(k)+dz1(k-1) ) - ! abk = 1.0 -afk - ! tke_pbl(i,k) = 0.5*MAX(qke(i,k)*abk+qke(i,k-1)*afk,1.0e-3) - !ENDDO + !IF (I==IMD .AND. J==JMD) THEN + ! PRINT*,"MYNN DRIVER END: k=",k," sh=",sh(k) + ! PRINT*," sqw=",sqw(k)," thl=",thl(k)," exch_m=",exch_m(i,k) + ! PRINT*," xland=",xland(i)," rmol=",rmol(i)," ust=",ust(i) + ! PRINT*," qke=",qke(i,k)," el=",el_pbl(i,k)," tsq=",tsq(i,k) + ! PRINT*," PBLH=",PBLH(i)," u=",u(i,k)," v=",v(i,k) + ! PRINT*," vq=",vq(k)," vt=",vt(k) + !ENDIF + enddo !end-k + endif - ENDDO !end i-loop + enddo !end i-loop !ACF copy qke into qke_adv if using advection IF (bl_mynn_tkeadvect) THEN @@ -1549,13 +1431,7 @@ END SUBROUTINE mynn_bl_driver !> @} !======================================================================= -!> This subroutine gives the closure constants and initializes the -!! turbulent qantities. ! SUBROUTINE mym_initialize: -! ================================================================== -! This subroutine computes the length scales up and down -! and then computes the min, average of the up/down length scales, and also -! considers the distance to the surface. ! ! Input variables: ! iniflag : <>0; turbulent quantities will be initialized @@ -1607,47 +1483,44 @@ END SUBROUTINE mynn_bl_driver ! !------------------------------------------------------------------- -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine initializes the mixing length, TKE, \f$\theta^{'2}\f$, !! \f$q^{'2}\f$, and \f$\theta^{'}q^{'}\f$. !!\section gen_mym_ini GSD MYNN-EDMF mym_initialize General Algorithm !> @{ SUBROUTINE mym_initialize ( & - & kts,kte, & + & kts,kte,xland, & & dz, dx, zw, & & u, v, thl, qw, & - & thlsg, qwsg, & ! & ust, rmo, pmz, phh, flt, flq, & & zi, theta, thetav, sh, sm, & & ust, rmo, el, & & Qke, Tsq, Qsq, Cov, Psig_bl, cldfra_bl1D, & & bl_mynn_mixlength, & - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & + & edmf_w1,edmf_a1, & & INITIALIZE_QKE, & & spp_pbl,rstoch_col) ! !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte - INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf + INTEGER, INTENT(IN) :: bl_mynn_mixlength LOGICAL, INTENT(IN) :: INITIALIZE_QKE ! REAL, INTENT(IN) :: ust, rmo, pmz, phh, flt, flq - REAL, INTENT(IN) :: ust, rmo, Psig_bl, dx + REAL, INTENT(IN) :: rmo, Psig_bl, xland + REAL(kind=kind_phys), INTENT(IN) :: dx, ust, zi REAL, DIMENSION(kts:kte), INTENT(in) :: dz REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,cldfra_bl1D,& - edmf_w1,edmf_a1,edmf_qc1 + edmf_w1,edmf_a1 REAL, DIMENSION(kts:kte), INTENT(out) :: tsq,qsq,cov REAL, DIMENSION(kts:kte), INTENT(inout) :: el,qke - REAL, DIMENSION(kts:kte) :: & &ql,pdk,pdt,pdq,pdc,dtl,dqw,dtv,& &gm,gh,sm,sh,qkw,vt,vq INTEGER :: k,l,lmax - REAL :: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1.,flt=0.,flq=0.,tmpq - REAL :: zi - REAL, DIMENSION(kts:kte) :: theta,thetav,thlsg,qwsg - + REAL :: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1.,flt=0.,fltv=0.,flq=0.,tmpq + REAL, DIMENSION(kts:kte) :: theta,thetav REAL, DIMENSION(kts:kte) :: rstoch_col INTEGER ::spp_pbl @@ -1662,7 +1535,6 @@ SUBROUTINE mym_initialize ( & CALL mym_level2 ( kts,kte, & & dz, & & u, v, thl, thetav, qw, & - & thlsg, qwsg, & & ql, vt, vq, & & dtl, dqw, dtv, gm, gh, sm, sh ) ! @@ -1701,17 +1573,18 @@ SUBROUTINE mym_initialize ( & DO l = 1,lmax ! !> - call mym_length() to calculate the master length scale. - CALL mym_length ( & - & kts,kte, & - & dz, dx, zw, & - & rmo, flt, flq, & - & vt, vq, & - & u, v, qke, & - & dtv, & - & el, & - & zi,theta, & - & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength,& - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf) + CALL mym_length ( & + & kts,kte,xland, & + & dz, dx, zw, & + & rmo, flt, fltv, flq, & + & vt, vq, & + & u, v, qke, & + & dtv, & + & el, & + & zi,theta, & + & qkw,Psig_bl,cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1 ) ! DO k = kts+1,kte elq = el(k)*qkw(k) @@ -1795,7 +1668,7 @@ END SUBROUTINE mym_initialize ! These are defined on the walls of the grid boxes. ! -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the level 2, non-dimensional wind shear !! \f$G_M\f$ and vertical temperature gradient \f$G_H\f$ as well as !! the level 2 stability funcitons \f$S_h\f$ and \f$S_m\f$. @@ -1821,7 +1694,6 @@ END SUBROUTINE mym_initialize SUBROUTINE mym_level2 (kts,kte, & & dz, & & u, v, thl, thetav, qw, & - & thlsg, qwsg, & & ql, vt, vq, & & dtl, dqw, dtv, gm, gh, sm, sh ) ! @@ -1836,7 +1708,7 @@ SUBROUTINE mym_level2 (kts,kte, & REAL, DIMENSION(kts:kte), INTENT(in) :: dz REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,ql,vt,vq,& - thetav,thlsg,qwsg + thetav REAL, DIMENSION(kts:kte), INTENT(out) :: & &dtl,dqw,dtv,gm,gh,sm,sh @@ -1873,11 +1745,7 @@ SUBROUTINE mym_level2 (kts,kte, & duz = ( u(k)-u(k-1) )**2 +( v(k)-v(k-1) )**2 duz = duz /dzk**2 dtz = ( thl(k)-thl(k-1) )/( dzk ) - !Alternatively, use SGS clouds for thl - !dtz = ( thlsg(k)-thlsg(k-1) )/( dzk ) dqz = ( qw(k)-qw(k-1) )/( dzk ) - !Alternatively, use SGS clouds for qw - !dqz = ( qwsg(k)-qwsg(k-1) )/( dzk ) ! vtt = 1.0 +vt(k)*abk +vt(k-1)*afk ! Beta-theta in NN09, Eq. 39 vqq = tv0 +vq(k)*abk +vq(k-1)*afk ! Beta-q @@ -1951,19 +1819,21 @@ END SUBROUTINE mym_level2 ! NOTE: the mixing lengths are meant to be calculated at the full- ! sigmal levels (or interfaces beween the model layers). ! -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the mixing lengths. SUBROUTINE mym_length ( & - & kts,kte, & + & kts,kte,xland, & & dz, dx, zw, & - & rmo, flt, flq, & + & rmo, flt, fltv, flq, & & vt, vq, & & u1, v1, qke, & & dtv, & & el, & - & zi,theta, & - & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength,& - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf) + & zi, theta, qkw, & + & Psig_bl, cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1 ) + !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte @@ -1973,12 +1843,13 @@ SUBROUTINE mym_length ( & # define kte HARDCODE_VERTICAL #endif - INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf + INTEGER, INTENT(IN) :: bl_mynn_mixlength REAL, DIMENSION(kts:kte), INTENT(in) :: dz REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,flq,Psig_bl,dx + REAL, INTENT(in) :: rmo,flt,fltv,flq,Psig_bl,xland + REAL(kind=kind_phys), INTENT(IN) :: dx,zi REAL, DIMENSION(kts:kte), INTENT(IN) :: u1,v1,qke,vt,vq,cldfra_bl1D,& - edmf_w1,edmf_a1,edmf_qc1 + edmf_w1,edmf_a1 REAL, DIMENSION(kts:kte), INTENT(out) :: qkw, el REAL, DIMENSION(kts:kte), INTENT(in) :: dtv @@ -1986,7 +1857,7 @@ SUBROUTINE mym_length ( & REAL, DIMENSION(kts:kte), INTENT(IN) :: theta REAL, DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg,thetaw - REAL :: wt,wt2,zi,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg + REAL :: wt,wt2,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg ! THE FOLLOWING CONSTANTS ARE IMPORTANT FOR REGULATING THE ! MIXING LENGTHS: @@ -2011,13 +1882,12 @@ SUBROUTINE mym_length ( & !SURFACE LAYER LENGTH SCALE MODS TO REDUCE IMPACT IN UPPER BOUNDARY LAYER REAL, PARAMETER :: ZSLH = 100. !< Max height correlated to surface conditions (m) REAL, PARAMETER :: CSL = 2. !< CSL = constant of proportionality to L O(1) - REAL :: z_m INTEGER :: i,j,k REAL :: afk,abk,zwk,zwk1,dzk,qdz,vflx,bv,tau_cloud,wstar,elb,els, & - & els1,elf,el_stab,el_unstab,el_mf,el_stab_mf,elb_mf, & - & PBLH_PLUS_ENT,Uonset,Ugrid,el_les + & elf,el_stab,el_mf,el_stab_mf,elb_mf, & + & PBLH_PLUS_ENT,Uonset,Ugrid,wt_u,el_les REAL, PARAMETER :: ctau = 1000. !constant for tau_cloud ! tv0 = 0.61*tref @@ -2028,7 +1898,7 @@ SUBROUTINE mym_length ( & CASE (0) ! ORIGINAL MYNN MIXING LENGTH + BouLac cns = 2.7 - alp1 = 0.21 + alp1 = 0.23 alp2 = 1.0 alp3 = 5.0 alp4 = 100. @@ -2086,15 +1956,11 @@ SUBROUTINE mym_length ( & elf = elb ENDIF - z_m = MAX(0.,zwk - 4.) - ! ** Length scale in the surface layer ** IF ( rmo .GT. 0.0 ) THEN els = karman*zwk/(1.0+cns*MIN( zwk*rmo, zmax )) - els1 = karman*z_m/(1.0+cns*MIN( zwk*rmo, zmax )) ELSE els = karman*zwk*( 1.0 - alp4* zwk*rmo )**0.2 - els1 = karman*z_m*( 1.0 - alp4* zwk*rmo )**0.2 END IF ! ** HARMONC AVERGING OF MIXING LENGTH SCALES: @@ -2109,18 +1975,21 @@ SUBROUTINE mym_length ( & CASE (1) !NONLOCAL (using BouLac) FORM OF MIXING LENGTH - cns = 3.5 - alp1 = 0.21 + ugrid = sqrt(u1(kts)**2 + v1(kts)**2) + uonset= 15. + wt_u = (1.0 - min(max(ugrid - uonset, 0.0)/30.0, 0.5)) + cns = 2.7 !was 3.5 + alp1 = 0.22 alp2 = 0.3 - alp3 = 1.5 + alp3 = 2.0 * wt_u !taper off bouyancy enhancement in shear-driven pbls alp4 = 5.0 alp5 = 0.3 alp6 = 50. ! Impose limits on the height integration for elt and the transition layer depth - zi2=MAX(zi,200.) !minzi) - h1=MAX(0.3*zi2,200.) - h1=MIN(h1,500.) ! 1/2 transition layer depth + zi2=MAX(zi,300.) !minzi) + h1=MAX(0.3*zi2,300.) + h1=MIN(h1,600.) ! 1/2 transition layer depth h2=h1/2.0 ! 1/4 transition layer depth qtke(kts)=MAX(0.5*qke(kts), 0.01) !tke at full sigma levels @@ -2143,7 +2012,7 @@ SUBROUTINE mym_length ( & zwk = zw(k) DO WHILE (zwk .LE. zi2+h1) dzk = 0.5*( dz(k)+dz(k-1) ) - qdz = MAX( qkw(k)-qmin, 0.03 )*dzk + qdz = min(max( qkw(k)-qmin, 0.03 ), 30.0)*dzk elt = elt +qdz*zwk vsc = vsc +qdz k = k+1 @@ -2151,7 +2020,9 @@ SUBROUTINE mym_length ( & END DO elt = MIN( MAX( alp1*elt/vsc, 10.), 400.) - vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq + !avoid use of buoyancy flux functions which are ill-defined at the surface + !vflx = ( vt(kts)+1.0 )*flt + ( vq(kts)+tv0 )*flq + vflx = fltv vsc = ( gtr*elt*MAX( vflx, 0.0 ) )**onethird ! ** Strictly, el(i,j,1) is not zero. ** @@ -2166,31 +2037,23 @@ SUBROUTINE mym_length ( & ! ** Length scale limited by the buoyancy effect ** IF ( dtv(k) .GT. 0.0 ) THEN - alp2 = 0.3 + 0.15*0.5*(cldfra_bl1D(k)+cldfra_bl1D(k-1)) - bv = SQRT( gtr*dtv(k) ) - !elb = alp2*qkw(k) / bv & ! formulation, - ! & *( 1.0 + alp3/alp2*& ! except keep - ! &SQRT( vsc/( bv*elt ) ) ) ! elb bounded by zwk - elb = MAX(alp2*qkw(k), & - & alp6*edmf_a1(k)*edmf_w1(k)) / bv & + bv = max( sqrt( gtr*dtv(k) ), 0.001) + elb = MAX(alp2*qkw(k), & + & alp6*edmf_a1(k-1)*edmf_w1(k-1)) / bv & & *( 1.0 + alp3*SQRT( vsc/(bv*elt) ) ) elb = MIN(elb, zwk) - elf = 0.65 * qkw(k)/bv - !elBLavg(k) = MAX(elBLavg(k), alp6*edmf_a1(k)*edmf_w1(k)/bv) + elf = 0.80 * qkw(k)/bv + elBLavg(k) = MAX(elBLavg(k), alp6*edmf_a1(k-1)*edmf_w1(k-1)/bv) ELSE elb = 1.0e10 elf = elb ENDIF - z_m = MAX(0.,zwk - 4.) - ! ** Length scale in the surface layer ** IF ( rmo .GT. 0.0 ) THEN els = karman*zwk/(1.0+cns*MIN( zwk*rmo, zmax )) - els1 = karman*z_m/(1.0+cns*MIN( zwk*rmo, zmax )) ELSE els = karman*zwk*( 1.0 - alp4* zwk*rmo )**0.2 - els1 = karman*z_m*( 1.0 - alp4* zwk*rmo )**0.2 END IF ! ** NOW BLEND THE MIXING LENGTH SCALES: @@ -2200,8 +2063,7 @@ SUBROUTINE mym_length ( & !defined relative to the PBLH (zi) + transition layer (h1) !el(k) = MIN(elb/( elb/elt+elb/els+1.0 ),elf) !try squared-blending - !el_unstab = SQRT( els**2/(1. + (els1**2/elt**2) )) - el(k) = SQRT( els**2/(1. + (els1**2/elt**2) +(els1**2/elb**2))) + el(k) = SQRT( els**2/(1. + (els**2/elt**2) +(els**2/elb**2))) el(k) = MIN (el(k), elf) el(k) = el(k)*(1.-wt) + alp5*elBLavg(k)*wt @@ -2215,20 +2077,20 @@ SUBROUTINE mym_length ( & Uonset = 3.5 + dz(kts)*0.1 Ugrid = sqrt(u1(kts)**2 + v1(kts)**2) cns = 3.5 !JOE-test * (1.0 - MIN(MAX(Ugrid - Uonset, 0.0)/10.0, 1.0)) - alp1 = 0.21 + alp1 = 0.22 alp2 = 0.30 - alp3 = 1.5 + alp3 = 2.0 alp4 = 5.0 alp5 = alp2 !like alp2, but for free atmosphere alp6 = 50.0 !used for MF mixing length ! Impose limits on the height integration for elt and the transition layer depth !zi2=MAX(zi,minzi) - zi2=MAX(zi, 200.) + zi2=MAX(zi, 300.) !h1=MAX(0.3*zi2,mindz) !h1=MIN(h1,maxdz) ! 1/2 transition layer depth - h1=MAX(0.3*zi2,200.) - h1=MIN(h1,500.) + h1=MAX(0.3*zi2,300.) + h1=MIN(h1,600.) h2=h1*0.5 ! 1/4 transition layer depth qtke(kts)=MAX(0.5*qke(kts),0.01) !tke at full sigma levels @@ -2250,7 +2112,7 @@ SUBROUTINE mym_length ( & zwk = zw(k) DO WHILE (zwk .LE. PBLH_PLUS_ENT) dzk = 0.5*( dz(k)+dz(k-1) ) - qdz = MAX( qkw(k)-qmin, 0.03 )*dzk + qdz = min(max( qkw(k)-qmin, 0.03 ), 30.0)*dzk elt = elt +qdz*zwk vsc = vsc +qdz k = k+1 @@ -2258,7 +2120,9 @@ SUBROUTINE mym_length ( & END DO elt = MIN( MAX(alp1*elt/vsc, 10.), 400.) - vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq + !avoid use of buoyancy flux functions which are ill-defined at the surface + !vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq + vflx = fltv vsc = ( gtr*elt*MAX( vflx, 0.0 ) )**onethird ! ** Strictly, el(i,j,1) is not zero. ** @@ -2276,7 +2140,7 @@ SUBROUTINE mym_length ( & bv = MAX( SQRT( gtr*dtv(k) ), 0.001) !elb_mf = alp2*qkw(k) / bv & elb_mf = MAX(alp2*qkw(k), & - & alp6*edmf_a1(k)*edmf_w1(k)) / bv & + & alp6*edmf_a1(k-1)*edmf_w1(k-1)) / bv & & *( 1.0 + alp3*SQRT( vsc/( bv*elt ) ) ) elb = MIN(MAX(alp5*qkw(k), alp6*edmf_a1(k)*edmf_w1(k))/bv, zwk) @@ -2321,33 +2185,24 @@ SUBROUTINE mym_length ( & elb_mf = elb END IF elf = elf/(1. + (elf/800.)) !bound free-atmos mixing length to < 800 m. -! elb_mf = elb_mf/(1. + (elb_mf/800.)) !bound buoyancy mixing length to < 800 m. elb_mf = MAX(elb_mf, 0.01) !to avoid divide-by-zero below - z_m = MAX(0.,zwk - 4.) - ! ** Length scale in the surface layer ** IF ( rmo .GT. 0.0 ) THEN els = karman*zwk/(1.0+cns*MIN( zwk*rmo, zmax )) - els1 = karman*z_m/(1.0+cns*MIN( zwk*rmo, zmax )) ELSE els = karman*zwk*( 1.0 - alp4* zwk*rmo )**0.2 - els1 = karman*z_m*( 1.0 - alp4* zwk*rmo )**0.2 END IF ! ** NOW BLEND THE MIXING LENGTH SCALES: wt=.5*TANH((zwk - (zi2+h1))/h2) + .5 - ! "el_unstab" = blended els-elt - !el_unstab = els/(1. + (els1/elt)) !try squared-blending - !el(k) = SQRT( els**2/(1. + (els1**2/elt**2) )) - el(k) = SQRT( els**2/(1. + (els1**2/elt**2) +(els1**2/elb_mf**2))) - !el(k) = MIN(el_unstab, elb_mf) + el(k) = SQRT( els**2/(1. + (els**2/elt**2) +(els**2/elb_mf**2))) el(k) = el(k)*(1.-wt) + elf*wt - ! include scale-awareness. For now, use simple asymptotic kz -> 12 m. - el_les= MIN(els/(1. + (els1/12.)), elb_mf) + ! include scale-awareness. For now, use simple asymptotic kz -> 12 m (should be ~dz). + el_les= MIN(els/(1. + (els/12.)), elb_mf) el(k) = el(k)*Psig_bl + (1.-Psig_bl)*el_les END DO @@ -2363,7 +2218,7 @@ SUBROUTINE mym_length ( & END SUBROUTINE mym_length ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine was taken from the BouLac scheme in WRF-ARW and modified for !! integration into the MYNN PBL scheme. WHILE loops were added to reduce the !! computational expense. This subroutine computes the length scales up and down @@ -2526,7 +2381,7 @@ SUBROUTINE boulac_length0(k,kts,kte,zw,dz,qtke,theta,lb1,lb2) END SUBROUTINE boulac_length0 ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine was taken from the BouLac scheme in WRF-ARW !! and modified for integration into the MYNN PBL scheme. !! WHILE loops were added to reduce the computational expense. @@ -2717,7 +2572,7 @@ END SUBROUTINE boulac_length ! # dtl, dqw, dtv, gm and gh are allowed to share storage units with ! dfm, dfh, dfq, tcd and qcd, respectively, for saving memory. ! -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the vertical diffusivity coefficients and the !! production terms for the turbulent quantities. !>\section gen_mym_turbulence GSD mym_turbulence General Algorithm @@ -2733,29 +2588,30 @@ END SUBROUTINE boulac_length !! - Production terms of TKE,\f$\theta^{'2}\f$,\f$q^{'2}\f$, and \f$\theta^{'}q^{'}\f$ !! are calculated. !! - Eddy diffusivity \f$K_h\f$ and eddy viscosity \f$K_m\f$ are calculated. -!! - TKE budget terms are calculated (if the namelist parameter \p bl_mynn_tkebudget +!! - TKE budget terms are calculated (if the namelist parameter \p tke_budget !! is set to True) SUBROUTINE mym_turbulence ( & & kts,kte, & - & closure, & + & xland,closure, & & dz, dx, zw, & & u, v, thl, thetav, ql, qw, & - & thlsg, qwsg, & & qke, tsq, qsq, cov, & & vt, vq, & - & rmo, flt, flq, & + & rmo, flt, fltv, flq, & & zi,theta, & & sh, sm, & & El, & & Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, & & qWT1D,qSHEAR1D,qBUOY1D,qDISS1D, & - & bl_mynn_tkebudget, & - & Psig_bl,Psig_shcu,cldfra_bl1D,bl_mynn_mixlength,& - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & + & tke_budget, & + & Psig_bl,Psig_shcu,cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1, & & TKEprodTD, & - & spp_pbl,rstoch_col) + & spp_pbl,rstoch_col ) + !------------------------------------------------------------------- -! + INTEGER, INTENT(IN) :: kts,kte #ifdef HARDCODE_VERTICAL @@ -2763,39 +2619,39 @@ SUBROUTINE mym_turbulence ( & # define kte HARDCODE_VERTICAL #endif - INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf - REAL, INTENT(IN) :: closure - REAL, DIMENSION(kts:kte), INTENT(in) :: dz + INTEGER, INTENT(IN) :: bl_mynn_mixlength,tke_budget + REAL(kind=kind_phys), INTENT(IN) :: closure + REAL, DIMENSION(kts:kte), INTENT(in) :: dz REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,flq,Psig_bl,Psig_shcu,dx - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,thetav,qw,& - &ql,vt,vq,qke,tsq,qsq,cov,cldfra_bl1D,edmf_w1,edmf_a1,edmf_qc1,& - &TKEprodTD,thlsg,qwsg + REAL, INTENT(in) :: rmo,flt,fltv,flq,Psig_bl,Psig_shcu,xland + REAL(kind=kind_phys), INTENT(IN) :: dx,zi + REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,thetav,qw, & + &ql,vt,vq,qke,tsq,qsq,cov,cldfra_bl1D,edmf_w1,edmf_a1, & + &TKEprodTD - REAL, DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq,& + REAL, DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq, & &pdk,pdt,pdq,pdc,tcd,qcd,el - REAL, DIMENSION(kts:kte), INTENT(inout) :: & + REAL, DIMENSION(kts:kte), INTENT(inout) :: & qWT1D,qSHEAR1D,qBUOY1D,qDISS1D REAL :: q3sq_old,dlsq1,qWTP_old,qWTP_new - REAL :: dudz,dvdz,dTdz,& + REAL :: dudz,dvdz,dTdz, & upwp,vpwp,Tpwp - LOGICAL, INTENT(in) :: bl_mynn_tkebudget REAL, DIMENSION(kts:kte) :: qkw,dtl,dqw,dtv,gm,gh,sm,sh INTEGER :: k ! REAL :: cc2,cc3,e1c,e2c,e3c,e4c,e5c - REAL :: e6c,dzk,afk,abk,vtt,vqq,& + REAL :: e6c,dzk,afk,abk,vtt,vqq, & &cw25,clow,cupp,gamt,gamq,smd,gamv,elq,elh - REAL :: zi, cldavg + REAL :: cldavg REAL, DIMENSION(kts:kte), INTENT(in) :: theta REAL :: a2fac, duz, ri !JOE-Canuto/Kitamura mod - REAL:: auh,aum,adh,adm,aeh,aem,Req,Rsl,Rsl2,& - gmelq,sm20,sh20,sm25max,sh25max,sm25min,sh25min,& + REAL:: auh,aum,adh,adm,aeh,aem,Req,Rsl,Rsl2, & + gmelq,sm20,sh20,sm25max,sh25max,sm25min,sh25min, & sm_pbl,sh_pbl,zi2,wt,slht,wtpr DOUBLE PRECISION q2sq, t2sq, r2sq, c2sq, elsq, gmel, ghel @@ -2805,7 +2661,7 @@ SUBROUTINE mym_turbulence ( & ! Stochastic INTEGER, INTENT(IN) :: spp_pbl REAL, DIMENSION(KTS:KTE) :: rstoch_col - REAL :: Prnum, Prlim + REAL :: Prnum, shb REAL, PARAMETER :: Prlimit = 5.0 @@ -2825,21 +2681,21 @@ SUBROUTINE mym_turbulence ( & CALL mym_level2 (kts,kte, & & dz, & & u, v, thl, thetav, qw, & - & thlsg, qwsg, & & ql, vt, vq, & & dtl, dqw, dtv, gm, gh, sm, sh ) ! CALL mym_length ( & - & kts,kte, & + & kts,kte,xland, & & dz, dx, zw, & - & rmo, flt, flq, & + & rmo, flt, fltv, flq, & & vt, vq, & & u, v, qke, & & dtv, & & el, & & zi,theta, & - & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength, & - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf ) + & qkw,Psig_bl,cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1 ) ! DO k = kts+1,kte @@ -3003,10 +2859,16 @@ SUBROUTINE mym_turbulence ( & !IF ( sm(k) > sm25max ) sm(k) = sm25max !IF ( sm(k) < sm25min ) sm(k) = sm25min !sm(k) = Prnum*sh(k) - slht = zi*0.1 - wtpr = min( max( (slht - zw(k))/slht, 0.0), 1.0) ! 1 at z=0, 0 above sfc layer - Prlim = 1.0*wtpr + (1.0 - wtpr)*Prlimit - sm(k) = MIN(sm(k), Prlimit*Sh(k)) + + !surface layer PR + !slht = zi*0.1 + !wtpr = min( max( (slht - zw(k))/slht, 0.0), 1.0) ! 1 at z=0, 0 above sfc layer + !Prlim = 1.0*wtpr + (1.0 - wtpr)*Prlimit + !Prlim = 2.0*wtpr + (1.0 - wtpr)*Prlimit + !sm(k) = MIN(sm(k), Prlim*Sh(k)) + !Pending more testing, keep same Pr limit in sfc layer + shb = max(sh(k), 0.002) + sm(k) = MIN(sm(k), Prlimit*shb) ! ** Level 3 : start ** IF ( closure .GE. 3.0 ) THEN @@ -3161,11 +3023,6 @@ SUBROUTINE mym_turbulence ( & ! with active plumes and clouds. cldavg = 0.5*(cldfra_bl1D(k-1) + cldfra_bl1D(k)) IF (edmf_a1(k) > 0.001 .OR. cldavg > 0.02) THEN - !sm(k) = MAX(sm(k), MAX(1.0 - 2.0*cldavg, 0.0)**0.33 * 0.03 * & - ! & MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) - !sh(k) = MAX(sh(k), MAX(1.0 - 2.0*cldavg, 0.0)**0.33 * 0.03 * & - ! & MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) - ! for mass-flux columns sm(k) = MAX(sm(k), 0.03*MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) sh(k) = MAX(sh(k), 0.03*MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) @@ -3179,14 +3036,14 @@ SUBROUTINE mym_turbulence ( & ! Production of TKE (pdk), T-variance (pdt), ! q-variance (pdq), and covariance (pdc) - pdk(k) = elq*( sm(k)*gm(k) & - & +sh(k)*gh(k)+gamv ) + & + pdk(k) = elq*( sm(k)*gm(k) & + & +sh(k)*gh(k)+gamv ) + & & TKEprodTD(k) pdt(k) = elh*( sh(k)*dtl(k)+gamt )*dtl(k) pdq(k) = elh*( sh(k)*dqw(k)+gamq )*dqw(k) - pdc(k) = elh*( sh(k)*dtl(k)+gamt )& - &*dqw(k)*0.5 & - &+elh*( sh(k)*dqw(k)+gamq )*dtl(k)*0.5 + pdc(k) = elh*( sh(k)*dtl(k)+gamt ) & + & *dqw(k)*0.5 & + & + elh*( sh(k)*dqw(k)+gamq )*dtl(k)*0.5 ! Contergradient terms tcd(k) = elq*gamt @@ -3201,7 +3058,7 @@ SUBROUTINE mym_turbulence ( & dfq(k) = dfm(k) ! Modified: Dec/22/2005, up to here - IF ( bl_mynn_tkebudget ) THEN + IF (tke_budget .eq. 1) THEN !TKE BUDGET ! dudz = ( u(k)-u(k-1) )/dzk ! dvdz = ( v(k)-v(k-1) )/dzk @@ -3230,7 +3087,7 @@ SUBROUTINE mym_turbulence ( & !!!Dissipation Term (now it evaluated on mym_predict) !qDISS1D(k) = (q3sq**(3./2.))/(b1*MAX(el(k),1.)) !! ORIGINAL CODE - !! >> EOB + !! >> EOB ENDIF END DO @@ -3313,7 +3170,7 @@ END SUBROUTINE mym_turbulence ! scheme (program). ! !------------------------------------------------------------------- -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine predicts the turbulent quantities at the next step. SUBROUTINE mym_predict (kts,kte, & & closure, & @@ -3324,7 +3181,8 @@ SUBROUTINE mym_predict (kts,kte, & & pdk, pdt, pdq, pdc, & & qke, tsq, qsq, cov, & & s_aw,s_awqke,bl_mynn_edmf_tke, & - & qWT1D, qDISS1D,bl_mynn_tkebudget) !! TKE budget (Puhales, 2020) + & qWT1D, qDISS1D,tke_budget) !! TKE budget (Puhales, 2020) + !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte @@ -3333,19 +3191,18 @@ SUBROUTINE mym_predict (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(IN) :: closure - INTEGER, INTENT(IN) :: bl_mynn_edmf_tke - REAL, INTENT(IN) :: delt + REAL(kind=kind_phys), INTENT(IN) :: closure + INTEGER, INTENT(IN) :: bl_mynn_edmf_tke,tke_budget REAL, DIMENSION(kts:kte), INTENT(IN) :: dz, dfq, el, rho REAL, DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc - REAL, INTENT(IN) :: flt, flq, ust, pmz, phh + REAL, INTENT(IN) :: flt, flq, pmz, phh + REAL(kind=kind_phys), INTENT(IN) :: ust, delt REAL, DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov ! WA 8/3/15 REAL, DIMENSION(kts:kte+1), INTENT(INOUT) :: s_awqke,s_aw !! TKE budget (Puhales, 2020, WRF 4.2.1) << EOB REAL, DIMENSION(kts:kte), INTENT(OUT) :: qWT1D, qDISS1D - LOGICAL, INTENT(IN) :: bl_mynn_tkebudget REAL, DIMENSION(kts:kte) :: tke_up,dzinv !! >> EOB @@ -3486,7 +3343,7 @@ SUBROUTINE mym_predict (kts,kte, & !! TKE budget (Puhales, 2020, WRF 4.2.1) << EOB - IF (bl_mynn_tkebudget) THEN + IF (tke_budget .eq. 1) THEN !! TKE Vertical transport << EOBvt tke_up=0.5*qke dzinv=1./dz @@ -3716,22 +3573,22 @@ END SUBROUTINE mym_predict ! Set these values to those adopted by you. ! !------------------------------------------------------------------- -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the nonconvective component of the !! subgrid cloud fraction and mixing ratio as well as the functions used to !! calculate the buoyancy flux. Different cloud PDFs can be selected by !! use of the namelist parameter \p bl_mynn_cloudpdf . - SUBROUTINE mym_condensation (kts,kte, & - & dx, dz, zw, & - & thl, qw, qv, qc, qi, & - & p,exner, & - & tsq, qsq, cov, & - & Sh, el, bl_mynn_cloudpdf,& - & qc_bl1D, qi_bl1D, & - & cldfra_bl1D, & - & PBLH1,HFX1, & - & Vt, Vq, th, sgm, rmo, & - & spp_pbl,rstoch_col ) + SUBROUTINE mym_condensation (kts,kte, & + & dx, dz, zw, xland, & + & thl, qw, qv, qc, qi, qs, & + & p,exner, & + & tsq, qsq, cov, & + & Sh, el, bl_mynn_cloudpdf, & + & qc_bl1D, qi_bl1D, & + & cldfra_bl1D, & + & PBLH1,HFX1, & + & Vt, Vq, th, sgm, rmo, & + & spp_pbl,rstoch_col ) !------------------------------------------------------------------- @@ -3742,10 +3599,11 @@ SUBROUTINE mym_condensation (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(IN) :: dx,PBLH1,HFX1,rmo + REAL, INTENT(IN) :: HFX1,rmo,xland + REAL(kind=kind_phys), INTENT(IN) :: dx,pblh1 REAL, DIMENSION(kts:kte), INTENT(IN) :: dz REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw - REAL, DIMENSION(kts:kte), INTENT(IN) :: p,exner,thl,qw,qv,qc,qi, & + REAL, DIMENSION(kts:kte), INTENT(IN) :: p,exner,thl,qw,qv,qc,qi,qs, & &tsq, qsq, cov, th REAL, DIMENSION(kts:kte), INTENT(INOUT) :: vt,vq,sgm @@ -3758,7 +3616,8 @@ SUBROUTINE mym_condensation (kts,kte, & REAL :: qsl,esat,qsat,dqsl,cld0,q1k,qlk,eq1,qll,& &q2p,pt,rac,qt,t,xl,rsl,cpm,Fng,qww,alpha,beta,bb,& &ls,wt,cld_factor,fac_damp,liq_frac,ql_ice,ql_water,& - &qmq,qsat_tk + &qmq,qsat_tk,q1_rh,rh_hack + REAL, PARAMETER :: rhcrit=0.83 !for hom pdf min sigma INTEGER :: i,j,k REAL :: erf @@ -3769,7 +3628,7 @@ SUBROUTINE mym_condensation (kts,kte, & !variables for SGS BL clouds REAL :: zagl,damp,PBLH2 - REAL :: lfac + REAL :: cfmax !JAYMES: variables for tropopause-height estimation REAL :: theta1, theta2, ht1, ht2 @@ -3854,9 +3713,6 @@ SUBROUTINE mym_condensation (kts,kte, & qc_bl1D(k) = liq_frac*ql(k) qi_bl1D(k) = (1.0 - liq_frac)*ql(k) - if(cldfra_bl1D(k)>0.01 .and. qc_bl1D(k)<1.E-6)qc_bl1D(k)=1.E-6 - if(cldfra_bl1D(k)>0.01 .and. qi_bl1D(k)<1.E-8)qi_bl1D(k)=1.E-8 - !Now estimate the buoyancy flux functions q2p = xlvcp/exner(k) pt = thl(k) +q2p*ql(k) ! potential temp @@ -3914,9 +3770,6 @@ SUBROUTINE mym_condensation (kts,kte, & qc_bl1D(k) = liq_frac*ql(k) qi_bl1D(k) = (1.0 - liq_frac)*ql(k) - if(cldfra_bl1D(k)>0.01 .and. qc_bl1D(k)<1.E-6)qc_bl1D(k)=1.E-6 - if(cldfra_bl1D(k)>0.01 .and. qi_bl1D(k)<1.E-8)qi_bl1D(k)=1.E-8 - !Now estimate the buoyancy flux functions q2p = xlvcp/exner(k) pt = thl(k) +q2p*ql(k) ! potential temp @@ -3945,7 +3798,7 @@ SUBROUTINE mym_condensation (kts,kte, & xl = xl_blend(t) ! obtain latent heat qsat_tk = qsat_blend(t, p(k)) ! saturation water vapor mixing ratio at tk and p - rh(k)=MAX(MIN(1.0,qw(k)/MAX(1.E-8,qsat_tk)),0.001) + rh(k)=MAX(MIN(1.00,qw(k)/MAX(1.E-10,qsat_tk)),0.001) !dqw/dT: Clausius-Clapeyron dqsl = qsat_tk*ep_2*xlv/( r_d*t**2 ) @@ -3966,101 +3819,89 @@ SUBROUTINE mym_condensation (kts,kte, & !Use the form of Eq. (6) in Chaboureau and Bechtold (2002) !except neglect all but the first term for sig_r - r3sq = MAX( qsq(k), 0.0 ) + r3sq = max( qsq(k), 0.0 ) !Calculate sigma using higher-order moments: sgm(k) = SQRT( r3sq ) !Set limits on sigma relative to saturation water vapor - sgm(k) = MIN( sgm(k), qsat_tk*0.666 ) !500 ) - sgm(k) = MAX( sgm(k), qsat_tk*0.040 ) !Note: 0.02 results in SWDOWN similar - !to the first-order version of sigma - q1(k) = qmq / sgm(k) ! Q1, the normalized saturation - - !Original C-B cloud fraction, allows cloud fractions out to q1 = -3.5 - cldfra_bl1D(K) = MAX(0., MIN(1., 0.5+0.36*ATAN(1.55*q1(k)))) ! Eq. 7 in CB02 - !This form only allows cloud fractions out to q1 = -1.8 - !cldfra_bl1D(K) = MAX(0., MIN(1., 0.5+0.41*ATAN(1.55*q1(k)))) - !This form only allows cloud fractions out to q1 = -1 - !cldfra_bl1D(K) = MAX(0., MIN(1., 0.5+0.50*ATAN(1.55*q1(k)))) + sgm(k) = min( sgm(k), qsat_tk*0.666 ) + sgm(k) = max( sgm(k), qsat_tk*0.035 ) + q1(k) = qmq / sgm(k) ! Q1, the normalized saturation + + !Add condition for falling/settling into low-RH layers, so at least + !some cloud fraction is applied for all qc and qi. + rh_hack = rh(k) + !ensure adequate RH & q1 when qi is at least 1e-9 + if (qi(k)>1.e-9) then + rh_hack =min(1.0, rhcrit + 0.06*(9.0 + log10(qi(k)))) + rh(k) =max(rh(k), rh_hack) + !add rh-based q1 + q1_rh =-3. + 3.*(rh_hack-rhcrit)/(1.-rhcrit) + q1(k) =max(q1_rh, q1(k) ) + endif + !ensure adequate RH & q1 when qc is at least 1e-6 + if (qc(k)>1.e-6) then + rh_hack =min(1.0, rhcrit + 0.09*(6.0 + log10(qc(k)))) + rh(k) =max(rh(k), rh_hack) + !add rh-based q1 + q1_rh =-3. + 3.*(rh_hack-rhcrit)/(1.-rhcrit) + q1(k) =max(q1_rh, q1(k) ) + endif - END DO + q1k = q1(k) ! backup Q1 for later modification - ! Specify hydrometeors - ! JAYMES- this option added 8 May 2015 - ! The cloud water formulations are taken from CB02, Eq. 8. - ! "fng" represents the non-Gaussian contribution to the liquid - ! water flux; these formulations are from Cuijpers and Bechtold - ! (1995), Eq. 7. CB95 also draws from Bechtold et al. 1995, - ! hereafter BCMT95 - zagl = 0. - DO k = kts,kte-1 - t = th(k)*exner(k) - q1k = q1(k) - zagl = zagl + dz(k) + ! Specify cloud fraction + !Original C-B cloud fraction, allows cloud fractions out to q1 = -3.5 + !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.55*q1(k)))) ! Eq. 7 in CB02 + !Waynes LES fit - over-diffuse, when limits removed from vt & vq & fng + !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.2*(q1(k)+0.4)))) + !Best compromise: Improves marine stratus without adding much cold bias. + cldfra_bl1D(k) = max(0., min(1., 0.5+0.36*atan(1.8*(q1(k)+0.2)))) - !CLOUD WATER AND ICE + ! Specify hydrometeors + ! JAYMES- this option added 8 May 2015 + ! The cloud water formulations are taken from CB02, Eq. 8. IF (q1k < 0.) THEN !unsaturated -#ifdef SINGLE_PREC ql_water = sgm(k)*EXP(1.2*q1k-1.) -#else - ql_water = sgm(k)*EXP(1.2*q1k-1) -#endif ql_ice = sgm(k)*EXP(1.2*q1k-1.) ELSE IF (q1k > 2.) THEN !supersaturated ql_water = sgm(k)*q1k ql_ice = sgm(k)*q1k - !ql_ice = MIN(80.*qv(k),0.1)*sgm(k)*q1k ELSE !slightly saturated (0 > q1 < 2) ql_water = sgm(k)*(EXP(-1.) + 0.66*q1k + 0.086*q1k**2) ql_ice = sgm(k)*(EXP(-1.) + 0.66*q1k + 0.086*q1k**2) - !ql_ice = MIN(80.*qv(k),0.1)*sgm(k)*(EXP(-1.) + 0.66*q1k + 0.086*q1k**2) ENDIF - !In saturated grid cells, use average of current estimate and prev time step - IF ( qc(k) > 1.e-7 ) ql_water = 0.5 * ( ql_water + qc(k) ) - IF ( qi(k) > 1.e-9 ) ql_ice = 0.5 * ( ql_ice + qi(k) ) + !In saturated grid cells, use average of SGS and resolved values + !if ( qc(k) > 1.e-6 ) ql_water = 0.5 * ( ql_water + qc(k) ) + !ql_ice is actually the total frozen condensate (snow+ice), + !if ( (qi(k)+qs(k)) > 1.e-9 ) ql_ice = 0.5 * ( ql_ice + (qi(k)+qs(k)) ) - IF (cldfra_bl1D(k) < 0.01) THEN + if (cldfra_bl1D(k) < 0.001) then ql_ice = 0.0 ql_water = 0.0 cldfra_bl1D(k) = 0.0 - ENDIF - - !PHASE PARTITIONING: Make some inferences about the relative amounts of - !subgrid cloud water vs. ice based on collocated explicit clouds. Otherise, - !use a simple temperature-dependent partitioning. -! IF ( qc(k) + qi(k) > 0.0 ) THEN ! explicit condensate exists, retain its phase partitioning -! IF ( qi(k) == 0.0 ) THEN ! explicit contains no ice; assume subgrid liquid -! liq_frac = 1.0 -! ELSE IF ( qc(k) == 0.0 ) THEN ! explicit contains no liquid; assume subgrid ice -! liq_frac = 0.0 -! ELSE IF ( (qc(k) >= 1.E-10) .AND. (qi(k) >= 1.E-10) ) THEN ! explicit contains mixed phase of workably -! ! large amounts; assume subgrid follows -! ! same partioning -! liq_frac = qc(k) / ( qc(k) + qi(k) ) -! ELSE -! liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(t0c-tice))) ! explicit contains mixed phase, but at least one -! ! species is very small, so make a temperature- -! ! depedent guess -! ENDIF -! ELSE ! no explicit condensate, so make a temperature-dependent guess - liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(t0c-tice))) -! ENDIF + endif + liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(tliq-tice))) qc_bl1D(k) = liq_frac*ql_water ! apply liq_frac to ql_water and ql_ice qi_bl1D(k) = (1.0-liq_frac)*ql_ice - !Above tropopause: eliminate subgrid clouds from CB scheme - if (k .ge. k_tropo-1) then + !Above tropopause: eliminate subgrid clouds from CB scheme. Note that this was + !"k_tropo - 1" as of 20 Feb 2023. Changed to allow more high-level clouds. + if (k .ge. k_tropo) then cldfra_bl1D(K) = 0. - qc_bl1D(k) = 0. - qi_bl1D(k) = 0. + qc_bl1D(k) = 0. + qi_bl1D(k) = 0. endif - ENDDO - - !Buoyancy-flux-related calculations follow... - DO k = kts,kte-1 - t = th(k)*exner(k) + !Buoyancy-flux-related calculations follow... + !limiting Q1 to avoid too much diffusion in cloud layers + !q1k=max(Q1(k),-2.0) + if ((xland-1.5).GE.0) then ! water + q1k=max(Q1(k),-2.5) + else ! land + q1k=max(Q1(k),-2.0) + endif ! "Fng" represents the non-Gaussian transport factor ! (non-dimensional) from Bechtold et al. 1995 ! (hereafter BCMT95), section 3(c). Their suggested @@ -4072,8 +3913,7 @@ SUBROUTINE mym_condensation (kts,kte, & !ELSE ! Fng = 1.-1.5*q1k !ENDIF - !limiting to avoid mixing away stratus, was -5 - q1k=MAX(Q1(k),-1.0) + ! Use the form of "Fng" from Bechtold and Siebesma (1998, JAS) IF (q1k .GE. 1.0) THEN Fng = 1.0 ELSEIF (q1k .GE. -1.7 .AND. q1k .LT. 1.0) THEN @@ -4083,42 +3923,36 @@ SUBROUTINE mym_condensation (kts,kte, & ELSE Fng = MIN(23.9 + EXP(-1.6*(q1k+2.5)), 60.) ENDIF - Fng = MIN(Fng, 20.) - xl = xl_blend(t) - bb = b(k)*t/th(k) ! bb is "b" in BCMT95. Their "b" differs from - ! "b" in CB02 (i.e., b(k) above) by a factor + cfmax= min(cldfra_bl1D(k), 0.6) + bb = b(k)*t/th(k) ! bb is "b" in BCMT95. Their "b" differs from + ! "b" in CB02 (i.e., b(k) above) by a factor ! of T/theta. Strictly, b(k) above is formulated in ! terms of sat. mixing ratio, but bb in BCMT95 is ! cast in terms of sat. specific humidity. The - ! conversion is neglected here. + ! conversion is neglected here. qww = 1.+0.61*qw(k) alpha = 0.61*th(k) beta = (th(k)/t)*(xl/cp) - 1.61*th(k) - vt(k) = qww - MIN(cldfra_bl1D(K),0.5)*beta*bb*Fng - 1. - vq(k) = alpha + MIN(cldfra_bl1D(K),0.5)*beta*a(k)*Fng - tv0 + vt(k) = qww - cfmax*beta*bb*Fng - 1. + vq(k) = alpha + cfmax*beta*a(k)*Fng - tv0 ! vt and vq correspond to beta-theta and beta-q, respectively, ! in NN09, Eq. B8. They also correspond to the bracketed ! expressions in BCMT95, Eq. 15, since (s*ql/sigma^2) = cldfra*Fng ! The "-1" and "-tv0" terms are included for consistency with ! the legacy vt and vq formulations (above). - ! dampen the amplification factor (cld_factor) with height in order - ! to limit excessively large cloud fractions aloft - !fac_damp = 1.! -MIN(MAX( zagl-(PBLH2+1000.),0.0)/ & - ! MAX((zw(k_tropo)-(PBLH2+1000.)),500.), 1.) - fac_damp = min(zagl * 0.01, 1.0) - !cld_factor = 1.0 + fac_damp*MAX(0.0, ( RH(k) - 0.5 ) / 0.51 )**3.3 + ! dampen amplification factor where need be + fac_damp = min(zagl * 0.0025, 1.0) !cld_factor = 1.0 + fac_damp*MAX(0.0, ( RH(k) - 0.75 ) / 0.26 )**1.9 !HRRRv4 - !cld_factor = 1.0 + fac_damp*(MAX(0.0, ( RH(k) - 0.80 )) / 0.22 )**2 - cld_factor = 1.0 + fac_damp*(MAX(0.0, ( RH(k) - 0.90 )) / 0.11 )**2 - !cld_factor = 1.0 - cldfra_bl1D(K) = MIN( 1., cld_factor*cldfra_bl1D(K) ) - ENDDO + !cld_factor = 1.0 + fac_damp*min((max(0.0, ( RH(k) - 0.92 )) / 0.25 )**2, 0.3) + cld_factor = 1.0 + fac_damp*min((max(0.0, ( RH(k) - 0.92 )) / 0.145)**2, 0.35) + cldfra_bl1D(K) = min( 1., cld_factor*cldfra_bl1D(K) ) + enddo END SELECT !end cloudPDF option - !FOR TESTING PURPOSES ONLY, ISOLATE ON THE MASS-CLOUDS. + !For testing purposes only, option for isolating on the mass-flux clouds. IF (bl_mynn_cloudpdf .LT. 0) THEN DO k = kts,kte-1 cldfra_bl1D(k) = 0.0 @@ -4143,42 +3977,42 @@ SUBROUTINE mym_condensation (kts,kte, & END SUBROUTINE mym_condensation ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine solves for tendencies of U, V, \f$\theta\f$, qv, !! qc, and qi - SUBROUTINE mynn_tendencies(kts,kte,i, & - &closure, & - &delt,dz,rho, & - &u,v,th,tk,qv,qc,qi,qnc,qni, & - &psfc,p,exner, & - &thl,sqv,sqc,sqi,sqw, & - &qnwfa,qnifa,ozone, & - &ust,flt,flq,flqv,flqc,wspd, & - &uoce,voce, & - &tsq,qsq,cov, & - &tcd,qcd, & - &dfm,dfh,dfq, & - &Du,Dv,Dth,Dqv,Dqc,Dqi,Dqnc,Dqni, & - &Dqnwfa,Dqnifa,Dozone, & - &vdfg1,diss_heat, & - &s_aw,s_awthl,s_awqt,s_awqv,s_awqc, & - &s_awu,s_awv, & - &s_awqnc,s_awqni, & - &s_awqnwfa,s_awqnifa, & - &sd_aw,sd_awthl,sd_awqt,sd_awqv, & - &sd_awqc,sd_awu,sd_awv, & - &sub_thl,sub_sqv, & - &sub_u,sub_v, & - &det_thl,det_sqv,det_sqc, & - &det_u,det_v, & - &FLAG_QC,FLAG_QI,FLAG_QNC,FLAG_QNI, & - &FLAG_QNWFA,FLAG_QNIFA, & - &cldfra_bl1d, & - &bl_mynn_cloudmix, & - &bl_mynn_mixqt, & - &bl_mynn_edmf, & - &bl_mynn_edmf_mom, & - &bl_mynn_mixscalars ) + SUBROUTINE mynn_tendencies(kts,kte,i, & + &delt,dz,rho, & + &u,v,th,tk,qv,qc,qi,qs,qnc,qni, & + &psfc,p,exner, & + &thl,sqv,sqc,sqi,sqs,sqw, & + &qnwfa,qnifa,qnbca,ozone, & + &ust,flt,flq,flqv,flqc,wspd, & + &uoce,voce, & + &tsq,qsq,cov, & + &tcd,qcd, & + &dfm,dfh,dfq, & + &Du,Dv,Dth,Dqv,Dqc,Dqi,Dqs,Dqnc,Dqni, & + &Dqnwfa,Dqnifa,Dqnbca,Dozone, & + &diss_heat, & + &s_aw,s_awthl,s_awqt,s_awqv,s_awqc, & + &s_awu,s_awv, & + &s_awqnc,s_awqni, & + &s_awqnwfa,s_awqnifa,s_awqnbca, & + &sd_aw,sd_awthl,sd_awqt,sd_awqv, & + &sd_awqc,sd_awu,sd_awv, & + &sub_thl,sub_sqv, & + &sub_u,sub_v, & + &det_thl,det_sqv,det_sqc, & + &det_u,det_v, & + &FLAG_QC,FLAG_QI,FLAG_QNC,FLAG_QNI, & + &FLAG_QS, & + &FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & + &cldfra_bl1d, & + &bl_mynn_cloudmix, & + &bl_mynn_mixqt, & + &bl_mynn_edmf, & + &bl_mynn_edmf_mom, & + &bl_mynn_mixscalars ) !------------------------------------------------------------------- INTEGER, INTENT(in) :: kts,kte,i @@ -4188,12 +4022,11 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(in) :: closure - INTEGER, INTENT(in) :: bl_mynn_cloudmix,bl_mynn_mixqt,& - bl_mynn_edmf,bl_mynn_edmf_mom, & + INTEGER, INTENT(in) :: bl_mynn_cloudmix,bl_mynn_mixqt, & + bl_mynn_edmf,bl_mynn_edmf_mom, & bl_mynn_mixscalars - LOGICAL, INTENT(IN) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QNC,& - FLAG_QNWFA,FLAG_QNIFA + LOGICAL, INTENT(IN) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QS, & + &FLAG_QNC,FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA ! thl - liquid water potential temperature ! qw - total water @@ -4202,23 +4035,23 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ! flq - surface flux of qw ! mass-flux plumes - REAL, DIMENSION(kts:kte+1), INTENT(in) :: s_aw,s_awthl,s_awqt,& - &s_awqnc,s_awqni,s_awqv,s_awqc,s_awu,s_awv, & - &s_awqnwfa,s_awqnifa, & + REAL, DIMENSION(kts:kte+1), INTENT(in) :: s_aw,s_awthl,s_awqt, & + &s_awqnc,s_awqni,s_awqv,s_awqc,s_awu,s_awv, & + &s_awqnwfa,s_awqnifa,s_awqnbca, & &sd_aw,sd_awthl,sd_awqt,sd_awqv,sd_awqc,sd_awu,sd_awv ! tendencies from mass-flux environmental subsidence and detrainment - REAL, DIMENSION(kts:kte), INTENT(in) :: sub_thl,sub_sqv, & + REAL, DIMENSION(kts:kte), INTENT(in) :: sub_thl,sub_sqv, & &sub_u,sub_v,det_thl,det_sqv,det_sqc,det_u,det_v - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,th,tk,qv,qc,qi,qni,qnc,& + REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,th,tk,qv,qc,qi,qs,qni,qnc,& &rho,p,exner,dfq,dz,tsq,qsq,cov,tcd,qcd,cldfra_bl1d,diss_heat - REAL, DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc,sqi,& - &qnwfa,qnifa,ozone,dfm,dfh - REAL, DIMENSION(kts:kte), INTENT(inout) :: du,dv,dth,dqv,dqc,dqi,& - &dqni,dqnc,dqnwfa,dqnifa,dozone - REAL, INTENT(IN) :: delt,ust,flt,flq,flqv,flqc,wspd,uoce,voce,& - &psfc + REAL, DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc,sqi,sqs, & + &qnwfa,qnifa,qnbca,ozone,dfm,dfh + REAL, DIMENSION(kts:kte), INTENT(inout) :: du,dv,dth,dqv,dqc,dqi,dqs, & + &dqni,dqnc,dqnwfa,dqnifa,dqnbca,dozone + REAL, INTENT(IN) :: flt,flq,flqv,flqc,uoce,voce + REAL(kind=kind_phys), INTENT(IN) :: ust,delt,psfc,wspd !debugging - REAL ::wsp,wsp2 + REAL ::wsp,wsp2,tk2,th2 LOGICAL :: problem integer :: kproblem @@ -4227,14 +4060,13 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & !local vars REAL, DIMENSION(kts:kte) :: dtz,dfhc,dfmc,delp - REAL, DIMENSION(kts:kte) :: sqv2,sqc2,sqi2,sqw2,qni2,qnc2, & !AFTER MIXING - qnwfa2,qnifa2,ozone2 + REAL, DIMENSION(kts:kte) :: sqv2,sqc2,sqi2,sqs2,sqw2,qni2,qnc2, & !AFTER MIXING + qnwfa2,qnifa2,qnbca2,ozone2 REAL, DIMENSION(kts:kte) :: zfac,plumeKh,rhoinv REAL, DIMENSION(kts:kte) :: a,b,c,d,x REAL, DIMENSION(kts:kte+1) :: rhoz, & !rho on model interface & khdz, kmdz REAL :: rhs,gfluxm,gfluxp,dztop,maxdfh,mindfh,maxcf,maxKh,zw - REAL :: vdfg1 !Katata-fogdes REAL :: t,esat,qsl,onoff,kh,km,dzk,rhosfc REAL :: ustdrag,ustdiff,qvflux REAL :: th_new,portion_qc,portion_qi,condensate,qsat @@ -4352,7 +4184,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=u(kte) ! CALL tridiag(kte,a,b,c,d) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte ! du(k)=(d(k-kts+1)-u(k))/delt @@ -4416,7 +4249,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=v(kte) ! CALL tridiag(kte,a,b,c,d) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte ! dv(k)=(d(k-kts+1)-v(k))/delt @@ -4483,8 +4317,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=thl(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !thl(k)=d(k-kts+1) @@ -4546,8 +4380,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqw(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqw2) - CALL tridiag3(kte,a,b,c,d,sqw2) + CALL tridiag2(kte,a,b,c,d,sqw2) +! CALL tridiag3(kte,a,b,c,d,sqw2) ! DO k=kts,kte ! sqw2(k)=d(k-kts+1) @@ -4603,8 +4437,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqc(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqc2) - CALL tridiag3(kte,a,b,c,d,sqc2) + CALL tridiag2(kte,a,b,c,d,sqc2) +! CALL tridiag3(kte,a,b,c,d,sqc2) ! DO k=kts,kte ! sqc2(k)=d(k-kts+1) @@ -4681,8 +4515,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqv(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqv2) - CALL tridiag3(kte,a,b,c,d,sqv2) + CALL tridiag2(kte,a,b,c,d,sqv2) +! CALL tridiag3(kte,a,b,c,d,sqv2) ! DO k=kts,kte ! sqv2(k)=d(k-kts+1) @@ -4697,19 +4531,6 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & IF (bl_mynn_cloudmix > 0 .AND. FLAG_QI) THEN k=kts - -! a(k)=0. -! b(k)=1.+dtz(k)*dfh(k+1) -! c(k)= -dtz(k)*dfh(k+1) -! d(k)=sqi(k) !+ qcd(k)*delt !should we have qcd for ice? -! -! DO k=kts+1,kte-1 -! a(k)= -dtz(k)*dfh(k) -! b(k)=1.+dtz(k)*(dfh(k)+dfh(k+1)) -! c(k)= -dtz(k)*dfh(k+1) -! d(k)=sqi(k) !+ qcd(k)*delt -! ENDDO - !rho-weighted: a(k)= -dtz(k)*khdz(k)*rhoinv(k) b(k)=1.+dtz(k)*(khdz(k+1)+khdz(k))*rhoinv(k) @@ -4743,8 +4564,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqi(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqi2) - CALL tridiag3(kte,a,b,c,d,sqi2) + CALL tridiag2(kte,a,b,c,d,sqi2) +! CALL tridiag3(kte,a,b,c,d,sqi2) ! DO k=kts,kte ! sqi2(k)=d(k-kts+1) @@ -4753,6 +4574,42 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & sqi2=sqi ENDIF +!============================================ +! MIX SNOW ( sqs ) +!============================================ +IF (bl_mynn_cloudmix > 0 .AND. FLAG_QS) THEN + + k=kts +!rho-weighted: + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + b(k)=1.+dtz(k)*(khdz(k+1)+khdz(k))*rhoinv(k) + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) + d(k)=sqs(k) + + DO k=kts+1,kte-1 + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + b(k)=1.+dtz(k)*(khdz(k)+khdz(k+1))*rhoinv(k) + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) + d(k)=sqs(k) + ENDDO + +!! prescribed value + a(kte)=0. + b(kte)=1. + c(kte)=0. + d(kte)=sqs(kte) + +! CALL tridiag(kte,a,b,c,d) + CALL tridiag2(kte,a,b,c,d,sqs2) +! CALL tridiag3(kte,a,b,c,d,sqs2) + +! DO k=kts,kte +! sqs2(k)=d(k-kts+1) +! ENDDO +ELSE + sqs2=sqs +ENDIF + !!============================================ !! cloud ice number concentration (qni) !!============================================ @@ -4781,8 +4638,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qni(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qni2(k)=d(k-kts+1) @@ -4799,6 +4656,7 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & !!============================================ IF (bl_mynn_cloudmix > 0 .AND. FLAG_QNC .AND. & bl_mynn_mixscalars > 0) THEN + k=kts a(k)= -dtz(k)*khdz(k)*rhoinv(k) @@ -4821,8 +4679,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qnc(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qnc2(k)=d(k-kts+1) @@ -4862,8 +4720,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qnwfa(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qnwfa2(k)=d(k) @@ -4904,8 +4762,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qnifa(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qnifa2(k)=d(k-kts+1) @@ -4917,6 +4775,48 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & qnifa2=qnifa ENDIF +!============================================ +! Black-carbon aerosols ( qnbca ). +!============================================ +IF (bl_mynn_cloudmix > 0 .AND. FLAG_QNBCA .AND. & + bl_mynn_mixscalars > 0) THEN + + k=kts + + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + b(k)=1.+dtz(k)*(khdz(k) + khdz(k+1))*rhoinv(k) - & + & 0.5*dtz(k)*rhoinv(k)*s_aw(k+1)*nonloc + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1)*nonloc + d(k)=qnbca(k) - dtz(k)*rhoinv(k)*s_awqnbca(k+1)*nonloc + + DO k=kts+1,kte-1 + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + 0.5*dtz(k)*rhoinv(k)*s_aw(k)*nonloc + b(k)=1.+dtz(k)*(khdz(k) + khdz(k+1))*rhoinv(k) + & + & 0.5*dtz(k)*rhoinv(k)*(s_aw(k)-s_aw(k+1))*nonloc + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1)*nonloc + d(k)=qnbca(k) + dtz(k)*rhoinv(k)*(s_awqnbca(k)-s_awqnbca(k+1))*nonloc + ENDDO + +! prescribed value + a(kte)=0. + b(kte)=1. + c(kte)=0. + d(kte)=qnbca(kte) + +! CALL tridiag(kte,a,b,c,d) +! CALL tridiag2(kte,a,b,c,d,x) + CALL tridiag3(kte,a,b,c,d,x) + + DO k=kts,kte + !qnbca2(k)=d(k-kts+1) + qnbca2(k)=x(k) + ENDDO + +ELSE + !If not mixing aerosols, set "updated" array equal to original array + qnbca2=qnbca +ENDIF + !============================================ ! Ozone - local mixing only !============================================ @@ -4943,8 +4843,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=ozone(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !ozone2(k)=d(k-kts+1) @@ -5041,6 +4941,19 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ENDDO ENDIF + !=================== + ! CLOUD SNOW TENDENCY + !=================== + IF (FLAG_QS) THEN + DO k=kts,kte + Dqs(k)=(sqs2(k)/(1.-sqs2(k)) - qs(k))/delt + ENDDO + ELSE + DO k=kts,kte + Dqs(k) = 0. + ENDDO + ENDIF + !=================== ! CLOUD ICE NUM CONC TENDENCY !=================== @@ -5065,9 +4978,9 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ENDIF !ensure non-negative moist species - CALL moisture_check(kte, delt, delp, exner, & - sqv2, sqc2, sqi2, thl, & - dqv, dqc, dqi, dth ) + CALL moisture_check(kte, delt, delp, exner, & + sqv2, sqc2, sqi2, sqs2, thl, & + dqv, dqc, dqi, dqs, dth ) !===================== ! OZONE TENDENCY CHECK @@ -5083,8 +4996,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & !=================== IF (FLAG_QI) THEN DO k=kts,kte - Dth(k)=(thl(k) + xlvcp/exner(k)*sqc2(k) & - & + xlscp/exner(k)*sqi2(k) & + Dth(k)=(thl(k) + xlvcp/exner(k)*sqc2(k) & + & + xlscp/exner(k)*(sqi2(k)+sqs(k)) & & - th(k))/delt !Use form from Tripoli and Cotton (1981) with their !suggested min temperature to improve accuracy: @@ -5124,6 +5037,19 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ENDDO ENDIF + !======================== + ! BLACK-CARBON TENDENCIES + !======================== + IF (FLAG_QNBCA .AND. bl_mynn_mixscalars > 0) THEN + DO k=kts,kte + Dqnbca(k)=(qnbca2(k) - qnbca(k))/delt + ENDDO + ELSE + DO k=kts,kte + Dqnbca(k)=0. + ENDDO + ENDIF + !ensure non-negative moist species !note: if called down here, dth needs to be updated, but ! if called before the theta-tendency calculation, do not compute dth @@ -5136,21 +5062,28 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & do k=kts,kte wsp = sqrt(u(k)**2 + v(k)**2) wsp2 = sqrt((u(k)+du(k)*delt)**2 + (v(k)+du(k)*delt)**2) - if (wsp2 > 200.) then + th2 = th(k) + Dth(k)*delt + tk2 = th2*exner(k) + if (wsp2 > 200. .or. tk2 > 360. .or. tk2 < 160.) then problem = .true. - print*,"Huge wind speed: i=",i," k=",k," wsp=",wsp2 - print*," du=",du(k)*delt," dv=",dv(k)*delt + print*,"Outgoing problem at: i=",i," k=",k + print*," incoming wsp=",wsp," outgoing wsp=",wsp2 + print*," incoming T=",th(k)*exner(k),"outgoing T:",tk2 + print*," du=",du(k)*delt," dv=",dv(k)*delt," dth=",dth(k)*delt print*," km=",kmdz(k)*dz(k)," kh=",khdz(k)*dz(k) print*," u*=",ust," wspd=",wspd,"rhosfc=",rhosfc + print*," LH=",flq*rhosfc*1004.," HFX=",flt*rhosfc*1004. print*," drag term=",ust**2/wspd*dtz(k)*rhosfc/rho(kts) kproblem = k endif enddo if (problem) then - print*,"=temp:",thl(max(kproblem-5,1):min(kproblem+5,kte)) - print*,"===qv:",sqv(max(kproblem-5,1):min(kproblem+5,kte)) - print*,"====u:",u(max(kproblem-5,1):min(kproblem+5,kte)) - print*,"====v:",v(max(kproblem-5,1):min(kproblem+5,kte)) + print*,"==thl:",thl(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qv:",sqv2(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qc:",sqc2(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qi:",sqi2(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====u:",u(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====v:",v(max(kproblem-3,1):min(kproblem+3,kte)) endif endif @@ -5162,11 +5095,9 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & END SUBROUTINE mynn_tendencies ! ================================================================== -!>\ingroup gp_mynnedmf -!!ensure non-negative moist species. SUBROUTINE moisture_check(kte, delt, dp, exner, & - qv, qc, qi, th, & - dqv, dqc, dqi, dth ) + qv, qc, qi, qs, th, & + dqv, dqc, dqi, dqs, dth ) ! This subroutine was adopted from the CAM-UW ShCu scheme and ! adapted for use here. @@ -5183,12 +5114,12 @@ SUBROUTINE moisture_check(kte, delt, dp, exner, & implicit none integer, intent(in) :: kte - real, intent(in) :: delt + real(kind=kind_phys), intent(in) :: delt real, dimension(kte), intent(in) :: dp, exner - real, dimension(kte), intent(inout) :: qv, qc, qi, th - real, dimension(kte), intent(inout) :: dqv, dqc, dqi, dth + real, dimension(kte), intent(inout) :: qv, qc, qi, qs, th + real, dimension(kte), intent(inout) :: dqv, dqc, dqi, dqs, dth integer k - real :: dqc2, dqi2, dqv2, sum, aa, dum + real :: dqc2, dqi2, dqs2, dqv2, sum, aa, dum real, parameter :: qvmin = 1e-20, & qcmin = 0.0, & qimin = 0.0 @@ -5196,19 +5127,22 @@ SUBROUTINE moisture_check(kte, delt, dp, exner, & do k = kte, 1, -1 ! From the top to the surface dqc2 = max(0.0, qcmin-qc(k)) !qc deficit (>=0) dqi2 = max(0.0, qimin-qi(k)) !qi deficit (>=0) + dqs2 = max(0.0, qimin-qs(k)) !qs deficit (>=0) !fix tendencies dqc(k) = dqc(k) + dqc2/delt dqi(k) = dqi(k) + dqi2/delt - dqv(k) = dqv(k) - (dqc2+dqi2)/delt + dqs(k) = dqs(k) + dqs2/delt + dqv(k) = dqv(k) - (dqc2+dqi2+dqs2)/delt dth(k) = dth(k) + xlvcp/exner(k)*(dqc2/delt) + & - xlscp/exner(k)*(dqi2/delt) + xlscp/exner(k)*((dqi2+dqs2)/delt) !update species qc(k) = qc(k) + dqc2 qi(k) = qi(k) + dqi2 - qv(k) = qv(k) - dqc2 - dqi2 + qs(k) = qs(k) + dqs2 + qv(k) = qv(k) - dqc2 - dqi2 - dqs2 th(k) = th(k) + xlvcp/exner(k)*dqc2 + & - xlscp/exner(k)*dqi2 + xlscp/exner(k)*(dqi2+dqs2) !then fix qv dqv2 = max(0.0, qvmin-qv(k)) !qv deficit (>=0) @@ -5221,6 +5155,7 @@ SUBROUTINE moisture_check(kte, delt, dp, exner, & qv(k) = max(qv(k),qvmin) qc(k) = max(qc(k),qcmin) qi(k) = max(qi(k),qimin) + qs(k) = max(qs(k),qimin) end do ! Extra moisture used to satisfy 'qv(1)>=qvmin' is proportionally ! extracted from all the layers that has 'qv > 2*qvmin'. This fully @@ -5251,8 +5186,6 @@ END SUBROUTINE moisture_check ! ================================================================== -!>\ingroup gp_mynnedmf -!! SUBROUTINE mynn_mix_chem(kts,kte,i, & delt,dz,pblh, & nchem, kdvel, ndvel, & @@ -5261,26 +5194,26 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & flt, tcd, qcd, & dfh, & s_aw, s_awchem, & - emis_ant_no,frp, & - fire_turb ) + emis_ant_no, frp, rrfs_sd, & + enh_mix, smoke_dbg ) !------------------------------------------------------------------- INTEGER, INTENT(in) :: kts,kte,i - REAL, DIMENSION(kts:kte), INTENT(IN) :: dfh,dz,tcd,qcd REAL, DIMENSION(kts:kte), INTENT(INOUT) :: rho - REAL, INTENT(IN) :: delt,flt + REAL, INTENT(IN) :: flt + REAL(kind=kind_phys), INTENT(IN) :: delt,pblh INTEGER, INTENT(IN) :: nchem, kdvel, ndvel REAL, DIMENSION( kts:kte+1), INTENT(IN) :: s_aw REAL, DIMENSION( kts:kte, nchem ), INTENT(INOUT) :: chem1 REAL, DIMENSION( kts:kte+1,nchem), INTENT(IN) :: s_awchem REAL, DIMENSION( ndvel ), INTENT(IN) :: vd1 - REAL, INTENT(IN) :: emis_ant_no,frp,pblh - LOGICAL, INTENT(IN) :: fire_turb + REAL(kind=kind_phys), INTENT(IN) :: emis_ant_no,frp + LOGICAL, INTENT(IN) :: rrfs_sd,enh_mix,smoke_dbg !local vars REAL, DIMENSION(kts:kte) :: dtz - REAL, DIMENSION(1:kte-kts+1) :: a,b,c,d,x + REAL, DIMENSION(kts:kte) :: a,b,c,d,x REAL :: rhs,dztop REAL :: t,dzk REAL :: hght @@ -5292,9 +5225,9 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & REAL, DIMENSION(kts:kte) :: rhoinv REAL, DIMENSION(kts:kte+1) :: rhoz,khdz - REAL, PARAMETER :: no_threshold = 0.1 - REAL, PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing - REAL, PARAMETER :: pblh_threshold = 250.0 + REAL, PARAMETER :: NO_threshold = 10.0 ! For anthropogenic sources + REAL, PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing over big fires + REAL, PARAMETER :: pblh_threshold = 100.0 dztop=.5*(dz(kte)+dz(kte-1)) @@ -5324,18 +5257,19 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & khdz(k) = MAX(khdz(k), -0.5*(s_aw(k)-s_aw(k+1))) ENDDO - !Enhance diffusion over fires - IF ( fire_turb ) THEN + !Enhanced mixing over fires + IF ( rrfs_sd .and. enh_mix ) THEN DO k=kts+1,kte-1 khdz_old = khdz(k) khdz_back = pblh * 0.15 / dz(k) !Modify based on anthropogenic emissions of NO and FRP IF ( pblh < pblh_threshold ) THEN - IF ( emis_ant_no > no_threshold ) THEN - khdz(k) = MAX(1.1*khdz(k),sqrt((emis_ant_no / no_threshold)) / dz(k) * rhoz(k)) ! JLS 12/21/21 + IF ( emis_ant_no > NO_threshold ) THEN + khdz(k) = MAX(1.1*khdz(k),sqrt((emis_ant_no / NO_threshold)) / dz(k) * rhoz(k)) ! JLS 12/21/21 ! khdz(k) = MAX(khdz(k),khdz_back) ENDIF IF ( frp > frp_threshold ) THEN + kmaxfire = ceiling(log(frp)) khdz(k) = MAX(1.1*khdz(k), (1. - k/(kmaxfire*2.)) * ((log(frp))**2.- 2.*log(frp)) / dz(k)*rhoz(k)) ! JLS 12/21/21 ! khdz(k) = MAX(khdz(k),khdz_back) ENDIF @@ -5354,7 +5288,7 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & b(k)=1.+dtz(k)*(khdz(k+1)+khdz(k))*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1) c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1) d(k)=chem1(k,ic) & !dtz(k)*flt !neglecting surface sources - & + dtz(k) * -vd1(ic)*chem1(1,ic) & + & - dtz(k)*vd1(ic)*chem1(k,ic) & & - dtz(k)*rhoinv(k)*s_awchem(k+1,ic) DO k=kts+1,kte-1 @@ -5371,11 +5305,14 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & c(kte)=0. d(kte)=chem1(kte,ic) - !CALL tridiag(kte,a,b,c,d) CALL tridiag3(kte,a,b,c,d,x) + IF ( smoke_dbg ) THEN + print*,'aerosol mixing ic,chem1,chem2(k,ic)',ic,(chem1(kts:kts+10,ic)),(x(kts:kts+10)) + print*,'aerosol PBL mixing ic,vd1(ic)',ic,vd1(ic) + END IF + DO k=kts,kte - !chem_new(k,ic)=d(k) chem1(k,ic)=x(k) ENDDO ENDDO @@ -5383,7 +5320,7 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & END SUBROUTINE mynn_mix_chem ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf SUBROUTINE retrieve_exchange_coeffs(kts,kte,& &dfm,dfh,dz,K_m,K_h) @@ -5411,7 +5348,7 @@ SUBROUTINE retrieve_exchange_coeffs(kts,kte,& END SUBROUTINE retrieve_exchange_coeffs ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf SUBROUTINE tridiag(n,a,b,c,d) !! to solve system of linear eqs on tridiagonal matrix n times n @@ -5447,7 +5384,7 @@ SUBROUTINE tridiag(n,a,b,c,d) END SUBROUTINE tridiag ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf subroutine tridiag2(n,a,b,c,d,x) implicit none ! a - sub-diagonal (means it is the diagonal below the main diagonal) @@ -5482,7 +5419,7 @@ subroutine tridiag2(n,a,b,c,d,x) end subroutine tridiag2 ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf subroutine tridiag3(kte,a,b,c,d,x) !ccccccccccccccccccccccccccccccc @@ -5524,65 +5461,7 @@ subroutine tridiag3(kte,a,b,c,d,x) end subroutine tridiag3 ! ================================================================== - -!>\ingroup gp_mynnedmf -!! - SUBROUTINE mynn_bl_init_driver( & - &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN, & - &RQCBLTEN,RQIBLTEN & !,RQNIBLTEN,RQNCBLTEN & - &,QKE, & - &EXCH_H & - !&,icloud_bl,qc_bl,cldfra_bl & - &,RESTART,ALLOWED_TO_READ,LEVEL & - &,IDS,IDE,JDS,JDE,KDS,KDE & - &,IMS,IME,JMS,JME,KMS,KME & - &,ITS,ITE,JTS,JTE,KTS,KTE) - - !--------------------------------------------------------------- - LOGICAL,INTENT(IN) :: ALLOWED_TO_READ,RESTART - INTEGER,INTENT(IN) :: LEVEL !,icloud_bl - - INTEGER,INTENT(IN) :: IDS,IDE,JDS,JDE,KDS,KDE, & - & IMS,IME,JMS,JME,KMS,KME, & - & ITS,ITE,JTS,JTE,KTS,KTE - - - REAL,DIMENSION(IMS:IME,KMS:KME),INTENT(INOUT) :: & - &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN, & - &RQCBLTEN,RQIBLTEN,& !RQNIBLTEN,RQNCBLTEN & - &QKE,EXCH_H - - INTEGER :: I,J,K,ITF,JTF,KTF - - JTF=MIN0(JTE,JDE-1) - KTF=MIN0(KTE,KDE-1) - ITF=MIN0(ITE,IDE-1) - - IF(.NOT.RESTART)THEN - DO K=KTS,KTF - DO I=ITS,ITF - RUBLTEN(i,k)=0. - RVBLTEN(i,k)=0. - RTHBLTEN(i,k)=0. - RQVBLTEN(i,k)=0. - if( p_qc >= param_first_scalar ) RQCBLTEN(i,k)=0. - if( p_qi >= param_first_scalar ) RQIBLTEN(i,k)=0. - !if( p_qnc >= param_first_scalar ) RQNCBLTEN(i,k)=0. - !if( p_qni >= param_first_scalar ) RQNIBLTEN(i,k)=0. - !QKE(i,k)=0. - EXCH_H(i,k)=0. -! if(icloud_bl > 0) qc_bl(i,k)=0. -! if(icloud_bl > 0) cldfra_bl(i,k)=0. - ENDDO - ENDDO - ENDIF - - mynn_level=level - - END SUBROUTINE mynn_bl_init_driver - -! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates hybrid diagnotic boundary-layer height (PBLH). !! !! NOTES ON THE PBLH FORMULATION: The 1.5-theta-increase method defines @@ -5627,7 +5506,7 @@ SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea,kzi) # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(OUT) :: zi + REAL(kind=kind_phys), INTENT(OUT) :: zi REAL, INTENT(IN) :: landsea REAL, DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D REAL, DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D @@ -5744,7 +5623,8 @@ SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea,kzi) END SUBROUTINE GET_PBLH !> @} -!>\ingroup gp_mynnedmf +! ================================================================== +!>\ingroup gsd_mynn_edmf !! This subroutine is the Dynamic Multi-Plume (DMP) Mass-Flux Scheme. !! !! dmp_mf() calculates the nonlocal turbulent transport from the dynamic @@ -5762,46 +5642,47 @@ END SUBROUTINE GET_PBLH !! !! This scheme remains under development, so consider it experimental code. !! - SUBROUTINE DMP_mf( & - & kts,kte,dt,zw,dz,p,rho, & - & momentum_opt, & - & tke_opt, & - & scalar_opt, & - & u,v,w,th,thl,thv,tk, & - & qt,qv,qc,qke, & - & qnc,qni,qnwfa,qnifa, & - & exner,vt,vq,sgm, & - & ust,flt,fltv,flq,flqv, & - & pblh,kpbl,DX,landsea,ts, & + SUBROUTINE DMP_mf( & + & kts,kte,dt,zw,dz,p,rho, & + & momentum_opt, & + & tke_opt, & + & scalar_opt, & + & u,v,w,th,thl,thv,tk, & + & qt,qv,qc,qke, & + & qnc,qni,qnwfa,qnifa,qnbca, & + & exner,vt,vq,sgm, & + & ust,flt,fltv,flq,flqv, & + & pblh,kpbl,dx,landsea,ts, & ! outputs - updraft properties - & edmf_a,edmf_w, & - & edmf_qt,edmf_thl, & - & edmf_ent,edmf_qc, & + & edmf_a,edmf_w, & + & edmf_qt,edmf_thl, & + & edmf_ent,edmf_qc, & ! outputs - variables needed for solver - & s_aw,s_awthl,s_awqt, & - & s_awqv,s_awqc, & - & s_awu,s_awv,s_awqke, & - & s_awqnc,s_awqni, & - & s_awqnwfa,s_awqnifa, & - & sub_thl,sub_sqv, & - & sub_u,sub_v, & - & det_thl,det_sqv,det_sqc, & - & det_u,det_v, & + & s_aw,s_awthl,s_awqt, & + & s_awqv,s_awqc, & + & s_awu,s_awv,s_awqke, & + & s_awqnc,s_awqni, & + & s_awqnwfa,s_awqnifa, & + & s_awqnbca, & + & sub_thl,sub_sqv, & + & sub_u,sub_v, & + & det_thl,det_sqv,det_sqc, & + & det_u,det_v, & ! chem/smoke - & nchem,chem1,s_awchem, & - & mix_chem, & + & nchem,chem1,s_awchem, & + & mix_chem, & ! in/outputs - subgrid scale clouds & qc_bl1d,cldfra_bl1d, & & qc_bl1D_old,cldfra_bl1D_old, & ! inputs - flags for moist arrays - & F_QC,F_QI, & - F_QNC,F_QNI, & - & F_QNWFA,F_QNIFA, & - & Psig_shcu, & + & F_QC,F_QI, & + & F_QNC,F_QNI, & + & F_QNWFA,F_QNIFA,F_QNBCA, & + & Psig_shcu, & ! output info - &nup2,ktop,maxmf,ztop, & - ! unputs for stochastic perturbations - &spp_pbl,rstoch_col) + & nup2,ktop,maxmf,ztop, & + ! inputs for stochastic perturbations + & spp_pbl,rstoch_col ) ! inputs: INTEGER, INTENT(IN) :: KTS,KTE,KPBL,momentum_opt,tke_opt,scalar_opt @@ -5815,21 +5696,22 @@ SUBROUTINE DMP_mf( & INTEGER, INTENT(IN) :: spp_pbl REAL, DIMENSION(KTS:KTE) :: rstoch_col - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,W,TH,THL,TK,QT,QV,QC,& - exner,dz,THV,P,rho,qke,qnc,qni,qnwfa,qnifa - REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW !height at full-sigma - REAL, INTENT(IN) :: DT,UST,FLT,FLTV,FLQ,FLQV,PBLH,& - DX,Psig_shcu,landsea,ts - LOGICAL, OPTIONAL :: F_QC,F_QI,F_QNC,F_QNI,F_QNWFA,F_QNIFA + REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,W,TH,THL,TK,QT,QV,QC, & + exner,dz,THV,P,rho,qke,qnc,qni,qnwfa,qnifa,qnbca + REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: zw !height at full-sigma + REAL, INTENT(IN) :: flt,fltv,flq,flqv,Psig_shcu,landsea,ts + REAL(kind=kind_phys), INTENT(IN) :: dx,dt,ust,pblh + LOGICAL, OPTIONAL :: F_QC,F_QI,F_QNC,F_QNI,F_QNWFA,F_QNIFA,F_QNBCA ! outputs - updraft properties - REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a,edmf_w, & - & edmf_qt,edmf_thl, edmf_ent,edmf_qc + REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a,edmf_w, & + & edmf_qt,edmf_thl,edmf_ent,edmf_qc !add one local edmf variable: REAL,DIMENSION(KTS:KTE) :: edmf_th ! output INTEGER, INTENT(OUT) :: nup2,ktop - REAL, INTENT(OUT) :: maxmf,ztop + REAL(kind=kind_phys), INTENT(OUT) :: maxmf + REAL, INTENT(OUT) :: ztop ! outputs - variables needed for solver REAL,DIMENSION(KTS:KTE+1) :: s_aw, & !sum ai*rho*wis_awphi s_awthl, & !sum ai*rho*wi*phii @@ -5840,6 +5722,7 @@ SUBROUTINE DMP_mf( & s_awqni, & s_awqnwfa, & s_awqnifa, & + s_awqnbca, & s_awu, & s_awv, & s_awqke, s_aw2 @@ -5847,14 +5730,14 @@ SUBROUTINE DMP_mf( & REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: qc_bl1d,cldfra_bl1d, & qc_bl1d_old,cldfra_bl1d_old - INTEGER, PARAMETER :: NUP=10, debug_mf=0 + INTEGER, PARAMETER :: nup=10, debug_mf=0 !------------- local variables ------------------- ! updraft properties defined on interfaces (k=1 is the top of the ! first model layer REAL,DIMENSION(KTS:KTE+1,1:NUP) :: UPW,UPTHL,UPQT,UPQC,UPQV, & UPA,UPU,UPV,UPTHV,UPQKE,UPQNC, & - UPQNI,UPQNWFA,UPQNIFA + UPQNI,UPQNWFA,UPQNIFA,UPQNBCA ! entrainment variables REAL,DIMENSION(KTS:KTE,1:NUP) :: ENT,ENTf INTEGER,DIMENSION(KTS:KTE,1:NUP) :: ENTi @@ -5862,7 +5745,8 @@ SUBROUTINE DMP_mf( & INTEGER :: K,I,k50 REAL :: fltv2,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & pwmin,pwmax,wmin,wmax,wlv,Psig_w,maxw,maxqc,wpbl - REAL :: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,QNCn,QNIn,QNWFAn,QNIFAn, & + REAL :: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,QNCn,QNIn, & + QNWFAn,QNIFAn,QNBCAn, & Wn2,Wn,EntEXP,EntEXM,EntW,BCOEFF,THVkm1,THVk,Pk,rho_int ! w parameters @@ -5904,13 +5788,14 @@ SUBROUTINE DMP_mf( & ! VARIABLES FOR CHABOUREAU-BECHTOLD CLOUD FRACTION REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: vt, vq, sgm - REAL :: sigq,xl,rsl,cpm,a,qmq,mf_cf,Q1,diffqt,qsat_tk,& + REAL :: sigq,xl,rsl,cpm,a,qmq,mf_cf,Aup,Q1,diffqt,qsat_tk,& Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid, & Ac_mf,Ac_strat,qc_mf + REAL, PARAMETER :: cf_thresh = 0.5 ! only overwrite stratus CF less than this value ! Variables for plume interpolation/saturation check REAL,DIMENSION(KTS:KTE) :: exneri,dzi - REAL :: THp, QTp, QCp, QCs, esat, qsl + REAL :: THp, QTp, QCp, QCs, esat, qsl REAL :: csigma,acfac,ac_wsp,ac_cld !plume overshoot @@ -5931,7 +5816,7 @@ SUBROUTINE DMP_mf( & REAL,DIMENSION(KTS:KTE+1) :: envi_a,envi_w !environmental variables defined at model interface REAL :: temp,sublim,qc_ent,qv_ent,qt_ent,thl_ent,detrate, & detrateUV,oow,exc_fac,aratio,detturb,qc_grid,qc_sgs,& - qc_plume + qc_plume,exc_heat,exc_moist,tk_int REAL, PARAMETER :: Cdet = 1./45. REAL, PARAMETER :: dzpmax = 300. !limit dz used in detrainment - can be excessing in thick layers !parameter "Csub" determines the propotion of upward vertical velocity that contributes to @@ -5971,6 +5856,7 @@ SUBROUTINE DMP_mf( & UPQNI=0. UPQNWFA=0. UPQNIFA=0. + UPQNBCA=0. IF ( mix_chem ) THEN UPCHEM(KTS:KTE+1,1:NUP,1:nchem)=0.0 ENDIF @@ -6000,6 +5886,7 @@ SUBROUTINE DMP_mf( & s_awqni=0. s_awqnwfa=0. s_awqnifa=0. + s_awqnbca=0. IF ( mix_chem ) THEN s_awchem(kts:kte+1,1:nchem) = 0.0 ENDIF @@ -6200,18 +6087,34 @@ SUBROUTINE DMP_mf( & UPV(1,I)=(V(KTS)*DZ(KTS+1)+V(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQC(1,I)=0.0 !UPQC(1,I)=(QC(KTS)*DZ(KTS+1)+QC(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) - UPQT(1,I)=(QT(KTS)*DZ(KTS+1)+QT(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1))& - & +exc_fac*UPW(1,I)*sigmaQT/sigmaW + + exc_heat = exc_fac*UPW(1,I)*sigmaTH/sigmaW UPTHV(1,I)=(THV(KTS)*DZ(KTS+1)+THV(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) & - & +exc_fac*UPW(1,I)*sigmaTH/sigmaW + & + exc_heat !was UPTHL(1,I)= UPTHV(1,I)/(1.+svp1*UPQT(1,I)) !assume no saturated parcel at surface UPTHL(1,I)=(THL(KTS)*DZ(KTS+1)+THL(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) & - & +exc_fac*UPW(1,I)*sigmaTH/sigmaW + & + exc_heat + + !calculate exc_moist by use of surface fluxes + exc_moist=exc_fac*UPW(1,I)*sigmaQT/sigmaW + !calculate exc_moist by conserving rh: +! tk_int =(tk(kts)*dz(kts+1)+tk(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) +! pk =(p(kts)*dz(kts+1)+p(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) +! qtk =(qt(kts)*dz(kts+1)+qt(kts+1)*dz(kts))/(dz(kts)+dz(kts+1)) +! qsat_tk = qsat_blend(tk_int, pk) ! saturation water vapor mixing ratio at tk and p +! rhgrid =MAX(MIN(1.0,qtk/MAX(1.E-8,qsat_tk)),0.001) +! tk_int = tk_int + exc_heat +! qsat_tk = qsat_blend(tk_int, pk) +! exc_moist= max(rhgrid*qsat_tk - qtk, 0.0) + UPQT(1,I)=(QT(KTS)*DZ(KTS+1)+QT(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1))& + & +exc_moist + UPQKE(1,I)=(QKE(KTS)*DZ(KTS+1)+QKE(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNC(1,I)=(QNC(KTS)*DZ(KTS+1)+QNC(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNI(1,I)=(QNI(KTS)*DZ(KTS+1)+QNI(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNWFA(1,I)=(QNWFA(KTS)*DZ(KTS+1)+QNWFA(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNIFA(1,I)=(QNIFA(KTS)*DZ(KTS+1)+QNIFA(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) + UPQNBCA(1,I)=(QNBCA(KTS)*DZ(KTS+1)+QNBCA(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) ENDDO IF ( mix_chem ) THEN @@ -6284,6 +6187,7 @@ SUBROUTINE DMP_mf( & QNIn=UPQNI(k-1,I)*(1.-EntExp) + QNI(k)*EntExp QNWFAn=UPQNWFA(k-1,I)*(1.-EntExp) + QNWFA(k)*EntExp QNIFAn=UPQNIFA(k-1,I)*(1.-EntExp) + QNIFA(k)*EntExp + QNBCAn=UPQNBCA(k-1,I)*(1.-EntExp) + QNBCA(k)*EntExp !capture the updated qc, qt & thl modified by entranment alone, !since they will be modified later if condensation occurs. @@ -6299,14 +6203,14 @@ SUBROUTINE DMP_mf( & !Vn =V(K) *(1-EntExp)+UPV(K-1,I)*EntExp !QKEn=QKE(k)*(1-EntExp)+UPQKE(K-1,I)*EntExp - IF ( mix_chem ) THEN + if ( mix_chem ) then do ic = 1,nchem ! Exponential Entrainment: !chemn(ic) = chem(k,ic)*(1-EntExp)+UPCHEM(K-1,I,ic)*EntExp ! Linear entrainment: chemn(ic)=UPCHEM(k-1,i,ic)*(1.-EntExp) + chem1(k,ic)*EntExp enddo - ENDIF + endif ! Define pressure at model interface Pk =(P(k)*DZ(k+1)+P(k+1)*DZ(k))/(DZ(k+1)+DZ(k)) @@ -6380,13 +6284,10 @@ SUBROUTINE DMP_mf( & dzp = dz(k) ENDIF - !Limit very tall plumes - Wn=Wn*EXP(-MAX(ZW(k+1)-MIN(pblh+2000.,3500.),0.0)/1000.) - - !JOE- minimize the plume penetratration in stratocu-topped PBL - ! IF (fltv2 < 0.06) THEN - ! IF(ZW(k+1) >= pblh-200. .AND. qc(k) > 1e-5 .AND. I > 4) Wn=0. - ! ENDIF + !minimize the plume penetratration in stratocu-topped PBL + !IF (fltv2 < 0.06) THEN + ! IF(ZW(k+1) >= pblh-200. .AND. qc(k) > 1e-5 .AND. I > 4) Wn=0. + !ENDIF !Modify environment variables (representative of the model layer - envm*) !following the updraft dynamical detrainment of Asai and Kasahara (1967, JAS). @@ -6424,6 +6325,7 @@ SUBROUTINE DMP_mf( & UPQNI(K,I)=QNIn UPQNWFA(K,I)=QNWFAn UPQNIFA(K,I)=QNIFAn + UPQNBCA(K,I)=QNBCAn UPA(K,I)=UPA(K-1,I) IF ( mix_chem ) THEN do ic = 1,nchem @@ -6479,13 +6381,13 @@ SUBROUTINE DMP_mf( & s_awthl(k+1)= s_awthl(k+1) + rho_int*UPA(K,i)*UPW(K,i)*UPTHL(K,i)*Psig_w s_awqt(k+1) = s_awqt(k+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQT(K,i)*Psig_w !to conform to grid mean properties, move qc to qv in grid mean - !saturated layers, so total water fluxes are preserve but + !saturated layers, so total water fluxes are preserved but !negative qc fluxes in unsaturated layers is reduced. - IF (qc(k) > 1e-12 .OR. qc(k+1) > 1e-12) then +! if (qc(k) > 1e-12 .or. qc(k+1) > 1e-12) then qc_plume = UPQC(K,i) - ELSE - qc_plume = 0.0 - ENDIF +! else +! qc_plume = 0.0 +! endif s_awqc(k+1) = s_awqc(k+1) + rho_int*UPA(K,i)*UPW(K,i)*qc_plume*Psig_w IF (momentum_opt > 0) THEN s_awu(k+1) = s_awu(k+1) + rho_int*UPA(K,i)*UPW(K,i)*UPU(K,i)*Psig_w @@ -6521,6 +6423,7 @@ SUBROUTINE DMP_mf( & s_awqni(k+1)= s_awqni(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNI(K,i)*Psig_w s_awqnwfa(k+1)= s_awqnwfa(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNWFA(K,i)*Psig_w s_awqnifa(k+1)= s_awqnifa(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNIFA(K,i)*Psig_w + s_awqnbca(k+1)= s_awqnbca(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNBCA(K,i)*Psig_w ENDDO ENDDO ENDIF @@ -6550,6 +6453,7 @@ SUBROUTINE DMP_mf( & s_awqni= s_awqni*adjustment s_awqnwfa= s_awqnwfa*adjustment s_awqnifa= s_awqnifa*adjustment + s_awqnbca= s_awqnbca*adjustment IF (momentum_opt > 0) THEN s_awu = s_awu*adjustment s_awv = s_awv*adjustment @@ -6596,9 +6500,9 @@ SUBROUTINE DMP_mf( & !smoke/chem IF ( mix_chem ) THEN - DO k=KTS,KTE-1 + DO k=kts,kte-1 IF(k > KTOP) exit - rho_int = (rho(k)*DZ(k+1)+rho(k+1)*DZ(k))/(DZ(k+1)+DZ(k)) + rho_int = (rho(k)*dz(k+1)+rho(k+1)*dz(k))/(dz(k+1)+dz(k)) DO I=1,NUP !NUP2 IF(I > NUP2) exit do ic = 1,nchem @@ -6615,14 +6519,14 @@ SUBROUTINE DMP_mf( & ENDIF !Calculate the effects environmental subsidence. - !All envi_*variables are valid at the interfaces, like the edmf_* variables + !All envi_*variables are valid at the interfaces, like the edmf_* variables IF (env_subs) THEN - DO k=KTS+1,KTE-1 + DO k=kts+1,kte-1 !First, smooth the profiles of w & a, since sharp vertical gradients !in plume variables are not likely extended to env variables !Note1: w is treated as negative further below !Note2: both w & a will be transformed into env variables further below - envi_w(k) = onethird*(edmf_w(K-1)+edmf_w(K)+edmf_w(K+1)) + envi_w(k) = onethird*(edmf_w(k-1)+edmf_w(k)+edmf_w(k+1)) envi_a(k) = onethird*(edmf_a(k-1)+edmf_a(k)+edmf_a(k+1))*adjustment ENDDO !define env variables at k=1 (top of first model layer) @@ -6643,22 +6547,26 @@ SUBROUTINE DMP_mf( & sublim = 1.0 ENDIF !Transform w & a into env variables - DO k=KTS,KTE + DO k=kts,kte temp=envi_a(k) envi_a(k)=1.0-temp envi_w(k)=csub*sublim*envi_w(k)*temp/(1.-temp) ENDDO !calculate tendencies from subsidence and detrainment valid at the middle of - !each model layer - dzi(kts) = 0.5*(DZ(kts)+DZ(kts+1)) - sub_thl(kts)=0.5*envi_w(kts)*envi_a(kts)*(thl(kts+1)-thl(kts))/dzi(kts) - sub_sqv(kts)=0.5*envi_w(kts)*envi_a(kts)*(qv(kts+1)-qv(kts))/dzi(kts) - DO k=KTS+1,KTE-1 - dzi(k) = 0.5*(DZ(k)+DZ(k+1)) - sub_thl(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (thl(k+1)-thl(k))/dzi(k) - sub_sqv(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (qv(k+1)-qv(k))/dzi(k) + !each model layer. The lowest model layer uses an assumes w=0 at the surface. + dzi(kts) = 0.5*(dz(kts)+dz(kts+1)) + rho_int = (rho(kts)*dz(kts+1)+rho(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) + sub_thl(kts)= 0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*thl(kts+1)-rho(kts)*thl(kts))/dzi(kts)/rho_int + sub_sqv(kts)= 0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*qv(kts+1)-rho(kts)*qv(kts))/dzi(kts)/rho_int + DO k=kts+1,kte-1 + dzi(k) = 0.5*(dz(k)+dz(k+1)) + rho_int = (rho(k)*dz(k+1)+rho(k+1)*dz(k))/(dz(k+1)+dz(k)) + sub_thl(k)= 0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & + (rho(k+1)*thl(k+1)-rho(k)*thl(k))/dzi(k)/rho_int + sub_sqv(k)= 0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & + (rho(k+1)*qv(k+1)-rho(k)*qv(k))/dzi(k)/rho_int ENDDO DO k=KTS,KTE-1 @@ -6668,13 +6576,17 @@ SUBROUTINE DMP_mf( & ENDDO IF (momentum_opt > 0) THEN - sub_u(kts)=0.5*envi_w(kts)*envi_a(kts)*(u(kts+1)-u(kts))/dzi(kts) - sub_v(kts)=0.5*envi_w(kts)*envi_a(kts)*(v(kts+1)-v(kts))/dzi(kts) - DO k=KTS+1,KTE-1 + rho_int = (rho(kts)*dz(kts+1)+rho(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) + sub_u(kts)=0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*u(kts+1)-rho(kts)*u(kts))/dzi(kts)/rho_int + sub_v(kts)=0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*v(kts+1)-rho(kts)*v(kts))/dzi(kts)/rho_int + DO k=kts+1,kte-1 + rho_int = (rho(k)*dz(k+1)+rho(k+1)*dz(k))/(dz(k+1)+dz(k)) sub_u(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (u(k+1)-u(k))/dzi(k) + (rho(k+1)*u(k+1)-rho(k)*u(k))/dzi(k)/rho_int sub_v(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (v(k+1)-v(k))/dzi(k) + (rho(k+1)*v(k+1)-rho(k)*v(k))/dzi(k)/rho_int ENDDO DO k=KTS,KTE-1 @@ -6695,27 +6607,27 @@ SUBROUTINE DMP_mf( & !JOE: ADD CLDFRA_bl1d, qc_bl1d. Note that they have already been defined in ! mym_condensation. Here, a shallow-cu component is added, but no cumulus -! clouds can be added at k=1 (start loop at k=2). - DO K=KTS+1,KTE-2 - IF(k > KTOP) exit - IF(0.5*(edmf_qc(k)+edmf_qc(k-1))>0.0)THEN - - !interpolate plume thl, th, and qt to mass levels +! clouds can be added at k=1 (start loop at k=2). + do k=kts+1,kte-2 + IF(k > KTOP) exit + IF(0.5*(edmf_qc(k)+edmf_qc(k-1))>0.0 .and. (cldfra_bl1d(k) < cf_thresh))THEN + !interpolate plume quantities to mass levels + Aup = (edmf_a(k)*dzi(k-1)+edmf_a(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) THp = (edmf_th(k)*dzi(k-1)+edmf_th(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) QTp = (edmf_qt(k)*dzi(k-1)+edmf_qt(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) !convert TH to T - t = THp*exner(k) +! t = THp*exner(k) !SATURATED VAPOR PRESSURE - esat = esat_blend(t) + esat = esat_blend(tk(k)) !SATURATED SPECIFIC HUMIDITY - qsl=ep_2*esat/max(1.e-4,(p(k)-ep_3*esat)) + qsl=ep_2*esat/max(1.e-7,(p(k)-ep_3*esat)) !condensed liquid in the plume on mass levels - IF (edmf_qc(k)>0.0 .AND. edmf_qc(k-1)>0.0)THEN - QCp = 0.5*(edmf_qc(k)+edmf_qc(k-1)) - ELSE - QCp = MAX(edmf_qc(k),edmf_qc(k-1)) - ENDIF + if (edmf_qc(k)>0.0 .and. edmf_qc(k-1)>0.0) then + QCp = (edmf_qc(k)*dzi(k-1)+edmf_qc(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) + else + QCp = max(edmf_qc(k),edmf_qc(k-1)) + endif !COMPUTE CLDFRA & QC_BL FROM MASS-FLUX SCHEME and recompute vt & vq xl = xl_blend(tk(k)) ! obtain blended heat capacity @@ -6728,7 +6640,7 @@ SUBROUTINE DMP_mf( & b9 = a*rsl ! CB02 variable "b" q2p = xlvcp/exner(k) - pt = thl(k) +q2p*QCp*0.5*(edmf_a(k)+edmf_a(k-1)) ! potential temp (env + plume) + pt = thl(k) +q2p*QCp*Aup ! potential temp (env + plume) bb = b9*tk(k)/pt ! bb is "b9" in BCMT95. Their "b9" differs from ! "b9" in CB02 by a factor ! of T/theta. Strictly, b9 above is formulated in @@ -6748,17 +6660,33 @@ SUBROUTINE DMP_mf( & endif !CB form: - !sigq = 9.E-3 * 0.5*(edmf_a(k)+edmf_a(k-1)) * & - ! & 0.5*(edmf_w(k)+edmf_w(k-1)) * f ! convective component of sigma (CB2005) + !sigq = 3.5E-3 * Aup * 0.5*(edmf_w(k)+edmf_w(k-1)) * f ! convective component of sigma (CB2005) !sigq = SQRT(sigq**2 + sgm(k)**2) ! combined conv + stratus components !Per S.DeRoode 2009? - sigq = 10. * edmf_a(k) * (edmf_qt(k)-qt(k)) - - sigq = MAX(sigq, 1.0E-6) + !sigq = 5. * Aup * (QTp - qt(k)) + sigq = 10. * Aup * (QTp - qt(k)) + !constrain sigq wrt saturation: + sigq = max(sigq, qsat_tk*0.02 ) + sigq = min(sigq, qsat_tk*0.25 ) qmq = a * (qt(k) - qsat_tk) ! saturation deficit/excess; - ! the numerator of Q1 - mf_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.01),0.6) + Q1 = qmq/sigq ! the numerator of Q1 + + if ((landsea-1.5).GE.0) then ! WATER + !modified form from LES + !mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.2)),0.01),0.6) + !Original CB + mf_cf = min(max(0.5 + 0.36 * atan(1.55*Q1),0.01),0.6) + mf_cf = max(mf_cf, 1.2 * Aup) + mf_cf = min(mf_cf, 5.0 * Aup) + else ! LAND + !LES form + !mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.4)),0.01),0.6) + !Original CB + mf_cf = min(max(0.5 + 0.36 * atan(1.55*Q1),0.01),0.6) + mf_cf = max(mf_cf, 1.75 * Aup) + mf_cf = min(mf_cf, 5.0 * Aup) + endif !IF ( debug_code ) THEN ! print*,"In MYNN, StEM edmf" @@ -6769,74 +6697,71 @@ SUBROUTINE DMP_mf( & !ENDIF ! Update cloud fractions and specific humidities in grid cells - ! where the mass-flux scheme is active. Now, we also use the - ! stratus component of the SGS clouds as well. The stratus cloud - ! fractions (Ac_strat) are reduced slightly to give way to the - ! mass-flux SGS cloud fractions (Ac_mf). - IF (cldfra_bl1d(k) < 0.5) THEN - IF (mf_cf > 0.5*(edmf_a(k)+edmf_a(k-1))) THEN - !cldfra_bl1d(k) = mf_cf - !qc_bl1d(k) = QCp*0.5*(edmf_a(k)+edmf_a(k-1))/mf_cf - Ac_mf = mf_cf - Ac_strat = cldfra_bl1d(k)*(1.0-mf_cf) - cldfra_bl1d(k) = Ac_mf + Ac_strat - !dillute Qc from updraft area to larger cloud area - qc_mf = QCp*0.5*(edmf_a(k)+edmf_a(k-1))/mf_cf - !The mixing ratios from the stratus component are not well - !estimated in shallow-cumulus regimes. Ensure stratus clouds - !have mixing ratio similar to cumulus - QCs = MAX(qc_bl1d(k), 0.5*qc_mf) - qc_bl1d(k) = (qc_mf*Ac_mf + QCs*Ac_strat)/cldfra_bl1d(k) - ELSE - !cldfra_bl1d(k)=0.5*(edmf_a(k)+edmf_a(k-1)) - !qc_bl1d(k) = QCp - Ac_mf = 0.5*(edmf_a(k)+edmf_a(k-1)) - Ac_strat = cldfra_bl1d(k)*(1.0-Ac_mf) - cldfra_bl1d(k)=Ac_mf + Ac_strat - qc_mf = QCp - !Ensure stratus clouds have mixing ratio similar to cumulus - QCs = MAX(qc_bl1d(k), 0.5*qc_mf) - qc_bl1d(k) = (QCp*Ac_mf + QCs*Ac_strat)/cldfra_bl1d(k) - ENDIF - ELSE - Ac_mf = mf_cf - ENDIF + ! where the mass-flux scheme is active. The specific humidities + ! are converted to grid means (not in-cloud quantities). + if ((landsea-1.5).GE.0) then ! water + if (QCp * Aup > 5e-5) then + qc_bl1d(k) = 1.86 * (QCp * Aup) - 2.2e-5 + else + qc_bl1d(k) = 1.18 * (QCp * Aup) + endif + if (mf_cf .ge. Aup) then + qc_bl1d(k) = qc_bl1d(k) / mf_cf + endif + cldfra_bl1d(k) = mf_cf + Ac_mf = mf_cf + else ! land + if (QCp * Aup > 5e-5) then + qc_bl1d(k) = 1.86 * (QCp * Aup) - 2.2e-5 + else + qc_bl1d(k) = 1.18 * (QCp * Aup) + endif + if (mf_cf .ge. Aup) then + qc_bl1d(k) = qc_bl1d(k) / mf_cf + endif + cldfra_bl1d(k) = mf_cf + Ac_mf = mf_cf + endif !Now recalculate the terms for the buoyancy flux for mass-flux clouds: - !See mym_condensation for details on these formulations. The - !cloud-fraction bounding was added to improve cloud retention, - !following RAP and HRRR testing. - !Fng = 2.05 ! the non-Gaussian transport factor (assumed constant) - !Use Bechtold and Siebesma (1998) piecewise estimation of Fng: - Q1 = qmq/MAX(sigq,1E-6) - Q1=MAX(Q1,-5.0) - IF (Q1 .GE. 1.0) THEN + !See mym_condensation for details on these formulations. + !Use Bechtold and Siebesma (1998) piecewise estimation of Fng with + !limits ,since they really should be recalculated after all the other changes...: + !Only overwrite vt & vq in non-stratus condition + !if ((landsea-1.5).GE.0) then ! WATER + Q1=max(Q1,-2.25) + !else + ! Q1=max(Q1,-2.0) + !endif + + if (Q1 .ge. 1.0) then Fng = 1.0 - ELSEIF (Q1 .GE. -1.7 .AND. Q1 .LT. 1.0) THEN + elseif (Q1 .ge. -1.7 .and. Q1 .lt. 1.0) then Fng = EXP(-0.4*(Q1-1.0)) - ELSEIF (Q1 .GE. -2.5 .AND. Q1 .LT. -1.7) THEN + elseif (Q1 .ge. -2.5 .and. Q1 .lt. -1.7) then Fng = 3.0 + EXP(-3.8*(Q1+1.7)) - ELSE - Fng = MIN(23.9 + EXP(-1.6*(Q1+2.5)), 60.) - ENDIF + else + Fng = min(23.9 + EXP(-1.6*(Q1+2.5)), 60.) + endif - vt(k) = qww - MIN(0.40,Ac_mf)*beta*bb*Fng - 1. - vq(k) = alpha + MIN(0.40,Ac_mf)*beta*a*Fng - tv0 - ENDIF - ENDDO + !link the buoyancy flux function to active clouds only (c*Aup): + vt(k) = qww - (1.5*Aup)*beta*bb*Fng - 1. + vq(k) = alpha + (1.5*Aup)*beta*a*Fng - tv0 + endif !check for (qc in plume) .and. (cldfra_bl < threshold) + enddo !k-loop ENDIF !end nup2 > 0 !modify output (negative: dry plume, positive: moist plume) - IF (ktop > 0) THEN + if (ktop > 0) then maxqc = maxval(edmf_qc(1:ktop)) - IF ( maxqc < 1.E-8) maxmf = -1.0*maxmf - ENDIF + if ( maxqc < 1.E-8) maxmf = -1.0*maxmf + endif ! -! debugging +! debugging ! -IF (edmf_w(1) > 4.0) THEN +if (edmf_w(1) > 4.0) then ! surface values print *,'flq:',flq,' fltv:',fltv2 print *,'pblh:',pblh,' wstar:',wstar @@ -6883,10 +6808,12 @@ SUBROUTINE DMP_mf( & END SUBROUTINE DMP_MF !================================================================= -!>\ingroup gp_mynnedmf -!! zero or one condensation for edmf: calculates THV and QC +!>\ingroup gsd_mynn_edmf +!! This subroutine subroutine condensation_edmf(QT,THL,P,zagl,THV,QC) ! +! zero or one condensation for edmf: calculates THV and QC +! real,intent(in) :: QT,THL,P,zagl real,intent(out) :: THV real,intent(inout):: QC @@ -6944,10 +6871,11 @@ end subroutine condensation_edmf !=============================================================== -!> zero or one condensation for edmf: calculates THL and QC -!! similar to condensation_edmf but with different inputs subroutine condensation_edmf_r(QT,THL,P,zagl,THV,QC) ! +! zero or one condensation for edmf: calculates THL and QC +! similar to condensation_edmf but with different inputs +! real,intent(in) :: QT,THV,P,zagl real,intent(out) :: THL, QC @@ -6979,10 +6907,12 @@ subroutine condensation_edmf_r(QT,THL,P,zagl,THV,QC) end subroutine condensation_edmf_r !=============================================================== -!> This is the downdraft mass flux scheme - analogus to edmf_JPL but -!! flipped updraft to downdraft. This scheme is currently only tested -!! for Stratocumulus cloud conditions. For a detailed desctiption of the -!! model, see paper. +! =================================================================== +! This is the downdraft mass flux scheme - analogus to edmf_JPL but +! flipped updraft to downdraft. This scheme is currently only tested +! for Stratocumulus cloud conditions. For a detailed desctiption of the +! model, see paper. + SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & &u,v,th,thl,thv,tk,qt,qv,qc, & &rho,exner, & @@ -6997,11 +6927,12 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & INTEGER, INTENT(IN) :: KTS,KTE,KPBL REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,TH,THL,TK,QT,QV,QC,& - THV,P,rho,exner,rthraten,dz + THV,P,rho,exner,dz + REAL(kind=kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: rthraten ! zw .. heights of the downdraft levels (edges of boxes) REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW - REAL, INTENT(IN) :: DT,UST,WTHL,WQT,PBLH - + REAL, INTENT(IN) :: WTHL,WQT + REAL(kind=kind_phys), INTENT(IN) :: dt,ust,pblh ! outputs - downdraft properties REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a_dd,edmf_w_dd, & & edmf_qt_dd,edmf_thl_dd, edmf_ent_dd,edmf_qc_dd @@ -7342,17 +7273,19 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & END SUBROUTINE DDMF_JPL !=============================================================== -!> Add scale-aware factor (Psig) here, taken from Honnert et al. (2011) \cite Honnert_2011 -!! and/or from Shin and Hong (2013) \cite Shin_2013. + SUBROUTINE SCALE_AWARE(dx,PBL1,Psig_bl,Psig_shcu) !--------------------------------------------------------------- ! NOTES ON SCALE-AWARE FORMULATION ! + !JOE: add scale-aware factor (Psig) here, taken from Honnert et al. (2011, + ! JAS) and/or from Hyeyum Hailey Shin and Song-You Hong (2013, JAS) + ! ! Psig_bl tapers local mixing ! Psig_shcu tapers nonlocal mixing - REAL,INTENT(IN) :: dx,PBL1 + REAL(kind=kind_phys), INTENT(IN) :: dx,pbl1 REAL, INTENT(OUT) :: Psig_bl,Psig_shcu REAL :: dxdh @@ -7415,7 +7348,7 @@ SUBROUTINE SCALE_AWARE(dx,PBL1,Psig_bl,Psig_shcu) END SUBROUTINE SCALE_AWARE ! ===================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! \author JAYMES- added 22 Apr 2015 !! This function calculates saturation vapor pressure. Separate ice and liquid functions !! are used (identical to those in module_mp_thompson.F, v3.6). Then, the @@ -7428,20 +7361,40 @@ FUNCTION esat_blend(t) REAL, INTENT(IN):: t REAL :: esat_blend,XC,ESL,ESI,chi - - XC=MAX(-80.,t - t0c) !note t0c = 273.15, tice is set in module mynn_common - -! For 253 < t < 273.16 K, the vapor pressures are "blended" as a function of temperature, -! using the approach of Chaboureau and Bechtold (2002), JAS, p. 2363. The resulting + !liquid + REAL, PARAMETER:: J0= .611583699E03 + REAL, PARAMETER:: J1= .444606896E02 + REAL, PARAMETER:: J2= .143177157E01 + REAL, PARAMETER:: J3= .264224321E-1 + REAL, PARAMETER:: J4= .299291081E-3 + REAL, PARAMETER:: J5= .203154182E-5 + REAL, PARAMETER:: J6= .702620698E-8 + REAL, PARAMETER:: J7= .379534310E-11 + REAL, PARAMETER:: J8=-.321582393E-13 + !ice + REAL, PARAMETER:: K0= .609868993E03 + REAL, PARAMETER:: K1= .499320233E02 + REAL, PARAMETER:: K2= .184672631E01 + REAL, PARAMETER:: K3= .402737184E-1 + REAL, PARAMETER:: K4= .565392987E-3 + REAL, PARAMETER:: K5= .521693933E-5 + REAL, PARAMETER:: K6= .307839583E-7 + REAL, PARAMETER:: K7= .105785160E-9 + REAL, PARAMETER:: K8= .161444444E-12 + + XC=MAX(-80.,t - t0c) !note t0c = 273.15, tice is set in module mynn_common to 240 + +! For 240 < t < 268.16 K, the vapor pressures are "blended" as a function of temperature, +! using the approach similar to Chaboureau and Bechtold (2002), JAS, p. 2363. The resulting ! values are returned from the function. - IF (t .GE. t0c) THEN + IF (t .GE. (t0c-6.)) THEN esat_blend = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) ELSE IF (t .LE. tice) THEN esat_blend = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) ELSE - ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) - ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) - chi = (t0c - t)/(t0c - tice) + ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) + chi = ((t0c-6.) - t)/((t0c-6.) - tice) esat_blend = (1.-chi)*ESL + chi*ESI END IF @@ -7449,41 +7402,56 @@ END FUNCTION esat_blend ! ==================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This function extends function "esat" and returns a "blended" -!! saturation mixing ratio. +!! saturation mixing ratio. Tice currently set to 240 K, t0c = 273.15 K. !!\author JAYMES - FUNCTION qsat_blend(t, P, waterice) + FUNCTION qsat_blend(t, P) IMPLICIT NONE REAL, INTENT(IN):: t, P - CHARACTER(LEN=1), OPTIONAL, INTENT(IN) :: waterice - CHARACTER(LEN=1) :: wrt REAL :: qsat_blend,XC,ESL,ESI,RSLF,RSIF,chi - - IF ( .NOT. PRESENT(waterice) ) THEN - wrt = 'b' - ELSE - wrt = waterice - ENDIF + !liquid + REAL, PARAMETER:: J0= .611583699E03 + REAL, PARAMETER:: J1= .444606896E02 + REAL, PARAMETER:: J2= .143177157E01 + REAL, PARAMETER:: J3= .264224321E-1 + REAL, PARAMETER:: J4= .299291081E-3 + REAL, PARAMETER:: J5= .203154182E-5 + REAL, PARAMETER:: J6= .702620698E-8 + REAL, PARAMETER:: J7= .379534310E-11 + REAL, PARAMETER:: J8=-.321582393E-13 + !ice + REAL, PARAMETER:: K0= .609868993E03 + REAL, PARAMETER:: K1= .499320233E02 + REAL, PARAMETER:: K2= .184672631E01 + REAL, PARAMETER:: K3= .402737184E-1 + REAL, PARAMETER:: K4= .565392987E-3 + REAL, PARAMETER:: K5= .521693933E-5 + REAL, PARAMETER:: K6= .307839583E-7 + REAL, PARAMETER:: K7= .105785160E-9 + REAL, PARAMETER:: K8= .161444444E-12 XC=MAX(-80.,t - t0c) - IF ((t .GE. t0c) .OR. (wrt .EQ. 'w')) THEN - ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + IF (t .GE. (t0c-6.)) THEN + ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + ESL = min(ESL, P*0.15) ! Even with P=1050mb and T=55C, the sat. vap. pres only contributes to ~15% of total pres. qsat_blend = 0.622*ESL/max(P-ESL, 1e-5) -! ELSE IF (t .LE. 253.) THEN ELSE IF (t .LE. tice) THEN ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) + ESI = min(ESI, P*0.15) qsat_blend = 0.622*ESI/max(P-ESI, 1e-5) ELSE ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + ESL = min(ESL, P*0.15) ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) + ESI = min(ESI, P*0.15) RSLF = 0.622*ESL/max(P-ESL, 1e-5) RSIF = 0.622*ESI/max(P-ESI, 1e-5) -! chi = (273.16-t)/20.16 - chi = (t0c - t)/(t0c - tice) +! chi = (268.16-t)/(268.16-240.) + chi = ((t0c-6.) - t)/((t0c-6.) - tice) qsat_blend = (1.-chi)*RSLF + chi*RSIF END IF @@ -7491,7 +7459,7 @@ END FUNCTION qsat_blend ! =================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This function interpolates the latent heats of vaporization and sublimation into !! a single, temperature-dependent, "blended" value, following !! Chaboureau and Bechtold (2002) \cite Chaboureau_2002, Appendix. @@ -7511,7 +7479,7 @@ FUNCTION xl_blend(t) ELSE xlvt = xlv + (cpv-cliq)*(t-t0c) !vaporization/condensation xlst = xls + (cpv-cice)*(t-t0c) !sublimation/deposition -! chi = (273.16-t)/20.16 +! chi = (273.16-t)/(273.16-240.) chi = (t0c - t)/(t0c - tice) xl_blend = (1.-chi)*xlvt + chi*xlst !blended END IF @@ -7519,13 +7487,14 @@ FUNCTION xl_blend(t) END FUNCTION xl_blend ! =================================================================== -!> New stability function parameters for momentum (Puhales, 2020, WRF 4.2.1) -!! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of -!! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly -!! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an -!! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very -!! stable conditions [z/L ~ O(10)]. + FUNCTION phim(zet) + ! New stability function parameters for momentum (Puhales, 2020, WRF 4.2.1) + ! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of + ! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly + ! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an + ! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very + ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE REAL, INTENT(IN):: zet @@ -7569,14 +7538,15 @@ FUNCTION phim(zet) phim = phi_m END FUNCTION phim +! =================================================================== -!> New stability function parameters for heat (Puhales, 2020, WRF 4.2.1) -!! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of -!! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly -!! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an -!! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very -!! stable conditions [z/L ~ O(10)]. FUNCTION phih(zet) + ! New stability function parameters for heat (Puhales, 2020, WRF 4.2.1) + ! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of + ! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly + ! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an + ! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very + ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE REAL, INTENT(IN):: zet @@ -7618,8 +7588,6 @@ FUNCTION phih(zet) END FUNCTION phih ! ================================================================== -!>\ingroup gp_mynnedmf -!! Calculate the buoyancy production of TKE from cloud-top cooling. SUBROUTINE topdown_cloudrad(kts,kte,dz1,zw,xland,kpbl,PBLH, & &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & &cldfra_bl1D,rthraten, & @@ -7628,9 +7596,11 @@ SUBROUTINE topdown_cloudrad(kts,kte,dz1,zw,xland,kpbl,PBLH, & !input integer, intent(in) :: kte,kts real, dimension(kts:kte), intent(in) :: dz1,sqc,sqi,sqw,& - thl,th1,ex1,p1,rho1,thetav,cldfra_bl1D,rthraten + thl,th1,ex1,p1,rho1,thetav,cldfra_bl1D + real(kind=kind_phys), dimension(kts:kte), intent(in) :: rthraten real, dimension(kts:kte+1), intent(in) :: zw - real, intent(in) :: pblh,xland + real(kind=kind_phys), intent(in) :: pblh + real, intent(in) :: xland integer,intent(in) :: kpbl !output real, intent(out) :: maxKHtopdown diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 08a28f2bd..2467d4eda 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -82,12 +82,6 @@ subroutine mynnedmf_wrapper_init ( & return end if - if (lheatstrg) then - errmsg = 'Logic error: lheatstrg not implemented for MYNN PBL' - errflg = 1 - return - end if - end subroutine mynnedmf_wrapper_init !>\defgroup gp_mynnedmf MYNN-EDMF PBL and Shallow Convection Module @@ -105,13 +99,14 @@ SUBROUTINE mynnedmf_wrapper_run( & & qgrs_water_vapor, & & qgrs_liquid_cloud, & & qgrs_ice_cloud, & + & qgrs_snow_cloud, & & qgrs_cloud_droplet_num_conc, & & qgrs_cloud_ice_num_conc, & & qgrs_ozone, & & qgrs_water_aer_num_conc, & & qgrs_ice_aer_num_conc, & & qgrs_cccn, & - & prsl,exner, & + & prsl,prsi,exner, & & slmsk,tsurf,qsfc,ps, & & ust,ch,hflx,qflx,wspd,rb, & & dtsfc1,dqsfc1, & @@ -140,16 +135,18 @@ SUBROUTINE mynnedmf_wrapper_run( & & nupdraft,maxMF,ktop_plume, & & dudt, dvdt, dtdt, & & dqdt_water_vapor, dqdt_liquid_cloud, & ! <=== ntqv, ntcw - & dqdt_ice_cloud, dqdt_ozone, & ! <=== ntiw, ntoz + & dqdt_ice_cloud, dqdt_snow_cloud, & ! <=== ntiw, ntsw + & dqdt_ozone, & ! <=== ntoz & dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc, & ! <=== ntlnc, ntinc & dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc,& ! <=== ntwa, ntia & dqdt_cccn, & ! <=== ntccn & flag_for_pbl_generic_tend, & & dtend, dtidx, index_of_temperature, & & index_of_x_wind, index_of_y_wind, ntke, & - & ntqv, ntcw, ntiw, ntoz, ntlnc, ntinc, ntwa, ntia, & + & ntqv, ntcw, ntiw, ntsw, & + & ntoz, ntlnc, ntinc, ntwa, ntia, & & index_of_process_pbl, htrsw, htrlw, xmu, & - & bl_mynn_tkebudget, bl_mynn_tkeadvect, & + & tke_budget, bl_mynn_tkeadvect, & & bl_mynn_cloudpdf, bl_mynn_mixlength, & & bl_mynn_edmf, & & bl_mynn_edmf_mom, bl_mynn_edmf_tke, & @@ -158,14 +155,16 @@ SUBROUTINE mynnedmf_wrapper_run( & & icloud_bl, do_mynnsfclay, & & imp_physics, imp_physics_gfdl, & & imp_physics_thompson, imp_physics_wsm6, & - & chem3d, frp, mix_chem, rrfs_smoke, fire_turb, nchem, ndvel, & + & chem3d, frp, mix_chem, rrfs_sd, enh_mix, & + & nchem, ndvel, & & imp_physics_nssl, nssl_ccn_on, & - & ltaerosol, mraerosol, spp_wts_pbl, spp_pbl, lprnt, huge, errmsg, errflg ) + & ltaerosol, mraerosol, spp_wts_pbl, spp_pbl, & + & lprnt, huge, errmsg, errflg ) ! should be moved to inside the mynn: use machine, only: kind_phys use bl_mynn_common, only: cp, r_d, grav, g_inv, zero, & - xlv, xlvcp, xlscp + xlv, xlvcp, xlscp, p608 use module_bl_mynn, only: mynn_bl_driver !------------------------------------------------------------------- @@ -186,8 +185,8 @@ SUBROUTINE mynnedmf_wrapper_run( & ! NAMELIST OPTIONS (INPUT): logical, intent(in) :: & & bl_mynn_tkeadvect, & - & bl_mynn_tkebudget, & - & ltaerosol, mraerosol, & + & ltaerosol, & + & mraerosol, & & lprnt, & & do_mynnsfclay, & & flag_for_pbl_generic_tend, & @@ -204,9 +203,10 @@ SUBROUTINE mynnedmf_wrapper_run( & & bl_mynn_output, & & imp_physics, imp_physics_wsm6, & & imp_physics_thompson, imp_physics_gfdl, & - & imp_physics_nssl, & - & spp_pbl - real, intent(in) :: & + & imp_physics_nssl, imp_physics_fa, & + & spp_pbl, & + & tke_budget + real(kind=kind_phys), intent(in) :: & & bl_mynn_closure !TENDENCY DIAGNOSTICS @@ -214,28 +214,25 @@ SUBROUTINE mynnedmf_wrapper_run( & integer, intent(in) :: dtidx(:,:) integer, intent(in) :: index_of_temperature, index_of_x_wind integer, intent(in) :: index_of_y_wind, index_of_process_pbl - integer, intent(in) :: ntoz, ntqv, ntcw, ntiw, ntlnc + integer, intent(in) :: ntoz, ntqv, ntcw, ntiw, ntsw, ntlnc integer, intent(in) :: ntinc, ntwa, ntia, ntke !MISC CONFIGURATION OPTIONS - INTEGER, PARAMETER :: & + INTEGER, PARAMETER :: & & bl_mynn_mixscalars=1 - LOGICAL :: & - & FLAG_QI, FLAG_QNI, FLAG_QC, FLAG_QNC, & - & FLAG_QNWFA, FLAG_QNIFA, FLAG_OZONE + LOGICAL :: & + & FLAG_QI, FLAG_QNI, FLAG_QC, FLAG_QS, FLAG_QNC, & + & FLAG_QNWFA, FLAG_QNIFA, FLAG_QNBCA, FLAG_OZONE ! Define locally until needed from CCPP LOGICAL, PARAMETER :: cycling = .false. - INTEGER, PARAMETER :: param_first_scalar = 1 - INTEGER :: & - & p_qc, p_qr, p_qi, p_qs, p_qg, p_qnc, p_qni !MYNN-1D REAL(kind=kind_phys), intent(in) :: delt, dtf INTEGER, intent(in) :: im, levs LOGICAL, intent(in) :: flag_init, flag_restart INTEGER :: initflag, k, i - INTEGER :: IDS,IDE,JDS,JDE,KDS,KDE, & - & IMS,IME,JMS,JME,KMS,KME, & + INTEGER :: IDS,IDE,JDS,JDE,KDS,KDE, & + & IMS,IME,JMS,JME,KMS,KME, & & ITS,ITE,JTS,JTE,KTS,KTE REAL(kind=kind_phys) :: tem @@ -245,6 +242,7 @@ SUBROUTINE mynnedmf_wrapper_run( & real(kind=kind_phys), dimension(:,:), intent(inout) :: & & dtdt, dudt, dvdt, & & dqdt_water_vapor, dqdt_liquid_cloud, dqdt_ice_cloud, & + & dqdt_snow_cloud, & & dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc, & & dqdt_ozone, dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc real(kind=kind_phys), dimension(:,:), intent(inout) ::dqdt_cccn @@ -259,10 +257,11 @@ SUBROUTINE mynnedmf_wrapper_run( & real(kind=kind_phys), dimension(:,:), intent(inout) :: & & dqke,qWT,qSHEAR,qBUOY,qDISS real(kind=kind_phys), dimension(:,:), intent(inout) :: & - & t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice_cloud + & t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice_cloud, & + & qgrs_snow_cloud real(kind=kind_phys), dimension(:,:), intent(in) :: & & u,v,omega, & - & exner,prsl, & + & exner,prsl,prsi, & & qgrs_cloud_droplet_num_conc, & & qgrs_cloud_ice_num_conc, & & qgrs_ozone, & @@ -274,20 +273,21 @@ SUBROUTINE mynnedmf_wrapper_run( & real(kind=kind_phys), dimension(:), intent(in) :: xmu real(kind=kind_phys), dimension(:,:), intent(in) :: htrsw, htrlw ! spp_wts_pbl only allocated if spp_pbl == 1 - real(kind_phys), dimension(:,:), intent(in) :: spp_wts_pbl + real(kind=kind_phys), dimension(:,:), intent(in) :: spp_wts_pbl !LOCAL real(kind=kind_phys), dimension(im,levs) :: & - & sqv,sqc,sqi,qnc,qni,ozone,qnwfa,qnifa, & + & sqv,sqc,sqi,sqs,qnc,qni,ozone,qnwfa,qnifa,qnbca, & & dz, w, p, rho, th, qv, delp, & & RUBLTEN, RVBLTEN, RTHBLTEN, RQVBLTEN, & - & RQCBLTEN, RQNCBLTEN, RQIBLTEN, RQNIBLTEN, & - & RQNWFABLTEN, RQNIFABLTEN + & RQCBLTEN, RQNCBLTEN, RQIBLTEN, RQNIBLTEN, RQSBLTEN, & + & RQNWFABLTEN, RQNIFABLTEN, RQNBCABLTEN real(kind=kind_phys), allocatable :: old_ozone(:,:) !smoke/chem arrays - real(kind_phys), dimension(:), intent(inout) :: frp - logical, intent(in) :: mix_chem, fire_turb, rrfs_smoke + real(kind=kind_phys), dimension(:), intent(inout) :: frp + logical, intent(in) :: mix_chem, enh_mix, rrfs_sd + logical, parameter :: smoke_dbg = .false. !set temporarily real(kind=kind_phys), dimension(:,:,:), intent(inout) :: chem3d real(kind=kind_phys), dimension(im) :: emis_ant_no real(kind=kind_phys), dimension(im,ndvel) :: vdep @@ -321,7 +321,7 @@ SUBROUTINE mynnedmf_wrapper_run( & !LOCAL real, dimension(im) :: & - & hfx,qfx,rmol,xland,uoce,voce,vdfg,znt,ts + & hfx,qfx,rmol,xland,uoce,voce,znt,ts integer :: idtend real, dimension(im) :: dusfci1,dvsfci1,dtsfci1,dqsfci1 real(kind=kind_phys), allocatable :: save_qke_adv(:,:) @@ -357,63 +357,33 @@ SUBROUTINE mynnedmf_wrapper_run( & !initialize arrays for test EMIS_ANT_NO = 0. - vdep = 0. ! hli for chem dry deposition, 0 temporarily - - ! Check incoming moist species to ensure non-negative values - ! First, create height (dz) and pressure differences (delp) - ! across model layers - do k=1,levs - do i=1,im - dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv - enddo - enddo - - do i=1,im - delp(i,1) = ps(i) - (prsl(i,2)*dz(i,1) + prsl(i,1)*dz(i,2))/(dz(i,1)+dz(i,2)) - do k=2,levs-1 - delp(i,k) = (prsl(i,k)*dz(i,k-1) + prsl(i,k-1)*dz(i,k))/(dz(i,k)+dz(i,k-1)) - & - (prsl(i,k+1)*dz(i,k) + prsl(i,k)*dz(i,k+1))/(dz(i,k)+dz(i,k+1)) - enddo - delp(i,levs) = delp(i,levs-1) - enddo - - do i=1,im - call moisture_check2(levs, delt, & - delp(i,:), exner(i,:), & - qgrs_water_vapor(i,:), & - qgrs_liquid_cloud(i,:),& - qgrs_ice_cloud(i,:), & - t3d(i,:) ) - enddo + vdep = 0. FLAG_OZONE = ntoz>0 ! Assign variables for each microphysics scheme - if (imp_physics == imp_physics_wsm6) then - ! WSM6 + if (imp_physics == imp_physics_wsm6 .or. imp_physics == imp_physics_fa) then + ! WSM6 or Ferrier-Aligo FLAG_QI = .true. FLAG_QNI= .false. FLAG_QC = .true. FLAG_QNC= .false. + FLAG_QS = .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) sqi(i,k) = qgrs_ice_cloud(i,k) + sqs(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = 0. qni(i,k) = 0. qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo elseif (imp_physics == imp_physics_nssl ) then @@ -422,21 +392,16 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .true. FLAG_QC = .true. FLAG_QNC= .true. + FLAG_QS = .false. FLAG_QNWFA= nssl_ccn_on ! ERM: Perhaps could use this field for CCN field? FLAG_QNIFA= .false. - ! p_q vars not used? - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) sqi(i,k) = qgrs_ice_cloud(i,k) + sqs(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) @@ -445,6 +410,7 @@ SUBROUTINE mynnedmf_wrapper_run( & qnwfa(i,k) = qgrs_cccn(i,k) ENDIF qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo elseif (imp_physics == imp_physics_thompson) then @@ -453,78 +419,69 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QI = .true. FLAG_QNI= .true. FLAG_QC = .true. + FLAG_QS = .true. FLAG_QNC= .true. FLAG_QNWFA= .true. FLAG_QNIFA= .true. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) sqi(i,k) = qgrs_ice_cloud(i,k) + sqs(i,k) = qgrs_snow_cloud(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) qnwfa(i,k) = qgrs_water_aer_num_conc(i,k) qnifa(i,k) = qgrs_ice_aer_num_conc(i,k) + qnbca(i,k) = 0. enddo enddo else if(mraerosol) then FLAG_QI = .true. FLAG_QNI= .true. FLAG_QC = .true. + FLAG_QS = .true. FLAG_QNC= .true. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) sqi(i,k) = qgrs_ice_cloud(i,k) + sqs(i,k) = qgrs_snow_cloud(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo else FLAG_QI = .true. FLAG_QNI= .true. FLAG_QC = .true. + FLAG_QS = .true. FLAG_QNC= .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) sqi(i,k) = qgrs_ice_cloud(i,k) + sqs(i,k) = qgrs_snow_cloud(i,k) qnc(i,k) = 0. qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo endif @@ -534,15 +491,10 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .false. FLAG_QC = .true. FLAG_QNC= .false. + FLAG_QS = .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) @@ -550,8 +502,10 @@ SUBROUTINE mynnedmf_wrapper_run( & sqi(i,k) = qgrs_ice_cloud(i,k) qnc(i,k) = 0. qni(i,k) = 0. + sqs(i,k) = 0. qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) enddo enddo @@ -562,24 +516,21 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .false. FLAG_QC = .true. FLAG_QNC= .false. + FLAG_QS = .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 0 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) sqi(i,k) = 0. + sqs(i,k) = 0. qnc(i,k) = 0. qni(i,k) = 0. qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) enddo enddo @@ -588,21 +539,38 @@ SUBROUTINE mynnedmf_wrapper_run( & allocate(old_ozone(im,levs)) old_ozone = ozone endif - if (lprnt)write(0,*)"prepping MYNN-EDMF variables..." do k=1,levs do i=1,im - ! dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv th(i,k)=t3d(i,k)/exner(i,k) - ! keep as specific humidity - ! qv(i,k)=qvsh(i,k)/(1.0 - qvsh(i,k)) - ! qc(i,k)=qc(i,k)/(1.0 - qvsh(i,k)) - ! qi(i,k)=qi(i,k)/(1.0 - qvsh(i,k)) - rho(i,k)=prsl(i,k)/(r_d*t3d(i,k)) + rho(i,k)=prsl(i,k)/(r_d*t3d(i,k)*(1.+p608*max(sqv(i,k),1e-8))) w(i,k) = -omega(i,k)/(rho(i,k)*grav) + enddo + enddo + + ! Check incoming moist species to ensure non-negative values + ! First, create height difference (dz) + do k=1,levs + do i=1,im + dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv + enddo + enddo + + do i=1,im + do k=1,levs + delp(i,k) = prsi(i,k) - prsi(i,k+1) enddo enddo + do i=1,im + call moisture_check2(levs, delt, & + delp(i,:), exner(i,:), & + sqv(i,:), sqc(i,:), & + sqi(i,:), sqs(i,:), & + t3d(i,:) ) + enddo + + !intialize more variables do i=1,im if (slmsk(i)==1. .or. slmsk(i)==2.) then !sea/land/ice mask (=0/1/2) in FV3 xland(i)=1.0 !but land/water = (1/2) in SFCLAY_mynn @@ -611,11 +579,15 @@ SUBROUTINE mynnedmf_wrapper_run( & endif uoce(i)=0.0 voce(i)=0.0 - vdfg(i)=0.0 !ust(i) = sqrt(stress(i)) ch(i)=0.0 hfx(i)=hflx(i)*rho(i,1)*cp qfx(i)=qflx(i)*rho(i,1) + !filter bad incoming fluxes + if (hfx(i) > 1200.)hfx(i) = 1200. + if (hfx(i) < -500.)hfx(i) = -500. + if (qfx(i) > .0005)qfx(i) = 0.0005 + if (qfx(i) < -.0002)qfx(i) = -0.0002 dtsfc1(i) = hfx(i) dqsfc1(i) = qfx(i)*XLV @@ -690,7 +662,7 @@ SUBROUTINE mynnedmf_wrapper_run( & if (lprnt) then print* write(0,*)"===CALLING mynn_bl_driver; input:" - print*,"bl_mynn_tkebudget=",bl_mynn_tkebudget," bl_mynn_tkeadvect=",bl_mynn_tkeadvect + print*,"tke_budget=",tke_budget," bl_mynn_tkeadvect=",bl_mynn_tkeadvect print*,"bl_mynn_cloudpdf=",bl_mynn_cloudpdf," bl_mynn_mixlength=",bl_mynn_mixlength print*,"bl_mynn_edmf=",bl_mynn_edmf," bl_mynn_edmf_mom=",bl_mynn_edmf_mom print*,"bl_mynn_edmf_tke=",bl_mynn_edmf_tke @@ -716,7 +688,7 @@ SUBROUTINE mynnedmf_wrapper_run( & print*,"znt:",znt(1)," delt=",delt print*,"im=",im," levs=",levs print*,"PBLH=",pblh(1)," KPBL=",KPBL(1)," xland=",xland(1) - print*,"vdfg=",vdfg(1)," ch=",ch(1) + print*,"ch=",ch(1) !print*,"TKE:",TKE_PBL(1,1),TKE_PBL(1,2),TKE_PBL(1,levs) print*,"qke:",qke(1,1),qke(1,2),qke(1,levs) print*,"el_pbl:",el_pbl(1,1),el_pbl(1,2),el_pbl(1,levs) @@ -732,34 +704,36 @@ SUBROUTINE mynnedmf_wrapper_run( & & cycling=cycling, & & delt=delt,dz=dz,dx=dx,znt=znt, & & u=u,v=v,w=w,th=th,sqv3D=sqv,sqc3D=sqc, & - & sqi3D=sqi,qnc=qnc,qni=qni, & - & qnwfa=qnwfa,qnifa=qnifa,ozone=ozone, & + & sqi3D=sqi,sqs3D=sqs,qnc=qnc,qni=qni, & + & qnwfa=qnwfa,qnifa=qnifa,qnbca=qnbca,ozone=ozone, & & p=prsl,exner=exner,rho=rho,T3D=t3d, & & xland=xland,ts=ts,qsfc=qsfc,ps=ps, & & ust=ust,ch=ch,hfx=hfx,qfx=qfx,rmol=rmol, & - & wspd=wspd,uoce=uoce,voce=voce,vdfg=vdfg, & !input + & wspd=wspd,uoce=uoce,voce=voce, & !input & qke=QKE,qke_adv=qke_adv, & !output & sh3d=Sh3d,sm3d=Sm3d, & !chem/smoke & nchem=nchem,kdvel=kdvel,ndvel=ndvel, & - & Chem3d=chem3d,Vdep=vdep, & + & Chem3d=chem3d,Vdep=vdep,smoke_dbg=smoke_dbg, & & FRP=frp,EMIS_ANT_NO=emis_ant_no, & - & mix_chem=mix_chem,fire_turb=fire_turb, & - & rrfs_smoke=rrfs_smoke, & + & mix_chem=mix_chem,enh_mix=enh_mix, & + & rrfs_sd=rrfs_sd, & !----- & Tsq=tsq,Qsq=qsq,Cov=cov, & !output & RUBLTEN=RUBLTEN,RVBLTEN=RVBLTEN,RTHBLTEN=RTHBLTEN, & !output & RQVBLTEN=RQVBLTEN,RQCBLTEN=rqcblten, & & RQIBLTEN=rqiblten,RQNCBLTEN=rqncblten, & !output + & RQSBLTEN=rqsblten, & !output & RQNIBLTEN=rqniblten,RQNWFABLTEN=RQNWFABLTEN, & !output - & RQNIFABLTEN=RQNIFABLTEN,dozone=dqdt_ozone, & !output + & RQNIFABLTEN=RQNIFABLTEN,RQNBCABLTEN=RQNBCABLTEN, & !output + & dozone=dqdt_ozone, & !output & EXCH_H=exch_h,EXCH_M=exch_m, & !output & pblh=pblh,KPBL=KPBL, & !output & el_pbl=el_pbl, & !output & dqke=dqke, & !output & qWT=qWT,qSHEAR=qSHEAR,qBUOY=qBUOY,qDISS=qDISS, & !output & bl_mynn_tkeadvect=bl_mynn_tkeadvect, & - & bl_mynn_tkebudget=bl_mynn_tkebudget, & !input parameter + & tke_budget=tke_budget, & !input parameter & bl_mynn_cloudpdf=bl_mynn_cloudpdf, & !input parameter & bl_mynn_mixlength=bl_mynn_mixlength, & !input parameter & icloud_bl=icloud_bl, & !input parameter @@ -772,7 +746,7 @@ SUBROUTINE mynnedmf_wrapper_run( & & bl_mynn_cloudmix=bl_mynn_cloudmix, & !input parameter & bl_mynn_mixqt=bl_mynn_mixqt, & !input parameter & edmf_a=edmf_a,edmf_w=edmf_w,edmf_qt=edmf_qt, & !output - & edmf_thl=edmf_thl,edmf_ent=edmf_ent,edmf_qc=edmf_qc,&!output + & edmf_thl=edmf_thl,edmf_ent=edmf_ent,edmf_qc=edmf_qc,& !output & sub_thl3D=sub_thl,sub_sqv3D=sub_sqv, & & det_thl3D=det_thl,det_sqv3D=det_sqv, & & nupdraft=nupdraft,maxMF=maxMF, & !output @@ -780,12 +754,12 @@ SUBROUTINE mynnedmf_wrapper_run( & & spp_pbl=spp_pbl,pattern_spp_pbl=spp_wts_pbl, & !input & RTHRATEN=htrlw, & !input & FLAG_QI=flag_qi,FLAG_QNI=flag_qni, & !input - & FLAG_QC=flag_qc,FLAG_QNC=flag_qnc, & !input + & FLAG_QC=flag_qc,FLAG_QNC=flag_qnc,FLAG_QS=flag_qs, & !input & FLAG_QNWFA=FLAG_QNWFA,FLAG_QNIFA=FLAG_QNIFA, & !input - & FLAG_OZONE=FLAG_OZONE, & !input + & FLAG_QNBCA=FLAG_QNBCA,FLAG_OZONE=FLAG_OZONE, & !input & IDS=1,IDE=im,JDS=1,JDE=1,KDS=1,KDE=levs, & !input & IMS=1,IME=im,JMS=1,JME=1,KMS=1,KME=levs, & !input - & ITS=1,ITE=im,JTS=1,JTE=1,KTS=1,KTE=levs) !input + & ITS=1,ITE=im,JTS=1,JTE=1,KTS=1,KTE=levs ) !input ! POST MYNN (INTERSTITIAL) WORK: @@ -826,13 +800,14 @@ SUBROUTINE mynnedmf_wrapper_run( & !enddo !DO moist/scalar/tracer tendencies: - if (imp_physics == imp_physics_wsm6) then + if (imp_physics == imp_physics_wsm6 .or. imp_physics == imp_physics_fa) then ! WSM6 do k=1,levs do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_snow_cloud(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 enddo enddo @@ -860,6 +835,7 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow_cloud(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 dqdt_water_aer_num_conc(i,k) = RQNWFABLTEN(i,k) dqdt_ice_aer_num_conc(i,k) = RQNIFABLTEN(i,k) @@ -894,6 +870,7 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow_cloud(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) enddo enddo if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then @@ -918,6 +895,7 @@ SUBROUTINE mynnedmf_wrapper_run( & call dtend_helper(100+ntqv,RQVBLTEN) call dtend_helper(100+ntcw,RQCBLTEN) call dtend_helper(100+ntiw,RQIBLTEN) + call dtend_helper(100+ntsw,RQSBLTEN) call dtend_helper(100+ntinc,RQNIBLTEN) endif !do k=1,levs @@ -939,6 +917,7 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow_cloud(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) IF ( nssl_ccn_on ) THEN ! dqdt_cccn(i,k) = RQNWFABLTEN(i,k) ENDIF @@ -1014,8 +993,7 @@ SUBROUTINE mynnedmf_wrapper_run( & print*,"znt:",znt(1)," delt=",delt print*,"im=",im," levs=",levs print*,"PBLH=",pblh(1)," KPBL=",KPBL(1)," xland=",xland(1) - print*,"vdfg=",vdfg(1)," ch=",ch(1) - !print*,"TKE:",TKE_PBL(1,1),TKE_PBL(1,2),TKE_PBL(1,levs) + print*,"ch=",ch(1) print*,"qke:",qke(1,1),qke(1,2),qke(1,levs) print*,"el_pbl:",el_pbl(1,1),el_pbl(1,2),el_pbl(1,levs) print*,"Sh3d:",Sh3d(1,1),sh3d(1,2),sh3d(1,levs) @@ -1062,7 +1040,7 @@ END SUBROUTINE dtend_helper ! ================================================================== SUBROUTINE moisture_check2(kte, delt, dp, exner, & - qv, qc, qi, th ) + qv, qc, qi, qs, th ) ! ! If qc < qcmin, qi < qimin, or qv < qvmin happens in any layer, ! force them to be larger than minimum value by (1) condensating @@ -1076,11 +1054,11 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & implicit none integer, intent(in) :: kte - real, intent(in) :: delt - real, dimension(kte), intent(in) :: dp, exner - real, dimension(kte), intent(inout) :: qv, qc, qi, th + real(kind=kind_phys), intent(in) :: delt + real(kind=kind_phys), dimension(kte), intent(in) :: dp, exner + real(kind=kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, qs, th integer k - real :: dqc2, dqi2, dqv2, sum, aa, dum + real :: dqc2, dqi2, dqs2, dqv2, sum, aa, dum real, parameter :: qvmin1= 1e-8, & !min at k=1 qvmin = 1e-20, & !min above k=1 qcmin = 0.0, & @@ -1089,17 +1067,19 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & do k = kte, 1, -1 ! From the top to the surface dqc2 = max(0.0, qcmin-qc(k)) !qc deficit (>=0) dqi2 = max(0.0, qimin-qi(k)) !qi deficit (>=0) + dqs2 = max(0.0, qimin-qs(k)) !qs deficit (>=0) !update species qc(k) = qc(k) + dqc2 qi(k) = qi(k) + dqi2 - qv(k) = qv(k) - dqc2 - dqi2 + qs(k) = qs(k) + dqs2 + qv(k) = qv(k) - dqc2 - dqi2 - dqs2 !for theta !th(k) = th(k) + xlvcp/exner(k)*dqc2 + & ! xlscp/exner(k)*dqi2 !for temperature th(k) = th(k) + xlvcp*dqc2 + & - xlscp*dqi2 + xlscp*(dqi2+dqs2) !then fix qv if lending qv made it negative if (k .eq. 1) then @@ -1115,6 +1095,7 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & endif qc(k) = max(qc(k),qcmin) qi(k) = max(qi(k),qimin) + qs(k) = max(qs(k),qimin) end do ! Extra moisture used to satisfy 'qv(1)>=qvmin' is proportionally diff --git a/physics/mynnedmf_wrapper.meta b/physics/mynnedmf_wrapper.meta index a44a13f1b..1703699bb 100644 --- a/physics/mynnedmf_wrapper.meta +++ b/physics/mynnedmf_wrapper.meta @@ -311,6 +311,14 @@ type = real kind = kind_phys intent = inout +[qgrs_snow_cloud] + standard_name = snow_mixing_ratio + long_name = ratio of mass of snow water to mass of dry air plus vapor (without condensates) + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [qgrs_cloud_droplet_num_conc] standard_name = mass_number_concentration_of_cloud_liquid_water_particles_in_air long_name = number concentration of cloud droplets (liquid) @@ -367,6 +375,14 @@ type = real kind = kind_phys intent = in +[prsi] + standard_name = air_pressure_at_interface + long_name = air pressure at model layer interfaces + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [exner] standard_name = dimensionless_exner_function long_name = Exner function at layers @@ -1025,6 +1041,14 @@ type = real kind = kind_phys intent = inout +[dqdt_snow_cloud] + standard_name = process_split_cumulative_tendency_of_snow_mixing_ratio + long_name = ratio of mass of snow water tendency to mass of dry air plus vapor (without condensates) due to model physics + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [dqdt_ozone] standard_name = process_split_cumulative_tendency_of_ozone_mixing_ratio long_name = ozone mixing ratio tendency due to model physics @@ -1151,6 +1175,13 @@ dimensions = () type = integer intent = in +[ntsw] + 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 [ntlnc] standard_name = index_of_mass_number_concentration_of_cloud_droplets_in_tracer_concentration_array long_name = tracer index for liquid number concentration @@ -1210,12 +1241,12 @@ type = real kind = kind_phys intent = in -[bl_mynn_tkebudget] +[tke_budget] standard_name = control_for_tke_budget_output long_name = flag for activating TKE budget units = flag dimensions = () - type = logical + type = integer intent = in [bl_mynn_tkeadvect] standard_name = flag_for_tke_advection @@ -1329,6 +1360,13 @@ dimensions = () type = integer intent = in +[imp_physics_fa] + standard_name = identifier_for_fer_hires_microphysics_scheme + long_name = choice of Ferrier-Aligo microphysics scheme + units = flag + dimensions = () + type = integer + intent = in [imp_physics_nssl] standard_name = identifier_for_nssl_microphysics_scheme long_name = choice of NSSL 2-moment microphysics scheme @@ -1359,7 +1397,7 @@ type = real kind = kind_phys intent = inout -[rrfs_smoke] +[rrfs_sd] standard_name = do_smoke_coupling long_name = flag controlling rrfs_smoke collection (default off) units = flag @@ -1373,7 +1411,7 @@ dimensions = () type = logical intent = in -[fire_turb] +[enh_mix] standard_name = do_planetary_boundary_layer_fire_enhancement long_name = flag for rrfs smoke mynn enh vermix units = flag diff --git a/physics/sgscloud_radpre.F90 b/physics/sgscloud_radpre.F90 index ae0f39dde..87054128c 100644 --- a/physics/sgscloud_radpre.F90 +++ b/physics/sgscloud_radpre.F90 @@ -35,7 +35,7 @@ module sgscloud_radpre !! !>\section sgscloud_radpre_mod SGS Cloud Scheme Pre General Algorithm subroutine sgscloud_radpre_run( & - im,dt,levs, & + im,dt,fhswr,levs, & flag_init,flag_restart, & con_g, con_pi, eps, epsm1, & r_v, cpv, rcp, & @@ -43,8 +43,11 @@ subroutine sgscloud_radpre_run( & do_mynnedmf, & qc, qi, qv, T3D, P3D, exner, & qr, qs, qg, & - qci_conv,ud_mf, & + qci_conv,qlc,qli,ud_mf, & +! qci_conv_timeave, & +! ud_mf_timeave, & imfdeepcnv, imfdeepcnv_gf, & + imfdeepcnv_sas, & qc_save, qi_save, qs_save, & qc_bl,qi_bl,cldfra_bl, & delp,clouds1,clouds2,clouds3, & @@ -53,6 +56,7 @@ subroutine sgscloud_radpre_run( & nlay, plyr, xlat, dz,de_lgth, & cldsa,mtopa,mbota, & imp_physics, imp_physics_gfdl,& + imp_physics_fa, & iovr, & errmsg, errflg ) @@ -67,18 +71,20 @@ subroutine sgscloud_radpre_run( & real(kind=kind_phys), intent(in) :: con_g, con_pi, eps, epsm1 real(kind=kind_phys), intent(in) :: r_v, cpv, rcp real(kind=kind_phys), intent(in) :: xlv, xlf, cp - real(kind=kind_phys), intent(in) :: dt + real(kind=kind_phys), intent(in) :: dt,fhswr real :: xls, xlvcp, xlscp !derived below real(kind=kind_phys) :: gfac integer, intent(in) :: im, levs, imfdeepcnv, imfdeepcnv_gf, & - & nlay, imp_physics, imp_physics_gfdl + & nlay, imfdeepcnv_sas, imp_physics, imp_physics_gfdl, imp_physics_fa logical, intent(in) :: flag_init, flag_restart, do_mynnedmf real(kind=kind_phys), dimension(:,:), intent(inout) :: qc, qi real(kind=kind_phys), dimension(:,:), intent(inout) :: qr, qs, qg - ! qci_conv only allocated if GF is used + ! note: qci_conv only allocated if GF is used real(kind=kind_phys), dimension(:,:), intent(inout) :: qci_conv + real(kind=kind_phys), dimension(:,:), intent(inout) :: qlc, qli !for SAS real(kind=kind_phys), dimension(:,:), intent(in) :: ud_mf + !real(kind=kind_phys), dimension(:,:), intent(in) :: ud_mf_timeave, qci_conv_timeave real(kind=kind_phys), dimension(:,:), intent(in) :: T3D,delp real(kind=kind_phys), dimension(:,:), intent(in) :: qv,P3D,exner real(kind=kind_phys), dimension(:,:), intent(inout) :: & @@ -112,7 +118,8 @@ subroutine sgscloud_radpre_run( & real :: rhgrid,h2oliq,qsat,tem1,tem2,clwt,es,onemrh,value !Chaboureau and Bechtold (2002 and 2005) - real :: a, f, sigq, qmq, qt, xl, tlk, th, thl, rsl, cpm, cb_cf + real :: a, f, sigq, qmq, qt, xl, th, thl, rsl, cpm, cb_cf + real(kind=kind_phys) :: tlk !Option to convective cloud fraction integer, parameter :: conv_cf_opt = 0 !0: C-B, 1: X-R @@ -188,7 +195,7 @@ subroutine sgscloud_radpre_run( & !endif if (qc(i,k) < 1.e-6 .and. cldfra_bl(i,k)>0.001) then - qc(i,k) = qc_bl(i,k)*cldfra_bl(i,k) + qc(i,k) = qc_bl(i,k) !eff radius cloud water (microns) from Miles et al. (2007) if (nint(slmsk(i)) == 1) then !land @@ -206,8 +213,8 @@ subroutine sgscloud_radpre_run( & !~700 mb and decrease snow to zero by ~300 mb snow_frac = min(0.5, max((p3d(i,k)-30000.0),0.0)/140000.0) ice_frac = 1.0 - snow_frac - if (qi(i,k) < 1.e-8 .and. cldfra_bl(i,k)>0.001) then - qi(i,k) = ice_frac*qi_bl(i,k)*cldfra_bl(i,k) + if (qi(i,k) < 1.e-9 .and. cldfra_bl(i,k)>0.001) then + qi(i,k) = ice_frac*qi_bl(i,k) !eff radius cloud ice (microns), from Mishra et al. (2014, JGR Atmos, fig 6b) if(qi(i,k)>1.E-8)clouds5(i,k)=max(173.45 + 2.14*Tc, 20.) @@ -219,8 +226,8 @@ subroutine sgscloud_radpre_run( & clouds4(i,k) = max(0.0, qi(i,k) * gfac * delp(i,k)) endif - if (qs(i,k) < 1.e-8 .and. cldfra_bl(i,k)>0.001) then - qs(i,k) = snow_frac*qi_bl(i,k)*cldfra_bl(i,k) + if (qs(i,k) < 1.e-9 .and. cldfra_bl(i,k)>0.001) then + qs(i,k) = snow_frac*qi_bl(i,k) !eff radius cloud ice (microns), from Mishra et al. (2014, JGR Atmos, fig 6b) if(qs(i,k)>1.E-8)clouds9(i,k)=max(2.*(173.45 + 2.14*Tc), 50.) @@ -270,7 +277,6 @@ subroutine sgscloud_radpre_run( & if (imfdeepcnv == imfdeepcnv_gf) then do k = 1, levs do i = 1, im - !if ( qci_conv(i,k) > 0. .AND. (qi(i,k) < 1E-7 .AND. qc(i,k) < 1E-7 ) ) then if ( qci_conv(i,k) > 0. ) then Tk = T3D(i,k) Tc = Tk - 273.15 @@ -321,10 +327,15 @@ subroutine sgscloud_radpre_run( & sigq = SQRT(sigq**2 + 1e-10) ! combined conv + background components qmq = a * (qt - qsat) ! saturation deficit/excess; ! the numerator of Q1 - cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.01),0.99) + cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.0),0.99) + if (qci_conv(i,k) .lt. 1e-9) cb_cf = 0.0 if (do_mynnedmf .and. qmq .ge. 0.0) then ! leverage C-B stratus clouds from MYNN in saturated conditions - clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) + if (cb_cf .gt. 0.0) then + clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) + else + !default to MYNN clouds - already specified + endif else ! unsaturated clouds1(i,k) = cb_cf endif @@ -354,7 +365,101 @@ subroutine sgscloud_radpre_run( & endif ! qci_conv enddo enddo - endif ! imfdeepcnv_gf + + elseif (imfdeepcnv == imfdeepcnv_sas) then + + do k = 1, levs + do i = 1, im + h2oliq = qlc(i,k)+qli(i,k) + if ( h2oliq > 0. ) then + Tk = T3D(i,k) + Tc = Tk - 273.15 + + !Partition the convective clouds into water & frozen species + liqfrac = min(1., max(0., (Tk-244.)/29.)) + + qc(i,k) = qc(i,k)+qlc(i,k) + !split ice & snow 50-50% + qi(i,k) = qi(i,k)+0.5*qli(i,k) + qs(i,k) = qs(i,k)+0.5*qli(i,k) + + !eff radius cloud water (microns) + if (nint(slmsk(i)) == 1) then !land + if(qc(i,k)>1.E-8)clouds3(i,k)=5.4 + else + !from Miles et al. + if(qc(i,k)>1.E-8)clouds3(i,k)=9.6 + endif + !from Mishra et al. (2014, JGR Atmos), assume R_sno = 2*R_ice + if(qi(i,k)>1.e-8)clouds5(i,k)=max( 173.45 + 2.14*Tc , 20.) + if(qs(i,k)>1.e-8)clouds9(i,k)=max(2.0*(173.45 + 2.14*Tc), 50.) + + if ( conv_cf_opt .eq. 0 ) then + !print *,'Chab-Bechtold cloud fraction used' + !Alternatively, use Chaboureau-Bechtold (CB) convective component + !Based on both CB2002 and CB2005. + xl = xlv*liqfrac + xls*(1.-liqfrac) ! blended heat capacity + tlk = t3d(i,k) - xlvcp/exner(i,k)*qc(i,k) & + & - xlscp/exner(i,k)*qi(i,k)! liquid temp + ! get saturation water vapor mixing ratio at tl and p + es = min( p3d(i,k), fpvs( tlk ) ) ! fpvs and prsl in pa + qsat= max( QMIN, eps*es / (p3d(i,k) + epsm1*es) ) + rsl = xl*qsat / (r_v*tlk**2) ! slope of C-C curve at t = tl + ! CB02, Eqn. 4 + qt = qc(i,k) + qi(i,k) + qv(i,k) !total water + cpm = cp + qt*cpv ! CB02, sec. 2, para. 1 + a = 1./(1. + xl*rsl/cpm) ! CB02 variable "a" + !Now calculate convective component of the cloud fraction: + if (a > 0.0) then + f = min(1.0/a, 4.0) ! f is the vertical profile + else ! scaling function (CB2005) + f = 1.0 + endif + sigq = 1.5E-3 * ud_mf(i,k)/dt * f + !sigq = 3.E-3 * ud_mf(i,k)/dt * f + sigq = SQRT(sigq**2 + 1e-10) ! combined conv + background components + qmq = a * (qt - qsat) ! saturation deficit/excess; + ! the numerator of Q1 + cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.0),0.99) + if (h2oliq .lt. 1e-9) cb_cf = 0.0 + if (do_mynnedmf .and. qmq .ge. 0.0) then + ! leverage C-B stratus clouds from MYNN in saturated conditions + if (cb_cf .gt. 0.0) then + clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) + else + !default to MYNN clouds - already specified + endif + else ! unsaturated + clouds1(i,k) = cb_cf + endif + else + !print *,'SAS with Xu-Randall cloud fraction' + ! Xu-Randall (1996) cloud fraction + es = min( p3d(i,k), fpvs( t3d(i,k) ) ) ! fpvs and prsl in pa + qsat = max( QMIN, eps*es / (p3d(i,k) + epsm1*es) ) + rhgrid = max( 0., min( 1.00, qv(i,k)/qsat ) ) + h2oliq = qc(i,k) + qi(i,k) + qr(i,k) + qs(i,k) + qg(i,k) ! g/kg + clwt = 1.0e-6 * (p3d(i,k)*0.00001) + + if (h2oliq > clwt) then + onemrh= max( 1.e-10, 1.0-rhgrid ) + tem1 = min(max((onemrh*qsat)**0.49,0.0001),1.0) !jhan + tem1 = 100.0 / tem1 + value = max( min( tem1*(h2oliq-clwt), 50.0 ), 0.0 ) + tem2 = sqrt( sqrt(rhgrid) ) + + clouds1(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) + else + clouds1(i,k) = 0.0 + endif + !print*,"XuRandla- cf:",clouds1(i,k)," rh:",rhgrid," qt:",h2oliq + !print*,"XuRandlb- clwt:",clwt," qsat:",qsat," p:",p3d(i,k) + endif ! end convective cf choice + endif ! qlc/qli check + enddo + enddo + + endif ! convection scheme check endif ! timestep > 1 diff --git a/physics/sgscloud_radpre.meta b/physics/sgscloud_radpre.meta index 28c1b7da6..887ea0b45 100644 --- a/physics/sgscloud_radpre.meta +++ b/physics/sgscloud_radpre.meta @@ -29,6 +29,14 @@ dimensions = () type = integer intent = in +[fhswr] + standard_name = period_of_shortwave_radiation_calls + long_name = frequency for shortwave radiation + units = s + dimensions = () + type = real + kind = kind_phys + intent = in [flag_init] standard_name = flag_for_first_timestep long_name = flag signaling first time step for time integration loop @@ -218,6 +226,22 @@ type = real kind = kind_phys intent = inout +[qlc] + standard_name = cloud_condensed_water_mixing_ratio_convective_transport_tracer + long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) in the convectively transported tracer array + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[qli] + standard_name = ice_water_mixing_ratio_convective_transport_tracer + long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) in the convectively transported tracer array + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [imfdeepcnv] standard_name = control_for_deep_convection_scheme long_name = flag for mass-flux deep convection scheme @@ -232,6 +256,13 @@ dimensions = () type = integer intent = in +[imfdeepcnv_sas] + standard_name = identifier_for_simplified_arakawa_schubert_deep_convection + long_name = flag for SAS deep convection scheme + units = flag + dimensions = () + type = integer + intent = in [qc_save] standard_name = cloud_condensed_water_mixing_ratio_save long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) before entering a physics scheme @@ -427,6 +458,13 @@ dimensions = () type = integer intent = in +[imp_physics_fa] + standard_name = identifier_for_fer_hires_microphysics_scheme + long_name = choice of Ferrier-Aligo microphysics scheme + units = flag + dimensions = () + type = integer + intent = in [iovr] standard_name = flag_for_cloud_overlap_method_for_radiation long_name = max-random overlap clouds From 4e79188487d86b5b88a02d9c940d99ab31d4f06f Mon Sep 17 00:00:00 2001 From: joeolson42 Date: Wed, 1 Mar 2023 16:28:20 +0000 Subject: [PATCH 02/19] updating mynnedmf wrapper --- physics/mynnedmf_wrapper.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 2467d4eda..ca0b9f141 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -155,6 +155,7 @@ SUBROUTINE mynnedmf_wrapper_run( & & icloud_bl, do_mynnsfclay, & & imp_physics, imp_physics_gfdl, & & imp_physics_thompson, imp_physics_wsm6, & + & imp_physics_fa, & & chem3d, frp, mix_chem, rrfs_sd, enh_mix, & & nchem, ndvel, & & imp_physics_nssl, nssl_ccn_on, & From 3d36fb27569f80d8e26ae3d2bf7615ad1b5d2096 Mon Sep 17 00:00:00 2001 From: joeolson42 Date: Mon, 6 Mar 2023 22:43:14 +0000 Subject: [PATCH 03/19] Precision (kind_phys) changes to address reviewer comments --- physics/module_bl_mynn.F90 | 940 +++++++++++++++++------------------ physics/mynnedmf_wrapper.F90 | 114 ++--- 2 files changed, 527 insertions(+), 527 deletions(-) diff --git a/physics/module_bl_mynn.F90 b/physics/module_bl_mynn.F90 index b95f401c4..dab09871c 100644 --- a/physics/module_bl_mynn.F90 +++ b/physics/module_bl_mynn.F90 @@ -256,45 +256,45 @@ MODULE module_bl_mynn !=================================================================== ! From here on, these are MYNN-specific parameters: ! The parameters below depend on stability functions of module_sf_mynn. - REAL, PARAMETER :: cphm_st=5.0, cphm_unst=16.0, & - cphh_st=5.0, cphh_unst=16.0 + real(kind_phys), PARAMETER :: cphm_st=5.0, cphm_unst=16.0, & + cphh_st=5.0, cphh_unst=16.0 ! Closure constants - REAL, PARAMETER :: & - &pr = 0.74, & - &g1 = 0.235, & ! NN2009 = 0.235 - &b1 = 24.0, & - &b2 = 15.0, & ! CKmod NN2009 - &c2 = 0.729, & ! 0.729, & !0.75, & - &c3 = 0.340, & ! 0.340, & !0.352, & - &c4 = 0.0, & - &c5 = 0.2, & + real(kind_phys), PARAMETER :: & + &pr = 0.74, & + &g1 = 0.235, & ! NN2009 = 0.235 + &b1 = 24.0, & + &b2 = 15.0, & ! CKmod NN2009 + &c2 = 0.729, & ! 0.729, & !0.75, & + &c3 = 0.340, & ! 0.340, & !0.352, & + &c4 = 0.0, & + &c5 = 0.2, & &a1 = b1*( 1.0-3.0*g1 )/6.0, & ! &c1 = g1 -1.0/( 3.0*a1*b1**(1.0/3.0) ), & &c1 = g1 -1.0/( 3.0*a1*2.88449914061481660), & &a2 = a1*( g1-c1 )/( g1*pr ), & &g2 = b2/b1*( 1.0-c3 ) +2.0*a1/b1*( 3.0-2.0*c2 ) - REAL, PARAMETER :: & - &cc2 = 1.0-c2, & - &cc3 = 1.0-c3, & - &e1c = 3.0*a2*b2*cc3, & - &e2c = 9.0*a1*a2*cc2, & + real(kind_phys), PARAMETER :: & + &cc2 = 1.0-c2, & + &cc3 = 1.0-c3, & + &e1c = 3.0*a2*b2*cc3, & + &e2c = 9.0*a1*a2*cc2, & &e3c = 9.0*a2*a2*cc2*( 1.0-c5 ), & - &e4c = 12.0*a1*a2*cc2, & + &e4c = 12.0*a1*a2*cc2, & &e5c = 6.0*a1*a1 ! Constants for min tke in elt integration (qmin), max z/L in els (zmax), ! and factor for eddy viscosity for TKE (Kq = Sqfac*Km): - REAL, PARAMETER :: qmin=0.0, zmax=1.0, Sqfac=3.0 + real(kind_phys), PARAMETER :: qmin=0.0, zmax=1.0, Sqfac=3.0 ! Note that the following mixing-length constants are now specified in mym_length ! &cns=3.5, alp1=0.23, alp2=0.3, alp3=3.0, alp4=10.0, alp5=0.2 - REAL, PARAMETER :: gpw=5./3., qcgmin=1.e-8, qkemin=1.e-12 - REAL, PARAMETER :: tliq = 269. !all hydrometeors are liquid when T > tliq + real(kind_phys), PARAMETER :: gpw=5./3., qcgmin=1.e-8, qkemin=1.e-12 + real(kind_phys), PARAMETER :: tliq = 269. !all hydrometeors are liquid when T > tliq ! Constants for cloud PDF (mym_condensation) - REAL, PARAMETER :: rr2=0.7071068, rrp=0.3989423 + real(kind_phys), PARAMETER :: rr2=0.7071068, rrp=0.3989423 !>Use Canuto/Kitamura mod (remove Ric and negative TKE) (1:yes, 0:no) !!For more info, see Canuto et al. (2008 JAS) and Kitamura (Journal of the @@ -304,12 +304,12 @@ MODULE module_bl_mynn !!(above) back to NN2009 values (see commented out lines next to the !!parameters above). This only removes the negative TKE problem !!but does not necessarily improve performance - neutral impact. - REAL, PARAMETER :: CKmod=1. + real(kind_phys), PARAMETER :: CKmod=1. !>Use Ito et al. (2015, BLM) scale-aware (0: no, 1: yes). Note that this also has impacts !!on the cloud PDF and mass-flux scheme, using Honnert et al. (2011) similarity function !!for TKE in the upper PBL/cloud layer. - REAL, PARAMETER :: scaleaware=1. + real(kind_phys), PARAMETER :: scaleaware=1. !>Of the following the options, use one OR the other, not both. !>Adding top-down diffusion driven by cloud-top radiative cooling @@ -416,7 +416,7 @@ SUBROUTINE mynn_bl_driver( & INTEGER, INTENT(in) :: bl_mynn_cloudmix INTEGER, INTENT(in) :: bl_mynn_mixqt INTEGER, INTENT(in) :: icloud_bl - REAL(kind=kind_phys), INTENT(in) :: closure + real(kind_phys), INTENT(in) :: closure LOGICAL, INTENT(in) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QNC,& FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & @@ -444,80 +444,82 @@ SUBROUTINE mynn_bl_driver( & ! to prevent a crash on Cheyenne. Do not change it back without testing if the code runs ! on Cheyenne with the GNU compiler. - REAL(kind=kind_phys), INTENT(in) :: delt - REAL(kind=kind_phys), DIMENSION(:), INTENT(in) :: dx - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: dz, & + real(kind_phys), INTENT(in) :: delt + real(kind_phys), DIMENSION(:), INTENT(in) :: dx + real(kind_phys), DIMENSION(:,:), INTENT(in) :: dz, & &u,v,w,th,sqv3D,p,exner,rho,T3D - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: & + real(kind_phys), DIMENSION(:,:), INTENT(in) :: & &sqc3D,sqi3D,sqs3D,qni,qnc,qnwfa,qnifa,qnbca - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in):: ozone - REAL(kind=kind_phys), DIMENSION(:), INTENT(in):: ust, & + real(kind_phys), DIMENSION(:,:), INTENT(in):: ozone + real(kind_phys), DIMENSION(:), INTENT(in):: ust, & &ch,qsfc,ps,wspd - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & &Qke,Tsq,Qsq,Cov,qke_adv - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & - &rublten,rvblten,rthblten,rqvblten,rqcblten, & - &rqiblten,rqsblten,rqniblten,rqncblten, & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & + &rublten,rvblten,rthblten,rqvblten,rqcblten, & + &rqiblten,rqsblten,rqniblten,rqncblten, & &rqnwfablten,rqnifablten,rqnbcablten - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: dozone - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: rthraten + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: dozone + real(kind_phys), DIMENSION(:,:), INTENT(in) :: rthraten - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(out) :: exch_h,exch_m - REAL, DIMENSION(:), INTENT(in) :: xland,ts,znt,hfx,qfx, & - &uoce,voce + real(kind_phys), DIMENSION(:,:), INTENT(out) :: exch_h,exch_m + real(kind_phys), DIMENSION(:), INTENT(in) :: xland, & + &ts,znt,hfx,qfx,uoce,voce !These 10 arrays are only allocated when bl_mynn_output > 0 - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & - & edmf_a,edmf_w,edmf_qt,edmf_thl,edmf_ent,edmf_qc, & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & + & edmf_a,edmf_w,edmf_qt,edmf_thl,edmf_ent,edmf_qc, & & sub_thl3D,sub_sqv3D,det_thl3D,det_sqv3D -! REAL, DIMENSION(IMS:IME,KMS:KME) :: & +! real, DIMENSION(IMS:IME,KMS:KME) :: & ! & edmf_a_dd,edmf_w_dd,edmf_qt_dd,edmf_thl_dd,edmf_ent_dd,edmf_qc_dd - REAL(kind=kind_phys), DIMENSION(:), INTENT(inout) :: Pblh - REAL, DIMENSION(:), INTENT(inout) :: rmol + real(kind_phys), DIMENSION(:), INTENT(inout) :: Pblh + real(kind_phys), DIMENSION(:), INTENT(inout) :: rmol - REAL, DIMENSION(IMS:IME) :: psig_bl,psig_shcu + real(kind_phys), DIMENSION(IMS:IME) :: psig_bl,psig_shcu - INTEGER,DIMENSION(:),INTENT(INOUT) :: & + INTEGER,DIMENSION(:),INTENT(INOUT) :: & &KPBL,nupdraft,ktop_plume - REAL(kind=kind_phys), DIMENSION(:), INTENT(out) :: maxmf + real(kind_phys), DIMENSION(:), INTENT(out) :: maxmf - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: el_pbl + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: el_pbl - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(out) :: & + real(kind_phys), DIMENSION(:,:), INTENT(out) :: & &qWT,qSHEAR,qBUOY,qDISS,dqke ! 3D budget arrays are not allocated when tke_budget == 0 ! 1D (local) budget arrays are used for passing between subroutines. - REAL, DIMENSION(kts:kte) :: qwt1,qshear1,qbuoy1,qdiss1, & - &dqke1,diss_heat + real(kind_phys), DIMENSION(kts:kte) :: & + &qwt1,qshear1,qbuoy1,qdiss1,dqke1,diss_heat - REAL(kind=kind_phys), DIMENSION(:,:), intent(out) :: Sh3D,Sm3D + real(kind_phys), DIMENSION(:,:), intent(out) :: Sh3D,Sm3D - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & &qc_bl,qi_bl,cldfra_bl - REAL, DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D,cldfra_bl1D, & - qc_bl1D_old,qi_bl1D_old,cldfra_bl1D_old + real(kind_phys), DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D, & + &cldfra_bl1D,qc_bl1D_old,qi_bl1D_old,cldfra_bl1D_old ! smoke/chemical arrays INTEGER, INTENT(IN ) :: nchem, kdvel, ndvel - REAL(kind=kind_phys), DIMENSION(:,:,:), INTENT(INOUT) :: chem3d - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(IN) :: vdep - REAL(kind=kind_phys), DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO + real(kind_phys), DIMENSION(:,:,:), INTENT(INOUT) :: chem3d + real(kind_phys), DIMENSION(:,:), INTENT(IN) :: vdep + real(kind_phys), DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO !local - REAL, DIMENSION(kts:kte ,nchem) :: chem1 - REAL, DIMENSION(kts:kte+1,nchem) :: s_awchem1 - REAL, DIMENSION(ndvel) :: vd1 + real(kind_phys), DIMENSION(kts:kte ,nchem) :: chem1 + real(kind_phys), DIMENSION(kts:kte+1,nchem) :: s_awchem1 + real(kind_phys), DIMENSION(ndvel) :: vd1 INTEGER :: ic !local vars INTEGER :: ITF,JTF,KTF, IMD,JMD INTEGER :: i,j,k,kproblem - REAL, DIMENSION(KTS:KTE) :: thl,tl,qv1,qc1,qi1,qs1,sqw, & + real(kind_phys), DIMENSION(KTS:KTE) :: & + &thl,tl,qv1,qc1,qi1,qs1,sqw, & &el, dfm, dfh, dfq, tcd, qcd, pdk, pdt, pdq, pdc, & &vt, vq, sgm - REAL, DIMENSION(KTS:KTE) :: thetav,sh,sm,u1,v1,w1,p1, & + real(kind_phys), DIMENSION(KTS:KTE) :: & + &thetav,sh,sm,u1,v1,w1,p1, & &ex1,dz1,th1,tk1,rho1,qke1,tsq1,qsq1,cov1, & &sqv,sqi,sqc,sqs, & &du1,dv1,dth1,dqv1,dqc1,dqi1,dqs1,ozone1, & @@ -525,40 +527,46 @@ SUBROUTINE mynn_bl_driver( & &qnbca1,dqnwfa1,dqnifa1,dqnbca1,dozone1 !mass-flux variables - REAL, DIMENSION(KTS:KTE) :: dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf - REAL, DIMENSION(KTS:KTE) :: edmf_a1,edmf_w1,edmf_qt1, & - &edmf_thl1,edmf_ent1,edmf_qc1 - REAL, DIMENSION(KTS:KTE) :: edmf_a_dd1,edmf_w_dd1, & - &edmf_qt_dd1,edmf_thl_dd1, & + real(kind_phys), DIMENSION(KTS:KTE) :: & + &dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf + real(kind_phys), DIMENSION(KTS:KTE) :: & + &edmf_a1,edmf_w1,edmf_qt1,edmf_thl1, & + &edmf_ent1,edmf_qc1 + real(kind_phys), DIMENSION(KTS:KTE) :: & + &edmf_a_dd1,edmf_w_dd1,edmf_qt_dd1,edmf_thl_dd1, & &edmf_ent_dd1,edmf_qc_dd1 - REAL, DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v,& - det_thl,det_sqv,det_sqc,det_u,det_v - REAL,DIMENSION(KTS:KTE+1) :: s_aw1,s_awthl1,s_awqt1, & - s_awqv1,s_awqc1,s_awu1,s_awv1,s_awqke1, & - s_awqnc1,s_awqni1,s_awqnwfa1,s_awqnifa1, & - s_awqnbca1 - REAL,DIMENSION(KTS:KTE+1) :: sd_aw1,sd_awthl1,sd_awqt1, & - sd_awqv1,sd_awqc1,sd_awu1,sd_awv1,sd_awqke1 - - REAL, DIMENSION(KTS:KTE+1) :: zw - REAL :: cpm,sqcg,flt,fltv,flq,flqv,flqc,pmz,phh,exnerg,zet,phi_m,& - & afk,abk,ts_decay, qc_bl2, qi_bl2, & - & th_sfc,ztop_plume,wsp + real(kind_phys), DIMENSION(KTS:KTE) :: & + &sub_thl,sub_sqv,sub_u,sub_v, & + &det_thl,det_sqv,det_sqc,det_u,det_v + real(kind_phys), DIMENSION(KTS:KTE+1) :: & + &s_aw1,s_awthl1,s_awqt1, & + &s_awqv1,s_awqc1,s_awu1,s_awv1,s_awqke1, & + &s_awqnc1,s_awqni1,s_awqnwfa1,s_awqnifa1, & + &s_awqnbca1 + real(kind_phys), DIMENSION(KTS:KTE+1) :: & + &sd_aw1,sd_awthl1,sd_awqt1, & + &sd_awqv1,sd_awqc1,sd_awu1,sd_awv1,sd_awqke1 + + real(kind_phys), DIMENSION(KTS:KTE+1) :: zw + real(kind_phys) :: cpm,sqcg,flt,fltv,flq,flqv,flqc, & + &pmz,phh,exnerg,zet,phi_m, & + &afk,abk,ts_decay, qc_bl2, qi_bl2, & + &th_sfc,ztop_plume,wsp !top-down diffusion - REAL, DIMENSION(ITS:ITE) :: maxKHtopdown - REAL, DIMENSION(KTS:KTE) :: KHtopdown,TKEprodTD + real(kind_phys), DIMENSION(ITS:ITE) :: maxKHtopdown + real(kind_phys), DIMENSION(KTS:KTE) :: KHtopdown,TKEprodTD LOGICAL :: INITIALIZE_QKE,problem ! Stochastic fields - INTEGER, INTENT(IN) :: spp_pbl - REAL(kind=kind_phys), DIMENSION( :, :), INTENT(IN) :: pattern_spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(:,:), INTENT(IN) :: pattern_spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col ! Substepping TKE INTEGER :: nsub - real(kind=kind_phys) :: delt2 + real(kind_phys) :: delt2 if (debug_code) then !check incoming values @@ -1502,26 +1510,27 @@ SUBROUTINE mym_initialize ( & & spp_pbl,rstoch_col) ! !------------------------------------------------------------------- - - INTEGER, INTENT(IN) :: kts,kte - INTEGER, INTENT(IN) :: bl_mynn_mixlength - LOGICAL, INTENT(IN) :: INITIALIZE_QKE -! REAL, INTENT(IN) :: ust, rmo, pmz, phh, flt, flq - REAL, INTENT(IN) :: rmo, Psig_bl, xland - REAL(kind=kind_phys), INTENT(IN) :: dx, ust, zi - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,cldfra_bl1D,& - edmf_w1,edmf_a1 - REAL, DIMENSION(kts:kte), INTENT(out) :: tsq,qsq,cov - REAL, DIMENSION(kts:kte), INTENT(inout) :: el,qke - REAL, DIMENSION(kts:kte) :: & - &ql,pdk,pdt,pdq,pdc,dtl,dqw,dtv,& + + integer, INTENT(IN) :: kts,kte + integer, INTENT(IN) :: bl_mynn_mixlength + logical, INTENT(IN) :: INITIALIZE_QKE +! real(kind_phys), INTENT(IN) :: ust, rmo, pmz, phh, flt, flq + real(kind_phys), INTENT(IN) :: rmo, Psig_bl, xland + real(kind_phys), INTENT(IN) :: dx, ust, zi + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v,thl,& + &qw,cldfra_bl1D,edmf_w1,edmf_a1 + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: tsq,qsq,cov + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: el,qke + real(kind_phys), DIMENSION(kts:kte) :: & + &ql,pdk,pdt,pdq,pdc,dtl,dqw,dtv, & &gm,gh,sm,sh,qkw,vt,vq INTEGER :: k,l,lmax - REAL :: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1.,flt=0.,fltv=0.,flq=0.,tmpq - REAL, DIMENSION(kts:kte) :: theta,thetav - REAL, DIMENSION(kts:kte) :: rstoch_col + real(kind_phys):: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1., & + &flt=0.,fltv=0.,flq=0.,tmpq + real(kind_phys), DIMENSION(kts:kte) :: theta,thetav + real(kind_phys), DIMENSION(kts:kte) :: rstoch_col INTEGER ::spp_pbl !> - At first ql, vt and vq are set to zero. @@ -1706,18 +1715,19 @@ SUBROUTINE mym_level2 (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,ql,vt,vq,& - thetav - REAL, DIMENSION(kts:kte), INTENT(out) :: & + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v, & + &thl,qw,ql,vt,vq,thetav + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: & &dtl,dqw,dtv,gm,gh,sm,sh - INTEGER :: k + integer :: k - REAL :: rfc,f1,f2,rf1,rf2,smc,shc,& - &ri1,ri2,ri3,ri4,duz,dtz,dqz,vtt,vqq,dtq,dzk,afk,abk,ri,rf + real(kind_phys):: rfc,f1,f2,rf1,rf2,smc,shc, & + &ri1,ri2,ri3,ri4,duz,dtz,dqz,vtt,vqq,dtq,dzk, & + &afk,abk,ri,rf - REAL :: a2fac + real(kind_phys):: a2fac ! ev = 2.5e6 ! tv0 = 0.61*tref @@ -1844,51 +1854,49 @@ SUBROUTINE mym_length ( & #endif INTEGER, INTENT(IN) :: bl_mynn_mixlength - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,fltv,flq,Psig_bl,xland - REAL(kind=kind_phys), INTENT(IN) :: dx,zi - REAL, DIMENSION(kts:kte), INTENT(IN) :: u1,v1,qke,vt,vq,cldfra_bl1D,& - edmf_w1,edmf_a1 - REAL, DIMENSION(kts:kte), INTENT(out) :: qkw, el - REAL, DIMENSION(kts:kte), INTENT(in) :: dtv - - REAL :: elt,vsc - - REAL, DIMENSION(kts:kte), INTENT(IN) :: theta - REAL, DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg,thetaw - REAL :: wt,wt2,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: zw + real(kind_phys), INTENT(in) :: rmo,flt,fltv,flq,Psig_bl,xland + real(kind_phys), INTENT(IN) :: dx,zi + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: u1,v1, & + &qke,vt,vq,cldfra_bl1D,edmf_w1,edmf_a1 + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: qkw, el + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dtv + real(kind_phys):: elt,vsc + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: theta + real(kind_phys), DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg,thetaw + real(kind_phys):: wt,wt2,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg ! THE FOLLOWING CONSTANTS ARE IMPORTANT FOR REGULATING THE ! MIXING LENGTHS: - REAL :: cns, & !< for surface layer (els) in stable conditions - alp1, & !< for turbulent length scale (elt) - alp2, & !< for buoyancy length scale (elb) - alp3, & !< for buoyancy enhancement factor of elb - alp4, & !< for surface layer (els) in unstable conditions - alp5, & !< for BouLac mixing length or above PBLH - alp6 !< for mass-flux/ + real(kind_phys):: cns, & !< for surface layer (els) in stable conditions + alp1, & !< for turbulent length scale (elt) + alp2, & !< for buoyancy length scale (elb) + alp3, & !< for buoyancy enhancement factor of elb + alp4, & !< for surface layer (els) in unstable conditions + alp5, & !< for BouLac mixing length or above PBLH + alp6 !< for mass-flux/ !THE FOLLOWING LIMITS DO NOT DIRECTLY AFFECT THE ACTUAL PBLH. !THEY ONLY IMPOSE LIMITS ON THE CALCULATION OF THE MIXING LENGTH !SCALES SO THAT THE BOULAC MIXING LENGTH (IN FREE ATMOS) DOES !NOT ENCROACH UPON THE BOUNDARY LAYER MIXING LENGTH (els, elb & elt). - REAL, PARAMETER :: minzi = 300. !< min mixed-layer height - REAL, PARAMETER :: maxdz = 750. !< max (half) transition layer depth + real(kind_phys), PARAMETER :: minzi = 300. !< min mixed-layer height + real(kind_phys), PARAMETER :: maxdz = 750. !< max (half) transition layer depth !! =0.3*2500 m PBLH, so the transition !! layer stops growing for PBLHs > 2.5 km. - REAL, PARAMETER :: mindz = 300. !< 300 !min (half) transition layer depth + real(kind_phys), PARAMETER :: mindz = 300. !< 300 !min (half) transition layer depth !SURFACE LAYER LENGTH SCALE MODS TO REDUCE IMPACT IN UPPER BOUNDARY LAYER - REAL, PARAMETER :: ZSLH = 100. !< Max height correlated to surface conditions (m) - REAL, PARAMETER :: CSL = 2. !< CSL = constant of proportionality to L O(1) + real(kind_phys), PARAMETER :: ZSLH = 100. !< Max height correlated to surface conditions (m) + real(kind_phys), PARAMETER :: CSL = 2. !< CSL = constant of proportionality to L O(1) INTEGER :: i,j,k - REAL :: afk,abk,zwk,zwk1,dzk,qdz,vflx,bv,tau_cloud,wstar,elb,els, & - & elf,el_stab,el_mf,el_stab_mf,elb_mf, & + real(kind_phys):: afk,abk,zwk,zwk1,dzk,qdz,vflx,bv,tau_cloud, & + & wstar,elb,els,elf,el_stab,el_mf,el_stab_mf,elb_mf, & & PBLH_PLUS_ENT,Uonset,Ugrid,wt_u,el_les - REAL, PARAMETER :: ctau = 1000. !constant for tau_cloud + real(kind_phys), PARAMETER :: ctau = 1000. !constant for tau_cloud ! tv0 = 0.61*tref ! gtr = 9.81/tref @@ -2249,14 +2257,14 @@ SUBROUTINE boulac_length0(k,kts,kte,zw,dz,qtke,theta,lb1,lb2) !------------------------------------------------------------------- INTEGER, INTENT(IN) :: k,kts,kte - REAL, DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta - REAL, INTENT(OUT) :: lb1,lb2 - REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta + real(kind_phys), INTENT(OUT) :: lb1,lb2 + real(kind_phys), DIMENSION(kts:kte+1), INTENT(IN) :: zw !LOCAL VARS INTEGER :: izz, found - REAL :: dlu,dld - REAL :: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz + real(kind_phys):: dlu,dld + real(kind_phys):: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz !---------------------------------- @@ -2399,15 +2407,15 @@ SUBROUTINE boulac_length(kts,kte,zw,dz,qtke,theta,lb1,lb2) !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte - REAL, DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta - REAL, DIMENSION(kts:kte), INTENT(OUT) :: lb1,lb2 - REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta + real(kind_phys), DIMENSION(kts:kte), INTENT(OUT):: lb1,lb2 + real(kind_phys), DIMENSION(kts:kte+1), INTENT(IN) :: zw !LOCAL VARS INTEGER :: iz, izz, found - REAL, DIMENSION(kts:kte) :: dlu,dld - REAL, PARAMETER :: Lmax=2000. !soft limit - REAL :: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz + real(kind_phys), DIMENSION(kts:kte) :: dlu,dld + real(kind_phys), PARAMETER :: Lmax=2000. !soft limit + real(kind_phys):: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz !print*,"IN MYNN-BouLac",kts, kte @@ -2619,39 +2627,38 @@ SUBROUTINE mym_turbulence ( & # define kte HARDCODE_VERTICAL #endif - INTEGER, INTENT(IN) :: bl_mynn_mixlength,tke_budget - REAL(kind=kind_phys), INTENT(IN) :: closure - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,fltv,flq,Psig_bl,Psig_shcu,xland - REAL(kind=kind_phys), INTENT(IN) :: dx,zi - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,thetav,qw, & - &ql,vt,vq,qke,tsq,qsq,cov,cldfra_bl1D,edmf_w1,edmf_a1, & + INTEGER, INTENT(IN) :: bl_mynn_mixlength,tke_budget + real(kind_phys), INTENT(IN) :: closure + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: zw + real(kind_phys), INTENT(in) :: rmo,flt,fltv,flq, & + &Psig_bl,Psig_shcu,xland,dx,zi + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v,thl,thetav,qw, & + &ql,vt,vq,qke,tsq,qsq,cov,cldfra_bl1D,edmf_w1,edmf_a1, & &TKEprodTD - REAL, DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq, & + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq, & &pdk,pdt,pdq,pdc,tcd,qcd,el - REAL, DIMENSION(kts:kte), INTENT(inout) :: & + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: & qWT1D,qSHEAR1D,qBUOY1D,qDISS1D - REAL :: q3sq_old,dlsq1,qWTP_old,qWTP_new - REAL :: dudz,dvdz,dTdz, & - upwp,vpwp,Tpwp + real(kind_phys):: q3sq_old,dlsq1,qWTP_old,qWTP_new + real(kind_phys):: dudz,dvdz,dTdz,upwp,vpwp,Tpwp - REAL, DIMENSION(kts:kte) :: qkw,dtl,dqw,dtv,gm,gh,sm,sh + real(kind_phys), DIMENSION(kts:kte) :: qkw,dtl,dqw,dtv,gm,gh,sm,sh INTEGER :: k -! REAL :: cc2,cc3,e1c,e2c,e3c,e4c,e5c - REAL :: e6c,dzk,afk,abk,vtt,vqq, & +! real(kind_phys):: cc2,cc3,e1c,e2c,e3c,e4c,e5c + real(kind_phys):: e6c,dzk,afk,abk,vtt,vqq, & &cw25,clow,cupp,gamt,gamq,smd,gamv,elq,elh - REAL :: cldavg - REAL, DIMENSION(kts:kte), INTENT(in) :: theta + real(kind_phys):: cldavg + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: theta - REAL :: a2fac, duz, ri !JOE-Canuto/Kitamura mod + real(kind_phys):: a2fac, duz, ri !JOE-Canuto/Kitamura mod - REAL:: auh,aum,adh,adm,aeh,aem,Req,Rsl,Rsl2, & - gmelq,sm20,sh20,sm25max,sh25max,sm25min,sh25min, & + real:: auh,aum,adh,adm,aeh,aem,Req,Rsl,Rsl2, & + gmelq,sm20,sh20,sm25max,sh25max,sm25min,sh25min, & sm_pbl,sh_pbl,zi2,wt,slht,wtpr DOUBLE PRECISION q2sq, t2sq, r2sq, c2sq, elsq, gmel, ghel @@ -2659,11 +2666,10 @@ SUBROUTINE mym_turbulence ( & DOUBLE PRECISION e1, e2, e3, e4, enum, eden, wden ! Stochastic - INTEGER, INTENT(IN) :: spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col - REAL :: Prnum, shb - REAL, PARAMETER :: Prlimit = 5.0 - + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col + real(kind_phys):: Prnum, shb + real(kind_phys), PARAMETER :: Prlimit = 5.0 ! ! tv0 = 0.61*tref @@ -3191,29 +3197,29 @@ SUBROUTINE mym_predict (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL(kind=kind_phys), INTENT(IN) :: closure + real(kind_phys), INTENT(IN) :: closure INTEGER, INTENT(IN) :: bl_mynn_edmf_tke,tke_budget - REAL, DIMENSION(kts:kte), INTENT(IN) :: dz, dfq, el, rho - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc - REAL, INTENT(IN) :: flt, flq, pmz, phh - REAL(kind=kind_phys), INTENT(IN) :: ust, delt - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: dz, dfq, el, rho + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc + real(kind_phys), INTENT(IN) :: flt, flq, pmz, phh + real(kind_phys), INTENT(IN) :: ust, delt + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov ! WA 8/3/15 - REAL, DIMENSION(kts:kte+1), INTENT(INOUT) :: s_awqke,s_aw + real(kind_phys), DIMENSION(kts:kte+1), INTENT(INOUT) :: s_awqke,s_aw !! TKE budget (Puhales, 2020, WRF 4.2.1) << EOB - REAL, DIMENSION(kts:kte), INTENT(OUT) :: qWT1D, qDISS1D - REAL, DIMENSION(kts:kte) :: tke_up,dzinv + real(kind_phys), DIMENSION(kts:kte), INTENT(OUT) :: qWT1D, qDISS1D + real(kind_phys), DIMENSION(kts:kte) :: tke_up,dzinv !! >> EOB INTEGER :: k - REAL, DIMENSION(kts:kte) :: qkw, bp, rp, df3q - REAL :: vkz,pdk1,phm,pdt1,pdq1,pdc1,b1l,b2l,onoff - REAL, DIMENSION(kts:kte) :: dtz - REAL, DIMENSION(kts:kte) :: a,b,c,d,x + real(kind_phys), DIMENSION(kts:kte) :: qkw, bp, rp, df3q + real(kind_phys):: vkz,pdk1,phm,pdt1,pdq1,pdc1,b1l,b2l,onoff + real(kind_phys), DIMENSION(kts:kte) :: dtz + real(kind_phys), DIMENSION(kts:kte) :: a,b,c,d,x - REAL, DIMENSION(kts:kte) :: rhoinv - REAL, DIMENSION(kts:kte+1) :: rhoz,kqdz,kmdz + real(kind_phys), DIMENSION(kts:kte) :: rhoinv + real(kind_phys), DIMENSION(kts:kte+1) :: rhoz,kqdz,kmdz ! REGULATE THE MOMENTUM MIXING FROM THE MASS-FLUX SCHEME (on or off) IF (bl_mynn_edmf_tke == 0) THEN @@ -3599,45 +3605,45 @@ SUBROUTINE mym_condensation (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(IN) :: HFX1,rmo,xland - REAL(kind=kind_phys), INTENT(IN) :: dx,pblh1 - REAL, DIMENSION(kts:kte), INTENT(IN) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw - REAL, DIMENSION(kts:kte), INTENT(IN) :: p,exner,thl,qw,qv,qc,qi,qs, & - &tsq, qsq, cov, th + real(kind_phys), INTENT(IN) :: HFX1,rmo,xland + real(kind_phys), INTENT(IN) :: dx,pblh1 + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(IN) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: p,exner,thl,qw, & + &qv,qc,qi,qs,tsq,qsq,cov,th - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: vt,vq,sgm + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: vt,vq,sgm - REAL, DIMENSION(kts:kte) :: alp,a,bet,b,ql,q1,RH - REAL, DIMENSION(kts:kte), INTENT(OUT) :: qc_bl1D,qi_bl1D, & - cldfra_bl1D + real(kind_phys), DIMENSION(kts:kte) :: alp,a,bet,b,ql,q1,RH + real(kind_phys), DIMENSION(kts:kte), INTENT(OUT) :: qc_bl1D,qi_bl1D, & + &cldfra_bl1D DOUBLE PRECISION :: t3sq, r3sq, c3sq - REAL :: qsl,esat,qsat,dqsl,cld0,q1k,qlk,eq1,qll,& - &q2p,pt,rac,qt,t,xl,rsl,cpm,Fng,qww,alpha,beta,bb,& - &ls,wt,cld_factor,fac_damp,liq_frac,ql_ice,ql_water,& + real(kind_phys):: qsl,esat,qsat,dqsl,cld0,q1k,qlk,eq1,qll, & + &q2p,pt,rac,qt,t,xl,rsl,cpm,Fng,qww,alpha,beta,bb, & + &ls,wt,cld_factor,fac_damp,liq_frac,ql_ice,ql_water, & &qmq,qsat_tk,q1_rh,rh_hack - REAL, PARAMETER :: rhcrit=0.83 !for hom pdf min sigma + real(kind_phys), PARAMETER :: rhcrit=0.83 !for hom pdf min sigma INTEGER :: i,j,k - REAL :: erf + real(kind_phys):: erf !VARIABLES FOR ALTERNATIVE SIGMA - REAL::dth,dtl,dqw,dzk,els - REAL, DIMENSION(kts:kte), INTENT(IN) :: Sh,el + real:: dth,dtl,dqw,dzk,els + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: Sh,el !variables for SGS BL clouds - REAL :: zagl,damp,PBLH2 - REAL :: cfmax + real(kind_phys) :: zagl,damp,PBLH2 + real(kind_phys) :: cfmax !JAYMES: variables for tropopause-height estimation - REAL :: theta1, theta2, ht1, ht2 - INTEGER :: k_tropo + real(kind_phys) :: theta1, theta2, ht1, ht2 + INTEGER :: k_tropo ! Stochastic - INTEGER, INTENT(IN) :: spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col - REAL :: qw_pert + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col + real(kind_phys) :: qw_pert ! First, obtain an estimate for the tropopause height (k), using the method employed in the ! Thompson subgrid-cloud scheme. This height will be a consideration later when determining @@ -4035,46 +4041,47 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ! flq - surface flux of qw ! mass-flux plumes - REAL, DIMENSION(kts:kte+1), INTENT(in) :: s_aw,s_awthl,s_awqt, & - &s_awqnc,s_awqni,s_awqv,s_awqc,s_awu,s_awv, & + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: s_aw, & + &s_awthl,s_awqt,s_awqnc,s_awqni,s_awqv,s_awqc,s_awu,s_awv, & &s_awqnwfa,s_awqnifa,s_awqnbca, & &sd_aw,sd_awthl,sd_awqt,sd_awqv,sd_awqc,sd_awu,sd_awv ! tendencies from mass-flux environmental subsidence and detrainment - REAL, DIMENSION(kts:kte), INTENT(in) :: sub_thl,sub_sqv, & + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: sub_thl,sub_sqv, & &sub_u,sub_v,det_thl,det_sqv,det_sqc,det_u,det_v - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,th,tk,qv,qc,qi,qs,qni,qnc,& - &rho,p,exner,dfq,dz,tsq,qsq,cov,tcd,qcd,cldfra_bl1d,diss_heat - REAL, DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc,sqi,sqs, & - &qnwfa,qnifa,qnbca,ozone,dfm,dfh - REAL, DIMENSION(kts:kte), INTENT(inout) :: du,dv,dth,dqv,dqc,dqi,dqs, & - &dqni,dqnc,dqnwfa,dqnifa,dqnbca,dozone - REAL, INTENT(IN) :: flt,flq,flqv,flqc,uoce,voce - REAL(kind=kind_phys), INTENT(IN) :: ust,delt,psfc,wspd + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v,th,tk,qv,qc,qi,& + &qs,qni,qnc,rho,p,exner,dfq,dz,tsq,qsq,cov,tcd,qcd, & + &cldfra_bl1d,diss_heat + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc,& + &sqi,sqs,qnwfa,qnifa,qnbca,ozone,dfm,dfh + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: du,dv,dth,dqv, & + &dqc,dqi,dqs,dqni,dqnc,dqnwfa,dqnifa,dqnbca,dozone + real(kind_phys), INTENT(IN) :: flt,flq,flqv,flqc,uoce,voce + real(kind_phys), INTENT(IN) :: ust,delt,psfc,wspd !debugging - REAL ::wsp,wsp2,tk2,th2 + real(kind_phys):: wsp,wsp2,tk2,th2 LOGICAL :: problem integer :: kproblem -! REAL, INTENT(IN) :: gradu_top,gradv_top,gradth_top,gradqv_top +! real(kind_phys), INTENT(IN) :: gradu_top,gradv_top,gradth_top,gradqv_top !local vars - REAL, DIMENSION(kts:kte) :: dtz,dfhc,dfmc,delp - REAL, DIMENSION(kts:kte) :: sqv2,sqc2,sqi2,sqs2,sqw2,qni2,qnc2, & !AFTER MIXING - qnwfa2,qnifa2,qnbca2,ozone2 - REAL, DIMENSION(kts:kte) :: zfac,plumeKh,rhoinv - REAL, DIMENSION(kts:kte) :: a,b,c,d,x - REAL, DIMENSION(kts:kte+1) :: rhoz, & !rho on model interface - & khdz, kmdz - REAL :: rhs,gfluxm,gfluxp,dztop,maxdfh,mindfh,maxcf,maxKh,zw - REAL :: t,esat,qsl,onoff,kh,km,dzk,rhosfc - REAL :: ustdrag,ustdiff,qvflux - REAL :: th_new,portion_qc,portion_qi,condensate,qsat + real(kind_phys), DIMENSION(kts:kte) :: dtz,dfhc,dfmc,delp + real(kind_phys), DIMENSION(kts:kte) :: sqv2,sqc2,sqi2,sqs2,sqw2, & + &qni2,qnc2,qnwfa2,qnifa2,qnbca2,ozone2 + real(kind_phys), DIMENSION(kts:kte) :: zfac,plumeKh,rhoinv + real(kind_phys), DIMENSION(kts:kte) :: a,b,c,d,x + real(kind_phys), DIMENSION(kts:kte+1) :: rhoz, & !rho on model interface + &khdz,kmdz + real(kind_phys):: rhs,gfluxm,gfluxp,dztop,maxdfh,mindfh,maxcf,maxKh,zw + real(kind_phys):: t,esat,qsl,onoff,kh,km,dzk,rhosfc + real(kind_phys):: ustdrag,ustdiff,qvflux + real(kind_phys):: th_new,portion_qc,portion_qi,condensate,qsat INTEGER :: k,kk !Activate nonlocal mixing from the mass-flux scheme for !number concentrations and aerosols (0.0 = no; 1.0 = yes) - REAL, PARAMETER :: nonloc = 1.0 + real(kind_phys), PARAMETER :: nonloc = 1.0 dztop=.5*(dz(kte)+dz(kte-1)) @@ -5095,8 +5102,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & END SUBROUTINE mynn_tendencies ! ================================================================== - SUBROUTINE moisture_check(kte, delt, dp, exner, & - qv, qc, qi, qs, th, & + SUBROUTINE moisture_check(kte, delt, dp, exner, & + qv, qc, qi, qs, th, & dqv, dqc, dqi, dqs, dth ) ! This subroutine was adopted from the CAM-UW ShCu scheme and @@ -5113,16 +5120,16 @@ SUBROUTINE moisture_check(kte, delt, dp, exner, & ! applying corresponding input tendencies and corrective tendencies. implicit none - integer, intent(in) :: kte - real(kind=kind_phys), intent(in) :: delt - real, dimension(kte), intent(in) :: dp, exner - real, dimension(kte), intent(inout) :: qv, qc, qi, qs, th - real, dimension(kte), intent(inout) :: dqv, dqc, dqi, dqs, dth + integer, intent(in) :: kte + real(kind_phys), intent(in) :: delt + real(kind_phys), dimension(kte), intent(in) :: dp, exner + real(kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, qs, th + real(kind_phys), dimension(kte), intent(inout) :: dqv, dqc, dqi, dqs, dth integer k - real :: dqc2, dqi2, dqs2, dqv2, sum, aa, dum - real, parameter :: qvmin = 1e-20, & - qcmin = 0.0, & - qimin = 0.0 + real(kind_phys):: dqc2, dqi2, dqs2, dqv2, sum, aa, dum + real(kind_phys), parameter :: qvmin = 1e-20, & + qcmin = 0.0, & + qimin = 0.0 do k = kte, 1, -1 ! From the top to the surface dqc2 = max(0.0, qcmin-qc(k)) !qc deficit (>=0) @@ -5199,35 +5206,35 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & !------------------------------------------------------------------- INTEGER, INTENT(in) :: kts,kte,i - REAL, DIMENSION(kts:kte), INTENT(IN) :: dfh,dz,tcd,qcd - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: rho - REAL, INTENT(IN) :: flt - REAL(kind=kind_phys), INTENT(IN) :: delt,pblh + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: dfh,dz,tcd,qcd + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: rho + real(kind_phys), INTENT(IN) :: flt + real(kind_phys), INTENT(IN) :: delt,pblh INTEGER, INTENT(IN) :: nchem, kdvel, ndvel - REAL, DIMENSION( kts:kte+1), INTENT(IN) :: s_aw - REAL, DIMENSION( kts:kte, nchem ), INTENT(INOUT) :: chem1 - REAL, DIMENSION( kts:kte+1,nchem), INTENT(IN) :: s_awchem - REAL, DIMENSION( ndvel ), INTENT(IN) :: vd1 - REAL(kind=kind_phys), INTENT(IN) :: emis_ant_no,frp + real(kind_phys), DIMENSION( kts:kte+1), INTENT(IN) :: s_aw + real(kind_phys), DIMENSION( kts:kte, nchem ), INTENT(INOUT) :: chem1 + real(kind_phys), DIMENSION( kts:kte+1,nchem), INTENT(IN) :: s_awchem + real(kind_phys), DIMENSION( ndvel ), INTENT(IN) :: vd1 + real(kind_phys), INTENT(IN) :: emis_ant_no,frp LOGICAL, INTENT(IN) :: rrfs_sd,enh_mix,smoke_dbg !local vars - REAL, DIMENSION(kts:kte) :: dtz - REAL, DIMENSION(kts:kte) :: a,b,c,d,x - REAL :: rhs,dztop - REAL :: t,dzk - REAL :: hght - REAL :: khdz_old, khdz_back + real(kind_phys), DIMENSION(kts:kte) :: dtz + real(kind_phys), DIMENSION(kts:kte) :: a,b,c,d,x + real(kind_phys):: rhs,dztop + real(kind_phys):: t,dzk + real(kind_phys):: hght + real(kind_phys):: khdz_old, khdz_back INTEGER :: k,kk,kmaxfire ! JLS 12/21/21 INTEGER :: ic ! Chemical array loop index INTEGER, SAVE :: icall - REAL, DIMENSION(kts:kte) :: rhoinv - REAL, DIMENSION(kts:kte+1) :: rhoz,khdz - REAL, PARAMETER :: NO_threshold = 10.0 ! For anthropogenic sources - REAL, PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing over big fires - REAL, PARAMETER :: pblh_threshold = 100.0 + real(kind_phys), DIMENSION(kts:kte) :: rhoinv + real(kind_phys), DIMENSION(kts:kte+1) :: rhoz,khdz + real(kind_phys), PARAMETER :: NO_threshold = 10.0 ! For anthropogenic sources + real(kind_phys), PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing over big fires + real(kind_phys), PARAMETER :: pblh_threshold = 100.0 dztop=.5*(dz(kte)+dz(kte-1)) @@ -5328,13 +5335,13 @@ SUBROUTINE retrieve_exchange_coeffs(kts,kte,& INTEGER , INTENT(in) :: kts,kte - REAL, DIMENSION(KtS:KtE), INTENT(in) :: dz,dfm,dfh + real(kind_phys), DIMENSION(KtS:KtE), INTENT(in) :: dz,dfm,dfh - REAL, DIMENSION(KtS:KtE), INTENT(out) :: K_m, K_h + real(kind_phys), DIMENSION(KtS:KtE), INTENT(out) :: K_m, K_h INTEGER :: k - REAL :: dzk + real(kind_phys):: dzk K_m(kts)=0. K_h(kts)=0. @@ -5360,12 +5367,12 @@ SUBROUTINE tridiag(n,a,b,c,d) !------------------------------------------------------------------- INTEGER, INTENT(in):: n - REAL, DIMENSION(n), INTENT(in) :: a,b - REAL, DIMENSION(n), INTENT(inout) :: c,d + real(kind_phys), DIMENSION(n), INTENT(in) :: a,b + real(kind_phys), DIMENSION(n), INTENT(inout) :: c,d INTEGER :: i - REAL :: p - REAL, DIMENSION(n) :: q + real(kind_phys):: p + real(kind_phys), DIMENSION(n) :: q c(n)=0. q(1)=-c(1)/b(1) @@ -5395,10 +5402,10 @@ subroutine tridiag2(n,a,b,c,d,x) ! n - number of unknowns (levels) integer,intent(in) :: n - real, dimension(n),intent(in) :: a,b,c,d - real ,dimension(n),intent(out) :: x - real ,dimension(n) :: cp,dp - real :: m + real(kind_phys), dimension(n), intent(in) :: a,b,c,d + real(kind_phys), dimension(n), intent(out):: x + real(kind_phys), dimension(n) :: cp,dp + real(kind_phys):: m integer :: i ! initialize c-prime and d-prime @@ -5437,12 +5444,12 @@ subroutine tridiag3(kte,a,b,c,d,x) implicit none integer,intent(in) :: kte integer, parameter :: kts=1 - real, dimension(kte) :: a,b,c,d - real ,dimension(kte),intent(out) :: x + real(kind_phys), dimension(kte) :: a,b,c,d + real(kind_phys), dimension(kte), intent(out) :: x integer :: in ! integer kms,kme,kts,kte,in -! real a(kms:kme,3),c(kms:kme),x(kms:kme) +! real(kind_phys)a(kms:kme,3),c(kms:kme),x(kms:kme) do in=kte-1,kts,-1 d(in)=d(in)-c(in)*d(in+1)/b(in+1) @@ -5506,15 +5513,15 @@ SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea,kzi) # define kte HARDCODE_VERTICAL #endif - REAL(kind=kind_phys), INTENT(OUT) :: zi - REAL, INTENT(IN) :: landsea - REAL, DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D - REAL, DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D + real(kind_phys), INTENT(OUT) :: zi + real(kind_phys), INTENT(IN) :: landsea + real(kind_phys), DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D + real(kind_phys), DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D !LOCAL VARS - REAL :: PBLH_TKE,qtke,qtkem1,wt,maxqke,TKEeps,minthv - REAL :: delt_thv !delta theta-v; dependent on land/sea point - REAL, PARAMETER :: sbl_lim = 200. !upper limit of stable BL height (m). - REAL, PARAMETER :: sbl_damp = 400. !transition length for blending (m). + real(kind_phys):: PBLH_TKE,qtke,qtkem1,wt,maxqke,TKEeps,minthv + real(kind_phys):: delt_thv !delta theta-v; dependent on land/sea point + real(kind_phys), PARAMETER :: sbl_lim = 200. !upper limit of stable BL height (m). + real(kind_phys), PARAMETER :: sbl_damp = 400. !transition length for blending (m). INTEGER :: I,J,K,kthv,ktke,kzi !Initialize KPBL (kzi) @@ -5693,141 +5700,134 @@ SUBROUTINE DMP_mf( & #endif ! Stochastic - INTEGER, INTENT(IN) :: spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col - - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,W,TH,THL,TK,QT,QV,QC, & - exner,dz,THV,P,rho,qke,qnc,qni,qnwfa,qnifa,qnbca - REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: zw !height at full-sigma - REAL, INTENT(IN) :: flt,fltv,flq,flqv,Psig_shcu,landsea,ts - REAL(kind=kind_phys), INTENT(IN) :: dx,dt,ust,pblh + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col + + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: & + &U,V,W,TH,THL,TK,QT,QV,QC, & + &exner,dz,THV,P,rho,qke,qnc,qni,qnwfa,qnifa,qnbca + real(kind_phys),DIMENSION(KTS:KTE+1), INTENT(IN) :: zw !height at full-sigma + real(kind_phys), INTENT(IN) :: flt,fltv,flq,flqv,Psig_shcu, & + &landsea,ts,dx,dt,ust,pblh LOGICAL, OPTIONAL :: F_QC,F_QI,F_QNC,F_QNI,F_QNWFA,F_QNIFA,F_QNBCA ! outputs - updraft properties - REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a,edmf_w, & + real(kind_phys),DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a,edmf_w, & & edmf_qt,edmf_thl,edmf_ent,edmf_qc !add one local edmf variable: - REAL,DIMENSION(KTS:KTE) :: edmf_th + real(kind_phys),DIMENSION(KTS:KTE) :: edmf_th ! output INTEGER, INTENT(OUT) :: nup2,ktop - REAL(kind=kind_phys), INTENT(OUT) :: maxmf - REAL, INTENT(OUT) :: ztop + real(kind_phys), INTENT(OUT) :: maxmf + real(kind_phys), INTENT(OUT) :: ztop ! outputs - variables needed for solver - REAL,DIMENSION(KTS:KTE+1) :: s_aw, & !sum ai*rho*wis_awphi - s_awthl, & !sum ai*rho*wi*phii - s_awqt, & - s_awqv, & - s_awqc, & - s_awqnc, & - s_awqni, & - s_awqnwfa, & - s_awqnifa, & - s_awqnbca, & - s_awu, & - s_awv, & - s_awqke, s_aw2 - - REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: qc_bl1d,cldfra_bl1d, & - qc_bl1d_old,cldfra_bl1d_old + real(kind_phys),DIMENSION(KTS:KTE+1) :: s_aw, & !sum ai*rho*wis_awphi + &s_awthl,s_awqt,s_awqv,s_awqc,s_awqnc,s_awqni, & + &s_awqnwfa,s_awqnifa,s_awqnbca,s_awu,s_awv, & + &s_awqke,s_aw2 + + real(kind_phys),DIMENSION(KTS:KTE), INTENT(INOUT) :: & + &qc_bl1d,cldfra_bl1d,qc_bl1d_old,cldfra_bl1d_old INTEGER, PARAMETER :: nup=10, debug_mf=0 !------------- local variables ------------------- ! updraft properties defined on interfaces (k=1 is the top of the ! first model layer - REAL,DIMENSION(KTS:KTE+1,1:NUP) :: UPW,UPTHL,UPQT,UPQC,UPQV, & - UPA,UPU,UPV,UPTHV,UPQKE,UPQNC, & - UPQNI,UPQNWFA,UPQNIFA,UPQNBCA + real(kind_phys),DIMENSION(KTS:KTE+1,1:NUP) :: & + &UPW,UPTHL,UPQT,UPQC,UPQV, & + &UPA,UPU,UPV,UPTHV,UPQKE,UPQNC, & + &UPQNI,UPQNWFA,UPQNIFA,UPQNBCA ! entrainment variables - REAL,DIMENSION(KTS:KTE,1:NUP) :: ENT,ENTf - INTEGER,DIMENSION(KTS:KTE,1:NUP) :: ENTi + real(kind_phys),DIMENSION(KTS:KTE,1:NUP) :: ENT,ENTf + INTEGER,DIMENSION(KTS:KTE,1:NUP) :: ENTi ! internal variables INTEGER :: K,I,k50 - REAL :: fltv2,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & - pwmin,pwmax,wmin,wmax,wlv,Psig_w,maxw,maxqc,wpbl - REAL :: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,QNCn,QNIn, & + real(kind_phys):: fltv2,wstar,qstar,thstar,sigmaW,sigmaQT, & + &sigmaTH,z0,pwmin,pwmax,wmin,wmax,wlv,Psig_w,maxw,maxqc,wpbl + real(kind_phys):: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,QNCn,QNIn, & QNWFAn,QNIFAn,QNBCAn, & Wn2,Wn,EntEXP,EntEXM,EntW,BCOEFF,THVkm1,THVk,Pk,rho_int ! w parameters - REAL,PARAMETER :: & - &Wa=2./3., & - &Wb=0.002, & + real(kind_phys), PARAMETER :: & + &Wa=2./3., & + &Wb=0.002, & &Wc=1.5 ! Lateral entrainment parameters ( L0=100 and ENT0=0.1) were taken from ! Suselj et al (2013, jas). Note that Suselj et al (2014,waf) use L0=200 and ENT0=0.2. - REAL,PARAMETER :: & + real(kind_phys),PARAMETER :: & & L0=100., & & ENT0=0.1 ! Implement ideas from Neggers (2016, JAMES): - REAL, PARAMETER :: Atot = 0.10 ! Maximum total fractional area of all updrafts - REAL, PARAMETER :: lmax = 1000.! diameter of largest plume - REAL, PARAMETER :: dl = 100. ! diff size of each plume - the differential multiplied by the integrand - REAL, PARAMETER :: dcut = 1.2 ! max diameter of plume to parameterize relative to dx (km) - REAL :: d != -2.3 to -1.7 ;=-1.9 in Neggers paper; power law exponent for number density (N=Cl^d). + real(kind_phys), PARAMETER :: Atot = 0.10 ! Maximum total fractional area of all updrafts + real(kind_phys), PARAMETER :: lmax = 1000.! diameter of largest plume + real(kind_phys), PARAMETER :: dl = 100. ! diff size of each plume - the differential multiplied by the integrand + real(kind_phys), PARAMETER :: dcut = 1.2 ! max diameter of plume to parameterize relative to dx (km) + real(kind_phys):: d != -2.3 to -1.7 ;=-1.9 in Neggers paper; power law exponent for number density (N=Cl^d). ! Note that changing d to -2.0 makes each size plume equally contribute to the total coverage of all plumes. ! Note that changing d to -1.7 doubles the area coverage of the largest plumes relative to the smallest plumes. - REAL :: cn,c,l,n,an2,hux,maxwidth,wspd_pbl,cloud_base,width_flx + real(kind_phys):: cn,c,l,n,an2,hux,maxwidth,wspd_pbl,cloud_base,width_flx ! chem/smoke INTEGER, INTENT(IN) :: nchem - REAL,DIMENSION(:, :) :: chem1 - REAL,DIMENSION(kts:kte+1, nchem) :: s_awchem - REAL,DIMENSION(nchem) :: chemn - REAL,DIMENSION(KTS:KTE+1,1:NUP, nchem) :: UPCHEM + real(kind_phys),DIMENSION(:, :) :: chem1 + real(kind_phys),DIMENSION(kts:kte+1, nchem) :: s_awchem + real(kind_phys),DIMENSION(nchem) :: chemn + real(kind_phys),DIMENSION(KTS:KTE+1,1:NUP, nchem) :: UPCHEM INTEGER :: ic - REAL,DIMENSION(KTS:KTE+1, nchem) :: edmf_chem + real(kind_phys),DIMENSION(KTS:KTE+1, nchem) :: edmf_chem LOGICAL, INTENT(IN) :: mix_chem !JOE: add declaration of ERF - REAL :: ERF + real(kind_phys):: ERF LOGICAL :: superadiabatic ! VARIABLES FOR CHABOUREAU-BECHTOLD CLOUD FRACTION - REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: vt, vq, sgm - REAL :: sigq,xl,rsl,cpm,a,qmq,mf_cf,Aup,Q1,diffqt,qsat_tk,& - Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid, & + real(kind_phys),DIMENSION(KTS:KTE), INTENT(INOUT) :: vt, vq, sgm + real(kind_phys):: sigq,xl,rsl,cpm,a,qmq,mf_cf,Aup,Q1,diffqt,qsat_tk,& + Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid, & Ac_mf,Ac_strat,qc_mf - REAL, PARAMETER :: cf_thresh = 0.5 ! only overwrite stratus CF less than this value + real(kind_phys), PARAMETER :: cf_thresh = 0.5 ! only overwrite stratus CF less than this value ! Variables for plume interpolation/saturation check - REAL,DIMENSION(KTS:KTE) :: exneri,dzi - REAL :: THp, QTp, QCp, QCs, esat, qsl - REAL :: csigma,acfac,ac_wsp,ac_cld + real(kind_phys),DIMENSION(KTS:KTE) :: exneri,dzi + real(kind_phys):: THp, QTp, QCp, QCs, esat, qsl + real(kind_phys):: csigma,acfac,ac_wsp,ac_cld !plume overshoot INTEGER :: overshoot - REAL :: bvf, Frz, dzp + real(kind_phys):: bvf, Frz, dzp !Flux limiter: not let mass-flux of heat between k=1&2 exceed (fluxportion)*(surface heat flux). !This limiter makes adjustments to the entire column. - REAL :: adjustment, flx1 - REAL, PARAMETER :: fluxportion=0.75 ! set liberally, so has minimal impact. 0.5 starts to have a noticeable impact + real(kind_phys):: adjustment, flx1 + real(kind_phys), PARAMETER :: fluxportion=0.75 ! set liberally, so has minimal impact. 0.5 starts to have a noticeable impact ! over land (decrease maxMF by 10-20%), but no impact over water. !Subsidence - REAL,DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v, & !tendencies due to subsidence - det_thl,det_sqv,det_sqc,det_u,det_v, & !tendencied due to detrainment - envm_a,envm_w,envm_thl,envm_sqv,envm_sqc, & + real(kind_phys),DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v, & !tendencies due to subsidence + det_thl,det_sqv,det_sqc,det_u,det_v, & !tendencied due to detrainment + envm_a,envm_w,envm_thl,envm_sqv,envm_sqc, & envm_u,envm_v !environmental variables defined at middle of layer - REAL,DIMENSION(KTS:KTE+1) :: envi_a,envi_w !environmental variables defined at model interface - REAL :: temp,sublim,qc_ent,qv_ent,qt_ent,thl_ent,detrate, & - detrateUV,oow,exc_fac,aratio,detturb,qc_grid,qc_sgs,& + real(kind_phys),DIMENSION(KTS:KTE+1) :: envi_a,envi_w !environmental variables defined at model interface + real(kind_phys):: temp,sublim,qc_ent,qv_ent,qt_ent,thl_ent,detrate, & + detrateUV,oow,exc_fac,aratio,detturb,qc_grid,qc_sgs, & qc_plume,exc_heat,exc_moist,tk_int - REAL, PARAMETER :: Cdet = 1./45. - REAL, PARAMETER :: dzpmax = 300. !limit dz used in detrainment - can be excessing in thick layers + real(kind_phys), PARAMETER :: Cdet = 1./45. + real(kind_phys), PARAMETER :: dzpmax = 300. !limit dz used in detrainment - can be excessing in thick layers !parameter "Csub" determines the propotion of upward vertical velocity that contributes to !environmenatal subsidence. Some portion is expected to be compensated by downdrafts instead of !gentle environmental subsidence. 1.0 assumes all upward vertical velocity in the mass-flux scheme !is compensated by "gentle" environmental subsidence. - REAL, PARAMETER :: Csub=0.25 + real(kind_phys), PARAMETER :: Csub=0.25 !Factor for the pressure gradient effects on momentum transport - REAL, PARAMETER :: pgfac = 0.00 ! Zhang and Wu showed 0.4 is more appropriate for lower troposphere - REAL :: Uk,Ukm1,Vk,Vkm1,dxsa + real(kind_phys), PARAMETER :: pgfac = 0.00 ! Zhang and Wu showed 0.4 is more appropriate for lower troposphere + real(kind_phys):: Uk,Ukm1,Vk,Vkm1,dxsa ! check the inputs ! print *,'dt',dt @@ -6080,7 +6080,7 @@ SUBROUTINE DMP_mf( & wlv=wmin+(wmax-wmin)/NUP2*(i-1) !SURFACE UPDRAFT VERTICAL VELOCITY - UPW(1,I)=wmin + REAL(i)/REAL(NUP)*(wmax-wmin) + UPW(1,I)=wmin + real(i)/real(NUP)*(wmax-wmin) !IF (UPW(1,I) > 0.5*ZW(2)/dt) UPW(1,I) = 0.5*ZW(2)/dt UPU(1,I)=(U(KTS)*DZ(KTS+1)+U(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) @@ -6814,12 +6814,12 @@ subroutine condensation_edmf(QT,THL,P,zagl,THV,QC) ! ! zero or one condensation for edmf: calculates THV and QC ! -real,intent(in) :: QT,THL,P,zagl -real,intent(out) :: THV -real,intent(inout):: QC +real(kind_phys),intent(in) :: QT,THL,P,zagl +real(kind_phys),intent(out) :: THV +real(kind_phys),intent(inout):: QC integer :: niter,i -real :: diff,exn,t,th,qs,qcold +real(kind_phys):: diff,exn,t,th,qs,qcold ! constants used from module_model_constants.F ! p1000mb @@ -6876,11 +6876,11 @@ subroutine condensation_edmf_r(QT,THL,P,zagl,THV,QC) ! zero or one condensation for edmf: calculates THL and QC ! similar to condensation_edmf but with different inputs ! -real,intent(in) :: QT,THV,P,zagl -real,intent(out) :: THL, QC +real(kind_phys),intent(in) :: QT,THV,P,zagl +real(kind_phys),intent(out) :: THL, QC integer :: niter,i -real :: diff,exn,t,th,qs,qcold +real(kind_phys):: diff,exn,t,th,qs,qcold ! number of iterations niter=50 @@ -6926,58 +6926,58 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & &rthraten ) INTEGER, INTENT(IN) :: KTS,KTE,KPBL - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,TH,THL,TK,QT,QV,QC,& + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: U,V,TH,THL,TK,QT,QV,QC,& THV,P,rho,exner,dz - REAL(kind=kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: rthraten + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: rthraten ! zw .. heights of the downdraft levels (edges of boxes) - REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW - REAL, INTENT(IN) :: WTHL,WQT - REAL(kind=kind_phys), INTENT(IN) :: dt,ust,pblh + real(kind_phys),DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW + real(kind_phys), INTENT(IN) :: WTHL,WQT + real(kind_phys), INTENT(IN) :: dt,ust,pblh ! outputs - downdraft properties - REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a_dd,edmf_w_dd, & + real(kind_phys),DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a_dd,edmf_w_dd, & & edmf_qt_dd,edmf_thl_dd, edmf_ent_dd,edmf_qc_dd ! outputs - variables needed for solver (sd_aw - sum ai*wi, sd_awphi - sum ai*wi*phii) - REAL,DIMENSION(KTS:KTE+1) :: sd_aw, sd_awthl, sd_awqt, sd_awu, & + real(kind_phys),DIMENSION(KTS:KTE+1) :: sd_aw, sd_awthl, sd_awqt, sd_awu, & sd_awv, sd_awqc, sd_awqv, sd_awqke, sd_aw2 - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: qc_bl1d, cldfra_bl1d + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: qc_bl1d, cldfra_bl1d INTEGER, PARAMETER :: NDOWN=5, debug_mf=0 !fixing number of plumes to 5 ! draw downdraft starting height randomly between cloud base and cloud top INTEGER, DIMENSION(1:NDOWN) :: DD_initK - REAL , DIMENSION(1:NDOWN) :: randNum + real(kind_phys) , DIMENSION(1:NDOWN) :: randNum ! downdraft properties - REAL,DIMENSION(KTS:KTE+1,1:NDOWN) :: DOWNW,DOWNTHL,DOWNQT,& + real(kind_phys),DIMENSION(KTS:KTE+1,1:NDOWN) :: DOWNW,DOWNTHL,DOWNQT,& DOWNQC,DOWNA,DOWNU,DOWNV,DOWNTHV ! entrainment variables - REAl,DIMENSION(KTS+1:KTE+1,1:NDOWN) :: ENT,ENTf + Real(Kind_phys),DIMENSION(KTS+1:KTE+1,1:NDOWN) :: ENT,ENTf INTEGER,DIMENSION(KTS+1:KTE+1,1:NDOWN) :: ENTi ! internal variables INTEGER :: K,I,ki, kminrad, qlTop, p700_ind, qlBase - REAL :: wthv,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & + real(kind_phys):: wthv,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & pwmin,pwmax,wmin,wmax,wlv,wtv,went,mindownw - REAL :: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,Wn2,Wn,THVk,Pk, & + real(kind_phys):: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,Wn2,Wn,THVk,Pk, & EntEXP,EntW, Beta_dm, EntExp_M, rho_int - REAL :: jump_thetav, jump_qt, jump_thetal, & + real(kind_phys):: jump_thetav, jump_qt, jump_thetal, & refTHL, refTHV, refQT ! DD specific internal variables - REAL :: minrad,zminrad, radflux, F0, wst_rad, wst_dd + real(kind_phys):: minrad,zminrad, radflux, F0, wst_rad, wst_dd logical :: cloudflg - REAL :: sigq,xl,rsl,cpm,a,mf_cf,diffqt,& + real(kind_phys):: sigq,xl,rsl,cpm,a,mf_cf,diffqt,& Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid ! w parameters - REAL,PARAMETER :: & + real(kind_phys),PARAMETER :: & &Wa=1., & &Wb=1.5,& &Z00=100.,& &BCOEFF=0.2 ! entrainment parameters - REAL,PARAMETER :: & + real(kind_phys),PARAMETER :: & & L0=80,& & ENT0=0.2 @@ -7039,7 +7039,7 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & do i=1,NDOWN ! downdraft starts somewhere between cloud base to cloud top ! the probability is equally distributed - DD_initK(i) = qlTop ! nint(randNum(i)*REAL(qlTop-qlBase)) + qlBase + DD_initK(i) = qlTop ! nint(randNum(i)*real(qlTop-qlBase)) + qlBase enddo ! LOOP RADFLUX @@ -7109,13 +7109,13 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & do I=1,NDOWN !downdraft now starts at different height ki = DD_initK(I) - wlv=wmin+(wmax-wmin)/REAL(NDOWN)*(i-1) - wtv=wmin+(wmax-wmin)/REAL(NDOWN)*i + wlv=wmin+(wmax-wmin)/real(NDOWN)*(i-1) + wtv=wmin+(wmax-wmin)/real(NDOWN)*i !DOWNW(ki,I)=0.5*(wlv+wtv) DOWNW(ki,I)=wlv !DOWNA(ki,I)=0.5*ERF(wtv/(sqrt(2.)*sigmaW))-0.5*ERF(wlv/(sqrt(2.)*sigmaW)) - DOWNA(ki,I)=.1/REAL(NDOWN) + DOWNA(ki,I)=.1/real(NDOWN) DOWNU(ki,I)=(u(ki-1)*DZ(ki) + u(ki)*DZ(ki-1)) /(DZ(ki)+DZ(ki-1)) DOWNV(ki,I)=(v(ki-1)*DZ(ki) + v(ki)*DZ(ki-1)) /(DZ(ki)+DZ(ki-1)) @@ -7285,9 +7285,9 @@ SUBROUTINE SCALE_AWARE(dx,PBL1,Psig_bl,Psig_shcu) ! Psig_bl tapers local mixing ! Psig_shcu tapers nonlocal mixing - REAL(kind=kind_phys), INTENT(IN) :: dx,pbl1 - REAL, INTENT(OUT) :: Psig_bl,Psig_shcu - REAL :: dxdh + real(kind_phys), INTENT(IN) :: dx,pbl1 + real(kind_phys), INTENT(OUT) :: Psig_bl,Psig_shcu + real(kind_phys) :: dxdh Psig_bl=1.0 Psig_shcu=1.0 @@ -7359,28 +7359,28 @@ FUNCTION esat_blend(t) IMPLICIT NONE - REAL, INTENT(IN):: t - REAL :: esat_blend,XC,ESL,ESI,chi + real(kind_phys), INTENT(IN):: t + real(kind_phys):: esat_blend,XC,ESL,ESI,chi !liquid - REAL, PARAMETER:: J0= .611583699E03 - REAL, PARAMETER:: J1= .444606896E02 - REAL, PARAMETER:: J2= .143177157E01 - REAL, PARAMETER:: J3= .264224321E-1 - REAL, PARAMETER:: J4= .299291081E-3 - REAL, PARAMETER:: J5= .203154182E-5 - REAL, PARAMETER:: J6= .702620698E-8 - REAL, PARAMETER:: J7= .379534310E-11 - REAL, PARAMETER:: J8=-.321582393E-13 + real(kind_phys), PARAMETER:: J0= .611583699E03 + real(kind_phys), PARAMETER:: J1= .444606896E02 + real(kind_phys), PARAMETER:: J2= .143177157E01 + real(kind_phys), PARAMETER:: J3= .264224321E-1 + real(kind_phys), PARAMETER:: J4= .299291081E-3 + real(kind_phys), PARAMETER:: J5= .203154182E-5 + real(kind_phys), PARAMETER:: J6= .702620698E-8 + real(kind_phys), PARAMETER:: J7= .379534310E-11 + real(kind_phys), PARAMETER:: J8=-.321582393E-13 !ice - REAL, PARAMETER:: K0= .609868993E03 - REAL, PARAMETER:: K1= .499320233E02 - REAL, PARAMETER:: K2= .184672631E01 - REAL, PARAMETER:: K3= .402737184E-1 - REAL, PARAMETER:: K4= .565392987E-3 - REAL, PARAMETER:: K5= .521693933E-5 - REAL, PARAMETER:: K6= .307839583E-7 - REAL, PARAMETER:: K7= .105785160E-9 - REAL, PARAMETER:: K8= .161444444E-12 + real(kind_phys), PARAMETER:: K0= .609868993E03 + real(kind_phys), PARAMETER:: K1= .499320233E02 + real(kind_phys), PARAMETER:: K2= .184672631E01 + real(kind_phys), PARAMETER:: K3= .402737184E-1 + real(kind_phys), PARAMETER:: K4= .565392987E-3 + real(kind_phys), PARAMETER:: K5= .521693933E-5 + real(kind_phys), PARAMETER:: K6= .307839583E-7 + real(kind_phys), PARAMETER:: K7= .105785160E-9 + real(kind_phys), PARAMETER:: K8= .161444444E-12 XC=MAX(-80.,t - t0c) !note t0c = 273.15, tice is set in module mynn_common to 240 @@ -7410,28 +7410,28 @@ FUNCTION qsat_blend(t, P) IMPLICIT NONE - REAL, INTENT(IN):: t, P - REAL :: qsat_blend,XC,ESL,ESI,RSLF,RSIF,chi + real(kind_phys), INTENT(IN):: t, P + real(kind_phys):: qsat_blend,XC,ESL,ESI,RSLF,RSIF,chi !liquid - REAL, PARAMETER:: J0= .611583699E03 - REAL, PARAMETER:: J1= .444606896E02 - REAL, PARAMETER:: J2= .143177157E01 - REAL, PARAMETER:: J3= .264224321E-1 - REAL, PARAMETER:: J4= .299291081E-3 - REAL, PARAMETER:: J5= .203154182E-5 - REAL, PARAMETER:: J6= .702620698E-8 - REAL, PARAMETER:: J7= .379534310E-11 - REAL, PARAMETER:: J8=-.321582393E-13 + real(kind_phys), PARAMETER:: J0= .611583699E03 + real(kind_phys), PARAMETER:: J1= .444606896E02 + real(kind_phys), PARAMETER:: J2= .143177157E01 + real(kind_phys), PARAMETER:: J3= .264224321E-1 + real(kind_phys), PARAMETER:: J4= .299291081E-3 + real(kind_phys), PARAMETER:: J5= .203154182E-5 + real(kind_phys), PARAMETER:: J6= .702620698E-8 + real(kind_phys), PARAMETER:: J7= .379534310E-11 + real(kind_phys), PARAMETER:: J8=-.321582393E-13 !ice - REAL, PARAMETER:: K0= .609868993E03 - REAL, PARAMETER:: K1= .499320233E02 - REAL, PARAMETER:: K2= .184672631E01 - REAL, PARAMETER:: K3= .402737184E-1 - REAL, PARAMETER:: K4= .565392987E-3 - REAL, PARAMETER:: K5= .521693933E-5 - REAL, PARAMETER:: K6= .307839583E-7 - REAL, PARAMETER:: K7= .105785160E-9 - REAL, PARAMETER:: K8= .161444444E-12 + real(kind_phys), PARAMETER:: K0= .609868993E03 + real(kind_phys), PARAMETER:: K1= .499320233E02 + real(kind_phys), PARAMETER:: K2= .184672631E01 + real(kind_phys), PARAMETER:: K3= .402737184E-1 + real(kind_phys), PARAMETER:: K4= .565392987E-3 + real(kind_phys), PARAMETER:: K5= .521693933E-5 + real(kind_phys), PARAMETER:: K6= .307839583E-7 + real(kind_phys), PARAMETER:: K7= .105785160E-9 + real(kind_phys), PARAMETER:: K8= .161444444E-12 XC=MAX(-80.,t - t0c) @@ -7468,8 +7468,8 @@ FUNCTION xl_blend(t) IMPLICIT NONE - REAL, INTENT(IN):: t - REAL :: xl_blend,xlvt,xlst,chi + real(kind_phys), INTENT(IN):: t + real(kind_phys):: xl_blend,xlvt,xlst,chi !note: t0c = 273.15, tice is set in mynn_common IF (t .GE. t0c) THEN @@ -7497,12 +7497,12 @@ FUNCTION phim(zet) ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE - REAL, INTENT(IN):: zet - REAL :: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi - REAL, PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st - REAL, PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st - REAL, PARAMETER :: am_unst=10., ah_unst=34. - REAL :: phi_m,phim + real(kind_phys), INTENT(IN):: zet + real(kind_phys):: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi + real(kind_phys), PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st + real(kind_phys), PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st + real(kind_phys), PARAMETER :: am_unst=10., ah_unst=34. + real(kind_phys):: phi_m,phim if ( zet >= 0.0 ) then dummy_0=1+zet**bm_st @@ -7549,12 +7549,12 @@ FUNCTION phih(zet) ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE - REAL, INTENT(IN):: zet - REAL :: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi - REAL, PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st - REAL, PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st - REAL, PARAMETER :: am_unst=10., ah_unst=34. - REAL :: phh,phih + real(kind_phys), INTENT(IN):: zet + real(kind_phys):: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi + real(kind_phys), PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st + real(kind_phys), PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st + real(kind_phys), PARAMETER :: am_unst=10., ah_unst=34. + real(kind_phys):: phh,phih if ( zet >= 0.0 ) then dummy_0=1+zet**bh_st @@ -7594,23 +7594,23 @@ SUBROUTINE topdown_cloudrad(kts,kte,dz1,zw,xland,kpbl,PBLH, & &maxKHtopdown,KHtopdown,TKEprodTD ) !input - integer, intent(in) :: kte,kts - real, dimension(kts:kte), intent(in) :: dz1,sqc,sqi,sqw,& + integer, intent(in) :: kte,kts + real(kind_phys), dimension(kts:kte), intent(in) :: dz1,sqc,sqi,sqw,& thl,th1,ex1,p1,rho1,thetav,cldfra_bl1D - real(kind=kind_phys), dimension(kts:kte), intent(in) :: rthraten - real, dimension(kts:kte+1), intent(in) :: zw - real(kind=kind_phys), intent(in) :: pblh - real, intent(in) :: xland - integer,intent(in) :: kpbl + real(kind_phys), dimension(kts:kte), intent(in) :: rthraten + real(kind_phys), dimension(kts:kte+1), intent(in) :: zw + real(kind_phys), intent(in) :: pblh + real(kind_phys), intent(in) :: xland + integer , intent(in) :: kpbl !output - real, intent(out) :: maxKHtopdown - real, dimension(kts:kte), intent(out) :: KHtopdown,TKEprodTD + real(kind_phys), intent(out) :: maxKHtopdown + real(kind_phys), dimension(kts:kte), intent(out) :: KHtopdown,TKEprodTD !local - real, dimension(kts:kte) :: zfac,wscalek2,zfacent - real :: bfx0,sflux,wm2,wm3,h1,h2,bfxpbl,dthvx,tmp1 - real :: temps,templ,zl1,wstar3_2 - real :: ent_eff,radsum,radflux,we,rcldb,rvls,minrad,zminrad - real, parameter :: pfac =2.0, zfmin = 0.01, phifac=8.0 + real(kind_phys), dimension(kts:kte) :: zfac,wscalek2,zfacent + real(kind_phys) :: bfx0,sflux,wm2,wm3,h1,h2,bfxpbl,dthvx,tmp1 + real(kind_phys) :: temps,templ,zl1,wstar3_2 + real(kind_phys) :: ent_eff,radsum,radflux,we,rcldb,rvls,minrad,zminrad + real(kind_phys), parameter :: pfac =2.0, zfmin = 0.01, phifac=8.0 integer :: k,kk,kminrad logical :: cloudflg diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index ca0b9f141..9aa9e8c5a 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -25,25 +25,25 @@ subroutine mynnedmf_wrapper_init ( & implicit none - logical, intent(in) :: do_mynnedmf - logical, intent(in) :: lheatstrg - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - real(kind=kind_phys),intent(in) :: con_xlv - real(kind=kind_phys),intent(in) :: con_xlf - real(kind=kind_phys),intent(in) :: con_rv - real(kind=kind_phys),intent(in) :: con_rd - real(kind=kind_phys),intent(in) :: con_ep2 - real(kind=kind_phys),intent(in) :: con_grav - real(kind=kind_phys),intent(in) :: con_cp - real(kind=kind_phys),intent(in) :: con_cpv - real(kind=kind_phys),intent(in) :: con_rcp - real(kind=kind_phys),intent(in) :: con_p608 - real(kind=kind_phys),intent(in) :: con_cliq - real(kind=kind_phys),intent(in) :: con_cice - real(kind=kind_phys),intent(in) :: con_karman - real(kind=kind_phys),intent(in) :: con_t0c + logical, intent(in) :: do_mynnedmf + logical, intent(in) :: lheatstrg + character(len=*),intent(out):: errmsg + integer, intent(out) :: errflg + + real(kind_phys),intent(in) :: con_xlv + real(kind_phys),intent(in) :: con_xlf + real(kind_phys),intent(in) :: con_rv + real(kind_phys),intent(in) :: con_rd + real(kind_phys),intent(in) :: con_ep2 + real(kind_phys),intent(in) :: con_grav + real(kind_phys),intent(in) :: con_cp + real(kind_phys),intent(in) :: con_cpv + real(kind_phys),intent(in) :: con_rcp + real(kind_phys),intent(in) :: con_p608 + real(kind_phys),intent(in) :: con_cliq + real(kind_phys),intent(in) :: con_cice + real(kind_phys),intent(in) :: con_karman + real(kind_phys),intent(in) :: con_t0c ! Initialize CCPP error handling variables errmsg = '' @@ -172,7 +172,7 @@ SUBROUTINE mynnedmf_wrapper_run( & implicit none !------------------------------------------------------------------- - real(kind=kind_phys) :: huge + real(kind_phys) :: huge character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -207,11 +207,11 @@ SUBROUTINE mynnedmf_wrapper_run( & & imp_physics_nssl, imp_physics_fa, & & spp_pbl, & & tke_budget - real(kind=kind_phys), intent(in) :: & + real(kind_phys), intent(in) :: & & bl_mynn_closure !TENDENCY DIAGNOSTICS - real(kind=kind_phys), intent(inout), optional :: dtend(:,:,:) + real(kind_phys), intent(inout), optional :: dtend(:,:,:) integer, intent(in) :: dtidx(:,:) integer, intent(in) :: index_of_temperature, index_of_x_wind integer, intent(in) :: index_of_y_wind, index_of_process_pbl @@ -228,7 +228,7 @@ SUBROUTINE mynnedmf_wrapper_run( & LOGICAL, PARAMETER :: cycling = .false. !MYNN-1D - REAL(kind=kind_phys), intent(in) :: delt, dtf + REAL(kind_phys), intent(in) :: delt, dtf INTEGER, intent(in) :: im, levs LOGICAL, intent(in) :: flag_init, flag_restart INTEGER :: initflag, k, i @@ -236,31 +236,31 @@ SUBROUTINE mynnedmf_wrapper_run( & & IMS,IME,JMS,JME,KMS,KME, & & ITS,ITE,JTS,JTE,KTS,KTE - REAL(kind=kind_phys) :: tem + REAL(kind_phys) :: tem !MYNN-3D - real(kind=kind_phys), dimension(:,:), intent(in) :: phii - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(in) :: phii + real(kind_phys), dimension(:,:), intent(inout) :: & & dtdt, dudt, dvdt, & & dqdt_water_vapor, dqdt_liquid_cloud, dqdt_ice_cloud, & & dqdt_snow_cloud, & & dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc, & & dqdt_ozone, dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc - real(kind=kind_phys), dimension(:,:), intent(inout) ::dqdt_cccn - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) ::dqdt_cccn + real(kind_phys), dimension(:,:), intent(inout) :: & & qke, qke_adv, EL_PBL, Sh3D, Sm3D, & & qc_bl, qi_bl, cldfra_bl !These 10 arrays are only allocated when bl_mynn_output > 0 - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & & edmf_a,edmf_w,edmf_qt, & & edmf_thl,edmf_ent,edmf_qc, & & sub_thl,sub_sqv,det_thl,det_sqv - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & & dqke,qWT,qSHEAR,qBUOY,qDISS - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & & t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice_cloud, & & qgrs_snow_cloud - real(kind=kind_phys), dimension(:,:), intent(in) :: & + real(kind_phys), dimension(:,:), intent(in) :: & & u,v,omega, & & exner,prsl,prsi, & & qgrs_cloud_droplet_num_conc, & @@ -268,37 +268,37 @@ SUBROUTINE mynnedmf_wrapper_run( & & qgrs_ozone, & & qgrs_water_aer_num_conc, & & qgrs_ice_aer_num_conc - real(kind=kind_phys), dimension(:,:), intent(in) ::qgrs_cccn - real(kind=kind_phys), dimension(:,:), intent(out) :: & + real(kind_phys), dimension(:,:), intent(in) ::qgrs_cccn + real(kind_phys), dimension(:,:), intent(out) :: & & Tsq, Qsq, Cov, exch_h, exch_m - real(kind=kind_phys), dimension(:), intent(in) :: xmu - real(kind=kind_phys), dimension(:,:), intent(in) :: htrsw, htrlw + real(kind_phys), dimension(:), intent(in) :: xmu + real(kind_phys), dimension(:,:), intent(in) :: htrsw, htrlw ! spp_wts_pbl only allocated if spp_pbl == 1 - real(kind=kind_phys), dimension(:,:), intent(in) :: spp_wts_pbl + real(kind_phys), dimension(:,:), intent(in) :: spp_wts_pbl !LOCAL - real(kind=kind_phys), dimension(im,levs) :: & + real(kind_phys), dimension(im,levs) :: & & sqv,sqc,sqi,sqs,qnc,qni,ozone,qnwfa,qnifa,qnbca, & & dz, w, p, rho, th, qv, delp, & & RUBLTEN, RVBLTEN, RTHBLTEN, RQVBLTEN, & & RQCBLTEN, RQNCBLTEN, RQIBLTEN, RQNIBLTEN, RQSBLTEN, & & RQNWFABLTEN, RQNIFABLTEN, RQNBCABLTEN - real(kind=kind_phys), allocatable :: old_ozone(:,:) + real(kind_phys), allocatable :: old_ozone(:,:) !smoke/chem arrays - real(kind=kind_phys), dimension(:), intent(inout) :: frp + real(kind_phys), dimension(:), intent(inout) :: frp logical, intent(in) :: mix_chem, enh_mix, rrfs_sd logical, parameter :: smoke_dbg = .false. !set temporarily - real(kind=kind_phys), dimension(:,:,:), intent(inout) :: chem3d - real(kind=kind_phys), dimension(im) :: emis_ant_no - real(kind=kind_phys), dimension(im,ndvel) :: vdep + real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d + real(kind_phys), dimension(im) :: emis_ant_no + real(kind_phys), dimension(im,ndvel) :: vdep !MYNN-2D - real(kind=kind_phys), dimension(:), intent(in) :: & + real(kind_phys), dimension(:), intent(in) :: & & dx,zorl,slmsk,tsurf,qsfc,ps, & & hflx,qflx,ust,wspd,rb,recmol - real(kind=kind_phys), dimension(:), intent(in) :: & + real(kind_phys), dimension(:), intent(in) :: & & dusfc_cice,dvsfc_cice,dtsfc_cice,dqsfc_cice, & & stress_wat,hflx_wat,qflx_wat, & & oceanfrac,fice @@ -306,26 +306,26 @@ SUBROUTINE mynnedmf_wrapper_run( & logical, dimension(:), intent(in) :: & & wet, dry, icy - real(kind=kind_phys), dimension(:), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & & pblh,dusfc_diag,dvsfc_diag,dtsfc_diag,dqsfc_diag - real(kind=kind_phys), dimension(:), intent(out) :: & + real(kind_phys), dimension(:), intent(out) :: & & ch,dtsfc1,dqsfc1,dusfc1,dvsfc1, & & dtsfci_diag,dqsfci_diag,dusfci_diag,dvsfci_diag, & & maxMF integer, dimension(:), intent(inout) :: & & kpbl,nupdraft,ktop_plume - real(kind=kind_phys), dimension(:), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & & dusfc_cpl,dvsfc_cpl,dtsfc_cpl,dqsfc_cpl - real(kind=kind_phys), dimension(:), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & & dusfci_cpl,dvsfci_cpl,dtsfci_cpl,dqsfci_cpl !LOCAL - real, dimension(im) :: & + real(kind_phys), dimension(im) :: & & hfx,qfx,rmol,xland,uoce,voce,znt,ts integer :: idtend - real, dimension(im) :: dusfci1,dvsfci1,dtsfci1,dqsfci1 - real(kind=kind_phys), allocatable :: save_qke_adv(:,:) + real(kind_phys), dimension(im) :: dusfci1,dvsfci1,dtsfci1,dqsfci1 + real(kind_phys), allocatable :: save_qke_adv(:,:) ! Initialize CCPP error handling variables errmsg = '' @@ -1024,8 +1024,8 @@ SUBROUTINE mynnedmf_wrapper_run( & CONTAINS SUBROUTINE dtend_helper(itracer,field,mult) - real(kind=kind_phys), intent(in) :: field(im,levs) - real(kind=kind_phys), intent(in), optional :: mult(im,levs) + real(kind_phys), intent(in) :: field(im,levs) + real(kind_phys), intent(in), optional :: mult(im,levs) integer, intent(in) :: itracer integer :: idtend @@ -1055,9 +1055,9 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & implicit none integer, intent(in) :: kte - real(kind=kind_phys), intent(in) :: delt - real(kind=kind_phys), dimension(kte), intent(in) :: dp, exner - real(kind=kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, qs, th + real(kind_phys), intent(in) :: delt + real(kind_phys), dimension(kte), intent(in) :: dp, exner + real(kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, qs, th integer k real :: dqc2, dqi2, dqs2, dqv2, sum, aa, dum real, parameter :: qvmin1= 1e-8, & !min at k=1 From 0e20bda6e517cf39ea29efbe0c70b1eaae291152 Mon Sep 17 00:00:00 2001 From: joeolson42 Date: Thu, 9 Mar 2023 19:33:09 +0000 Subject: [PATCH 04/19] fixes for Grants comments and suggestions --- physics/module_bl_mynn.F90 | 12 ++++-- physics/mynnedmf_wrapper.F90 | 70 +++++++++++++++++------------------ physics/mynnedmf_wrapper.meta | 15 ++------ physics/sgscloud_radpre.F90 | 3 -- 4 files changed, 47 insertions(+), 53 deletions(-) diff --git a/physics/module_bl_mynn.F90 b/physics/module_bl_mynn.F90 index dab09871c..51a906faf 100644 --- a/physics/module_bl_mynn.F90 +++ b/physics/module_bl_mynn.F90 @@ -486,7 +486,7 @@ SUBROUTINE mynn_bl_driver( & real(kind_phys), DIMENSION(:,:), INTENT(inout) :: el_pbl - real(kind_phys), DIMENSION(:,:), INTENT(out) :: & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & &qWT,qSHEAR,qBUOY,qDISS,dqke ! 3D budget arrays are not allocated when tke_budget == 0 ! 1D (local) budget arrays are used for passing between subroutines. @@ -736,7 +736,7 @@ SUBROUTINE mynn_bl_driver( & rho1(k)=rho(i,k) sqc(k)=sqc3D(i,k) !/(1.+qv(i,k)) sqv(k)=sqv3D(i,k) !/(1.+qv(i,k)) - thetav(k)=th(i,k)*(1.+0.608*sqv(k)) + thetav(k)=th(i,k)*(1.+p608*sqv(k)) !keep snow out for now - increases ceiling bias sqw(k)=sqv(k)+sqc(k)+sqi(k)!+sqs(k) thl(k)=th1(k) - xlvcp/ex1(k)*sqc(k) & @@ -995,7 +995,7 @@ SUBROUTINE mynn_bl_driver( & !suggested min temperature to improve accuracy. !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) - thetav(k)=th1(k)*(1.+0.608*sqv(k)) + thetav(k)=th1(k)*(1.+p608*sqv(k)) enddo ! end k zw(kte+1)=zw(kte)+dz(i,kte) @@ -3867,7 +3867,11 @@ SUBROUTINE mym_condensation (kts,kte, & ! JAYMES- this option added 8 May 2015 ! The cloud water formulations are taken from CB02, Eq. 8. IF (q1k < 0.) THEN !unsaturated +#ifdef SINGLE_PREC + ql_water = sgm(k)*EXP(1.2*q1k-1.) +#else ql_water = sgm(k)*EXP(1.2*q1k-1.) +#endif ql_ice = sgm(k)*EXP(1.2*q1k-1.) ELSE IF (q1k > 2.) THEN !supersaturated ql_water = sgm(k)*q1k @@ -6861,7 +6865,7 @@ subroutine condensation_edmf(QT,THL,P,zagl,THV,QC) !THIS BASICALLY GIVE THE SAME RESULT AS THE PREVIOUS LINE !TH = THL + xlv/cp/EXN*QC - !THV= TH*(1. + 0.608*QT) + !THV= TH*(1. + p608*QT) !print *,'t,p,qt,qs,qc' !print *,t,p,qt,qs,qc diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 9aa9e8c5a..d2ca9f3cc 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -17,16 +17,15 @@ subroutine mynnedmf_wrapper_init ( & & con_cpv, con_cliq, con_cice, con_rcp, & & con_XLV, con_XLF, con_p608, con_ep2, & & con_karman, con_t0c, & - & do_mynnedmf, lheatstrg, & + & do_mynnedmf, & & errmsg, errflg ) use machine, only : kind_phys use bl_mynn_common implicit none - + logical, intent(in) :: do_mynnedmf - logical, intent(in) :: lheatstrg character(len=*),intent(out):: errmsg integer, intent(out) :: errflg @@ -98,8 +97,8 @@ SUBROUTINE mynnedmf_wrapper_run( & & phii,u,v,omega,t3d, & & qgrs_water_vapor, & & qgrs_liquid_cloud, & - & qgrs_ice_cloud, & - & qgrs_snow_cloud, & + & qgrs_ice, & + & qgrs_snow, & & qgrs_cloud_droplet_num_conc, & & qgrs_cloud_ice_num_conc, & & qgrs_ozone, & @@ -135,7 +134,7 @@ SUBROUTINE mynnedmf_wrapper_run( & & nupdraft,maxMF,ktop_plume, & & dudt, dvdt, dtdt, & & dqdt_water_vapor, dqdt_liquid_cloud, & ! <=== ntqv, ntcw - & dqdt_ice_cloud, dqdt_snow_cloud, & ! <=== ntiw, ntsw + & dqdt_ice, dqdt_snow, & ! <=== ntiw, ntsw & dqdt_ozone, & ! <=== ntoz & dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc, & ! <=== ntlnc, ntinc & dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc,& ! <=== ntwa, ntia @@ -242,8 +241,8 @@ SUBROUTINE mynnedmf_wrapper_run( & real(kind_phys), dimension(:,:), intent(in) :: phii real(kind_phys), dimension(:,:), intent(inout) :: & & dtdt, dudt, dvdt, & - & dqdt_water_vapor, dqdt_liquid_cloud, dqdt_ice_cloud, & - & dqdt_snow_cloud, & + & dqdt_water_vapor, dqdt_liquid_cloud, dqdt_ice, & + & dqdt_snow, & & dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc, & & dqdt_ozone, dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc real(kind_phys), dimension(:,:), intent(inout) ::dqdt_cccn @@ -258,8 +257,8 @@ SUBROUTINE mynnedmf_wrapper_run( & real(kind_phys), dimension(:,:), intent(inout) :: & & dqke,qWT,qSHEAR,qBUOY,qDISS real(kind_phys), dimension(:,:), intent(inout) :: & - & t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice_cloud, & - & qgrs_snow_cloud + & t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice, & + & qgrs_snow real(kind_phys), dimension(:,:), intent(in) :: & & u,v,omega, & & exner,prsl,prsi, & @@ -377,7 +376,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) sqs(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = 0. @@ -401,7 +400,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) sqs(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) @@ -429,8 +428,8 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) - sqs(i,k) = qgrs_snow_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) @@ -452,8 +451,8 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) - sqs(i,k) = qgrs_snow_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) @@ -475,8 +474,8 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) - sqs(i,k) = qgrs_snow_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) qnc(i,k) = 0. qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) @@ -500,7 +499,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) qnc(i,k) = 0. qni(i,k) = 0. sqs(i,k) = 0. @@ -807,8 +806,8 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_snow_cloud(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 enddo enddo @@ -822,7 +821,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 ! enddo !enddo @@ -834,9 +833,9 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) - dqdt_snow_cloud(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 dqdt_water_aer_num_conc(i,k) = RQNWFABLTEN(i,k) dqdt_ice_aer_num_conc(i,k) = RQNIFABLTEN(i,k) @@ -855,7 +854,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! qgrs_cloud_droplet_num_conc(i,k) = qgrs_cloud_droplet_num_conc(i,k) + RQNCBLTEN(i,k)*delt ! qgrs_cloud_ice_num_conc(i,k) = qgrs_cloud_ice_num_conc(i,k) + RQNIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 @@ -869,9 +868,9 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) - dqdt_snow_cloud(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) enddo enddo if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then @@ -887,8 +886,9 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 enddo enddo @@ -896,14 +896,14 @@ SUBROUTINE mynnedmf_wrapper_run( & call dtend_helper(100+ntqv,RQVBLTEN) call dtend_helper(100+ntcw,RQCBLTEN) call dtend_helper(100+ntiw,RQIBLTEN) - call dtend_helper(100+ntsw,RQSBLTEN) call dtend_helper(100+ntinc,RQNIBLTEN) + call dtend_helper(100+ntsw,RQSBLTEN) endif !do k=1,levs ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! qgrs_cloud_ice_num_conc(i,k) = qgrs_cloud_ice_num_conc(i,k) + RQNIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 ! enddo @@ -916,9 +916,9 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) - dqdt_snow_cloud(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) IF ( nssl_ccn_on ) THEN ! dqdt_cccn(i,k) = RQNWFABLTEN(i,k) ENDIF @@ -931,7 +931,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_rain(i,k) = 0.0 !dqdt_snow(i,k) = 0.0 !dqdt_graupel(i,k) = 0.0 @@ -947,7 +947,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 ! enddo !enddo @@ -957,7 +957,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = 0.0 + dqdt_ice(i,k) = 0.0 !dqdt_rain(i,k) = 0.0 !dqdt_snow(i,k) = 0.0 !dqdt_graupel(i,k) = 0.0 diff --git a/physics/mynnedmf_wrapper.meta b/physics/mynnedmf_wrapper.meta index 1703699bb..1928f1c37 100644 --- a/physics/mynnedmf_wrapper.meta +++ b/physics/mynnedmf_wrapper.meta @@ -125,13 +125,6 @@ dimensions = () type = logical intent = in -[lheatstrg] - standard_name = flag_for_canopy_heat_storage_in_land_surface_scheme - long_name = flag for canopy heat storage parameterization - units = flag - dimensions = () - type = logical - intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -303,7 +296,7 @@ type = real kind = kind_phys intent = inout -[qgrs_ice_cloud] +[qgrs_ice] standard_name = cloud_ice_mixing_ratio long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) units = kg kg-1 @@ -311,7 +304,7 @@ type = real kind = kind_phys intent = inout -[qgrs_snow_cloud] +[qgrs_snow] standard_name = snow_mixing_ratio long_name = ratio of mass of snow water to mass of dry air plus vapor (without condensates) units = kg kg-1 @@ -1033,7 +1026,7 @@ type = real kind = kind_phys intent = inout -[dqdt_ice_cloud] +[dqdt_ice] standard_name = process_split_cumulative_tendency_of_cloud_ice_mixing_ratio long_name = cloud condensed water mixing ratio tendency due to model physics units = kg kg-1 s-1 @@ -1041,7 +1034,7 @@ type = real kind = kind_phys intent = inout -[dqdt_snow_cloud] +[dqdt_snow] standard_name = process_split_cumulative_tendency_of_snow_mixing_ratio long_name = ratio of mass of snow water tendency to mass of dry air plus vapor (without condensates) due to model physics units = kg kg-1 s-1 diff --git a/physics/sgscloud_radpre.F90 b/physics/sgscloud_radpre.F90 index 87054128c..05ca1af2a 100644 --- a/physics/sgscloud_radpre.F90 +++ b/physics/sgscloud_radpre.F90 @@ -44,8 +44,6 @@ subroutine sgscloud_radpre_run( & qc, qi, qv, T3D, P3D, exner, & qr, qs, qg, & qci_conv,qlc,qli,ud_mf, & -! qci_conv_timeave, & -! ud_mf_timeave, & imfdeepcnv, imfdeepcnv_gf, & imfdeepcnv_sas, & qc_save, qi_save, qs_save, & @@ -84,7 +82,6 @@ subroutine sgscloud_radpre_run( & real(kind=kind_phys), dimension(:,:), intent(inout) :: qci_conv real(kind=kind_phys), dimension(:,:), intent(inout) :: qlc, qli !for SAS real(kind=kind_phys), dimension(:,:), intent(in) :: ud_mf - !real(kind=kind_phys), dimension(:,:), intent(in) :: ud_mf_timeave, qci_conv_timeave real(kind=kind_phys), dimension(:,:), intent(in) :: T3D,delp real(kind=kind_phys), dimension(:,:), intent(in) :: qv,P3D,exner real(kind=kind_phys), dimension(:,:), intent(inout) :: & From c9c973ae40b89b27159d87699065242bad8f194d Mon Sep 17 00:00:00 2001 From: "Haiqin.Li" Date: Fri, 10 Mar 2023 00:13:33 +0000 Subject: [PATCH 05/19] "merge RRFS-SD from the GSL repository to the community repository" --- physics/GFS_rrtmg_pre.F90 | 37 +- physics/GFS_rrtmg_pre.meta | 52 +- physics/cu_gf_deep.F90 | 4 +- physics/module_bl_mynn.F90 | 1048 +++++++++-------- physics/mynnedmf_wrapper.F90 | 100 +- physics/mynnedmf_wrapper.meta | 28 +- physics/radiation_aerosols.f | 10 +- physics/smoke_dust/coarsepm_settling_mod.F90 | 274 +++++ physics/smoke_dust/dep_dry_mod.F90 | 69 ++ .../smoke_dust}/dust_data_mod.F90 | 5 +- physics/smoke_dust/dust_fengsha_mod.F90 | 585 +++++++++ .../smoke_dust}/module_add_emiss_burn.F90 | 32 +- .../smoke_dust}/module_plumerise1.F90 | 30 +- .../smoke_dust}/module_smoke_plumerise.F90 | 62 +- physics/smoke_dust/module_wetdep_ls.F90 | 79 ++ .../smoke_dust}/module_zero_plumegen_coms.F90 | 24 +- .../smoke_dust}/plume_data_mod.F90 | 0 .../smoke_dust}/rrfs_smoke_config.F90 | 46 +- .../smoke_dust}/rrfs_smoke_postpbl.F90 | 22 +- .../smoke_dust}/rrfs_smoke_postpbl.meta | 22 +- .../smoke_dust}/rrfs_smoke_wrapper.F90 | 430 ++++--- .../smoke_dust}/rrfs_smoke_wrapper.meta | 110 +- .../smoke_dust}/seas_data_mod.F90 | 0 {smoke => physics/smoke_dust}/seas_mod.F90 | 21 +- .../smoke_dust}/seas_ngac_mod.F90 | 0 smoke/dep_dry_gocart_mod.F90 | 302 ----- smoke/dep_dry_mod.F90 | 303 ----- smoke/dep_simple_mod.F90 | 766 ------------ smoke/dep_vertmx_mod.F90 | 212 ---- smoke/dep_wet_ls_mod.F90 | 562 --------- smoke/dust_fengsha_mod.F90 | 601 ---------- smoke/rrfs_smoke_data.F90 | 651 ---------- smoke/rrfs_smoke_lsdep_wrapper.F90 | 323 ----- smoke/rrfs_smoke_lsdep_wrapper.meta | 208 ---- 34 files changed, 2089 insertions(+), 4929 deletions(-) create mode 100755 physics/smoke_dust/coarsepm_settling_mod.F90 create mode 100755 physics/smoke_dust/dep_dry_mod.F90 rename {smoke => physics/smoke_dust}/dust_data_mod.F90 (97%) create mode 100755 physics/smoke_dust/dust_fengsha_mod.F90 rename {smoke => physics/smoke_dust}/module_add_emiss_burn.F90 (90%) rename {smoke => physics/smoke_dust}/module_plumerise1.F90 (91%) rename {smoke => physics/smoke_dust}/module_smoke_plumerise.F90 (98%) create mode 100755 physics/smoke_dust/module_wetdep_ls.F90 rename {smoke => physics/smoke_dust}/module_zero_plumegen_coms.F90 (88%) rename {smoke => physics/smoke_dust}/plume_data_mod.F90 (100%) rename {smoke => physics/smoke_dust}/rrfs_smoke_config.F90 (66%) rename {smoke => physics/smoke_dust}/rrfs_smoke_postpbl.F90 (68%) rename {smoke => physics/smoke_dust}/rrfs_smoke_postpbl.meta (70%) rename {smoke => physics/smoke_dust}/rrfs_smoke_wrapper.F90 (66%) rename {smoke => physics/smoke_dust}/rrfs_smoke_wrapper.meta (85%) rename {smoke => physics/smoke_dust}/seas_data_mod.F90 (100%) rename {smoke => physics/smoke_dust}/seas_mod.F90 (96%) rename {smoke => physics/smoke_dust}/seas_ngac_mod.F90 (100%) delete mode 100755 smoke/dep_dry_gocart_mod.F90 delete mode 100755 smoke/dep_dry_mod.F90 delete mode 100755 smoke/dep_simple_mod.F90 delete mode 100755 smoke/dep_vertmx_mod.F90 delete mode 100755 smoke/dep_wet_ls_mod.F90 delete mode 100755 smoke/dust_fengsha_mod.F90 delete mode 100755 smoke/rrfs_smoke_data.F90 delete mode 100644 smoke/rrfs_smoke_lsdep_wrapper.F90 delete mode 100755 smoke/rrfs_smoke_lsdep_wrapper.meta diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index c8ed0339e..d43e182db 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -20,7 +20,7 @@ module GFS_rrtmg_pre subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& ltp, imfdeepcnv, imfdeepcnv_gf, me, ncnd, ntrac, num_p3d, npdf3d, & ncnvcld3d,ntqv, ntcw,ntiw, ntlnc, ntinc, ntrnc, ntsnc, ntccn, top_at_1,& - ntrw, ntsw, ntgl, nthl, ntwa, ntoz, & + ntrw, ntsw, ntgl, nthl, ntwa, ntoz, ntsmoke, ntdust, ntcoarsepm, & ntclamt, nleffr, nieffr, nseffr, lndp_type, kdt, & ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2, & ntss3, ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl, ntchm, & @@ -41,11 +41,10 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& kd, kt, kb, mtopa, mbota, raddt, tsfg, tsfa, de_lgth, alb1d, delp, dz, & !output from here and below plvl, plyr, tlvl, tlyr, qlyr, olyr, gasvmr_co2, gasvmr_n2o, gasvmr_ch4,& gasvmr_o2, gasvmr_co, gasvmr_cfc11, gasvmr_cfc12, gasvmr_cfc22, & - gasvmr_ccl4, gasvmr_cfc113, aerodp, clouds6, clouds7, clouds8, & + gasvmr_ccl4, gasvmr_cfc113, aerodp,ext550, clouds6, clouds7, clouds8, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, & - aero_dir_fdb, smoke_ext, dust_ext, & - spp_wts_rad, spp_rad, rrfs_smoke_band, ico2, errmsg, errflg) + aero_dir_fdb, spp_wts_rad, spp_rad, ico2, errmsg, errflg) use machine, only: kind_phys @@ -89,6 +88,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& ntcw, ntiw, ntlnc, ntinc, & ntrnc, ntsnc,ntccn, & ntrw, ntsw, ntgl, nthl, ntwa, ntoz, & + ntsmoke, ntdust, ntcoarsepm, & ntclamt, nleffr, nieffr, nseffr, & lndp_type, & kdt, imp_physics, & @@ -113,7 +113,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& idcor, & idcor_hogan, & idcor_oreopoulos, & - rrfs_smoke_band, & ! Band number for rrfs-smoke dust and smoke ico2 ! Flag for co2 source used in radiation integer, intent(in) :: ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2, ntss3, & @@ -126,7 +125,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& lmfshal, lmfdeep2, pert_clds, lcrick,& lcnorm, top_at_1, lextop, mraerosol logical, intent(in) :: aero_dir_fdb - real(kind=kind_phys), dimension(:,:), intent(in) :: smoke_ext, dust_ext logical, intent(in) :: nssl_ccn_on, nssl_invertccn integer, intent(in) :: spp_rad @@ -187,6 +185,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& gasvmr_ccl4,& gasvmr_cfc113 real(kind=kind_phys), dimension(:,:), intent(out) :: aerodp + real(kind=kind_phys), dimension(:,:), intent(out) :: ext550 real(kind=kind_phys), dimension(:,:), intent(out) :: clouds6, & clouds7, & clouds8, & @@ -637,13 +636,27 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& enddo endif +!>--- add smoke and dust --- + if (aero_dir_fdb) then + do k=1,lmk + do i=1,im + aer_nm(i,k,1 )=aer_nm(i,k,1 )+qgrs(i,k,ntdust)*0.33*1.e-9 ! dust bin1 + aer_nm(i,k,2 )=aer_nm(i,k,2 )+(qgrs(i,k,ntdust)*0.67+qgrs(i,k,ntcoarsepm)*0.02)*1.e-9 + aer_nm(i,k,3 )=aer_nm(i,k,3 )+qgrs(i,k,ntcoarsepm)*0.13*1.e-9 ! dust bin3 + aer_nm(i,k,4 )=aer_nm(i,k,4 )+qgrs(i,k,ntcoarsepm)*0.85*1.e-9 ! dust bin4 + aer_nm(i,k,12)=aer_nm(i,k,12)+qgrs(i,k,ntsmoke)*1.e-9*0.05 !Smoke BC + aer_nm(i,k,14)=aer_nm(i,k,14)+qgrs(i,k,ntsmoke)*1.e-9*0.95 !Smoke OA, we may need to revise later for OA vs. OC + enddo + enddo + endif + !> - Call module_radiation_aerosols::setaer() to setup aerosols !! property profile for radiation. call setaer (plvl, plyr, prslk1, tvly, rhly, slmsk, & ! --- inputs tracer1, aer_nm, xlon, xlat, IM, LMK, LMP,& lsswr, lslwr, iaermdl, iaerflg, top_at_1, con_pi, & - con_rd, con_g, faersw, faerlw, aerodp, errflg, errmsg) ! --- outputs + con_rd, con_g, faersw, faerlw, aerodp, ext550, errflg, errmsg) ! --- outputs ! CCPP do j = 1,NBDSW @@ -657,16 +670,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& enddo enddo - !> - Add aerosol direct feedback effect by smoke and dust - if(aero_dir_fdb) then ! add smoke/dust extinctions - do k = 1, LMK - do i = 1, IM - ! 550nm (~18000/cm) - faersw1(i,k,rrfs_smoke_band) = faersw1(i,k,rrfs_smoke_band) + MIN(4.,smoke_ext(i,k) + dust_ext(i,k)) - enddo - enddo - endif - do j = 1,NBDLW do k = 1, LMK do i = 1, IM diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index 53f05225b..782868be6 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -219,6 +219,27 @@ dimensions = () type = integer intent = in +[ntsmoke] + standard_name = index_for_smoke_in_tracer_concentration_array + long_name = tracer index for smoke + units = index + dimensions = () + type = integer + intent = in +[ntdust] + standard_name = index_for_dust_in_tracer_concentration_array + long_name = tracer index for dust + units = index + dimensions = () + type = integer + intent = in +[ntcoarsepm] + standard_name = index_for_coarse_pm_in_tracer_concentration_array + long_name = tracer index for coarse pm + units = index + dimensions = () + type = integer + intent = in [iaermdl] standard_name = control_for_aerosol_radiation_scheme long_name = control of aerosol scheme in radiation @@ -1264,6 +1285,14 @@ type = real kind = kind_phys intent = out +[ext550] + standard_name = atmosphere_optical_thickness_3d + long_name = 3d optical extinction for total aerosol species + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = out [clouds6] standard_name = cloud_rain_water_path long_name = cloud rain water path @@ -1437,22 +1466,6 @@ dimensions = () type = logical intent = in -[smoke_ext] - standard_name = extinction_coefficient_in_air_due_to_smoke - long_name = extinction coefficient in air due to smoke - units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[dust_ext] - standard_name = extinction_coefficient_in_air_due_to_dust - long_name = extinction coefficient in air due to dust - units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in [spp_wts_rad] standard_name = spp_weights_for_radiation_scheme long_name = spp weights for radiation scheme @@ -1468,13 +1481,6 @@ dimensions = () type = integer intent = in -[rrfs_smoke_band] - standard_name = index_of_shortwave_band_affected_by_smoke - long_name = rrtmg band number that smoke and dust should affect - units = count - dimensions = () - type = integer - intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/cu_gf_deep.F90 b/physics/cu_gf_deep.F90 index e1976d55c..5abb990de 100644 --- a/physics/cu_gf_deep.F90 +++ b/physics/cu_gf_deep.F90 @@ -25,8 +25,8 @@ module cu_gf_deep real(kind=kind_phys), parameter :: pgcd = 0.1 ! !> aerosol awareness, do not use yet! - integer, parameter :: autoconv=2 - integer, parameter :: aeroevap=3 + integer, parameter :: autoconv=1 !2 + integer, parameter :: aeroevap=1 !3 real(kind=kind_phys), parameter :: scav_factor = 0.5 !> still 16 ensembles for clousres integer, parameter:: maxens3=16 diff --git a/physics/module_bl_mynn.F90 b/physics/module_bl_mynn.F90 index ffb4b5696..d1fae478d 100644 --- a/physics/module_bl_mynn.F90 +++ b/physics/module_bl_mynn.F90 @@ -248,7 +248,7 @@ MODULE module_bl_mynn xlvcp , tv0 , tv1 , tref , & zero , half , one , two , & onethird , twothirds , tkmin , t0c , & - tice + tice , kind_phys IMPLICIT NONE @@ -301,6 +301,7 @@ MODULE module_bl_mynn ! &cns=3.5, alp1=0.23, alp2=0.3, alp3=3.0, alp4=10.0, alp5=0.2 REAL, PARAMETER :: gpw=5./3., qcgmin=1.e-8, qkemin=1.e-12 + REAL, PARAMETER :: tliq = 269. !all hydrometeors are liquid when T > tliq ! Constants for cloud PDF (mym_condensation) REAL, PARAMETER :: rr2=0.7071068, rrp=0.3989423 @@ -373,7 +374,7 @@ MODULE module_bl_mynn CONTAINS ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine is the GSD MYNN-EDNF PBL driver routine,which !! encompassed the majority of the subroutines that comprise the !! procedures that ultimately solve for tendencies of @@ -383,32 +384,30 @@ MODULE module_bl_mynn SUBROUTINE mynn_bl_driver( & &initflag,restart,cycling, & &delt,dz,dx,znt, & - &u,v,w,th,sqv3D,sqc3D,sqi3D, & + &u,v,w,th,sqv3d,sqc3d,sqi3d, & &qnc,qni, & &qnwfa,qnifa,ozone, & - &p,exner,rho,T3D, & + &p,exner,rho,t3d, & &xland,ts,qsfc,ps, & &ust,ch,hfx,qfx,rmol,wspd, & &uoce,voce, & !ocean current &vdfg, & !Katata-added for fog dep - &Qke,qke_adv, & + &qke,qke_adv, & &sh3d,sm3d, & - &nchem,kdvel,ndvel, & !Smoke/Chem variables - &chem3d, vdep, & - &frp,EMIS_ANT_NO, & ! JLS/RAR to adjust exchange coeffs - &mix_chem,fire_turb,rrfs_smoke, & ! end smoke/chem variables - - &Tsq,Qsq,Cov, & - &RUBLTEN,RVBLTEN,RTHBLTEN, & - &RQVBLTEN,RQCBLTEN,RQIBLTEN, & - &RQNCBLTEN,RQNIBLTEN, & - &RQNWFABLTEN,RQNIFABLTEN, & - &DOZONE, & + &chem3d,vdep,smoke_dbg, & + &frp,emis_ant_no, & ! JLS/RAR to adjust exchange coeffs + &mix_chem,enh_mix,rrfs_sd, & ! end smoke/chem variables + &tsq,qsq,cov, & + &rublten,rvblten,rthblten, & + &rqvblten,rqcblten,rqiblten, & + &rqncblten,rqniblten, & + &rqnwfablten,rqnifablten, & + &dozone, & &exch_h,exch_m, & - &Pblh,kpbl, & + &pblh,kpbl, & &el_pbl, & - &dqke,qWT,qSHEAR,qBUOY,qDISS, & + &dqke,qwt,qshear,qbuoy,qdiss, & &qc_bl,qi_bl,cldfra_bl, & &bl_mynn_tkeadvect, & &bl_mynn_tkebudget, & @@ -428,7 +427,7 @@ SUBROUTINE mynn_bl_driver( & &det_thl3D,det_sqv3D, & &nupdraft,maxMF,ktop_plume, & &spp_pbl,pattern_spp_pbl, & - &RTHRATEN, & + &rthraten, & &FLAG_QC,FLAG_QI,FLAG_QNC, & &FLAG_QNI,FLAG_QNWFA,FLAG_QNIFA, & &FLAG_OZONE & @@ -453,12 +452,12 @@ SUBROUTINE mynn_bl_driver( & INTEGER, INTENT(in) :: bl_mynn_cloudmix INTEGER, INTENT(in) :: bl_mynn_mixqt INTEGER, INTENT(in) :: icloud_bl - REAL, INTENT(in) :: closure + REAL(kind=kind_phys), INTENT(in) :: closure LOGICAL, INTENT(in) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QNC,& FLAG_QNWFA,FLAG_QNIFA,FLAG_OZONE - LOGICAL, INTENT(IN) :: mix_chem,fire_turb,rrfs_smoke + LOGICAL, INTENT(IN) :: mix_chem,enh_mix,rrfs_sd,smoke_dbg INTEGER, INTENT(in) :: & & IDS,IDE,JDS,JDE,KDS,KDE & @@ -480,71 +479,68 @@ SUBROUTINE mynn_bl_driver( & ! to prevent a crash on Cheyenne. Do not change it back without testing if the code runs ! on Cheyenne with the GNU compiler. - REAL, INTENT(in) :: delt - REAL, DIMENSION(:), INTENT(in) :: dx - REAL, DIMENSION(:,:), INTENT(in) :: dz, & + REAL(kind=kind_phys), INTENT(in) :: delt + REAL(kind=kind_phys), DIMENSION(:), INTENT(in) :: dx + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: dz, & &u,v,w,th,sqv3D,p,exner,rho,T3D - REAL, DIMENSION(:,:), INTENT(in):: & + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: & &sqc3D,sqi3D,qni,qnc,qnwfa,qnifa - REAL, DIMENSION(:,:), INTENT(in):: ozone - REAL, DIMENSION(:), INTENT(in) :: xland,ust, & - &ch,ts,qsfc,ps,hfx,qfx,wspd,uoce,voce,vdfg,znt - - REAL, DIMENSION(:,:), INTENT(inout) :: & + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in):: ozone + REAL(kind=kind_phys), DIMENSION(:), INTENT(in):: ust, & + &ch,qsfc,ps,wspd + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & &Qke,Tsq,Qsq,Cov,qke_adv + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & + &rublten,rvblten,rthblten,rqvblten,rqcblten, & + &rqiblten,rqniblten,rqncblten, & + &rqnwfablten,rqnifablten + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: dozone + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: rthraten - REAL, DIMENSION(:,:), INTENT(inout) :: & - &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN,RQCBLTEN, & - &RQIBLTEN,RQNIBLTEN,RQNCBLTEN, & - &RQNWFABLTEN,RQNIFABLTEN - REAL, DIMENSION(:,:), INTENT(inout) :: DOZONE - - REAL, DIMENSION(:,:), INTENT(in) :: RTHRATEN - - REAL, DIMENSION(:,:), INTENT(out) :: & - &exch_h,exch_m + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(out) :: exch_h,exch_m + REAL, DIMENSION(:), INTENT(in) :: xland,ts,znt,hfx,qfx, & + &uoce,voce !These 10 arrays are only allocated when bl_mynn_output > 0 - REAL, DIMENSION(:,:), INTENT(inout) :: & - & edmf_a,edmf_w,edmf_qt,edmf_thl,edmf_ent,edmf_qc, & + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & + & edmf_a,edmf_w,edmf_qt,edmf_thl,edmf_ent,edmf_qc, & & sub_thl3D,sub_sqv3D,det_thl3D,det_sqv3D ! REAL, DIMENSION(IMS:IME,KMS:KME) :: & ! & edmf_a_dd,edmf_w_dd,edmf_qt_dd,edmf_thl_dd,edmf_ent_dd,edmf_qc_dd - REAL, DIMENSION(:), INTENT(inout) :: Pblh,rmol + REAL(kind=kind_phys), DIMENSION(:), INTENT(inout) :: Pblh + REAL, DIMENSION(:), INTENT(inout) :: rmol REAL, DIMENSION(IMS:IME) :: Psig_bl,Psig_shcu - INTEGER,DIMENSION(:),INTENT(INOUT) :: & + INTEGER,DIMENSION(:),INTENT(INOUT) :: & &KPBL,nupdraft,ktop_plume - REAL, DIMENSION(:), INTENT(OUT) :: & - &maxmf + REAL(kind=kind_phys), DIMENSION(:), INTENT(out) :: maxmf - REAL, DIMENSION(:,:), INTENT(inout) :: & - &el_pbl + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: el_pbl - REAL, DIMENSION(:,:), INTENT(out) :: & + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(out) :: & &qWT,qSHEAR,qBUOY,qDISS,dqke ! 3D budget arrays are not allocated when bl_mynn_tkebudget == .false. ! 1D (local) budget arrays are used for passing between subroutines. REAL, DIMENSION(kts:kte) :: qWT1,qSHEAR1,qBUOY1,qDISS1,dqke1,diss_heat - REAL, DIMENSION(:,:), intent(out) :: Sh3D,Sm3D + REAL(kind=kind_phys), DIMENSION(:,:), intent(out) :: Sh3D,Sm3D - REAL, DIMENSION(:,:), INTENT(inout) :: & + REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & &qc_bl,qi_bl,cldfra_bl - REAL, DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D,cldfra_bl1D,& + REAL, DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D,cldfra_bl1D, & qc_bl1D_old,qi_bl1D_old,cldfra_bl1D_old ! smoke/chemical arrays INTEGER, INTENT(IN ) :: nchem, kdvel, ndvel ! REAL, DIMENSION( ims:ime, kms:kme, nchem ), INTENT(INOUT), optional :: chem3d ! REAL, DIMENSION( ims:ime, kdvel, ndvel ), INTENT(IN), optional :: vdep - REAL, DIMENSION(:, :, :), INTENT(INOUT) :: chem3d - REAL, DIMENSION(:, :), INTENT(IN) :: vdep - REAL, DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO + REAL(kind=kind_phys), DIMENSION(:, :, :), INTENT(INOUT) :: chem3d + REAL(kind=kind_phys), DIMENSION(:, :), INTENT(IN) :: vdep + REAL(kind=kind_phys), DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO !local REAL, DIMENSION(kts:kte ,nchem) :: chem1 REAL, DIMENSION(kts:kte+1,nchem) :: s_awchem1 @@ -553,68 +549,82 @@ SUBROUTINE mynn_bl_driver( & !local vars INTEGER :: ITF,JTF,KTF, IMD,JMD - INTEGER :: i,j,k - REAL, DIMENSION(KTS:KTE) :: thl,thvl,tl,qv1,qc1,qi1,sqw,& - &El, Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, & - &Vt, Vq, sgm, thlsg, sqwsg - REAL, DIMENSION(KTS:KTE) :: thetav,sh,sm,u1,v1,w1,p1, & - &ex1,dz1,th1,tk1,rho1,qke1,tsq1,qsq1,cov1, & - &sqv,sqi,sqc,du1,dv1,dth1,dqv1,dqc1,dqi1,ozone1, & - &k_m1,k_h1,qni1,dqni1,qnc1,dqnc1,qnwfa1,qnifa1, & + INTEGER :: i,j,k,kproblem + REAL, DIMENSION(KTS:KTE) :: thl,thvl,tl,qv1,qc1,qi1,sqw, & + &El, Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, & + &Vt, Vq, sgm, thlsg, sqwsg, vdfg + REAL, DIMENSION(KTS:KTE) :: thetav,sh,sm,u1,v1,w1,p1, & + &ex1,dz1,th1,tk1,rho1,qke1,tsq1,qsq1,cov1, & + &sqv,sqi,sqc,du1,dv1,dth1,dqv1,dqc1,dqi1,ozone1, & + &k_m1,k_h1,qni1,dqni1,qnc1,dqnc1,qnwfa1,qnifa1, & &dqnwfa1,dqnifa1,dozone1 !mass-flux variables REAL, DIMENSION(KTS:KTE) :: dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf - REAL, DIMENSION(KTS:KTE) :: edmf_a1,edmf_w1,edmf_qt1, & + REAL, DIMENSION(KTS:KTE) :: edmf_a1,edmf_w1,edmf_qt1, & &edmf_thl1,edmf_ent1,edmf_qc1 - REAL, DIMENSION(KTS:KTE) :: edmf_a_dd1,edmf_w_dd1, & - &edmf_qt_dd1,edmf_thl_dd1, & + REAL, DIMENSION(KTS:KTE) :: edmf_a_dd1,edmf_w_dd1, & + &edmf_qt_dd1,edmf_thl_dd1, & &edmf_ent_dd1,edmf_qc_dd1 - REAL, DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v,& + REAL, DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v, & det_thl,det_sqv,det_sqc,det_u,det_v - REAL,DIMENSION(KTS:KTE+1) :: s_aw1,s_awthl1,s_awqt1, & - s_awqv1,s_awqc1,s_awu1,s_awv1,s_awqke1, & + REAL,DIMENSION(KTS:KTE+1) :: s_aw1,s_awthl1,s_awqt1, & + s_awqv1,s_awqc1,s_awu1,s_awv1,s_awqke1, & s_awqnc1,s_awqni1,s_awqnwfa1,s_awqnifa1 - REAL,DIMENSION(KTS:KTE+1) :: sd_aw1,sd_awthl1,sd_awqt1, & + REAL,DIMENSION(KTS:KTE+1) :: sd_aw1,sd_awthl1,sd_awqt1, & sd_awqv1,sd_awqc1,sd_awu1,sd_awv1,sd_awqke1 REAL, DIMENSION(KTS:KTE+1) :: zw REAL :: cpm,sqcg,flt,fltv,flq,flqv,flqc,pmz,phh,exnerg,zet,phi_m,& & afk,abk,ts_decay, qc_bl2, qi_bl2, & - & th_sfc,ztop_plume,sqc9,sqi9 + & th_sfc,ztop_plume,sqc9,sqi9,wsp !top-down diffusion REAL, DIMENSION(ITS:ITE) :: maxKHtopdown REAL,DIMENSION(KTS:KTE) :: KHtopdown,TKEprodTD - LOGICAL :: INITIALIZE_QKE + LOGICAL :: INITIALIZE_QKE,problem ! Stochastic fields - INTEGER, INTENT(IN) ::spp_pbl - REAL, DIMENSION( :, :), INTENT(IN) ::pattern_spp_pbl - REAL, DIMENSION(KTS:KTE) ::rstoch_col + INTEGER, INTENT(IN) :: spp_pbl + REAL(kind=kind_phys), DIMENSION( :, :), INTENT(IN) :: pattern_spp_pbl + REAL, DIMENSION(KTS:KTE) :: rstoch_col ! Substepping TKE INTEGER :: nsub - real :: delt2 - - IF ( debug_code ) THEN - if (idbg .lt. ime) then - print*,'in MYNN driver; at beginning' - print*," th(1:5)=",th(idbg,1:5) - print*," u(1:5)=",u(idbg,1:5) - print*," v(1:5)=",v(idbg,1:5) - print*," w(1:5)=",w(idbg,1:5) - print*," sqv(1:5)=",sqv3D(idbg,1:5) - print*," p(1:5)=",p(idbg,1:5) - print*," rho(1:5)=",rho(idbg,1:5) - print*," xland=",xland(idbg)," u*=",ust(idbg), & - &" ts=",ts(idbg)," qsfc=",qsfc(idbg), & - &" z/L=",0.5*dz(idbg,1)*rmol(idbg)," ps=",ps(idbg),& - &" hfx=",hfx(idbg)," qfx=",qfx(idbg), & - &" wspd=",wspd(idbg)," znt=",znt(idbg) - endif - ENDIF + real(kind=kind_phys) :: delt2 + + + if (debug_code) then !check incoming values + do i=its,ite + problem = .false. + do k=kts,kte + wsp = sqrt(u(i,k)**2 + v(i,k)**2) + if (abs(hfx(i)) > 1200. .or. abs(qfx(i)) > 0.001 .or. & + wsp > 200. .or. t3d(i,k) > 360. .or. t3d(i,k) < 160. .or. & + sqv3d(i,k)< 0.0 .or. sqc3d(i,k)< 0.0 ) then + kproblem = k + problem = .true. + print*,"Incoming problem at: i=",i," k=1" + print*," QFX=",qfx(i)," HFX=",hfx(i) + print*," wsp=",wsp," T=",t3d(i,k) + print*," qv=",sqv3d(i,k)," qc=",sqc3d(i,k) + print*," u*=",ust(i)," wspd=",wspd(i) + print*," xland=",xland(i)," ts=",ts(i) + print*," z/L=",0.5*dz(i,1)*rmol(i)," ps=",ps(i) + print*," znt=",znt(i)," dx=",dx(i) + endif + enddo + if (problem) then + print*,"===tk:",t3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qv:",sqv3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qc:",sqc3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qi:",sqi3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====u:",u(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====v:",v(i,max(kproblem-3,1):min(kproblem+3,kte)) + endif + enddo + endif !*** Begin debugging IMD=(IMS+IME)/2 @@ -1052,9 +1062,9 @@ SUBROUTINE mynn_bl_driver( & ENDDO ! end k !initialize smoke/chem arrays (if used): - IF ( rrfs_smoke .and. mix_chem ) then + IF ( mix_chem ) then do ic = 1,ndvel - vd1(ic) = vdep(i,ic) !is this correct???? + vd1(ic) = vdep(i,ic) ! dry deposition velocity chem1(kts,ic) = chem3d(i,kts,ic) s_awchem1(kts,ic)=0. enddo @@ -1066,7 +1076,7 @@ SUBROUTINE mynn_bl_driver( & enddo ELSE do ic = 1,ndvel - vd1(ic) = 0. !is this correct??? (ite) or (ndvel) + vd1(ic) = 0. ! dry deposition velocity chem1(kts,ic) = 0. s_awchem1(kts,ic)=0. enddo @@ -1178,7 +1188,8 @@ SUBROUTINE mynn_bl_driver( & !! selected by use of the namelist parameter \p bl_mynn_cloudpdf. CALL mym_condensation ( kts,kte, & - &dx(i),dz1,zw,thl,sqw,sqv,sqc,sqi,& + &dx(i),dz1,zw,u1,v1,xland(i), & + &thl,sqw,sqv,sqc,sqi, & &p1,ex1,tsq1,qsq1,cov1, & &Sh,el,bl_mynn_cloudpdf, & &qc_bl1D,qi_bl1D,cldfra_bl1D, & @@ -1193,7 +1204,7 @@ SUBROUTINE mynn_bl_driver( & CALL topdown_cloudrad(kts,kte,dz1,zw, & &xland(i),kpbl(i),PBLH(i), & &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & - &cldfra_bl1D,rthraten, & + &cldfra_bl1D,rthraten(i,:), & &maxKHtopdown(i),KHtopdown,TKEprodTD ) ELSE maxKHtopdown(i) = 0.0 @@ -1311,7 +1322,6 @@ SUBROUTINE mynn_bl_driver( & !> - Call mynn_tendencies() to solve for tendencies of !! \f$U, V, \theta, q_{v}, q_{c}, and q_{i}\f$. CALL mynn_tendencies(kts,kte,i, & - &closure, & &delt, dz1, rho1, & &u1, v1, th1, tk1, qv1, & &qc1, qi1, qnc1, qni1, & @@ -1326,7 +1336,7 @@ SUBROUTINE mynn_bl_driver( & &Du1, Dv1, Dth1, Dqv1, & &Dqc1, Dqi1, Dqnc1, Dqni1, & &Dqnwfa1, Dqnifa1, Dozone1, & - &vdfg(i), diss_heat, & + &diss_heat, & ! mass flux components &s_aw1,s_awthl1,s_awqt1, & &s_awqv1,s_awqc1,s_awu1,s_awv1, & @@ -1349,7 +1359,8 @@ SUBROUTINE mynn_bl_driver( & &bl_mynn_mixscalars ) - IF ( rrfs_smoke .and. mix_chem ) THEN + IF ( mix_chem ) THEN + IF ( rrfs_sd ) THEN CALL mynn_mix_chem(kts,kte,i, & &delt, dz1, pblh(i), & &nchem, kdvel, ndvel, & @@ -1359,12 +1370,24 @@ SUBROUTINE mynn_bl_driver( & &dfh, & &s_aw1,s_awchem1, & &emis_ant_no(i), & - &frp(i), & - &fire_turb ) - + &frp(i), rrfs_sd, & + &enh_mix, smoke_dbg ) + ELSE + CALL mynn_mix_chem(kts,kte,i, & + &delt, dz1, pblh(i), & + &nchem, kdvel, ndvel, & + &chem1, vd1, & + &rho1,flt, & + &tcd, qcd, & + &dfh, & + &s_aw1,s_awchem1, & + &zero, & + &zero, rrfs_sd, & + &enh_mix, smoke_dbg ) + ENDIF DO ic = 1,nchem DO k = kts,kte - chem3d(i,k,ic) = chem1(k,ic) + chem3d(i,k,ic) = max(1.e-12, chem1(k,ic)) ENDDO ENDDO ENDIF @@ -1373,58 +1396,38 @@ SUBROUTINE mynn_bl_driver( & &dfm, dfh, dz1, K_m1, K_h1) !UPDATE 3D ARRAYS - DO k=KTS,KTE !KTF + do k=kts,kte exch_m(i,k)=K_m1(k) exch_h(i,k)=K_h1(k) - RUBLTEN(i,k)=du1(k) - RVBLTEN(i,k)=dv1(k) - RTHBLTEN(i,k)=dth1(k) - RQVBLTEN(i,k)=dqv1(k) - IF(bl_mynn_cloudmix > 0)THEN - IF (FLAG_QC) RQCBLTEN(i,k)=dqc1(k) - IF (FLAG_QI) RQIBLTEN(i,k)=dqi1(k) - ELSE - IF (FLAG_QC) RQCBLTEN(i,k)=0. - IF (FLAG_QI) RQIBLTEN(i,k)=0. - ENDIF - IF(bl_mynn_cloudmix > 0 .AND. bl_mynn_mixscalars > 0)THEN - IF (FLAG_QNC) RQNCBLTEN(i,k)=dqnc1(k) - IF (FLAG_QNI) RQNIBLTEN(i,k)=dqni1(k) - IF (FLAG_QNWFA) RQNWFABLTEN(i,k)=dqnwfa1(k) - IF (FLAG_QNIFA) RQNIFABLTEN(i,k)=dqnifa1(k) - ELSE - IF (FLAG_QNC) RQNCBLTEN(i,k)=0. - IF (FLAG_QNI) RQNIBLTEN(i,k)=0. - IF (FLAG_QNWFA) RQNWFABLTEN(i,k)=0. - IF (FLAG_QNIFA) RQNIFABLTEN(i,k)=0. - ENDIF - DOZONE(i,k)=DOZONE1(k) - - IF(icloud_bl > 0)THEN - !DIAGNOSTIC-DECAY FOR SUBGRID-SCALE CLOUDS - IF (CLDFRA_BL1D(k) < cldfra_bl1D_old(k)) THEN - !DECAY TIMESCALE FOR CALM CONDITION IS THE EDDY TURNOVER - !TIMESCALE, BUT FOR WINDY CONDITIONS, IT IS THE ADVECTIVE - !TIMESCALE. USE THE MINIMUM OF THE TWO. - ts_decay = MIN( 1800., 2.*dx(i)/MAX(SQRT(u1(k)**2 + v1(k)**2),1.0) ) - cldfra_bl(i,k)= MAX(cldfra_bl1D(k),cldfra_bl1D_old(k)-(0.25*delt/ts_decay)) - ! qc_bl2 and qi_bl2 are linked to decay rates - qc_bl2 = MAX(qc_bl1D(k),qc_bl1D_old(k)) - qi_bl2 = MAX(qi_bl1D(k),qi_bl1D_old(k)) - qc_bl(i,k) = MAX(qc_bl1D(k),qc_bl1D_old(k)-(MIN(qc_bl2,1.0E-5) * delt/ts_decay)) - qi_bl(i,k) = MAX(qi_bl1D(k),qi_bl1D_old(k)-(MIN(qi_bl2,1.0E-6) * delt/ts_decay)) - IF (cldfra_bl(i,k) < 0.005 .OR. & - (qc_bl(i,k) + qi_bl(i,k)) < 1E-9) THEN - CLDFRA_BL(i,k)= 0. - QC_BL(i,k) = 0. - QI_BL(i,k) = 0. - ENDIF - ELSE - qc_bl(i,k)=qc_bl1D(k) - qi_bl(i,k)=qi_bl1D(k) - cldfra_bl(i,k)=cldfra_bl1D(k) - ENDIF - ENDIF + rublten(i,k)=du1(k) + rvblten(i,k)=dv1(k) + rthblten(i,k)=dth1(k) + rqvblten(i,k)=dqv1(k) + if (bl_mynn_cloudmix > 0) then + if (FLAG_QC) rqcblten(i,k)=dqc1(k) + if (FLAG_QI) rqiblten(i,k)=dqi1(k) + else + if (FLAG_QC) rqcblten(i,k)=0. + if (FLAG_QI) rqiblten(i,k)=0. + endif + if (bl_mynn_cloudmix > 0 .and. bl_mynn_mixscalars > 0) then + if (FLAG_QNC) rqncblten(i,k)=dqnc1(k) + if (FLAG_QNI) rqniblten(i,k)=dqni1(k) + if (FLAG_QNWFA) rqnwfablten(i,k)=dqnwfa1(k) + if (FLAG_QNIFA) rqnifablten(i,k)=dqnifa1(k) + else + if (FLAG_QNC) rqncblten(i,k)=0. + if (FLAG_QNI) rqniblten(i,k)=0. + if (FLAG_QNWFA) rqnwfablten(i,k)=0. + if (FLAG_QNIFA) rqnifablten(i,k)=0. + endif + dozone(i,k)=dozone1(k) + + if (icloud_bl > 0) then + qc_bl(i,k)=qc_bl1D(k) + qi_bl(i,k)=qi_bl1D(k) + cldfra_bl(i,k)=cldfra_bl1D(k) + endif el_pbl(i,k)=el(k) qke(i,k)=qke1(k) @@ -1433,22 +1436,22 @@ SUBROUTINE mynn_bl_driver( & cov(i,k)=cov1(k) sh3d(i,k)=sh(k) sm3d(i,k)=sm(k) - ENDDO !end-k + enddo !end-k - IF ( bl_mynn_tkebudget ) THEN + if ( bl_mynn_tkebudget ) then !! TKE budget is now given in m**2/s**-3 (Puhales, 2020) !! Lower boundary condtions (using similarity relationships such as the prognostic equation for Qke) k=kts qSHEAR1(k)=4.*(ust(i)**3*phi_m/(karman*dz(i,k)))-qSHEAR1(k+1) !! staggered qBUOY1(k)=4.*(-ust(i)**3*zet/(karman*dz(i,k)))-qBUOY1(k+1) !! staggered !! unstaggering SHEAR and BUOY and trasfering all TKE budget to 3D array - DO k = kts,kte-1 + do k = kts,kte-1 qSHEAR(i,k)=0.5*(qSHEAR1(k)+qSHEAR1(k+1)) !!! unstaggering in z qBUOY(i,k)=0.5*(qBUOY1(k)+qBUOY1(k+1)) !!! unstaggering in z qWT(i,k)=qWT1(k) qDISS(i,k)=qDISS1(k) dqke(i,k)=(qke1(k)-dqke(i,k))*0.5/delt - ENDDO + enddo !! Upper boundary conditions k=kte qSHEAR(i,k)=0. @@ -1456,7 +1459,7 @@ SUBROUTINE mynn_bl_driver( & qWT(i,k)=0. qDISS(i,k)=0. dqke(i,k)=0. - ENDIF + endif !update updraft/downdraft properties if (bl_mynn_output > 0) THEN !research mode == 1 @@ -1495,9 +1498,9 @@ SUBROUTINE mynn_bl_driver( & DO k = kts,kte IF ( sh(k) < 0. .OR. sh(k)> 200.)print*,& "SUSPICIOUS VALUES AT: i,k=",i,k," sh=",sh(k) - IF ( ABS(vt(k)) > 0.9 )print*,& + IF ( ABS(vt(k)) > 2.0 )print*,& "SUSPICIOUS VALUES AT: i,k=",i,k," vt=",vt(k) - IF ( ABS(vq(k)) > 6000.)print*,& + IF ( ABS(vq(k)) > 7000.)print*,& "SUSPICIOUS VALUES AT: i,k=",i,k," vq=",vq(k) IF ( qke(i,k) < -1. .OR. qke(i,k)> 200.)print*,& "SUSPICIOUS VALUES AT: i,k=",i,k," qke=",qke(i,k) @@ -1549,13 +1552,7 @@ END SUBROUTINE mynn_bl_driver !> @} !======================================================================= -!> This subroutine gives the closure constants and initializes the -!! turbulent qantities. ! SUBROUTINE mym_initialize: -! ================================================================== -! This subroutine computes the length scales up and down -! and then computes the min, average of the up/down length scales, and also -! considers the distance to the surface. ! ! Input variables: ! iniflag : <>0; turbulent quantities will be initialized @@ -1607,7 +1604,7 @@ END SUBROUTINE mynn_bl_driver ! !------------------------------------------------------------------- -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine initializes the mixing length, TKE, \f$\theta^{'2}\f$, !! \f$q^{'2}\f$, and \f$\theta^{'}q^{'}\f$. !!\section gen_mym_ini GSD MYNN-EDMF mym_initialize General Algorithm @@ -1632,22 +1629,20 @@ SUBROUTINE mym_initialize ( & INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf LOGICAL, INTENT(IN) :: INITIALIZE_QKE ! REAL, INTENT(IN) :: ust, rmo, pmz, phh, flt, flq - REAL, INTENT(IN) :: ust, rmo, Psig_bl, dx + REAL, INTENT(IN) :: rmo, Psig_bl + REAL(kind=kind_phys), INTENT(IN) :: dx, ust, zi REAL, DIMENSION(kts:kte), INTENT(in) :: dz REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,cldfra_bl1D,& edmf_w1,edmf_a1,edmf_qc1 REAL, DIMENSION(kts:kte), INTENT(out) :: tsq,qsq,cov REAL, DIMENSION(kts:kte), INTENT(inout) :: el,qke - REAL, DIMENSION(kts:kte) :: & &ql,pdk,pdt,pdq,pdc,dtl,dqw,dtv,& &gm,gh,sm,sh,qkw,vt,vq INTEGER :: k,l,lmax REAL :: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1.,flt=0.,flq=0.,tmpq - REAL :: zi - REAL, DIMENSION(kts:kte) :: theta,thetav,thlsg,qwsg - + REAL, DIMENSION(kts:kte) :: theta,thetav,thlsg,qwsg REAL, DIMENSION(kts:kte) :: rstoch_col INTEGER ::spp_pbl @@ -1795,7 +1790,7 @@ END SUBROUTINE mym_initialize ! These are defined on the walls of the grid boxes. ! -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the level 2, non-dimensional wind shear !! \f$G_M\f$ and vertical temperature gradient \f$G_H\f$ as well as !! the level 2 stability funcitons \f$S_h\f$ and \f$S_m\f$. @@ -1951,7 +1946,7 @@ END SUBROUTINE mym_level2 ! NOTE: the mixing lengths are meant to be calculated at the full- ! sigmal levels (or interfaces beween the model layers). ! -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the mixing lengths. SUBROUTINE mym_length ( & & kts,kte, & @@ -1964,6 +1959,7 @@ SUBROUTINE mym_length ( & & zi,theta, & & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength,& & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf) + !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte @@ -1976,7 +1972,8 @@ SUBROUTINE mym_length ( & INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf REAL, DIMENSION(kts:kte), INTENT(in) :: dz REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,flq,Psig_bl,dx + REAL, INTENT(in) :: rmo,flt,flq,Psig_bl + REAL(kind=kind_phys), INTENT(IN) :: dx,zi REAL, DIMENSION(kts:kte), INTENT(IN) :: u1,v1,qke,vt,vq,cldfra_bl1D,& edmf_w1,edmf_a1,edmf_qc1 REAL, DIMENSION(kts:kte), INTENT(out) :: qkw, el @@ -1986,7 +1983,7 @@ SUBROUTINE mym_length ( & REAL, DIMENSION(kts:kte), INTENT(IN) :: theta REAL, DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg,thetaw - REAL :: wt,wt2,zi,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg + REAL :: wt,wt2,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg ! THE FOLLOWING CONSTANTS ARE IMPORTANT FOR REGULATING THE ! MIXING LENGTHS: @@ -2028,7 +2025,7 @@ SUBROUTINE mym_length ( & CASE (0) ! ORIGINAL MYNN MIXING LENGTH + BouLac cns = 2.7 - alp1 = 0.21 + alp1 = 0.23 alp2 = 1.0 alp3 = 5.0 alp4 = 100. @@ -2110,9 +2107,9 @@ SUBROUTINE mym_length ( & CASE (1) !NONLOCAL (using BouLac) FORM OF MIXING LENGTH cns = 3.5 - alp1 = 0.21 + alp1 = 0.22 !0.21 alp2 = 0.3 - alp3 = 1.5 + alp3 = 2.0 !1.5 alp4 = 5.0 alp5 = 0.3 alp6 = 50. @@ -2143,7 +2140,7 @@ SUBROUTINE mym_length ( & zwk = zw(k) DO WHILE (zwk .LE. zi2+h1) dzk = 0.5*( dz(k)+dz(k-1) ) - qdz = MAX( qkw(k)-qmin, 0.03 )*dzk + qdz = min(max( qkw(k)-qmin, 0.03 ), 30.0)*dzk elt = elt +qdz*zwk vsc = vsc +qdz k = k+1 @@ -2166,17 +2163,17 @@ SUBROUTINE mym_length ( & ! ** Length scale limited by the buoyancy effect ** IF ( dtv(k) .GT. 0.0 ) THEN - alp2 = 0.3 + 0.15*0.5*(cldfra_bl1D(k)+cldfra_bl1D(k-1)) - bv = SQRT( gtr*dtv(k) ) + alp2 = 0.3 !test+ 0.15*0.5*(cldfra_bl1D(k)+cldfra_bl1D(k-1)) + bv = max( sqrt( gtr*dtv(k) ), 0.001) !elb = alp2*qkw(k) / bv & ! formulation, ! & *( 1.0 + alp3/alp2*& ! except keep ! &SQRT( vsc/( bv*elt ) ) ) ! elb bounded by zwk - elb = MAX(alp2*qkw(k), & - & alp6*edmf_a1(k)*edmf_w1(k)) / bv & + elb = MAX(alp2*qkw(k), & + & alp6*edmf_a1(k-1)*edmf_w1(k-1)) / bv & & *( 1.0 + alp3*SQRT( vsc/(bv*elt) ) ) elb = MIN(elb, zwk) elf = 0.65 * qkw(k)/bv - !elBLavg(k) = MAX(elBLavg(k), alp6*edmf_a1(k)*edmf_w1(k)/bv) + elBLavg(k) = MAX(elBLavg(k), alp6*edmf_a1(k-1)*edmf_w1(k-1)/bv) ELSE elb = 1.0e10 elf = elb @@ -2215,9 +2212,9 @@ SUBROUTINE mym_length ( & Uonset = 3.5 + dz(kts)*0.1 Ugrid = sqrt(u1(kts)**2 + v1(kts)**2) cns = 3.5 !JOE-test * (1.0 - MIN(MAX(Ugrid - Uonset, 0.0)/10.0, 1.0)) - alp1 = 0.21 + alp1 = 0.22 !0.21 alp2 = 0.30 - alp3 = 1.5 + alp3 = 2.0 !1.5 alp4 = 5.0 alp5 = alp2 !like alp2, but for free atmosphere alp6 = 50.0 !used for MF mixing length @@ -2250,7 +2247,7 @@ SUBROUTINE mym_length ( & zwk = zw(k) DO WHILE (zwk .LE. PBLH_PLUS_ENT) dzk = 0.5*( dz(k)+dz(k-1) ) - qdz = MAX( qkw(k)-qmin, 0.03 )*dzk + qdz = min(max( qkw(k)-qmin, 0.03 ), 30.0)*dzk elt = elt +qdz*zwk vsc = vsc +qdz k = k+1 @@ -2276,7 +2273,7 @@ SUBROUTINE mym_length ( & bv = MAX( SQRT( gtr*dtv(k) ), 0.001) !elb_mf = alp2*qkw(k) / bv & elb_mf = MAX(alp2*qkw(k), & - & alp6*edmf_a1(k)*edmf_w1(k)) / bv & + & alp6*edmf_a1(k-1)*edmf_w1(k-1)) / bv & & *( 1.0 + alp3*SQRT( vsc/( bv*elt ) ) ) elb = MIN(MAX(alp5*qkw(k), alp6*edmf_a1(k)*edmf_w1(k))/bv, zwk) @@ -2363,7 +2360,7 @@ SUBROUTINE mym_length ( & END SUBROUTINE mym_length ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine was taken from the BouLac scheme in WRF-ARW and modified for !! integration into the MYNN PBL scheme. WHILE loops were added to reduce the !! computational expense. This subroutine computes the length scales up and down @@ -2526,7 +2523,7 @@ SUBROUTINE boulac_length0(k,kts,kte,zw,dz,qtke,theta,lb1,lb2) END SUBROUTINE boulac_length0 ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine was taken from the BouLac scheme in WRF-ARW !! and modified for integration into the MYNN PBL scheme. !! WHILE loops were added to reduce the computational expense. @@ -2717,7 +2714,7 @@ END SUBROUTINE boulac_length ! # dtl, dqw, dtv, gm and gh are allowed to share storage units with ! dfm, dfh, dfq, tcd and qcd, respectively, for saving memory. ! -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the vertical diffusivity coefficients and the !! production terms for the turbulent quantities. !>\section gen_mym_turbulence GSD mym_turbulence General Algorithm @@ -2754,6 +2751,7 @@ SUBROUTINE mym_turbulence ( & & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & & TKEprodTD, & & spp_pbl,rstoch_col) + !------------------------------------------------------------------- ! INTEGER, INTENT(IN) :: kts,kte @@ -2764,10 +2762,11 @@ SUBROUTINE mym_turbulence ( & #endif INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf - REAL, INTENT(IN) :: closure - REAL, DIMENSION(kts:kte), INTENT(in) :: dz + REAL(kind=kind_phys), INTENT(IN) :: closure + REAL, DIMENSION(kts:kte), INTENT(in) :: dz REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,flq,Psig_bl,Psig_shcu,dx + REAL, INTENT(in) :: rmo,flt,flq,Psig_bl,Psig_shcu + REAL(kind=kind_phys), INTENT(IN) :: dx,zi REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,thetav,qw,& &ql,vt,vq,qke,tsq,qsq,cov,cldfra_bl1D,edmf_w1,edmf_a1,edmf_qc1,& &TKEprodTD,thlsg,qwsg @@ -2789,7 +2788,7 @@ SUBROUTINE mym_turbulence ( & REAL :: e6c,dzk,afk,abk,vtt,vqq,& &cw25,clow,cupp,gamt,gamq,smd,gamv,elq,elh - REAL :: zi, cldavg + REAL :: cldavg REAL, DIMENSION(kts:kte), INTENT(in) :: theta REAL :: a2fac, duz, ri !JOE-Canuto/Kitamura mod @@ -3313,7 +3312,7 @@ END SUBROUTINE mym_turbulence ! scheme (program). ! !------------------------------------------------------------------- -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine predicts the turbulent quantities at the next step. SUBROUTINE mym_predict (kts,kte, & & closure, & @@ -3325,6 +3324,7 @@ SUBROUTINE mym_predict (kts,kte, & & qke, tsq, qsq, cov, & & s_aw,s_awqke,bl_mynn_edmf_tke, & & qWT1D, qDISS1D,bl_mynn_tkebudget) !! TKE budget (Puhales, 2020) + !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte @@ -3333,12 +3333,12 @@ SUBROUTINE mym_predict (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(IN) :: closure + REAL(kind=kind_phys), INTENT(IN) :: closure INTEGER, INTENT(IN) :: bl_mynn_edmf_tke - REAL, INTENT(IN) :: delt REAL, DIMENSION(kts:kte), INTENT(IN) :: dz, dfq, el, rho REAL, DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc - REAL, INTENT(IN) :: flt, flq, ust, pmz, phh + REAL, INTENT(IN) :: flt, flq, pmz, phh + REAL(kind=kind_phys), INTENT(IN) :: ust, delt REAL, DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov ! WA 8/3/15 REAL, DIMENSION(kts:kte+1), INTENT(INOUT) :: s_awqke,s_aw @@ -3716,22 +3716,22 @@ END SUBROUTINE mym_predict ! Set these values to those adopted by you. ! !------------------------------------------------------------------- -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the nonconvective component of the !! subgrid cloud fraction and mixing ratio as well as the functions used to !! calculate the buoyancy flux. Different cloud PDFs can be selected by !! use of the namelist parameter \p bl_mynn_cloudpdf . - SUBROUTINE mym_condensation (kts,kte, & - & dx, dz, zw, & - & thl, qw, qv, qc, qi, & - & p,exner, & - & tsq, qsq, cov, & - & Sh, el, bl_mynn_cloudpdf,& - & qc_bl1D, qi_bl1D, & - & cldfra_bl1D, & - & PBLH1,HFX1, & - & Vt, Vq, th, sgm, rmo, & - & spp_pbl,rstoch_col ) + SUBROUTINE mym_condensation (kts,kte, & + & dx, dz, zw, u1, v1, xland,& + & thl, qw, qv, qc, qi, & + & p,exner, & + & tsq, qsq, cov, & + & Sh, el, bl_mynn_cloudpdf, & + & qc_bl1D, qi_bl1D, & + & cldfra_bl1D, & + & PBLH1,HFX1, & + & Vt, Vq, th, sgm, rmo, & + & spp_pbl,rstoch_col ) !------------------------------------------------------------------- @@ -3742,11 +3742,12 @@ SUBROUTINE mym_condensation (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(IN) :: dx,PBLH1,HFX1,rmo + REAL, INTENT(IN) :: HFX1,rmo,xland + REAL(kind=kind_phys), INTENT(IN) :: dx,pblh1 REAL, DIMENSION(kts:kte), INTENT(IN) :: dz REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw REAL, DIMENSION(kts:kte), INTENT(IN) :: p,exner,thl,qw,qv,qc,qi, & - &tsq, qsq, cov, th + &tsq, qsq, cov, th, u1, v1 REAL, DIMENSION(kts:kte), INTENT(INOUT) :: vt,vq,sgm @@ -3758,7 +3759,7 @@ SUBROUTINE mym_condensation (kts,kte, & REAL :: qsl,esat,qsat,dqsl,cld0,q1k,qlk,eq1,qll,& &q2p,pt,rac,qt,t,xl,rsl,cpm,Fng,qww,alpha,beta,bb,& &ls,wt,cld_factor,fac_damp,liq_frac,ql_ice,ql_water,& - &qmq,qsat_tk + &qmq,qsat_tk,wsp,wspfac INTEGER :: i,j,k REAL :: erf @@ -3769,7 +3770,8 @@ SUBROUTINE mym_condensation (kts,kte, & !variables for SGS BL clouds REAL :: zagl,damp,PBLH2 - REAL :: lfac + REAL :: cfmax + INTEGER, PARAMETER :: buoy_opt=1 ! 0: traditional SD77, 1: CB02,CB05 !JAYMES: variables for tropopause-height estimation REAL :: theta1, theta2, ht1, ht2 @@ -3971,80 +3973,69 @@ SUBROUTINE mym_condensation (kts,kte, & sgm(k) = SQRT( r3sq ) !Set limits on sigma relative to saturation water vapor sgm(k) = MIN( sgm(k), qsat_tk*0.666 ) !500 ) - sgm(k) = MAX( sgm(k), qsat_tk*0.040 ) !Note: 0.02 results in SWDOWN similar + sgm(k) = MAX( sgm(k), qsat_tk*0.035 ) !Note: 0.02 results in SWDOWN similar !to the first-order version of sigma q1(k) = qmq / sgm(k) ! Q1, the normalized saturation - - !Original C-B cloud fraction, allows cloud fractions out to q1 = -3.5 - cldfra_bl1D(K) = MAX(0., MIN(1., 0.5+0.36*ATAN(1.55*q1(k)))) ! Eq. 7 in CB02 - !This form only allows cloud fractions out to q1 = -1.8 - !cldfra_bl1D(K) = MAX(0., MIN(1., 0.5+0.41*ATAN(1.55*q1(k)))) - !This form only allows cloud fractions out to q1 = -1 - !cldfra_bl1D(K) = MAX(0., MIN(1., 0.5+0.50*ATAN(1.55*q1(k)))) - - END DO - - ! Specify hydrometeors - ! JAYMES- this option added 8 May 2015 - ! The cloud water formulations are taken from CB02, Eq. 8. - ! "fng" represents the non-Gaussian contribution to the liquid - ! water flux; these formulations are from Cuijpers and Bechtold - ! (1995), Eq. 7. CB95 also draws from Bechtold et al. 1995, - ! hereafter BCMT95 - zagl = 0. - DO k = kts,kte-1 - t = th(k)*exner(k) - q1k = q1(k) - zagl = zagl + dz(k) - - !CLOUD WATER AND ICE + q1k = q1(k) ! backup Q1 for later modification + + ! Specify cloud fraction + !Original C-B cloud fraction, allows cloud fractions out to q1 = -3.5 + !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.55*q1(k)))) ! Eq. 7 in CB02 + !wayne's - over-diffuse, when limits removed from vt & vq & fng + !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.2*(q1(k)+0.4)))) + !effort to reduce rh-dependency + !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(2.9*(q1(k)+0.4)))) + cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.8*(q1(k)+0.4)))) + !moderate - best compromise?? + !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.55*(q1(k)+0.2)))) + !closer to original for Q1 < -1, best for holding onto stratus, not good flowers + !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.9*(q1(k)+0.4)))) + + + ! Specify hydrometeors + ! JAYMES- this option added 8 May 2015 + ! The cloud water formulations are taken from CB02, Eq. 8. IF (q1k < 0.) THEN !unsaturated -#ifdef SINGLE_PREC - ql_water = sgm(k)*EXP(1.2*q1k-1.) -#else ql_water = sgm(k)*EXP(1.2*q1k-1) -#endif ql_ice = sgm(k)*EXP(1.2*q1k-1.) ELSE IF (q1k > 2.) THEN !supersaturated ql_water = sgm(k)*q1k ql_ice = sgm(k)*q1k - !ql_ice = MIN(80.*qv(k),0.1)*sgm(k)*q1k ELSE !slightly saturated (0 > q1 < 2) ql_water = sgm(k)*(EXP(-1.) + 0.66*q1k + 0.086*q1k**2) ql_ice = sgm(k)*(EXP(-1.) + 0.66*q1k + 0.086*q1k**2) - !ql_ice = MIN(80.*qv(k),0.1)*sgm(k)*(EXP(-1.) + 0.66*q1k + 0.086*q1k**2) ENDIF - !In saturated grid cells, use average of current estimate and prev time step - IF ( qc(k) > 1.e-7 ) ql_water = 0.5 * ( ql_water + qc(k) ) - IF ( qi(k) > 1.e-9 ) ql_ice = 0.5 * ( ql_ice + qi(k) ) + !In saturated grid cells, use average of SGS and resolved values + if ( qc(k) > 1.e-7 ) ql_water = 0.5 * ( ql_water + qc(k) ) + if ( qi(k) > 1.e-9 ) ql_ice = 0.5 * ( ql_ice + qi(k) ) - IF (cldfra_bl1D(k) < 0.01) THEN + if (cldfra_bl1D(k) < 0.01) then ql_ice = 0.0 ql_water = 0.0 cldfra_bl1D(k) = 0.0 - ENDIF + endif !PHASE PARTITIONING: Make some inferences about the relative amounts of !subgrid cloud water vs. ice based on collocated explicit clouds. Otherise, !use a simple temperature-dependent partitioning. -! IF ( qc(k) + qi(k) > 0.0 ) THEN ! explicit condensate exists, retain its phase partitioning -! IF ( qi(k) == 0.0 ) THEN ! explicit contains no ice; assume subgrid liquid -! liq_frac = 1.0 -! ELSE IF ( qc(k) == 0.0 ) THEN ! explicit contains no liquid; assume subgrid ice -! liq_frac = 0.0 -! ELSE IF ( (qc(k) >= 1.E-10) .AND. (qi(k) >= 1.E-10) ) THEN ! explicit contains mixed phase of workably -! ! large amounts; assume subgrid follows -! ! same partioning -! liq_frac = qc(k) / ( qc(k) + qi(k) ) -! ELSE -! liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(t0c-tice))) ! explicit contains mixed phase, but at least one -! ! species is very small, so make a temperature- -! ! depedent guess -! ENDIF -! ELSE ! no explicit condensate, so make a temperature-dependent guess - liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(t0c-tice))) -! ENDIF + ! IF ( qc(k) + qi(k) > 0.0 ) THEN ! explicit condensate exists, retain its phase partitioning + ! IF ( qi(k) == 0.0 ) THEN ! explicit contains no ice; assume subgrid liquid + ! liq_frac = 1.0 + ! ELSE IF ( qc(k) == 0.0 ) THEN ! explicit contains no liquid; assume subgrid ice + ! liq_frac = 0.0 + ! ELSE IF ( (qc(k) >= 1.E-10) .AND. (qi(k) >= 1.E-10) ) THEN ! explicit contains mixed phase of workably + ! ! large amounts; assume subgrid follows + ! ! same partioning + ! liq_frac = qc(k) / ( qc(k) + qi(k) ) + ! ELSE + ! liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(t0c-tice))) ! explicit contains mixed phase, but at least one + ! ! species is very small, so make a temperature- + ! ! depedent guess + ! ENDIF + ! ELSE ! no explicit condensate, so make a temperature-dependent guess + liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(tliq-tice))) + ! ENDIF qc_bl1D(k) = liq_frac*ql_water ! apply liq_frac to ql_water and ql_ice qi_bl1D(k) = (1.0-liq_frac)*ql_ice @@ -4052,15 +4043,17 @@ SUBROUTINE mym_condensation (kts,kte, & !Above tropopause: eliminate subgrid clouds from CB scheme if (k .ge. k_tropo-1) then cldfra_bl1D(K) = 0. - qc_bl1D(k) = 0. - qi_bl1D(k) = 0. + qc_bl1D(k) = 0. + qi_bl1D(k) = 0. endif - ENDDO - - !Buoyancy-flux-related calculations follow... - DO k = kts,kte-1 - t = th(k)*exner(k) + !Buoyancy-flux-related calculations follow... + !limiting Q1 to avoid too much diffusion in cloud layers + if ((xland-1.5).GE.0) then ! water + q1k=max(Q1(k),-2.5) + else ! land + q1k=max(Q1(k),-2.0) + endif ! "Fng" represents the non-Gaussian transport factor ! (non-dimensional) from Bechtold et al. 1995 ! (hereafter BCMT95), section 3(c). Their suggested @@ -4072,8 +4065,7 @@ SUBROUTINE mym_condensation (kts,kte, & !ELSE ! Fng = 1.-1.5*q1k !ENDIF - !limiting to avoid mixing away stratus, was -5 - q1k=MAX(Q1(k),-1.0) + ! Use the form of "Fng" from Bechtold and Siebesma (1998, JAS) IF (q1k .GE. 1.0) THEN Fng = 1.0 ELSEIF (q1k .GE. -1.7 .AND. q1k .LT. 1.0) THEN @@ -4083,42 +4075,70 @@ SUBROUTINE mym_condensation (kts,kte, & ELSE Fng = MIN(23.9 + EXP(-1.6*(q1k+2.5)), 60.) ENDIF - Fng = MIN(Fng, 20.) - - xl = xl_blend(t) - bb = b(k)*t/th(k) ! bb is "b" in BCMT95. Their "b" differs from - ! "b" in CB02 (i.e., b(k) above) by a factor - ! of T/theta. Strictly, b(k) above is formulated in - ! terms of sat. mixing ratio, but bb in BCMT95 is - ! cast in terms of sat. specific humidity. The - ! conversion is neglected here. - qww = 1.+0.61*qw(k) - alpha = 0.61*th(k) - beta = (th(k)/t)*(xl/cp) - 1.61*th(k) - vt(k) = qww - MIN(cldfra_bl1D(K),0.5)*beta*bb*Fng - 1. - vq(k) = alpha + MIN(cldfra_bl1D(K),0.5)*beta*a(k)*Fng - tv0 - ! vt and vq correspond to beta-theta and beta-q, respectively, - ! in NN09, Eq. B8. They also correspond to the bracketed - ! expressions in BCMT95, Eq. 15, since (s*ql/sigma^2) = cldfra*Fng - ! The "-1" and "-tv0" terms are included for consistency with - ! the legacy vt and vq formulations (above). + + if (buoy_opt .eq. 1) then + cfmax= min(cldfra_bl1D(K), 0.6) + bb = b(k)*t/th(k) ! bb is "b" in BCMT95. Their "b" differs from + ! "b" in CB02 (i.e., b(k) above) by a factor + ! of T/theta. Strictly, b(k) above is formulated in + ! terms of sat. mixing ratio, but bb in BCMT95 is + ! cast in terms of sat. specific humidity. The + ! conversion is neglected here. + qww = 1.+0.61*qw(k) + alpha = 0.61*th(k) + beta = (th(k)/t)*(xl/cp) - 1.61*th(k) + vt(k) = qww - cfmax*beta*bb*Fng - 1. + vq(k) = alpha + cfmax*beta*a(k)*Fng - tv0 + ! vt and vq correspond to beta-theta and beta-q, respectively, + ! in NN09, Eq. B8. They also correspond to the bracketed + ! expressions in BCMT95, Eq. 15, since (s*ql/sigma^2) = cldfra*Fng + ! The "-1" and "-tv0" terms are included for consistency with + ! the legacy vt and vq formulations (above). + else + + !original buoyancy flux functions from SD77 + eq1 = rrp*exp( -0.5*q1k*q1k ) + qll = max( cldfra_bl1D(k)*q1k + eq1, 0.0 ) + q2p = xl/cp/exner(k) + + !qt is a THETA-V CONVERSION FOR TOTAL WATER + cfmax= min(cldfra_bl1D(K), 0.6) + qt = 1.0 +p608*qw(k) -(1.+p608)*(qc_bl1D(k)+qi_bl1D(k))*cfmax + rac = alp(k)*( cfmax-qll*eq1 )*( q2p*qt-(1.+p608)*th(k) ) + + !BUOYANCY FACTORS: wherever vt and vq are used, there is a + !"+1" and "+tv0", respectively, so these are subtracted out here. + !vt is unitless and vq has units of K. + vt(k) = qt-1.0 -rac*bet(k) + vq(k) = p608*th(k)-tv0 +rac + endif ! dampen the amplification factor (cld_factor) with height in order ! to limit excessively large cloud fractions aloft !fac_damp = 1.! -MIN(MAX( zagl-(PBLH2+1000.),0.0)/ & ! MAX((zw(k_tropo)-(PBLH2+1000.)),500.), 1.) - fac_damp = min(zagl * 0.01, 1.0) + !fac_damp = min(zagl * 0.01, 1.0) + wsp =sqrt(u1(k)**2 + v1(k)**2) + wspfac = 1.0 - min(max(0.,wsp-15),10.)/10. ! reduce as winds go from 15 to 25 m/s. + fac_damp = min(zagl * 0.0025, 1.0)*wspfac !cld_factor = 1.0 + fac_damp*MAX(0.0, ( RH(k) - 0.5 ) / 0.51 )**3.3 !cld_factor = 1.0 + fac_damp*MAX(0.0, ( RH(k) - 0.75 ) / 0.26 )**1.9 !HRRRv4 !cld_factor = 1.0 + fac_damp*(MAX(0.0, ( RH(k) - 0.80 )) / 0.22 )**2 - cld_factor = 1.0 + fac_damp*(MAX(0.0, ( RH(k) - 0.90 )) / 0.11 )**2 - !cld_factor = 1.0 + !cld_factor = 1.0 + fac_damp*(MAX(0.0, ( RH(k) - 0.90 )) / 0.11 )**2 + !cld_factor = 1.0 + fac_damp*1.8*(max(0.0, q1k + 0.2 ))**2 !too low of albedo + !cld_factor = 1.0 + fac_damp*1.8*(max(0.0, q1k + 0.2 ))**2 + !make this enhancement over water only? + !if ((xland-1.5).GE.0) then ! water + cld_factor = 1.0 + fac_damp*min((max(0.0, ( RH(k) - 0.92 )) / 0.25 )**2, 0.3) + !else + ! cld_factor = 1.0 + !endif cldfra_bl1D(K) = MIN( 1., cld_factor*cldfra_bl1D(K) ) - ENDDO + enddo END SELECT !end cloudPDF option - !FOR TESTING PURPOSES ONLY, ISOLATE ON THE MASS-CLOUDS. + !For testing purposes only, option for isolating on the mass-flux clouds. IF (bl_mynn_cloudpdf .LT. 0) THEN DO k = kts,kte-1 cldfra_bl1D(k) = 0.0 @@ -4143,11 +4163,10 @@ SUBROUTINE mym_condensation (kts,kte, & END SUBROUTINE mym_condensation ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine solves for tendencies of U, V, \f$\theta\f$, qv, !! qc, and qi SUBROUTINE mynn_tendencies(kts,kte,i, & - &closure, & &delt,dz,rho, & &u,v,th,tk,qv,qc,qi,qnc,qni, & &psfc,p,exner, & @@ -4160,7 +4179,7 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & &dfm,dfh,dfq, & &Du,Dv,Dth,Dqv,Dqc,Dqi,Dqnc,Dqni, & &Dqnwfa,Dqnifa,Dozone, & - &vdfg1,diss_heat, & + &diss_heat, & &s_aw,s_awthl,s_awqt,s_awqv,s_awqc, & &s_awu,s_awv, & &s_awqnc,s_awqni, & @@ -4188,7 +4207,6 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(in) :: closure INTEGER, INTENT(in) :: bl_mynn_cloudmix,bl_mynn_mixqt,& bl_mynn_edmf,bl_mynn_edmf_mom, & bl_mynn_mixscalars @@ -4215,10 +4233,10 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & &qnwfa,qnifa,ozone,dfm,dfh REAL, DIMENSION(kts:kte), INTENT(inout) :: du,dv,dth,dqv,dqc,dqi,& &dqni,dqnc,dqnwfa,dqnifa,dozone - REAL, INTENT(IN) :: delt,ust,flt,flq,flqv,flqc,wspd,uoce,voce,& - &psfc + REAL, INTENT(IN) :: flt,flq,flqv,flqc,uoce,voce + REAL(kind=kind_phys), INTENT(IN) :: ust,delt,psfc,wspd !debugging - REAL ::wsp,wsp2 + REAL ::wsp,wsp2,tk2,th2 LOGICAL :: problem integer :: kproblem @@ -4234,7 +4252,6 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & REAL, DIMENSION(kts:kte+1) :: rhoz, & !rho on model interface & khdz, kmdz REAL :: rhs,gfluxm,gfluxp,dztop,maxdfh,mindfh,maxcf,maxKh,zw - REAL :: vdfg1 !Katata-fogdes REAL :: t,esat,qsl,onoff,kh,km,dzk,rhosfc REAL :: ustdrag,ustdiff,qvflux REAL :: th_new,portion_qc,portion_qi,condensate,qsat @@ -4352,7 +4369,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=u(kte) ! CALL tridiag(kte,a,b,c,d) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte ! du(k)=(d(k-kts+1)-u(k))/delt @@ -4416,7 +4434,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=v(kte) ! CALL tridiag(kte,a,b,c,d) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte ! dv(k)=(d(k-kts+1)-v(k))/delt @@ -4483,8 +4502,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=thl(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !thl(k)=d(k-kts+1) @@ -4546,8 +4565,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqw(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqw2) - CALL tridiag3(kte,a,b,c,d,sqw2) + CALL tridiag2(kte,a,b,c,d,sqw2) +! CALL tridiag3(kte,a,b,c,d,sqw2) ! DO k=kts,kte ! sqw2(k)=d(k-kts+1) @@ -4603,8 +4622,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqc(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqc2) - CALL tridiag3(kte,a,b,c,d,sqc2) + CALL tridiag2(kte,a,b,c,d,sqc2) +! CALL tridiag3(kte,a,b,c,d,sqc2) ! DO k=kts,kte ! sqc2(k)=d(k-kts+1) @@ -4681,8 +4700,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqv(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqv2) - CALL tridiag3(kte,a,b,c,d,sqv2) + CALL tridiag2(kte,a,b,c,d,sqv2) +! CALL tridiag3(kte,a,b,c,d,sqv2) ! DO k=kts,kte ! sqv2(k)=d(k-kts+1) @@ -4743,8 +4762,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqi(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqi2) - CALL tridiag3(kte,a,b,c,d,sqi2) + CALL tridiag2(kte,a,b,c,d,sqi2) +! CALL tridiag3(kte,a,b,c,d,sqi2) ! DO k=kts,kte ! sqi2(k)=d(k-kts+1) @@ -4781,8 +4800,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qni(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qni2(k)=d(k-kts+1) @@ -4799,6 +4818,7 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & !!============================================ IF (bl_mynn_cloudmix > 0 .AND. FLAG_QNC .AND. & bl_mynn_mixscalars > 0) THEN + k=kts a(k)= -dtz(k)*khdz(k)*rhoinv(k) @@ -4821,8 +4841,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qnc(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qnc2(k)=d(k-kts+1) @@ -4862,8 +4882,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qnwfa(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qnwfa2(k)=d(k) @@ -4904,8 +4924,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qnifa(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qnifa2(k)=d(k-kts+1) @@ -4943,8 +4963,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=ozone(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !ozone2(k)=d(k-kts+1) @@ -5136,21 +5156,28 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & do k=kts,kte wsp = sqrt(u(k)**2 + v(k)**2) wsp2 = sqrt((u(k)+du(k)*delt)**2 + (v(k)+du(k)*delt)**2) - if (wsp2 > 200.) then + th2 = th(k) + Dth(k)*delt + tk2 = th2*exner(k) + if (wsp2 > 200. .or. tk2 > 360. .or. tk2 < 160.) then problem = .true. - print*,"Huge wind speed: i=",i," k=",k," wsp=",wsp2 - print*," du=",du(k)*delt," dv=",dv(k)*delt + print*,"Outgoing problem at: i=",i," k=",k + print*," incoming wsp=",wsp," outgoing wsp=",wsp2 + print*," incoming T=",th(k)*exner(k),"outgoing T:",tk2 + print*," du=",du(k)*delt," dv=",dv(k)*delt," dth=",dth(k)*delt print*," km=",kmdz(k)*dz(k)," kh=",khdz(k)*dz(k) print*," u*=",ust," wspd=",wspd,"rhosfc=",rhosfc + print*," LH=",flq*rhosfc*1004.," HFX=",flt*rhosfc*1004. print*," drag term=",ust**2/wspd*dtz(k)*rhosfc/rho(kts) kproblem = k endif enddo if (problem) then - print*,"=temp:",thl(max(kproblem-5,1):min(kproblem+5,kte)) - print*,"===qv:",sqv(max(kproblem-5,1):min(kproblem+5,kte)) - print*,"====u:",u(max(kproblem-5,1):min(kproblem+5,kte)) - print*,"====v:",v(max(kproblem-5,1):min(kproblem+5,kte)) + print*,"==thl:",thl(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qv:",sqv2(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qc:",sqc2(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qi:",sqi2(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====u:",u(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====v:",v(max(kproblem-3,1):min(kproblem+3,kte)) endif endif @@ -5162,8 +5189,6 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & END SUBROUTINE mynn_tendencies ! ================================================================== -!>\ingroup gp_mynnedmf -!!ensure non-negative moist species. SUBROUTINE moisture_check(kte, delt, dp, exner, & qv, qc, qi, th, & dqv, dqc, dqi, dth ) @@ -5183,7 +5208,7 @@ SUBROUTINE moisture_check(kte, delt, dp, exner, & implicit none integer, intent(in) :: kte - real, intent(in) :: delt + real(kind=kind_phys), intent(in) :: delt real, dimension(kte), intent(in) :: dp, exner real, dimension(kte), intent(inout) :: qv, qc, qi, th real, dimension(kte), intent(inout) :: dqv, dqc, dqi, dth @@ -5251,8 +5276,6 @@ END SUBROUTINE moisture_check ! ================================================================== -!>\ingroup gp_mynnedmf -!! SUBROUTINE mynn_mix_chem(kts,kte,i, & delt,dz,pblh, & nchem, kdvel, ndvel, & @@ -5261,26 +5284,27 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & flt, tcd, qcd, & dfh, & s_aw, s_awchem, & - emis_ant_no,frp, & - fire_turb ) + emis_ant_no, frp, rrfs_sd, & + enh_mix, smoke_dbg ) !------------------------------------------------------------------- INTEGER, INTENT(in) :: kts,kte,i REAL, DIMENSION(kts:kte), INTENT(IN) :: dfh,dz,tcd,qcd REAL, DIMENSION(kts:kte), INTENT(INOUT) :: rho - REAL, INTENT(IN) :: delt,flt + REAL, INTENT(IN) :: flt + REAL(kind=kind_phys), INTENT(IN) :: delt,pblh INTEGER, INTENT(IN) :: nchem, kdvel, ndvel REAL, DIMENSION( kts:kte+1), INTENT(IN) :: s_aw REAL, DIMENSION( kts:kte, nchem ), INTENT(INOUT) :: chem1 REAL, DIMENSION( kts:kte+1,nchem), INTENT(IN) :: s_awchem REAL, DIMENSION( ndvel ), INTENT(IN) :: vd1 - REAL, INTENT(IN) :: emis_ant_no,frp,pblh - LOGICAL, INTENT(IN) :: fire_turb + REAL(kind=kind_phys), INTENT(IN) :: emis_ant_no,frp + LOGICAL, INTENT(IN) :: rrfs_sd,enh_mix,smoke_dbg !local vars REAL, DIMENSION(kts:kte) :: dtz - REAL, DIMENSION(1:kte-kts+1) :: a,b,c,d,x + REAL, DIMENSION(kts:kte) :: a,b,c,d,x REAL :: rhs,dztop REAL :: t,dzk REAL :: hght @@ -5292,8 +5316,8 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & REAL, DIMENSION(kts:kte) :: rhoinv REAL, DIMENSION(kts:kte+1) :: rhoz,khdz - REAL, PARAMETER :: no_threshold = 0.1 - REAL, PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing + REAL, PARAMETER :: NO_threshold = 0.1 ! For anthropogenic sources + REAL, PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing over big fires REAL, PARAMETER :: pblh_threshold = 250.0 dztop=.5*(dz(kte)+dz(kte-1)) @@ -5324,18 +5348,19 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & khdz(k) = MAX(khdz(k), -0.5*(s_aw(k)-s_aw(k+1))) ENDDO - !Enhance diffusion over fires - IF ( fire_turb ) THEN + !Enhanced mixing over fires + IF ( rrfs_sd .and. enh_mix ) THEN DO k=kts+1,kte-1 khdz_old = khdz(k) khdz_back = pblh * 0.15 / dz(k) !Modify based on anthropogenic emissions of NO and FRP IF ( pblh < pblh_threshold ) THEN - IF ( emis_ant_no > no_threshold ) THEN - khdz(k) = MAX(1.1*khdz(k),sqrt((emis_ant_no / no_threshold)) / dz(k) * rhoz(k)) ! JLS 12/21/21 + IF ( emis_ant_no > NO_threshold ) THEN + khdz(k) = MAX(1.1*khdz(k),sqrt((emis_ant_no / NO_threshold)) / dz(k) * rhoz(k)) ! JLS 12/21/21 ! khdz(k) = MAX(khdz(k),khdz_back) ENDIF IF ( frp > frp_threshold ) THEN + kmaxfire = ceiling(log(frp)) khdz(k) = MAX(1.1*khdz(k), (1. - k/(kmaxfire*2.)) * ((log(frp))**2.- 2.*log(frp)) / dz(k)*rhoz(k)) ! JLS 12/21/21 ! khdz(k) = MAX(khdz(k),khdz_back) ENDIF @@ -5354,7 +5379,7 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & b(k)=1.+dtz(k)*(khdz(k+1)+khdz(k))*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1) c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1) d(k)=chem1(k,ic) & !dtz(k)*flt !neglecting surface sources - & + dtz(k) * -vd1(ic)*chem1(1,ic) & + & - dtz(k)*vd1(ic)*chem1(k,ic) & & - dtz(k)*rhoinv(k)*s_awchem(k+1,ic) DO k=kts+1,kte-1 @@ -5371,11 +5396,14 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & c(kte)=0. d(kte)=chem1(kte,ic) - !CALL tridiag(kte,a,b,c,d) CALL tridiag3(kte,a,b,c,d,x) + IF ( smoke_dbg ) THEN + print*,'aerosol mixing ic,chem1,chem2(k,ic)',ic,(chem1(kts:kts+10,ic)),(x(kts:kts+10)) + print*,'aerosol PBL mixing ic,vd1(ic)',ic,vd1(ic) + END IF + DO k=kts,kte - !chem_new(k,ic)=d(k) chem1(k,ic)=x(k) ENDDO ENDDO @@ -5383,7 +5411,7 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & END SUBROUTINE mynn_mix_chem ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf SUBROUTINE retrieve_exchange_coeffs(kts,kte,& &dfm,dfh,dz,K_m,K_h) @@ -5411,7 +5439,7 @@ SUBROUTINE retrieve_exchange_coeffs(kts,kte,& END SUBROUTINE retrieve_exchange_coeffs ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf SUBROUTINE tridiag(n,a,b,c,d) !! to solve system of linear eqs on tridiagonal matrix n times n @@ -5447,7 +5475,7 @@ SUBROUTINE tridiag(n,a,b,c,d) END SUBROUTINE tridiag ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf subroutine tridiag2(n,a,b,c,d,x) implicit none ! a - sub-diagonal (means it is the diagonal below the main diagonal) @@ -5482,7 +5510,7 @@ subroutine tridiag2(n,a,b,c,d,x) end subroutine tridiag2 ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf subroutine tridiag3(kte,a,b,c,d,x) !ccccccccccccccccccccccccccccccc @@ -5525,8 +5553,7 @@ end subroutine tridiag3 ! ================================================================== -!>\ingroup gp_mynnedmf -!! +!>\ingroup gsd_mynn_edmf SUBROUTINE mynn_bl_init_driver( & &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN, & &RQCBLTEN,RQIBLTEN & !,RQNIBLTEN,RQNCBLTEN & @@ -5582,7 +5609,7 @@ SUBROUTINE mynn_bl_init_driver( & END SUBROUTINE mynn_bl_init_driver ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates hybrid diagnotic boundary-layer height (PBLH). !! !! NOTES ON THE PBLH FORMULATION: The 1.5-theta-increase method defines @@ -5627,7 +5654,7 @@ SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea,kzi) # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(OUT) :: zi + REAL(kind=kind_phys), INTENT(OUT) :: zi REAL, INTENT(IN) :: landsea REAL, DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D REAL, DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D @@ -5744,7 +5771,8 @@ SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea,kzi) END SUBROUTINE GET_PBLH !> @} -!>\ingroup gp_mynnedmf +! ================================================================== +!>\ingroup gsd_mynn_edmf !! This subroutine is the Dynamic Multi-Plume (DMP) Mass-Flux Scheme. !! !! dmp_mf() calculates the nonlocal turbulent transport from the dynamic @@ -5818,8 +5846,9 @@ SUBROUTINE DMP_mf( & REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,W,TH,THL,TK,QT,QV,QC,& exner,dz,THV,P,rho,qke,qnc,qni,qnwfa,qnifa REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW !height at full-sigma - REAL, INTENT(IN) :: DT,UST,FLT,FLTV,FLQ,FLQV,PBLH,& - DX,Psig_shcu,landsea,ts + REAL, INTENT(IN) :: FLT,FLTV,FLQ,FLQV,& + Psig_shcu,landsea,ts + REAL(kind=kind_phys), INTENT(IN) :: dx,dt,ust,pblh LOGICAL, OPTIONAL :: F_QC,F_QI,F_QNC,F_QNI,F_QNWFA,F_QNIFA ! outputs - updraft properties @@ -5829,7 +5858,8 @@ SUBROUTINE DMP_mf( & REAL,DIMENSION(KTS:KTE) :: edmf_th ! output INTEGER, INTENT(OUT) :: nup2,ktop - REAL, INTENT(OUT) :: maxmf,ztop + REAL(kind=kind_phys), INTENT(OUT) :: maxmf + REAL, INTENT(OUT) :: ztop ! outputs - variables needed for solver REAL,DIMENSION(KTS:KTE+1) :: s_aw, & !sum ai*rho*wis_awphi s_awthl, & !sum ai*rho*wi*phii @@ -5847,7 +5877,7 @@ SUBROUTINE DMP_mf( & REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: qc_bl1d,cldfra_bl1d, & qc_bl1d_old,cldfra_bl1d_old - INTEGER, PARAMETER :: NUP=10, debug_mf=0 + INTEGER, PARAMETER :: nup=10, debug_mf=0 !------------- local variables ------------------- ! updraft properties defined on interfaces (k=1 is the top of the @@ -5863,7 +5893,7 @@ SUBROUTINE DMP_mf( & REAL :: fltv2,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & pwmin,pwmax,wmin,wmax,wlv,Psig_w,maxw,maxqc,wpbl REAL :: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,QNCn,QNIn,QNWFAn,QNIFAn, & - Wn2,Wn,EntEXP,EntEXM,EntW,BCOEFF,THVkm1,THVk,Pk,rho_int + Wn2,Wn,EntEXP,EntEXM,EntW,BCOEFF,THVkm1,THVk,Pk,qtk,rho_int ! w parameters REAL,PARAMETER :: & @@ -5904,13 +5934,14 @@ SUBROUTINE DMP_mf( & ! VARIABLES FOR CHABOUREAU-BECHTOLD CLOUD FRACTION REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: vt, vq, sgm - REAL :: sigq,xl,rsl,cpm,a,qmq,mf_cf,Q1,diffqt,qsat_tk,& + REAL :: sigq,xl,rsl,cpm,a,qmq,mf_cf,Aup,Q1,diffqt,qsat_tk,& Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid, & Ac_mf,Ac_strat,qc_mf + REAL, PARAMETER :: cf_thresh = 0.5 ! only overwrite stratus CF less than this value ! Variables for plume interpolation/saturation check REAL,DIMENSION(KTS:KTE) :: exneri,dzi - REAL :: THp, QTp, QCp, QCs, esat, qsl + REAL :: THp, QTp, QCp, QCs, esat, qsl REAL :: csigma,acfac,ac_wsp,ac_cld !plume overshoot @@ -5931,7 +5962,7 @@ SUBROUTINE DMP_mf( & REAL,DIMENSION(KTS:KTE+1) :: envi_a,envi_w !environmental variables defined at model interface REAL :: temp,sublim,qc_ent,qv_ent,qt_ent,thl_ent,detrate, & detrateUV,oow,exc_fac,aratio,detturb,qc_grid,qc_sgs,& - qc_plume + qc_plume,exc_heat,exc_moist,tk_int REAL, PARAMETER :: Cdet = 1./45. REAL, PARAMETER :: dzpmax = 300. !limit dz used in detrainment - can be excessing in thick layers !parameter "Csub" determines the propotion of upward vertical velocity that contributes to @@ -6200,13 +6231,28 @@ SUBROUTINE DMP_mf( & UPV(1,I)=(V(KTS)*DZ(KTS+1)+V(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQC(1,I)=0.0 !UPQC(1,I)=(QC(KTS)*DZ(KTS+1)+QC(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) - UPQT(1,I)=(QT(KTS)*DZ(KTS+1)+QT(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1))& - & +exc_fac*UPW(1,I)*sigmaQT/sigmaW + + exc_heat = exc_fac*UPW(1,I)*sigmaTH/sigmaW UPTHV(1,I)=(THV(KTS)*DZ(KTS+1)+THV(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) & - & +exc_fac*UPW(1,I)*sigmaTH/sigmaW + & + exc_heat !was UPTHL(1,I)= UPTHV(1,I)/(1.+svp1*UPQT(1,I)) !assume no saturated parcel at surface UPTHL(1,I)=(THL(KTS)*DZ(KTS+1)+THL(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) & - & +exc_fac*UPW(1,I)*sigmaTH/sigmaW + & + exc_heat + + !calculate exc_moist by use of surface fluxes + exc_moist=exc_fac*UPW(1,I)*sigmaQT/sigmaW + !calculate exc_moist by conserving rh: +! tk_int =(tk(kts)*dz(kts+1)+tk(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) +! pk =(p(kts)*dz(kts+1)+p(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) +! qtk =(qt(kts)*dz(kts+1)+qt(kts+1)*dz(kts))/(dz(kts)+dz(kts+1)) +! qsat_tk = qsat_blend(tk_int, pk) ! saturation water vapor mixing ratio at tk and p +! rhgrid =MAX(MIN(1.0,qtk/MAX(1.E-8,qsat_tk)),0.001) +! tk_int = tk_int + exc_heat +! qsat_tk = qsat_blend(tk_int, pk) +! exc_moist= max(rhgrid*qsat_tk - qtk, 0.0) + UPQT(1,I)=(QT(KTS)*DZ(KTS+1)+QT(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1))& + & +exc_moist + UPQKE(1,I)=(QKE(KTS)*DZ(KTS+1)+QKE(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNC(1,I)=(QNC(KTS)*DZ(KTS+1)+QNC(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNI(1,I)=(QNI(KTS)*DZ(KTS+1)+QNI(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) @@ -6299,14 +6345,14 @@ SUBROUTINE DMP_mf( & !Vn =V(K) *(1-EntExp)+UPV(K-1,I)*EntExp !QKEn=QKE(k)*(1-EntExp)+UPQKE(K-1,I)*EntExp - IF ( mix_chem ) THEN + if ( mix_chem ) then do ic = 1,nchem ! Exponential Entrainment: !chemn(ic) = chem(k,ic)*(1-EntExp)+UPCHEM(K-1,I,ic)*EntExp ! Linear entrainment: chemn(ic)=UPCHEM(k-1,i,ic)*(1.-EntExp) + chem1(k,ic)*EntExp enddo - ENDIF + endif ! Define pressure at model interface Pk =(P(k)*DZ(k+1)+P(k+1)*DZ(k))/(DZ(k+1)+DZ(k)) @@ -6479,7 +6525,7 @@ SUBROUTINE DMP_mf( & s_awthl(k+1)= s_awthl(k+1) + rho_int*UPA(K,i)*UPW(K,i)*UPTHL(K,i)*Psig_w s_awqt(k+1) = s_awqt(k+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQT(K,i)*Psig_w !to conform to grid mean properties, move qc to qv in grid mean - !saturated layers, so total water fluxes are preserve but + !saturated layers, so total water fluxes are preserved but !negative qc fluxes in unsaturated layers is reduced. IF (qc(k) > 1e-12 .OR. qc(k+1) > 1e-12) then qc_plume = UPQC(K,i) @@ -6697,22 +6743,22 @@ SUBROUTINE DMP_mf( & ! mym_condensation. Here, a shallow-cu component is added, but no cumulus ! clouds can be added at k=1 (start loop at k=2). DO K=KTS+1,KTE-2 - IF(k > KTOP) exit - IF(0.5*(edmf_qc(k)+edmf_qc(k-1))>0.0)THEN - - !interpolate plume thl, th, and qt to mass levels + IF(k > KTOP) exit + IF(0.5*(edmf_qc(k)+edmf_qc(k-1))>0.0)THEN + !interpolate plume quantities to mass levels + Aup = (edmf_a(k)*dzi(k-1)+edmf_a(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) THp = (edmf_th(k)*dzi(k-1)+edmf_th(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) QTp = (edmf_qt(k)*dzi(k-1)+edmf_qt(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) !convert TH to T - t = THp*exner(k) +! t = THp*exner(k) !SATURATED VAPOR PRESSURE - esat = esat_blend(t) + esat = esat_blend(tk(k)) !SATURATED SPECIFIC HUMIDITY - qsl=ep_2*esat/max(1.e-4,(p(k)-ep_3*esat)) + qsl=ep_2*esat/max(1.e-7,(p(k)-ep_3*esat)) !condensed liquid in the plume on mass levels IF (edmf_qc(k)>0.0 .AND. edmf_qc(k-1)>0.0)THEN - QCp = 0.5*(edmf_qc(k)+edmf_qc(k-1)) + QCp = (edmf_qc(k)*dzi(k-1)+edmf_qc(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) ELSE QCp = MAX(edmf_qc(k),edmf_qc(k-1)) ENDIF @@ -6728,7 +6774,7 @@ SUBROUTINE DMP_mf( & b9 = a*rsl ! CB02 variable "b" q2p = xlvcp/exner(k) - pt = thl(k) +q2p*QCp*0.5*(edmf_a(k)+edmf_a(k-1)) ! potential temp (env + plume) + pt = thl(k) +q2p*QCp*Aup ! potential temp (env + plume) bb = b9*tk(k)/pt ! bb is "b9" in BCMT95. Their "b9" differs from ! "b9" in CB02 by a factor ! of T/theta. Strictly, b9 above is formulated in @@ -6748,17 +6794,32 @@ SUBROUTINE DMP_mf( & endif !CB form: - !sigq = 9.E-3 * 0.5*(edmf_a(k)+edmf_a(k-1)) * & - ! & 0.5*(edmf_w(k)+edmf_w(k-1)) * f ! convective component of sigma (CB2005) + sigq = 3.5E-3 * Aup * 0.5*(edmf_w(k)+edmf_w(k-1)) * f ! convective component of sigma (CB2005) !sigq = SQRT(sigq**2 + sgm(k)**2) ! combined conv + stratus components !Per S.DeRoode 2009? - sigq = 10. * edmf_a(k) * (edmf_qt(k)-qt(k)) - - sigq = MAX(sigq, 1.0E-6) + !sigq = 4. * Aup * (QTp - qt(k)) + !constrain sigq wrt saturation: + sigq = max(sigq, qsat_tk*0.02 ) + sigq = min(sigq, qsat_tk*0.25 ) qmq = a * (qt(k) - qsat_tk) ! saturation deficit/excess; - ! the numerator of Q1 - mf_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.01),0.6) + Q1 = qmq/sigq ! the numerator of Q1 + + if ((landsea-1.5).GE.0) then ! WATER + mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.2)),0.01),0.6) + mf_cf = max(mf_cf, 1.2 * Aup) + else ! LAND + !mf_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.01),0.6) + mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.4)),0.01),0.6) ! New WA fit + mf_cf = max(mf_cf, 1.75 * Aup) + endif + + ! WA TEST 4/15/22 use fit to Aup rather than CB + !IF (Aup > 0.1) THEN + ! mf_cf = 2.5 * Aup + !ELSE + ! mf_cf = 1.8 * Aup + !ENDIF !IF ( debug_code ) THEN ! print*,"In MYNN, StEM edmf" @@ -6769,61 +6830,64 @@ SUBROUTINE DMP_mf( & !ENDIF ! Update cloud fractions and specific humidities in grid cells - ! where the mass-flux scheme is active. Now, we also use the - ! stratus component of the SGS clouds as well. The stratus cloud - ! fractions (Ac_strat) are reduced slightly to give way to the - ! mass-flux SGS cloud fractions (Ac_mf). - IF (cldfra_bl1d(k) < 0.5) THEN - IF (mf_cf > 0.5*(edmf_a(k)+edmf_a(k-1))) THEN - !cldfra_bl1d(k) = mf_cf - !qc_bl1d(k) = QCp*0.5*(edmf_a(k)+edmf_a(k-1))/mf_cf - Ac_mf = mf_cf - Ac_strat = cldfra_bl1d(k)*(1.0-mf_cf) - cldfra_bl1d(k) = Ac_mf + Ac_strat - !dillute Qc from updraft area to larger cloud area - qc_mf = QCp*0.5*(edmf_a(k)+edmf_a(k-1))/mf_cf - !The mixing ratios from the stratus component are not well - !estimated in shallow-cumulus regimes. Ensure stratus clouds - !have mixing ratio similar to cumulus - QCs = MAX(qc_bl1d(k), 0.5*qc_mf) - qc_bl1d(k) = (qc_mf*Ac_mf + QCs*Ac_strat)/cldfra_bl1d(k) - ELSE - !cldfra_bl1d(k)=0.5*(edmf_a(k)+edmf_a(k-1)) - !qc_bl1d(k) = QCp - Ac_mf = 0.5*(edmf_a(k)+edmf_a(k-1)) - Ac_strat = cldfra_bl1d(k)*(1.0-Ac_mf) - cldfra_bl1d(k)=Ac_mf + Ac_strat - qc_mf = QCp - !Ensure stratus clouds have mixing ratio similar to cumulus - QCs = MAX(qc_bl1d(k), 0.5*qc_mf) - qc_bl1d(k) = (QCp*Ac_mf + QCs*Ac_strat)/cldfra_bl1d(k) - ENDIF - ELSE - Ac_mf = mf_cf - ENDIF + ! where the mass-flux scheme is active. The specific humidities + ! are converted to grid means (not in-cloud quantities). + + if ((landsea-1.5).GE.0) then ! water + !don't overwrite stratus CF & qc_bl - degrades marine stratus + if (cldfra_bl1d(k) < cf_thresh) then + if (QCp * Aup > 5e-5) then + qc_bl1d(k) = 1.86 * (QCp * Aup) - 2.2e-5 + else + qc_bl1d(k) = 1.18 * (QCp * Aup) + endif + if (mf_cf .ge. Aup) then + qc_bl1d(k) = qc_bl1d(k) / mf_cf + endif + cldfra_bl1d(k) = mf_cf + Ac_mf = mf_cf + endif + else ! land + if (QCp * Aup > 5e-5) then + qc_bl1d(k) = 1.86 * (QCp * Aup) - 2.2e-5 + else + qc_bl1d(k) = 1.18 * (QCp * Aup) + endif + if (mf_cf .ge. Aup) then + qc_bl1d(k) = qc_bl1d(k) / mf_cf + endif + cldfra_bl1d(k) = mf_cf + Ac_mf = mf_cf + endif !Now recalculate the terms for the buoyancy flux for mass-flux clouds: - !See mym_condensation for details on these formulations. The - !cloud-fraction bounding was added to improve cloud retention, - !following RAP and HRRR testing. - !Fng = 2.05 ! the non-Gaussian transport factor (assumed constant) - !Use Bechtold and Siebesma (1998) piecewise estimation of Fng: - Q1 = qmq/MAX(sigq,1E-6) - Q1=MAX(Q1,-5.0) - IF (Q1 .GE. 1.0) THEN - Fng = 1.0 - ELSEIF (Q1 .GE. -1.7 .AND. Q1 .LT. 1.0) THEN - Fng = EXP(-0.4*(Q1-1.0)) - ELSEIF (Q1 .GE. -2.5 .AND. Q1 .LT. -1.7) THEN - Fng = 3.0 + EXP(-3.8*(Q1+1.7)) - ELSE - Fng = MIN(23.9 + EXP(-1.6*(Q1+2.5)), 60.) - ENDIF + !See mym_condensation for details on these formulations. + !Use Bechtold and Siebesma (1998) piecewise estimation of Fng with + !limits ,since they really should be recalculated after all the other changes...: + !Only overwrite vt & vq in non-stratus condition + if (cldfra_bl1d(k) < cf_thresh) then + !if ((landsea-1.5).GE.0) then ! WATER + Q1=max(Q1,-2.25) + !else + ! Q1=max(Q1,-2.0) + !endif + + if (Q1 .ge. 1.0) then + Fng = 1.0 + elseif (Q1 .ge. -1.7 .and. Q1 .lt. 1.0) then + Fng = EXP(-0.4*(Q1-1.0)) + elseif (Q1 .ge. -2.5 .and. Q1 .lt. -1.7) then + Fng = 3.0 + EXP(-3.8*(Q1+1.7)) + else + Fng = min(23.9 + EXP(-1.6*(Q1+2.5)), 60.) + endif - vt(k) = qww - MIN(0.40,Ac_mf)*beta*bb*Fng - 1. - vq(k) = alpha + MIN(0.40,Ac_mf)*beta*a*Fng - tv0 - ENDIF - ENDDO + !link the buoyancy flux function to active clouds only (c*Aup): + vt(k) = qww - (1.5*Aup)*beta*bb*Fng - 1. + vq(k) = alpha + (1.5*Aup)*beta*a*Fng - tv0 + endif + endif + enddo !k-loop ENDIF !end nup2 > 0 @@ -6883,10 +6947,12 @@ SUBROUTINE DMP_mf( & END SUBROUTINE DMP_MF !================================================================= -!>\ingroup gp_mynnedmf -!! zero or one condensation for edmf: calculates THV and QC +!>\ingroup gsd_mynn_edmf +!! This subroutine subroutine condensation_edmf(QT,THL,P,zagl,THV,QC) ! +! zero or one condensation for edmf: calculates THV and QC +! real,intent(in) :: QT,THL,P,zagl real,intent(out) :: THV real,intent(inout):: QC @@ -6944,10 +7010,11 @@ end subroutine condensation_edmf !=============================================================== -!> zero or one condensation for edmf: calculates THL and QC -!! similar to condensation_edmf but with different inputs subroutine condensation_edmf_r(QT,THL,P,zagl,THV,QC) ! +! zero or one condensation for edmf: calculates THL and QC +! similar to condensation_edmf but with different inputs +! real,intent(in) :: QT,THV,P,zagl real,intent(out) :: THL, QC @@ -6979,10 +7046,12 @@ subroutine condensation_edmf_r(QT,THL,P,zagl,THV,QC) end subroutine condensation_edmf_r !=============================================================== -!> This is the downdraft mass flux scheme - analogus to edmf_JPL but -!! flipped updraft to downdraft. This scheme is currently only tested -!! for Stratocumulus cloud conditions. For a detailed desctiption of the -!! model, see paper. +! =================================================================== +! This is the downdraft mass flux scheme - analogus to edmf_JPL but +! flipped updraft to downdraft. This scheme is currently only tested +! for Stratocumulus cloud conditions. For a detailed desctiption of the +! model, see paper. + SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & &u,v,th,thl,thv,tk,qt,qv,qc, & &rho,exner, & @@ -6997,11 +7066,12 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & INTEGER, INTENT(IN) :: KTS,KTE,KPBL REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,TH,THL,TK,QT,QV,QC,& - THV,P,rho,exner,rthraten,dz + THV,P,rho,exner,dz + REAL(kind=kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: rthraten ! zw .. heights of the downdraft levels (edges of boxes) REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW - REAL, INTENT(IN) :: DT,UST,WTHL,WQT,PBLH - + REAL, INTENT(IN) :: WTHL,WQT + REAL(kind=kind_phys), INTENT(IN) :: dt,ust,pblh ! outputs - downdraft properties REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a_dd,edmf_w_dd, & & edmf_qt_dd,edmf_thl_dd, edmf_ent_dd,edmf_qc_dd @@ -7342,17 +7412,19 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & END SUBROUTINE DDMF_JPL !=============================================================== -!> Add scale-aware factor (Psig) here, taken from Honnert et al. (2011) \cite Honnert_2011 -!! and/or from Shin and Hong (2013) \cite Shin_2013. + SUBROUTINE SCALE_AWARE(dx,PBL1,Psig_bl,Psig_shcu) !--------------------------------------------------------------- ! NOTES ON SCALE-AWARE FORMULATION ! + !JOE: add scale-aware factor (Psig) here, taken from Honnert et al. (2011, + ! JAS) and/or from Hyeyum Hailey Shin and Song-You Hong (2013, JAS) + ! ! Psig_bl tapers local mixing ! Psig_shcu tapers nonlocal mixing - REAL,INTENT(IN) :: dx,PBL1 + REAL(kind=kind_phys), INTENT(IN) :: dx,pbl1 REAL, INTENT(OUT) :: Psig_bl,Psig_shcu REAL :: dxdh @@ -7415,7 +7487,7 @@ SUBROUTINE SCALE_AWARE(dx,PBL1,Psig_bl,Psig_shcu) END SUBROUTINE SCALE_AWARE ! ===================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! \author JAYMES- added 22 Apr 2015 !! This function calculates saturation vapor pressure. Separate ice and liquid functions !! are used (identical to those in module_mp_thompson.F, v3.6). Then, the @@ -7449,7 +7521,7 @@ END FUNCTION esat_blend ! ==================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This function extends function "esat" and returns a "blended" !! saturation mixing ratio. !!\author JAYMES @@ -7491,7 +7563,7 @@ END FUNCTION qsat_blend ! =================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This function interpolates the latent heats of vaporization and sublimation into !! a single, temperature-dependent, "blended" value, following !! Chaboureau and Bechtold (2002) \cite Chaboureau_2002, Appendix. @@ -7519,13 +7591,14 @@ FUNCTION xl_blend(t) END FUNCTION xl_blend ! =================================================================== -!> New stability function parameters for momentum (Puhales, 2020, WRF 4.2.1) -!! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of -!! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly -!! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an -!! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very -!! stable conditions [z/L ~ O(10)]. + FUNCTION phim(zet) + ! New stability function parameters for momentum (Puhales, 2020, WRF 4.2.1) + ! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of + ! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly + ! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an + ! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very + ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE REAL, INTENT(IN):: zet @@ -7569,14 +7642,15 @@ FUNCTION phim(zet) phim = phi_m END FUNCTION phim +! =================================================================== -!> New stability function parameters for heat (Puhales, 2020, WRF 4.2.1) -!! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of -!! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly -!! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an -!! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very -!! stable conditions [z/L ~ O(10)]. FUNCTION phih(zet) + ! New stability function parameters for heat (Puhales, 2020, WRF 4.2.1) + ! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of + ! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly + ! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an + ! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very + ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE REAL, INTENT(IN):: zet @@ -7618,8 +7692,6 @@ FUNCTION phih(zet) END FUNCTION phih ! ================================================================== -!>\ingroup gp_mynnedmf -!! Calculate the buoyancy production of TKE from cloud-top cooling. SUBROUTINE topdown_cloudrad(kts,kte,dz1,zw,xland,kpbl,PBLH, & &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & &cldfra_bl1D,rthraten, & @@ -7628,9 +7700,11 @@ SUBROUTINE topdown_cloudrad(kts,kte,dz1,zw,xland,kpbl,PBLH, & !input integer, intent(in) :: kte,kts real, dimension(kts:kte), intent(in) :: dz1,sqc,sqi,sqw,& - thl,th1,ex1,p1,rho1,thetav,cldfra_bl1D,rthraten + thl,th1,ex1,p1,rho1,thetav,cldfra_bl1D + real(kind=kind_phys), dimension(kts:kte), intent(in) :: rthraten real, dimension(kts:kte+1), intent(in) :: zw - real, intent(in) :: pblh,xland + real(kind=kind_phys), intent(in) :: pblh + real, intent(in) :: xland integer,intent(in) :: kpbl !output real, intent(out) :: maxKHtopdown diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 08a28f2bd..8ac6378bd 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -2,6 +2,7 @@ !! This file contains all of the code related to running the MYNN !! eddy-diffusivity mass-flux scheme. +!>\ingroup gsd_mynn_edmf !> The following references best describe the code within !! Olson et al. (2019, NOAA Technical Memorandum) !! Nakanishi and Niino (2009) \cite NAKANISHI_2009 @@ -82,16 +83,12 @@ subroutine mynnedmf_wrapper_init ( & return end if - if (lheatstrg) then - errmsg = 'Logic error: lheatstrg not implemented for MYNN PBL' - errflg = 1 - return - end if - end subroutine mynnedmf_wrapper_init -!>\defgroup gp_mynnedmf MYNN-EDMF PBL and Shallow Convection Module -!> This scheme (1) performs pre-mynnedmf work, (2) runs the mynnedmf, and (3) performs post-mynnedmf work + subroutine mynnedmf_wrapper_finalize () + end subroutine mynnedmf_wrapper_finalize + +! \brief This scheme (1) performs pre-mynnedmf work, (2) runs the mynnedmf, and (3) performs post-mynnedmf work !> \section arg_table_mynnedmf_wrapper_run Argument Table !! \htmlinclude mynnedmf_wrapper_run.html !! @@ -158,14 +155,15 @@ SUBROUTINE mynnedmf_wrapper_run( & & icloud_bl, do_mynnsfclay, & & imp_physics, imp_physics_gfdl, & & imp_physics_thompson, imp_physics_wsm6, & - & chem3d, frp, mix_chem, rrfs_smoke, fire_turb, nchem, ndvel, & + & rrfs_sd, chem3d, frp, mix_chem, enh_mix, & + & nchem, ndvel, vdep, smoke_dbg, & & imp_physics_nssl, nssl_ccn_on, & - & ltaerosol, mraerosol, spp_wts_pbl, spp_pbl, lprnt, huge, errmsg, errflg ) + & ltaerosol, spp_wts_pbl, spp_pbl, lprnt, huge, errmsg, errflg ) ! should be moved to inside the mynn: use machine, only: kind_phys use bl_mynn_common, only: cp, r_d, grav, g_inv, zero, & - xlv, xlvcp, xlscp + xlv, xlvcp, xlscp, p608 use module_bl_mynn, only: mynn_bl_driver !------------------------------------------------------------------- @@ -182,12 +180,13 @@ SUBROUTINE mynnedmf_wrapper_run( & !smoke/chem integer, intent(in) :: nchem, ndvel integer, parameter :: kdvel=1 + logical, intent(in) :: smoke_dbg ! NAMELIST OPTIONS (INPUT): logical, intent(in) :: & & bl_mynn_tkeadvect, & & bl_mynn_tkebudget, & - & ltaerosol, mraerosol, & + & ltaerosol, & & lprnt, & & do_mynnsfclay, & & flag_for_pbl_generic_tend, & @@ -206,7 +205,7 @@ SUBROUTINE mynnedmf_wrapper_run( & & imp_physics_thompson, imp_physics_gfdl, & & imp_physics_nssl, & & spp_pbl - real, intent(in) :: & + real(kind=kind_phys), intent(in) :: & & bl_mynn_closure !TENDENCY DIAGNOSTICS @@ -274,7 +273,7 @@ SUBROUTINE mynnedmf_wrapper_run( & real(kind=kind_phys), dimension(:), intent(in) :: xmu real(kind=kind_phys), dimension(:,:), intent(in) :: htrsw, htrlw ! spp_wts_pbl only allocated if spp_pbl == 1 - real(kind_phys), dimension(:,:), intent(in) :: spp_wts_pbl + real(kind=kind_phys), dimension(:,:), intent(in) :: spp_wts_pbl !LOCAL real(kind=kind_phys), dimension(im,levs) :: & @@ -286,11 +285,11 @@ SUBROUTINE mynnedmf_wrapper_run( & real(kind=kind_phys), allocatable :: old_ozone(:,:) !smoke/chem arrays - real(kind_phys), dimension(:), intent(inout) :: frp - logical, intent(in) :: mix_chem, fire_turb, rrfs_smoke + real(kind=kind_phys), dimension(:), intent(inout) :: frp + logical, intent(in) :: mix_chem, enh_mix, rrfs_sd real(kind=kind_phys), dimension(:,:,:), intent(inout) :: chem3d + real(kind=kind_phys), dimension(:,: ), intent(inout) :: vdep real(kind=kind_phys), dimension(im) :: emis_ant_no - real(kind=kind_phys), dimension(im,ndvel) :: vdep !MYNN-2D real(kind=kind_phys), dimension(:), intent(in) :: & @@ -357,7 +356,6 @@ SUBROUTINE mynnedmf_wrapper_run( & !initialize arrays for test EMIS_ANT_NO = 0. - vdep = 0. ! hli for chem dry deposition, 0 temporarily ! Check incoming moist species to ensure non-negative values ! First, create height (dz) and pressure differences (delp) @@ -475,32 +473,6 @@ SUBROUTINE mynnedmf_wrapper_run( & qnifa(i,k) = qgrs_ice_aer_num_conc(i,k) enddo enddo - else if(mraerosol) then - FLAG_QI = .true. - FLAG_QNI= .true. - FLAG_QC = .true. - FLAG_QNC= .true. - FLAG_QNWFA= .false. - FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 - do k=1,levs - do i=1,im - sqv(i,k) = qgrs_water_vapor(i,k) - sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) - qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) - qni(i,k) = qgrs_cloud_ice_num_conc(i,k) - ozone(i,k) = qgrs_ozone(i,k) - qnwfa(i,k) = 0. - qnifa(i,k) = 0. - enddo - enddo else FLAG_QI = .true. FLAG_QNI= .true. @@ -594,11 +566,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im ! dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv th(i,k)=t3d(i,k)/exner(i,k) - ! keep as specific humidity - ! qv(i,k)=qvsh(i,k)/(1.0 - qvsh(i,k)) - ! qc(i,k)=qc(i,k)/(1.0 - qvsh(i,k)) - ! qi(i,k)=qi(i,k)/(1.0 - qvsh(i,k)) - rho(i,k)=prsl(i,k)/(r_d*t3d(i,k)) + rho(i,k)=prsl(i,k)/(r_d*t3d(i,k)*(1.+p608*max(sqv(i,k),1e-8))) w(i,k) = -omega(i,k)/(rho(i,k)*grav) enddo enddo @@ -616,6 +584,11 @@ SUBROUTINE mynnedmf_wrapper_run( & ch(i)=0.0 hfx(i)=hflx(i)*rho(i,1)*cp qfx(i)=qflx(i)*rho(i,1) + !filter bad incoming fluxes + if (hfx(i) > 1200.)hfx(i) = 1200. + if (hfx(i) < -500.)hfx(i) = -500. + if (qfx(i) > .0005)qfx(i) = 0.0005 + if (qfx(i) < -.0002)qfx(i) = -0.0002 dtsfc1(i) = hfx(i) dqsfc1(i) = qfx(i)*XLV @@ -742,10 +715,10 @@ SUBROUTINE mynnedmf_wrapper_run( & & sh3d=Sh3d,sm3d=Sm3d, & !chem/smoke & nchem=nchem,kdvel=kdvel,ndvel=ndvel, & - & Chem3d=chem3d,Vdep=vdep, & + & Chem3d=chem3d,Vdep=vdep,smoke_dbg=smoke_dbg, & & FRP=frp,EMIS_ANT_NO=emis_ant_no, & - & mix_chem=mix_chem,fire_turb=fire_turb, & - & rrfs_smoke=rrfs_smoke, & + & mix_chem=mix_chem,enh_mix=enh_mix, & + & rrfs_sd=rrfs_sd, & !----- & Tsq=tsq,Qsq=qsq,Cov=cov, & !output & RUBLTEN=RUBLTEN,RVBLTEN=RVBLTEN,RTHBLTEN=RTHBLTEN, & !output @@ -886,23 +859,6 @@ SUBROUTINE mynnedmf_wrapper_run( & ! !qgrs_ice_aer_num_conc(i,k) = qgrs_ice_aer_num_conc(i,k) + RQNIFABLTEN(i,k)*delt ! enddo !enddo - else if(mraerosol) then - do k=1,levs - do i=1,im - dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) - enddo - enddo - if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then - call dtend_helper(100+ntqv,RQVBLTEN) - call dtend_helper(100+ntcw,RQCBLTEN) - call dtend_helper(100+ntlnc,RQNCBLTEN) - call dtend_helper(100+ntiw,RQIBLTEN) - call dtend_helper(100+ntinc,RQNIBLTEN) - endif else !Thompson (2008) do k=1,levs @@ -1076,9 +1032,9 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & implicit none integer, intent(in) :: kte - real, intent(in) :: delt - real, dimension(kte), intent(in) :: dp, exner - real, dimension(kte), intent(inout) :: qv, qc, qi, th + real(kind=kind_phys), intent(in) :: delt + real(kind=kind_phys), dimension(kte), intent(in) :: dp, exner + real(kind=kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, th integer k real :: dqc2, dqi2, dqv2, sum, aa, dum real, parameter :: qvmin1= 1e-8, & !min at k=1 diff --git a/physics/mynnedmf_wrapper.meta b/physics/mynnedmf_wrapper.meta index a44a13f1b..044162dbb 100644 --- a/physics/mynnedmf_wrapper.meta +++ b/physics/mynnedmf_wrapper.meta @@ -1347,7 +1347,7 @@ standard_name = chem3d_mynn_pbl_transport long_name = mynn pbl transport of smoke and dust units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension,2) + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_chemical_species_vertically_mixed) type = real kind = kind_phys intent = inout @@ -1359,9 +1359,9 @@ type = real kind = kind_phys intent = inout -[rrfs_smoke] +[rrfs_sd] standard_name = do_smoke_coupling - long_name = flag controlling rrfs_smoke collection (default off) + long_name = flag controlling rrfs_sd collection (default off) units = flag dimensions = () type = logical @@ -1373,7 +1373,7 @@ dimensions = () type = logical intent = in -[fire_turb] +[enh_mix] standard_name = do_planetary_boundary_layer_fire_enhancement long_name = flag for rrfs smoke mynn enh vermix units = flag @@ -1394,16 +1394,24 @@ dimensions = () type = integer intent = in -[ltaerosol] - standard_name = flag_for_aerosol_physics - long_name = flag for aerosol physics +[vdep] + standard_name = dry_deposition_velocity_mynn_pbl_transport + long_name = dry deposition velocity by mynn pbl transport + units = m s-1 + dimensions = (horizontal_loop_extent,number_of_chemical_species_deposited) + type = real + kind = kind_phys + intent = in +[smoke_dbg] + standard_name = do_smoke_debug + long_name = flag for rrfs smoke plumerise debug units = flag dimensions = () type = logical intent = in -[mraerosol] - standard_name = do_merra2_aerosol_awareness - long_name = flag for merra2 aerosol-aware physics for example the thompson microphysics +[ltaerosol] + standard_name = flag_for_aerosol_physics + long_name = flag for aerosol physics units = flag dimensions = () type = logical diff --git a/physics/radiation_aerosols.f b/physics/radiation_aerosols.f index 3cd5c64e1..bbd2f25cb 100644 --- a/physics/radiation_aerosols.f +++ b/physics/radiation_aerosols.f @@ -2179,7 +2179,7 @@ subroutine setaer & & ( prsi,prsl,prslk,tvly,rhlay,slmsk,tracer,aerfld,xlon,xlat, & ! --- inputs & IMAX,NLAY,NLP1, lsswr,lslwr,iaermdl,iaerflg,top_at_1, & & con_pi,con_rd,con_g,aerosw,aerolw, & ! --- outputs - & aerodp, errflg, errmsg & + & aerodp, ext550, errflg, errmsg & & ) ! ================================================================== ! @@ -2259,6 +2259,7 @@ subroutine setaer & & aerosw, aerolw real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp + real (kind=kind_phys), dimension(:,:) , intent(out) :: ext550 integer, intent(out) :: errflg character(len=*), intent(out) :: errmsg @@ -2314,6 +2315,7 @@ subroutine setaer & aerodp(i,k) = f_zero enddo enddo + ext550(:,:) = f_zero if ( .not. (lsswr .or. lslwr) ) then return @@ -2411,7 +2413,7 @@ subroutine setaer & & alon,alat,slmsk,laersw,laerlw,con_rd, & & IMAX,NLAY,NLP1, & ! --- outputs: - & aerosw,aerolw,aerodp,errflg,errmsg & + & aerosw,aerolw,aerodp,ext550,errflg,errmsg & & ) endif ! end if_iaerflg_block @@ -4334,7 +4336,7 @@ subroutine aer_property_gocart & & alon,alat,slmsk, laersw,laerlw,con_rd, & & imax,nlay,nlp1, & ! --- outputs: - & aerosw,aerolw,aerodp,errflg,errmsg & + & aerosw,aerolw,aerodp,ext550,errflg,errmsg & & ) ! ================================================================== ! @@ -4401,6 +4403,7 @@ subroutine aer_property_gocart & real (kind=kind_phys), dimension(:,:,:,:), intent(out) :: & & aerosw, aerolw real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp + real (kind=kind_phys), dimension(:,:) , intent(out) :: ext550 integer, intent(out) :: errflg character(len=*), intent(out) :: errmsg @@ -4485,6 +4488,7 @@ subroutine aer_property_gocart & ! --- update diagnostic aod arrays do k = 1, NLAY aerodp(i,1) = aerodp(i,1) + tauae_550(k,1) + ext550(i,k) = tauae_550(k,1) do m = 1, NSPC aerodp(i,m+1) = aerodp(i,m+1)+spcodp(k,m) enddo diff --git a/physics/smoke_dust/coarsepm_settling_mod.F90 b/physics/smoke_dust/coarsepm_settling_mod.F90 new file mode 100755 index 000000000..9061840c3 --- /dev/null +++ b/physics/smoke_dust/coarsepm_settling_mod.F90 @@ -0,0 +1,274 @@ +module coarsepm_settling_mod + + use machine , only : kind_phys + use dust_data_mod, only : dyn_visc !den_dust, reff_dust, dyn_visc + + implicit none + +CONTAINS + + +SUBROUTINE coarsepm_settling_driver(dt,t_phy,rel_hum, & + chem,rho_phy,dz8w,p8w,p_phy,sedim, & + area,g,num_chem, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) + + IMPLICIT NONE + + INTEGER, INTENT(IN ) :: & + num_chem, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte + REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ),INTENT(INOUT ) :: chem + REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & + INTENT(IN ) :: t_phy,p_phy,dz8w,p8w,rho_phy,rel_hum + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ),INTENT(IN ) :: area + REAL(kind_phys), INTENT(IN ) :: dt,g + + REAL(kind_phys), DIMENSION( ims:ime, jms:jme, num_chem ), INTENT(OUT ) :: sedim + + integer :: nv,i,j,k,kk,lmx,idust + real(kind_phys), DIMENSION (1,1,kte-kts+1) :: tmp,airden,airmas,p_mid,delz,rh + real(kind_phys), DIMENSION (1,1,kte-kts+1,1) :: dust + real(kind_phys), DIMENSION (ime,jme,kme,num_chem) :: chem_before +! +! bstl is for budgets +! +! real(kind_phys), DIMENSION (5), PARAMETER :: den_dust(5)=(/2500.,2650.,2650.,2650.,2650./) +! real(kind_phys), DIMENSION (5), PARAMETER :: reff_dust(5)=(/0.73D-6,1.4D-6,2.4D-6,4.5D-6,8.0D-6/) + real(kind_phys), DIMENSION (1), PARAMETER :: den_dust (1)=(/2650. /) + real(kind_phys), DIMENSION (1), PARAMETER :: reff_dust(1)=(/2.4D-6/) + real(kind_phys), DIMENSION (1) :: bstl_dust + real(kind_phys) conver,converi + real(kind_phys),parameter::max_default=0. + + sedim = 0. + conver=1.e-9 + converi=1.e9 + lmx=kte-kts+1 +! + do j=jts,jte + do i=its,ite +! +! initialize some met stuff +! + kk=0 + bstl_dust(:)=0. + do k=kts,kte + kk=kk+1 + p_mid(1,1,kk)=.01*p_phy(i,kte-k+kts,j) + delz(1,1,kk)=dz8w(i,kte-k+kts,j) + airmas(1,1,kk)=-(p8w(i,k+1,j)-p8w(i,k,j))*area(i,j)/g + airden(1,1,kk)=rho_phy(i,k,j) + tmp(1,1,kk)=t_phy(i,k,j) + rh(1,1,kk) = rel_hum(i,k,j) ! hli + do nv = 1, num_chem + chem_before(i,j,k,nv) = chem(i,k,j,nv) + enddo + enddo +! +! max dust in column +! + idust=1 + kk=0 + do k=kts,kte + kk=kk+1 + dust(1,1,kk,1)=chem(i,k,j,1)*conver + enddo + + + call settling(1, 1, lmx, 1,g,dyn_visc, & + dust, tmp, p_mid, delz, airmas, & + den_dust, reff_dust, dt, bstl_dust, rh, idust, airden) + + kk = 0 + do k = kts,kte + kk = kk+1 + chem(i,k,j,1)=dust(1,1,kk,1)*converi ! coarse dust [ug/kg] + enddo +! +! +! + do nv = 1, num_chem + do k = kts,kte + sedim(i,j,nv) = sedim(i,j,nv)+(chem_before(i,j,k,nv) - chem(i,k,j,nv))*p8w(i,k,j)/g + enddo + sedim(i,j,nv) = sedim(i,j,nv) / dt !ug/m2/s + enddo +! +! +! + enddo + enddo +! +! +! +END SUBROUTINE coarsepm_settling_driver + + + subroutine settling(imx,jmx, lmx, nmx,g0,dyn_visc, & + tc, tmp, p_mid, delz, airmas, & + den, reff, dt, bstl, rh, idust, airden) +! **************************************************************************** +! * * +! * Calculate the loss by settling, using an implicit method * +! * * +! * Input variables: * +! * SIGE(k) - sigma coordinate of the vertical edges * +! * PS(i,j) - Surface pressure (mb) * +! * TMP(i,j,k) - Air temperature (K) * +! * CT(i,j) - Surface exchange coeff for moisture +! * * +! **************************************************************************** + + + IMPLICIT NONE + + INTEGER, INTENT(IN) :: imx, jmx, lmx, nmx,idust + INTEGER :: ntdt + REAL(kind_phys), INTENT(IN) :: dt,g0,dyn_visc + REAL(kind_phys), INTENT(IN) :: tmp(imx,jmx,lmx), delz(imx,jmx,lmx), & + airmas(imx,jmx,lmx), rh(imx,jmx,lmx), & + den(nmx), reff(nmx),p_mid(imx,jmx,lmx),& + airden(imx,jmx,lmx) + REAL(kind_phys), INTENT(INOUT) :: tc(imx,jmx,lmx,nmx) + REAL(kind_phys), INTENT(OUT) :: bstl(imx,jmx,nmx) + + REAL(kind_phys) :: tc1(imx,jmx,lmx,nmx), dt_settl(nmx), rcm(nmx), rho(nmx) + INTEGER :: ndt_settl(nmx) + REAL(kind_phys) :: dzmin, vsettl, dtmax, rhb, rwet(nmx), ratio_r(nmx) + REAL(kind_phys) :: c_stokes, free_path, c_cun, viscosity, growth_fac + REAL(kind_phys) :: vd_cor(lmx),vd_wk1 + INTEGER :: k, n, i, j, l, l2 + REAL(kind_phys) :: transfer_to_below_level,temp_tc + + ! for OMP: + REAL(kind_phys) :: rwet_priv(nmx), rho_priv(nmx) + + ! executable statements + + bstl = 0._kind_phys + + if(idust.ne.1.)return + +!!! WHERE (tc(:,:,:,:) < 0.0) tc(:,:,:,:) = 1.0E-32 + + dzmin = MINVAL(delz(:,:,:)) + IF (idust == 1) growth_fac = 1.0 + + DO k = 1,nmx + + ! Settling velocity (m/s) for each tracer (Stokes Law) + ! DEN density (kg/m3) + ! REFF effective radius (m) + ! dyn_visc dynamic viscosity (kg/m/s) + ! g0 gravity (m/s2) + ! 3.0 corresponds to a growth of a factor 3 of radius with 100% RH + ! 0.5 upper limit with temp correction + + tc1(:,:,:,k) = tc(:,:,:,k) + vsettl = 2.0/9.0 * g0 * den(k) * (growth_fac*reff(k))**2 / & + (0.5*dyn_visc) + + ! Determine the maximum time-step satisying the CFL condition: + ! dt <= (dz)_min / v_settl + ntdt=INT(dt) + dtmax = dzmin / vsettl + ndt_settl(k) = MAX( 1, INT( ntdt /dtmax) ) + ! limit maximum number of iterations + IF (ndt_settl(k) > 12) ndt_settl(k) = 12 + dt_settl(k) = REAL(ntdt) / REAL(ndt_settl(k)) + + ! Particles radius in centimeters + IF (idust.eq.1)then + rwet(k) = reff(k) + ratio_r(k) = 1.0 + rho(k) = den(k) + endif + END DO + + ! Solve the bidiagonal matrix (l,l) + +!$OMP PARALLEL DO & +!$OMP DEFAULT( SHARED ) & +!$OMP PRIVATE( i, j, l, l2, n, k, rhb, rwet_priv, ratio_r, c_stokes)& +!$OMP PRIVATE( free_path, c_cun, viscosity, rho_priv, vd_cor ) + + ! Loop over latitudes + DO j = 1,jmx + + DO k = 1,nmx + IF (idust.eq.1) THEN + rwet_priv(k) = rwet(k) + rho_priv(k) = rho(k) + END IF + + DO n = 1,ndt_settl(k) + + ! Solve each vertical layer successively (layer l) + transfer_to_below_level=0 + + DO l = lmx,1,-1 + l2 = lmx - l + 1 + +! DO j = 1,jmx + DO i = 1,imx + + ! Dynamic viscosity + c_stokes = 1.458E-6 * tmp(i,j,l)**1.5/(tmp(i,j,l) + 110.4) + + ! Mean free path as a function of pressure (mb) and + ! temperature (K) + ! order of p_mid is top->sfc + free_path = 1.1E-3/p_mid(i,j,l2)/SQRT(tmp(i,j,l)) +!!! free_path = 1.1E-3/p_edge(i,j,l2)/SQRT(tmp(i,j,l)) + + ! Slip Correction Factor + c_cun = 1.0+ free_path/rwet_priv(k)* & + (1.257 + 0.4*EXP(-1.1*rwet_priv(k)/free_path)) + + ! Corrected dynamic viscosity (kg/m/s) + viscosity = c_stokes / c_cun + + ! Settling velocity + + vd_cor(l) = 2.0/9.0*g0*rho_priv(k)*rwet_priv(k)**2/viscosity + + ! Update mixing ratio; order of delz: top->sfc + temp_tc=tc(i,j,l,k) !temp_tc - for temporal storage [ug/kg] + vd_wk1 = dt_settl(k)*vd_cor(l)/delz(i,j,l2) !fraction to leave level + + tc(i,j,l,k) = tc(i,j,l,k)*(1.- vd_wk1)+transfer_to_below_level ! [ug/kg] + + if (l.gt.1) transfer_to_below_level =(temp_tc*vd_wk1)*((delz(i,j,l2) & + *airden(i,j,l))/(delz(i,j,l2+1)*airden(i,j,l-1))) ! [ug/kg] + + END DO !i +! END DO !j + END DO !l + + END DO !n + END DO !k + + END DO !j +!$OMP END PARALLEL DO + + DO n = 1,nmx + DO i = 1,imx + DO j = 1,jmx + bstl(i,j,n) = 0._kind_phys + DO l = 1,lmx + IF (tc(i,j,l,n) < 0.0) tc(i,j,l,n) = 1.0D-32 + bstl(i,j,n) = bstl(i,j,n) + & + (tc(i,j,l,n) - tc1(i,j,l,n)) * airmas(i,j,l) + END DO + END DO + END DO + END DO + +END SUBROUTINE settling + +end module coarsepm_settling_mod diff --git a/physics/smoke_dust/dep_dry_mod.F90 b/physics/smoke_dust/dep_dry_mod.F90 new file mode 100755 index 000000000..ea7dd9963 --- /dev/null +++ b/physics/smoke_dust/dep_dry_mod.F90 @@ -0,0 +1,69 @@ +!>\file dep_dry_mod.F90 +!! This file is for the dry depostion driver. + +module dep_dry_mod + + use machine , only : kind_phys + + implicit none + + private + + public :: dry_dep_driver + +contains + + subroutine dry_dep_driver(rmol,ust,ndvel,ddvel,rel_hum, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) +!---------------------------------------------------------------------- + IMPLICIT NONE + + INTEGER, INTENT(IN ) :: ndvel, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) , & + INTENT(INOUT) :: ust, rmol + REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & + INTENT(IN ) :: rel_hum + + REAL(kind_phys), PARAMETER :: kpart=500. + REAL(kind_phys) :: dvpart + +! +! Output array + REAL(kind_phys), DIMENSION( its:ite, jts:jte, ndvel ), INTENT(INOUT) :: ddvel + + + integer :: i,j,k,nv +! +! necessary for aerosols (module dependent) +! +! .. Intrinsic Functions .. + INTRINSIC max, min + +! compute dry deposition velocities = ddvel + + ddvel(:,:,:) = 0.0 + do nv = 1, ndvel + do j = jts, jte + do i = its, ite + dvpart = ust(i,j)/kpart + + IF (rmol(i,j)<0.) THEN ! UNSTABLE LAYERING CORRECTION + dvpart = dvpart*(1.+(-300.*rmol(i,j))**0.66667) + ENDIF + + IF (rel_hum(i,1,j)>0.8) THEN ! HIGH RELATIVE HUMIDITY CORRECTION + dvpart = dvpart*(1.+0.37*exp((rel_hum(i,1,j)-0.8)/0.2)) + END IF + ddvel(i,j,nv) = MIN(0.50,dvpart) ! m/s + enddo + enddo + enddo + +end subroutine dry_dep_driver + +end module dep_dry_mod diff --git a/smoke/dust_data_mod.F90 b/physics/smoke_dust/dust_data_mod.F90 similarity index 97% rename from smoke/dust_data_mod.F90 rename to physics/smoke_dust/dust_data_mod.F90 index 9e9713e22..a710701f1 100755 --- a/smoke/dust_data_mod.F90 +++ b/physics/smoke_dust/dust_data_mod.F90 @@ -3,7 +3,6 @@ module dust_data_mod - use rrfs_smoke_data use machine , only : kind_phys use rrfs_smoke_config, only : p_dust_1, p_dust_2, p_dust_3, p_dust_4, p_dust_5, & p_edust1, p_edust2, p_edust3, p_edust4, p_edust5 @@ -80,8 +79,8 @@ module dust_data_mod ! -- FENGSHA uses precalculated drag partition from ASCAT. See: Prigent et al. (2012,2015) integer, parameter :: dust_calcdrag = 1 - real(kind_phys), parameter :: dust_alpha = 2.2 - real(kind_phys), parameter :: dust_gamma = 1.0 + real(kind_phys) :: dust_alpha = 2.2 + real(kind_phys) :: dust_gamma = 1.0 ! -- sea salt parameters diff --git a/physics/smoke_dust/dust_fengsha_mod.F90 b/physics/smoke_dust/dust_fengsha_mod.F90 new file mode 100755 index 000000000..54a64239d --- /dev/null +++ b/physics/smoke_dust/dust_fengsha_mod.F90 @@ -0,0 +1,585 @@ +!>\file dust_fengsha_mod.F90 +!! This file contains the FENGSHA dust scheme. + +module dust_fengsha_mod +! +! This module developed by Barry Baker (NOAA ARL) +! For serious questions contact barry.baker@noaa.gov +! +! 07/16/2019 - Adapted for NUOPC/GOCART, R. Montuoro +! 02/01/2020 - Adapted for FV3/CCPP, Haiqin Li + + use machine , only : kind_phys + use dust_data_mod + + implicit none + + private + + public :: gocart_dust_fengsha_driver + +contains + + subroutine gocart_dust_fengsha_driver(dt, & + chem,rho_phy,smois,p8w,ssm, & + isltyp,vegfra,snowh,xland,area,g,emis_dust, & + ust,znt,clay,sand,rdrag,uthr, & + num_emis_dust,num_chem,num_soil_layers, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte) + IMPLICIT NONE + INTEGER, INTENT(IN ) :: & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte, & + num_emis_dust,num_chem,num_soil_layers + + ! 2d input variables + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: ssm ! Sediment supply map + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: vegfra ! vegetative fraction (-) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: snowh ! snow height (m) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: xland ! dominant land use type + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: area ! area of grid cell + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: ust ! friction velocity + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: znt ! Surface Roughness length (m) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: clay ! Clay Fraction (-) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: sand ! Sand Fraction (-) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: rdrag ! Drag Partition (-) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: uthr ! Dry Threshold Velocity (m/s) + + INTEGER, DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: isltyp ! soil type + + ! 3d input variables + REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN) :: p8w + REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN) :: rho_phy + REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), INTENT(INOUT) :: chem + REAL(kind_phys), DIMENSION( ims:ime, 1, jms:jme,num_emis_dust),OPTIONAL, INTENT(INOUT) :: emis_dust + REAL(kind_phys), DIMENSION( ims:ime, num_soil_layers, jms:jme ), INTENT(IN) :: smois + + !0d input variables + REAL(kind_phys), INTENT(IN) :: dt ! time step + REAL(kind_phys), INTENT(IN) :: g ! gravity (m/s**2) + + ! Local variables + integer :: nmx,i,j,k,imx,jmx,lmx + integer :: ilwi + real(kind_phys) :: airden ! air density + REAL(kind_phys) :: airmas ! dry air mass + real(kind_phys) :: dxy + real(kind_phys) :: conver,converi ! conversion values + real(kind_phys) :: R ! local drag partition + real(kind_phys) :: ustar + real(kind_phys), DIMENSION (num_emis_dust) :: tc + real(kind_phys), DIMENSION (num_emis_dust) :: bems + real(kind_phys), DIMENSION (num_emis_dust) :: distribution + real(kind_phys), dimension (3) :: massfrac + real(kind_phys) :: erodtot + + ! conversion values + conver=1.e-9 + converi=1.e9 + + ! Number of dust bins + + imx=1 + jmx=1 + lmx=1 + nmx=ndust + + k=kts + do j=jts,jte + do i=its,ite + + ! Don't do dust over water!!! + + ilwi=0 + if(xland(i,j).lt.1.5)then + ilwi=1 + + ! Total concentration at lowest model level. This is still hardcoded for 5 bins. + + ! if(config_flags%chem_opt == 2 .or. config_flags%chem_opt == 11 ) then + ! tc(:)=1.e-16*conver + ! else + tc(1)=chem(i,kts,j,p_dust_1)*conver + tc(2)=chem(i,kts,j,p_dust_2)*conver + tc(3)=chem(i,kts,j,p_dust_3)*conver + tc(4)=chem(i,kts,j,p_dust_4)*conver + tc(5)=chem(i,kts,j,p_dust_5)*conver + ! endif + + ! Air mass and density at lowest model level. + + airmas=-(p8w(i,kts+1,j)-p8w(i,kts,j))*area(i,j)/g + airden=rho_phy(i,kts,j) + ustar=ust(i,j) + dxy=area(i,j) + + ! Mass fractions of clay, silt, and sand. + massfrac(1)=clay(i,j) + massfrac(2)=1-(clay(i,j)+sand(i,j)) + massfrac(3)=sand(i,j) + + + ! Total erodibility. + + erodtot = ssm(i,j) ! SUM(erod(i,j,:)) + + ! Don't allow roughness lengths greater than 20 cm to be lofted. + ! This kludge accounts for land use types like urban areas and + ! forests which would otherwise show up as high dust emitters. + ! This is a placeholder for a more widely accepted kludge + ! factor in the literature, which reduces lofting for rough areas. + ! Forthcoming... + + IF (znt(i,j) .gt. 0.2) then + ilwi=0 + endif + + ! limit where there is lots of vegetation + if (vegfra(i,j) .gt. .17) then + ilwi = 0 + endif + + ! limit where there is snow on the ground + if (snowh(i,j) .gt. 0) then + ilwi = 0 + endif + + ! Do not allow areas with bedrock, lava, or land-ice to loft + + IF (isltyp(i,j) .eq. 15 .or. isltyp(i,j) .eq. 16. .or. & + isltyp(i,j) .eq. 18) then + ilwi=0 + ENDIF + IF (isltyp(i,j) .eq. 0)then + ilwi=0 + endif + if(ilwi == 0 ) cycle + + ! get drag partition + ! FENGSHA uses the drag partition correction of MacKinnon et al 2004 + ! doi:10.1016/j.geomorph.2004.03.009 + if (dust_calcdrag .ne. 1) then + call fengsha_drag(znt(i,j),R) + else + ! use the precalculated version derived from ASCAT; Prigent et al. (2012,2015) + ! doi:10.1109/TGRS.2014.2338913 & doi:10.5194/amt-5-2703-2012 + ! pick only valid values + if (rdrag(i,j) > 0.) then + R = real(rdrag(i,j), kind=kind_phys) + else + cycle + endif + endif + + ! Call dust emission routine. + + call source_dust(imx,jmx, lmx, nmx, dt, tc, ustar, massfrac, & + erodtot, dxy, smois(i,1,j), airden, airmas, bems, g, dust_alpha, dust_gamma, & + R, uthr(i,j)) + + ! convert back to concentration + + chem(i,kts,j,p_dust_1)=tc(1)*converi + chem(i,kts,j,p_dust_2)=tc(2)*converi + chem(i,kts,j,p_dust_3)=tc(3)*converi + chem(i,kts,j,p_dust_4)=tc(4)*converi + chem(i,kts,j,p_dust_5)=tc(5)*converi + + ! For output diagnostics + + emis_dust(i,1,j,p_edust1)=bems(1) + emis_dust(i,1,j,p_edust2)=bems(2) + emis_dust(i,1,j,p_edust3)=bems(3) + emis_dust(i,1,j,p_edust4)=bems(4) + emis_dust(i,1,j,p_edust5)=bems(5) + endif + enddo + enddo + ! + + end subroutine gocart_dust_fengsha_driver + + + subroutine source_dust(imx, jmx, lmx, nmx, dt1, tc, ustar, massfrac, & + erod, dxy, smois, airden, airmas, bems, g0, alpha, gamma, & + R, uthres) + + ! **************************************************************************** + ! * Evaluate the source of each dust particles size bin by soil emission + ! * + ! * Input: + ! * EROD Fraction of erodible grid cell (-) + ! * smois Volumetric soil moisture (m3/m3) + ! * ALPHA Constant to fudge the total emission of dust (1/m) + ! * GAMMA Tuning constant for erodibility (-) + ! * DXY Surface of each grid cell (m2) + ! * AIRMAS Mass of air for each grid box (kg) + ! * AIRDEN Density of air for each grid box (kg/m3) + ! * USTAR Friction velocity (m/s) + ! * DT1 Time step (s) + ! * NMX Number of dust bins (-) + ! * IMX Number of I points (-) + ! * JMX Number of J points (-) + ! * LMX Number of L points (-) + ! * R Drag Partition (-) + ! * UTHRES FENGSHA Dry Threshold Velocities (m/s) + ! * + ! * Data: + ! * MASSFRAC Fraction of mass in each of 3 soil classes (-) (clay silt sand) + ! * DEN_DUST Dust density (kg/m3) + ! * DEN_SALT Saltation particle density (kg/m3) + ! * REFF_SALT Reference saltation particle diameter (m) + ! * REFF_DUST Reference dust particle diameter (m) + ! * LO_DUST Lower diameter limits for dust bins (m) + ! * UP_DUST Upper diameter limits for dust bins (m) + ! * FRAC_SALT Soil class mass fraction for saltation bins (-) + ! * + ! * Parameters: + ! * CMB Constant of proportionality (-) + ! * MMD_DUST Mass median diameter of dust (m) + ! * GSD_DUST Geometric standard deviation of dust (-) + ! * LAMBDA Side crack propagation length (m) + ! * CV Normalization constant (-) + ! * G0 Gravitational acceleration (m/s2) + ! * + ! * Working: + ! * RHOA Density of air in cgs (g/cm3) + ! * DS_REL Saltation surface area distribution (-) + ! * DLNDP Dust bin width (-) + ! * EMIT Total vertical mass flux (kg/m2/s) + ! * EMIT_VOL Total vertical volume flux (m/s) + ! * DSRC Mass of emitted dust (kg/timestep/cell) + ! * + ! * Output: + ! * TC Total concentration of dust (kg/kg/timestep/cell) + ! * BEMS Source of each dust type (kg/timestep/cell) + ! * + ! **************************************************************************** + implicit none + + ! Input + INTEGER, INTENT(IN) :: imx,jmx,lmx,nmx + REAL(kind_phys), INTENT(IN) :: dt1 + REAL(kind_phys), INTENT(IN) :: ustar + REAL(kind_phys), INTENT(IN) :: massfrac(3) + REAL(kind_phys), INTENT(IN) :: erod + REAL(kind_phys), INTENT(IN) :: dxy + REAL(kind_phys), INTENT(IN) :: smois + REAL(kind_phys), INTENT(IN) :: airden + REAL(kind_phys), INTENT(IN) :: airmas + REAL(kind_phys), INTENT(IN) :: g0 + REAL(kind_phys), INTENT(IN) :: alpha + REAL(kind_phys), INTENT(IN) :: gamma + REAL(kind_phys), INTENT(IN) :: R + REAL(kind_phys), INTENT(IN) :: uthres + + ! Output + REAL(kind_phys), INTENT(INOUT) :: tc(nmx) + + ! Local Variables + REAL(kind_phys), INTENT(OUT) :: bems(nmx) + + REAL(kind_phys) :: dvol(nmx) + REAL(kind_phys) :: distr_dust(nmx) + REAL(kind_phys) :: dlndp(nmx) + REAL(kind_phys) :: dsrc + REAL(kind_phys) :: dvol_tot + REAL(kind_phys) :: emit + REAL(kind_phys) :: emit_vol + REAL(kind_phys) :: rhoa + INTEGER :: i, j, n + + ! Constant of proportionality from Marticorena et al, 1997 (unitless) + ! Arguably more ~consistent~ fudge than alpha, which has many walnuts + ! sprinkled throughout the literature. - GC + + REAL(kind_phys), PARAMETER :: cmb=1.0 + REAL(kind_phys), PARAMETER :: kvhmax=2.0e-4 + + ! Parameters used in Kok distribution function. Advise not to play with + ! these without the expressed written consent of someone who knows what + ! they're doing. - GC + + REAL(kind_phys), PARAMETER :: mmd_dust=3.4D-6 ! median mass diameter (m) + REAL(kind_phys), PARAMETER :: gsd_dust=3.0 ! geom. std deviation + REAL(kind_phys), PARAMETER :: lambda=12.0D-6 ! crack propagation length (m) + REAL(kind_phys), PARAMETER :: cv=12.62D-6 ! normalization constant + REAL(kind_phys), PARAMETER :: RHOSOIL=2650. + + + ! calculate the total vertical dust flux + + emit = 0.0 + + call DustEmissionFENGSHA(smois,massfrac(1),massfrac(3), massfrac(2), & + erod, R, airden, ustar, uthres, alpha, gamma, kvhmax, & + g0, RHOSOIL, emit) + + ! Now that we have the total dust emission, distribute into dust bins using + ! lognormal distribution (Dr. Jasper Kok, in press), and + ! calculate total mass emitted over the grid box over the timestep. + ! + ! In calculating the Kok distribution, we assume upper and lower limits to each bin. + ! For reff_dust=(/0.73D-6,1.4D-6,2.4D-6,4.5D-6,8.0D-6/) (default), + ! lower limits were ASSUMED at lo_dust=(/0.1D-6,1.0D-6,1.8D-6,3.0D-6,6.0D-6/) + ! upper limits were ASSUMED at up_dust=(/1.0D-6,1.8D-6,3.0D-6,6.0D-6,10.0D-6/) + ! These may be changed within module_data_gocart_dust.F, but make sure it is + ! consistent with reff_dust values. These values were taken from the original + ! GOCART bin configuration. We use them here to calculate dust bin width, dlndp. + ! dVol is the volume distribution. You know...if you were wondering. GC + + dvol_tot=0. + DO n=1,nmx + dlndp(n)=LOG(up_dust(n)/lo_dust(n)) + dvol(n)=(2.0*reff_dust(n)/cv)*(1.+ERF(LOG(2.0*reff_dust(n)/mmd_dust)/(SQRT(2.)*LOG(gsd_dust))))*& + EXP(-(2.0*reff_dust(n)/lambda)**3.0)*dlndp(n) + dvol_tot=dvol_tot+dvol(n) + ! Convert mass flux to volume flux + !emit_vol=emit/den_dust(n) ! (m s^-1) + END DO + DO n=1,nmx + distr_dust(n)=dvol(n)/dvol_tot + !print *,"distr_dust(",n,")=",distr_dust(n) + END DO + + ! Now distribute total vertical emission into dust bins and update concentration. + + DO n=1,nmx + ! Calculate total mass emitted + dsrc = emit*distr_dust(n)*dxy*dt1 ! (kg) + IF (dsrc < 0.0) dsrc = 0.0 + + ! Update dust mixing ratio at first model level. + tc(n) = tc(n) + dsrc / airmas ! (kg/kg) + ! bems(i,j,n) = dsrc ! diagnostic + !bems(i,j,n) = 1000.*dsrc/(dxy(j)*dt1) ! diagnostic (g/m2/s) + bems(n) = 1.e+9*dsrc/(dxy*dt1) ! diagnostic (ug/m2/s) !lzhang + + END DO + tc(1)=tc(1)+0.286*tc(2) ! This is just for RRFS-SD. DO NOT use in other models!!! + tc(5)=0.714*tc(2)+tc(3)+tc(4) ! This is just for RRFS-SD. DO NOT use in other models!!! + + END SUBROUTINE source_dust + + + subroutine fengsha_drag(z0,R) + implicit none + + real(kind_phys), intent(in) :: z0 + real(kind_phys), intent(out) :: R + real(kind_phys), parameter :: z0s = 1.0e-04 !Surface roughness for ideal bare surface [m] + ! ------------------------------------------------------------------------ + ! Function: Calculates the MacKinnon et al. 2004 Drag Partition Correction + ! + ! R = 1.0 - log(z0 / z0s) / log( 0.7 * (12255./z0s) ** 0.8) + ! + !-------------------------------------------------------------------------- + ! Drag partition correction. See MacKinnon et al. (2004), + ! doi:10.1016/j.geomorph.2004.03.009 + R = 1.0 - log(z0 / z0s) / log( 0.7 * (12255./z0s) ** 0.8) + + ! Drag partition correction. See Marticorena et al. (1997), + ! doi:10.1029/96JD02964 + !R = 1.0 - log(z0 / z0s) / log( 0.7 * (10./z0s) ** 0.8) + + return + end subroutine fengsha_drag + + subroutine DustEmissionFENGSHA(slc, clay, sand, silt, & + ssm, rdrag, airdens, ustar, uthrs, alpha, gamma, & + kvhmax, grav, rhop, emissions) + + ! !USES: + implicit NONE + +! !INPUT PARAMETERS: + REAL(kind_phys), intent(in) :: slc ! liquid water content of soil layer, volumetric fraction [1] + REAL(kind_phys), intent(in) :: clay ! fractional clay content [1] + REAL(kind_phys), intent(in) :: sand ! fractional sand content [1] + REAL(kind_phys), intent(in) :: silt ! fractional silt content [1] + REAL(kind_phys), intent(in) :: ssm ! erosion map [1] + REAL(kind_phys), intent(in) :: rdrag ! drag partition [1/m] + REAL(kind_phys), intent(in) :: airdens ! air density at lowest level [kg/m^3] + REAL(kind_phys), intent(in) :: ustar ! friction velocity [m/sec] + REAL(kind_phys), intent(in) :: uthrs ! threshold velocity [m/2] + REAL(kind_phys), intent(in) :: alpha ! scaling factor [1] + REAL(kind_phys), intent(in) :: gamma ! scaling factor [1] + REAL(kind_phys), intent(in) :: kvhmax ! max. vertical to horizontal mass flux ratio [1] + REAL(kind_phys), intent(in) :: grav ! gravity [m/sec^2] + REAL(kind_phys), intent(in) :: rhop ! soil class density [kg/m^3] + + ! !OUTPUT PARAMETERS: + REAL(kind_phys), intent(inout) :: emissions ! binned surface emissions [kg/(m^2 sec)] + + ! !DESCRIPTION: Compute dust emissions using NOAA/ARL FENGSHA model + ! + ! !REVISION HISTORY: + ! + ! 22Feb2020 B.Baker/NOAA - Original implementation + ! 29Mar2021 R.Montuoro/NOAA - Refactored for process library + ! 09Aug2022 B.Baker/NOAA - Adapted for CCPP-Physics + + ! !Local Variables + real(kind_phys) :: alpha_grav + real(kind_phys) :: h + real(kind_phys) :: kvh + real(kind_phys) :: q + real(kind_phys) :: rustar + real(kind_phys) :: total_emissions + real(kind_phys) :: u_sum, u_thresh + +!EOP +!------------------------------------------------------------------------- +! Begin + +! Initialize emissions +! -------------------- + emissions = 0. + +! Prepare scaling factor +! ---------------------- + alpha_grav = alpha / grav + + ! Compute vertical-to-horizontal mass flux ratio + ! ---------------------------------------------- + kvh = DustFluxV2HRatioMB95(clay, kvhmax) + + ! Compute total emissions + ! ----------------------- + emissions = alpha_grav * (ssm ** gamma) * airdens * kvh + + ! Compute threshold wind friction velocity using drag partition + ! ------------------------------------------------------------- + rustar = rdrag * ustar + + ! Now compute size-dependent total emission flux + ! ---------------------------------------------- + ! Fecan moisture correction + ! ------------------------- + h = moistureCorrectionFecan(slc, sand, clay, rhop) + + ! Adjust threshold + ! ---------------- + u_thresh = uthrs * h + + u_sum = rustar + u_thresh + + ! Compute Horizontal Saltation Flux according to Eq (9) in Webb et al. (2020) + ! --------------------------------------------------------------------------- + q = max(0., rustar - u_thresh) * u_sum * u_sum + + ! Distribute emissions to bins and convert to mass flux (kg s-1) + ! -------------------------------------------------------------- + emissions = emissions * q + + + end subroutine DustEmissionFENGSHA +!----------------------------------------------------------------- + real function soilMoistureConvertVol2Grav(vsoil, sandfrac, rhop) + +! !USES: + implicit NONE + +! !INPUT PARAMETERS: + REAL(kind_phys), intent(in) :: vsoil ! volumetric soil moisture fraction [1] + REAL(kind_phys), intent(in) :: sandfrac ! fractional sand content [1] + REAL(kind_phys), intent(in) :: rhop ! dry dust density [kg m-3] + +! !DESCRIPTION: Convert soil moisture fraction from volumetric to gravimetric. +! +! !REVISION HISTORY: +! +! 02Apr2020, B.Baker/NOAA - Original implementation +! 01Apr2020, R.Montuoro/NOAA - Adapted for GOCART process library + +! !Local Variables + real :: vsat + +! !CONSTANTS: + REAL(kind_phys), parameter :: rhow = 1000. ! density of water [kg m-3] + +!EOP +!------------------------------------------------------------------------- +! Begin... + +! Saturated volumetric water content (sand-dependent) ! [m3 m-3] + vsat = 0.489 - 0.00126 * ( 100. * sandfrac ) + +! Gravimetric soil content + soilMoistureConvertVol2Grav = vsoil * rhow / (rhop * (1. - vsat)) + + end function soilMoistureConvertVol2Grav +!---------------------------------------------------------------- + real function moistureCorrectionFecan(slc, sand, clay, rhop) + +! !USES: + implicit NONE + +! !INPUT PARAMETERS: + REAL(kind_phys), intent(in) :: slc ! liquid water content of top soil layer, volumetric fraction [1] + REAL(kind_phys), intent(in) :: sand ! fractional sand content [1] + REAL(kind_phys), intent(in) :: clay ! fractional clay content [1] + REAL(kind_phys), intent(in) :: rhop ! dry dust density [kg m-3] + +! !DESCRIPTION: Compute correction factor to account for Fecal soil moisture +! +! !REVISION HISTORY: +! +! 02Apr2020, B.Baker/NOAA - Original implementation +! 01Apr2020, R.Montuoro/NOAA - Adapted for GOCART process library + +! !Local Variables + real :: grvsoilm + real :: drylimit + +!EOP +!--------------------------------------------------------------- +! Begin... + +! Convert soil moisture from volumetric to gravimetric + grvsoilm = soilMoistureConvertVol2Grav(slc, sand, 2650.) + +! Compute fecan dry limit + drylimit = clay * (14.0 * clay + 17.0) + +! Compute soil moisture correction + moistureCorrectionFecan = sqrt(1.0 + 1.21 * max(0., grvsoilm - drylimit)**0.68) + + end function moistureCorrectionFecan +!--------------------------------------------------------------- + real function DustFluxV2HRatioMB95(clay, kvhmax) + +! !USES: + implicit NONE + +! !INPUT PARAMETERS: + REAL(kind_phys), intent(in) :: clay ! fractional clay content [1] + REAL(kind_phys), intent(in) :: kvhmax ! maximum flux ratio [1] + +! !CONSTANTS: + REAL(kind_phys), parameter :: clay_thresh = 0.2 ! clay fraction above which the maximum flux ratio is returned + +! !DESCRIPTION: Computes the vertical-to-horizontal dust flux ratio according to +! B.Marticorena, G.Bergametti, J.Geophys.Res., 100(D8), 164! doi:10.1029/95JD00690 +! +! !REVISION HISTORY: +! +! 22Feb2020 B.Baker/NOAA - Original implementation +! 01Apr2021 R.Montuoro/NOAA - Adapted for GOCART process library +! +!EOP +!------------------------------------------------------------------------- +! Begin... + + if (clay > clay_thresh) then + DustFluxV2HRatioMB95 = kvhmax + else + DustFluxV2HRatioMB95 = 10.0**(13.4*clay-6.0) + end if + + end function DustFluxV2HRatioMB95 + +end module dust_fengsha_mod diff --git a/smoke/module_add_emiss_burn.F90 b/physics/smoke_dust/module_add_emiss_burn.F90 similarity index 90% rename from smoke/module_add_emiss_burn.F90 rename to physics/smoke_dust/module_add_emiss_burn.F90 index da35535f7..6cdd2e071 100755 --- a/smoke/module_add_emiss_burn.F90 +++ b/physics/smoke_dust/module_add_emiss_burn.F90 @@ -4,15 +4,14 @@ module module_add_emiss_burn !RAR: significantly modified for the new BB emissions use machine , only : kind_phys - use rrfs_smoke_data use rrfs_smoke_config CONTAINS - subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & + subroutine add_emis_burn(dtstep,dz8w,rho_phy,rel_hum, & chem,julday,gmt,xlat,xlong, & !luf_igbp,lu_fire1, & vegtype,vfrac,peak_hr, & time_int,ebu, & ! RAR - r_q,fhist,aod3d_smoke,aod3d_dust, & + r_q,fhist,ext3d_smoke,ext3d_dust, & ! nwfa,nifa, & rainc,rainnc, swdown,smoke_forecast, & ids,ide, jds,jde, kds,kde, & @@ -22,11 +21,10 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & ! USE module_configure, only: grid_config_rec_type ! USE module_state_description IMPLICIT NONE - type(smoke_data), intent(inout) :: data ! TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags - INTEGER, INTENT(IN ) :: ktau, julday, & + INTEGER, INTENT(IN ) :: julday, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte @@ -40,7 +38,7 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(IN) :: xlat,xlong, rainc,rainnc,swdown, peak_hr, vfrac real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(OUT) :: r_q ! RAR: real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(INOUT) :: fhist ! RAR: - real(kind_phys), DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(OUT) :: aod3d_smoke, aod3d_dust ! RAR: + real(kind_phys), DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(OUT) :: ext3d_smoke, ext3d_dust ! RAR: integer, DIMENSION(ims:ime,jms:jme), INTENT(IN) :: vegtype real(kind_phys), DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(IN) :: dz8w,rho_phy,rel_hum @@ -51,14 +49,14 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & real(kind_phys), INTENT(IN) :: dtstep, gmt real(kind_phys), INTENT(IN) :: time_int ! RAR: time in seconds since start of simulation - logical, INTENT(IN) :: smoke_forecast + integer, INTENT(IN) :: smoke_forecast integer :: i,j,k,n,m real(kind_phys) :: conv_rho, conv, ext2, dm_smoke, daero_num_wfa, daero_num_ifa !, lu_sum1_5, lu_sum12_14 !real(kind_phys) :: ebumax ! CHARACTER (LEN=80) :: message - INTEGER, PARAMETER :: kfire_max=35 ! max vertical level for BB plume rise + INTEGER, PARAMETER :: kfire_max=51 ! max vertical level for BB plume rise ! Diameters and standard deviations for emissions ! the diameters are the volume (mass) geometric mean diameters, following MADE_SORGAM real(kind_phys), PARAMETER :: dgvem_i= 0.08E-6 !0.03E-6 ! [ m ] @@ -148,7 +146,7 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & ! r_q(i,j)= fhist(i,j) ! no diurnal cycle !END IF - !IF (.NOT. smoke_forecast) THEN + !IF (smoke_forecast == 0) THEN r_q(i,j)= 1. !END IF @@ -174,21 +172,19 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & chem(i,k,j,p_smoke) = chem(i,k,j,p_smoke) + dm_smoke chem(i,k,j,p_smoke) = MIN(chem(i,k,j,p_smoke),5.e+3) - if (ktau<1000 .and. dbg_opt) then ! if ( k==kts ) then - ! WRITE(6,*) 'add_emiss_burn: ktau,gmt,dtstep,time_int ',ktau,gmt,dtstep,time_int + ! WRITE(6,*) 'add_emiss_burn: gmt,dtstep,time_int ',gmt,dtstep,time_int ! WRITE(*,*) 'add_emiss_burn: i,j,xlat(i,j),xlong(i,j) ',i,j,xlat(i,j),xlong(i,j) !WRITE(*,*) 'add_emiss_burn: luf_igbp(i,:,j) ',luf_igbp(i,:,j) !WRITE(*,*) 'add_emiss_burn: lu_fire1(i,j) ',lu_fire1(i,j) ! WRITE(6,*) 'add_emiss_burn: timeq,peak_hr(i,j),fhist(i,j),r_q(i,j) ',timeq,peak_hr(i,j),fhist(i,j),r_q(i,j) ! WRITE(*,*) 'add_emiss_burn: rainc(i,j),rainnc(i,j) ', rainc(i,j),rainnc(i,j) ! endif - if ( k==kts .OR. k==kfire_max ) then + if ( dbg_opt .and. (k==kts .OR. k==kfire_max) ) then WRITE(6,*) 'add_emiss_burn: i,j,k ',i,j,k WRITE(6,*) 'add_emiss_burn: rho_phy(i,k,j),dz8w(i,k,j),conv ',rho_phy(i,k,j),dz8w(i,k,j),conv WRITE(6,*) 'add_emiss_burn: ebu(i,k,j),dm_smoke ', ebu(i,k,j),dm_smoke endif - endif enddo enddo @@ -204,17 +200,17 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & chem(i,k,j,p_smoke)=1.e-16 END IF - aod3d_smoke(i,k,j)= 1.e-6* ext2* chem(i,k,j,p_smoke )*rho_phy(i,k,j)*dz8w(i,k,j) - aod3d_dust (i,k,j)= 1.e-6* ext2* chem(i,k,j,p_dust_1)*rho_phy(i,k,j)*dz8w(i,k,j) + ext3d_smoke(i,k,j)= 1.e-6* ext2* chem(i,k,j,p_smoke )*rho_phy(i,k,j)*dz8w(i,k,j) + ext3d_dust (i,k,j)= 1.e-6* ext2* chem(i,k,j,p_dust_1)*rho_phy(i,k,j)*dz8w(i,k,j) enddo enddo enddo - IF ( ktau<2000 .and. dbg_opt ) then + IF ( dbg_opt ) then WRITE(*,*) 'add_emis_burn: i,j,k,ext2 ',i,j,k,ext2 WRITE(*,*) 'add_emis_burn: rel_hum(its,kts,jts),rel_hum(ite,kfire_max,jte) ',rel_hum(its,kts,jts),rel_hum(ite,kfire_max,jte) - WRITE(*,*) 'add_emis_burn: aod3d_smoke(its,kts,jts),aod3d_smoke(ite,kfire_max,jte) ',aod3d_smoke(its,kts,jts),aod3d_smoke(ite,kfire_max,jte) - WRITE(*,*) 'add_emis_burn: aod3d_dust(its,kts,jts),aod3d_dust(ite,kfire_max,jte) ',aod3d_dust(its,kts,jts),aod3d_dust(ite,kfire_max,jte) + WRITE(*,*) 'add_emis_burn: ext3d_smoke(its,kts,jts),ext3d_smoke(ite,kfire_max,jte) ',ext3d_smoke(its,kts,jts),ext3d_smoke(ite,kfire_max,jte) + WRITE(*,*) 'add_emis_burn: ext3d_dust(its,kts,jts),ext3d_dust(ite,kfire_max,jte) ',ext3d_dust(its,kts,jts),ext3d_dust(ite,kfire_max,jte) END IF ! CASE DEFAULT diff --git a/smoke/module_plumerise1.F90 b/physics/smoke_dust/module_plumerise1.F90 similarity index 91% rename from smoke/module_plumerise1.F90 rename to physics/smoke_dust/module_plumerise1.F90 index 47bb4e74a..3c23faa6a 100755 --- a/smoke/module_plumerise1.F90 +++ b/physics/smoke_dust/module_plumerise1.F90 @@ -3,7 +3,6 @@ module module_plumerise1 - use rrfs_smoke_data use machine , only : kind_phys real(kind=kind_phys),parameter :: p1000mb = 100000. ! p at 1000mb (pascals) !- Implementing the fire radiative power (FRP) methodology for biomass burning @@ -35,10 +34,10 @@ module module_plumerise1 ! 'aggr' /) ! grassland CONTAINS -subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & +subroutine ebu_driver ( flam_frac,ebb_smoke,ebu, & t_phy,q_vap, & ! RAR: moist is replaced with q_vap rho_phy,vvel,u_phy,v_phy,p_phy, & - z_at_w,z,ktau,g,con_cp,con_rd, & ! scale_fire_emiss is part of config_flags + z_at_w,z,g,con_cp,con_rd, & ! scale_fire_emiss is part of config_flags plume_frp, k_min, k_max, & ! RAR: ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & @@ -49,7 +48,6 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & USE module_zero_plumegen_coms USE module_smoke_plumerise IMPLICIT NONE - type(smoke_data), intent(inout) :: data REAL(kind_phys), PARAMETER :: frp_threshold= 1.e+7 ! Minimum FRP (Watts) to have plume rise @@ -58,8 +56,7 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & ! TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags character(*), intent(inout) :: errmsg integer, intent(inout) :: errflg - INTEGER, INTENT(IN ) :: ktau, & - ids,ide, jds,jde, kds,kde, & + INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte ! real(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & @@ -98,7 +95,6 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & ! write(0,*)'plumerise' ! RAR: -! if (config_flags%biomass_burn_opt == BIOMASSB_SMOKE) then ! do j=jts,jte: ! do i=its,ite ! ebu(i,kts,j,p_ebu_smoke)= ebb_smoke(i,j) @@ -115,12 +111,12 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & cpor =con_cp/con_rd con_rocp=con_rd/con_cp - IF ( dbg_opt .and. ktau<2000) then + IF ( dbg_opt ) then WRITE(*,*) 'module_plumerise1: its,ite,jts,jte ', its,ite,jts,jte WRITE(*,*) 'module_plumerise1: ims,ime,jms,jme ', ims,ime,jms,jme !WRITE(*,*) 'module_plumerise1: p_ebu_smoke,num_ebu: ', p_ebu_smoke,num_ebu WRITE(*,*) 'module_plumerise1: maxval(ebu(:,kts,:)) ', maxval(ebu(:,kts,:)) - END IF + END IF !endif ! RAR: setting to zero the ebu emissions at the levels k>1, this is necessary when the plumerise is called, so the emissions at k>1 are updated @@ -136,7 +132,6 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & ! For now the flammable fraction is constant, based on the namelist. The next ! step to use LU index and meteorology to parameterize it -! IF (ktau==2) THEN do j=jts,jte do i=its,ite flam_frac(i,j)= 0. @@ -145,13 +140,12 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & end if enddo enddo - ! ENDIF ! RAR: new FRP based approach !check_pl: IF (config_flags%plumerise_flag == 2 ) THEN ! if the namelist option is set for plumerise ! Haiqin: plumerise_flag is added to the namelist options -!check_pl: IF (do_plumerise) THEN ! if the namelist option is set for plumerise +check_pl: IF (do_plumerise) THEN ! if the namelist option is set for plumerise do j=jts,jte do i=its,ite ! k_min(i,j)=0 @@ -175,7 +169,7 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & !theta_in(k)= t_phy(i,k,j)/pi_in(k)*cp enddo - IF (dbg_opt .and. ktau<2000) then + IF (dbg_opt) then WRITE(*,*) 'module_plumerise1: i,j ',i,j WRITE(*,*) 'module_plumerise1: plume_frp(i,j,:) ',plume_frp(i,j,:) WRITE(*,*) 'module_plumerise1: ebu(i,kts,j) ',ebu(i,kts,j) @@ -185,15 +179,15 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & END IF ! RAR: the plume rise calculation step: - CALL plumerise(data,kte,1,1,1,1,1,1, & + CALL plumerise(kte,1,1,1,1,1,1, & !firesize,mean_fct, & !num_ebu, eburn_in, eburn_out, & u_in, v_in, w_in, theta_in ,pi_in, & rho_phyin, qv_in, zmid, z_lev, & plume_frp(i,j,1), k_min(i,j), & - k_max(i,j), ktau, dbg_opt, g, con_cp, & + k_max(i,j), dbg_opt, g, con_cp, & con_rd, cpor, errmsg, errflg ) - !k_max(i,j), ktau, config_flags%debug_chem ) + !k_max(i,j), config_flags%debug_chem ) if(errflg/=0) return kp1= k_min(i,j) @@ -205,7 +199,7 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & enddo ebu(i,kts,j)= (1.-flam_frac(i,j))* ebb_smoke(i,j) - IF ( dbg_opt .and. ktau<2000) then + IF ( dbg_opt ) then WRITE(*,*) 'module_plumerise1: i,j ',i,j WRITE(*,*) 'module_plumerise1: k_min(i,j), k_max(i,j) ',k_min(i,j), k_max(i,j) END IF @@ -213,7 +207,7 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & enddo enddo -! ENDIF check_pl + ENDIF check_pl end subroutine ebu_driver diff --git a/smoke/module_smoke_plumerise.F90 b/physics/smoke_dust/module_smoke_plumerise.F90 similarity index 98% rename from smoke/module_smoke_plumerise.F90 rename to physics/smoke_dust/module_smoke_plumerise.F90 index 247b09f92..5a1a2319d 100755 --- a/smoke/module_smoke_plumerise.F90 +++ b/physics/smoke_dust/module_smoke_plumerise.F90 @@ -14,8 +14,6 @@ module module_smoke_plumerise use machine , only : kind_phys - use rrfs_smoke_data - use rrfs_smoke_config, only : FIRE_OPT_GBBEPx, FIRE_OPT_MODIS use plume_data_mod, only : num_frp_plume, p_frp_hr, p_frp_std, & !tropical_forest, boreal_forest, savannah, grassland, & wind_eff @@ -26,15 +24,14 @@ module module_smoke_plumerise CONTAINS ! RAR: - subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & + subroutine plumerise(m1,m2,m3,ia,iz,ja,jz, & ! firesize,mean_fct, & ! nspecies,eburn_in,eburn_out, & up,vp,wp,theta,pp,dn0,rv,zt_rams,zm_rams, & - frp_inst,k1,k2, ktau, dbg_opt, g, cp, rgas, & + frp_inst,k1,k2, dbg_opt, g, cp, rgas, & cpor, errmsg, errflg ) implicit none - type(smoke_data), intent(inout) :: data LOGICAL, INTENT (IN) :: dbg_opt @@ -46,7 +43,6 @@ subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & integer :: ng,m1,m2,m3,ia,iz,ja,jz,ibcon,mynum,i,j,k,imm,ixx,ispc !,nspecies - INTEGER, INTENT (IN) :: ktau INTEGER, INTENT (OUT) :: k1,k2 character(*), intent(inout) :: errmsg integer, intent(inout) :: errflg @@ -106,9 +102,6 @@ subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & !---------------------------------------------------------------------- ! print *,' Plumerise_scalar 1',ncall coms => get_thread_coms() - if (ktau==2) then - call coms%set_to_zero() - endif IF (frp_inst=k1+1 @@ -208,7 +199,7 @@ subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & ! enddo !enddo - IF (dbg_opt .AND. ktau<2000) then + IF (dbg_opt) then WRITE(*,*) 'plumerise after set_flam_vert: nkp,k1,k2, ', nkp,k1,k2 WRITE(*,*) 'plumerise after set_flam_vert: dzi ', dzi !WRITE(*,*) 'plumerise after set_flam_vert: eburn_in(2) ', eburn_in(2) @@ -220,7 +211,7 @@ subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & end subroutine plumerise !------------------------------------------------------------------------- -subroutine get_env_condition(coms,k1,k2,kmt,wind_eff,ktau,g,cp,rgas,cpor,errmsg,errflg) +subroutine get_env_condition(coms,k1,k2,kmt,wind_eff,g,cp,rgas,cpor,errmsg,errflg) !se module_zero_plumegen_coms !use rconstants @@ -232,11 +223,11 @@ subroutine get_env_condition(coms,k1,k2,kmt,wind_eff,ktau,g,cp,rgas,cpor,errmsg, real(kind=kind_phys),parameter :: p00=p1000mb real(kind=kind_phys) :: znz,themax,tlll,plll,rlll,zlll,dzdd,dzlll,tlcl,plcl,dzlcl,dummy !integer :: n_setgrid = 0 -integer :: wind_eff,ktau +integer :: wind_eff character(*), intent(inout) :: errmsg integer, intent(inout) :: errflg -if(ktau==2) then +if(.not.coms%initialized) then ! n_setgrid = 1 call set_grid(coms) ! define vertical grid of plume model ! coms%zt(k) = thermo and water levels @@ -348,6 +339,8 @@ subroutine set_grid(coms) coms%dzt(k) = 1. / (coms%zm(k) - coms%zm(k-1)) enddo coms%dzt(1) = coms%dzt(2) * coms%dzt(2) / coms%dzt(3) + +coms%initialized = .true. ! coms%dzm(1) = 0.5/coms%dz ! coms%dzm(2:mzp) = 1./coms%dz @@ -447,23 +440,24 @@ subroutine get_fire_properties(coms,imm,iveg_ag,burnt_area,FRP,errmsg,errflg) type(plumegen_coms), pointer :: coms integer :: moist, i, icount,imm,iveg_ag !,plumerise_flag real(kind=kind_phys):: bfract, effload, heat, hinc ,burnt_area,heat_fluxW,FRP -real(kind=kind_phys), dimension(2,4) :: heat_flux +!real(kind=kind_phys), dimension(2,4) :: heat_flux integer, intent(inout) :: errflg character(*), intent(inout) :: errmsg -INTEGER, parameter :: use_last = 0 +INTEGER, parameter :: use_last = 1 ! RAR 10/31/2022: I set to one, checking with Saulo + !real(kind=kind_phys), parameter :: beta = 5.0 !ref.: Wooster et al., 2005 REAL(kind=kind_phys), parameter :: beta = 0.88 !ref.: Paugam et al., 2015 -data heat_flux/ & +!data heat_flux/ & RAR: not used !--------------------------------------------------------------------- ! heat flux !IGBP Land Cover ! ! min ! max !Legend and ! reference ! kW/m^2 !description ! !-------------------------------------------------------------------- -30.0, 80.0, &! Tropical Forest ! igbp 2 & 4 -30.0, 80.0, &! Boreal(kind=kind_phys) forest ! igbp 1 & 3 -4.4, 23.0, &! cerrado/woody savanna | igbp 5 thru 9 -3.3, 3.3 /! Grassland/cropland ! igbp 10 thru 17 +!30.0, 80.0, &! Tropical Forest ! igbp 2 & 4 +!30.0, 80.0, &! Boreal(kind=kind_phys) forest ! igbp 1 & 3 +!4.4, 23.0, &! cerrado/woody savanna | igbp 5 thru 9 +!3.3, 3.3 /! Grassland/cropland ! igbp 10 thru 17 !-------------------------------------------------------------------- !-- fire at surface ! @@ -556,7 +550,7 @@ subroutine get_fire_properties(coms,imm,iveg_ag,burnt_area,FRP,errmsg,errflg) COMS%HEATING (ICOUNT) = heat_fluxW * 0.55 ! W/m**2 (0.55 converte para energia convectiva) ICOUNT = ICOUNT + 1 ENDDO -! ramp for 5 minutes +! ramp for 5 minutes, RAR: in the current version this is inactive IF(use_last /= 1) THEN HINC = COMS%HEATING (1) / 4. @@ -565,15 +559,17 @@ subroutine get_fire_properties(coms,imm,iveg_ag,burnt_area,FRP,errmsg,errflg) COMS%HEATING (3) = 2. * HINC COMS%HEATING (4) = 3. * HINC ELSE + HINC = COMS%HEATING (1) / 4. ! RAR: this needs to be revised later IF(imm==1) THEN - HINC = COMS%HEATING (1) / 4. + !HINC = COMS%HEATING (1) / 4. COMS%HEATING (1) = 0.1 COMS%HEATING (2) = HINC COMS%HEATING (3) = 2. * HINC COMS%HEATING (4) = 3. * HINC ELSE - HINC = (COMS%HEATING (1) - heat_flux(imm-1,iveg_ag) * 1000. *0.55)/ 4. - COMS%HEATING (1) = heat_flux(imm-1,iveg_ag) * 1000. *0.55 + 0.1 + ! RAR: I've commented out so we don't use the look-up table for heat flux + ! HINC = (COMS%HEATING (1) - heat_flux(imm-1,iveg_ag) * 1000. *0.55)/ 4. + ! COMS%HEATING (1) = heat_flux(imm-1,iveg_ag) * 1000. *0.55 + 0.1 COMS%HEATING (2) = COMS%HEATING (1)+ HINC COMS%HEATING (3) = COMS%HEATING (2)+ HINC COMS%HEATING (4) = COMS%HEATING (3)+ HINC diff --git a/physics/smoke_dust/module_wetdep_ls.F90 b/physics/smoke_dust/module_wetdep_ls.F90 new file mode 100755 index 000000000..87212920b --- /dev/null +++ b/physics/smoke_dust/module_wetdep_ls.F90 @@ -0,0 +1,79 @@ +!>\file module_wetdep_ls.F90 +!! This file contains aerosol wet deposition module. + +module module_wetdep_ls + use machine , only : kind_phys + use rrfs_smoke_config, only : p_qc, alpha => wetdep_ls_alpha + +contains +subroutine wetdep_ls(dt,var,rain,moist, & + rho,nchem,num_moist,dz8w,vvel, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) + implicit none + + integer, intent(in) :: nchem, num_moist, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte + real(kind_phys), intent(in) :: dt + real(kind_phys), dimension( ims:ime, kms:kme, jms:jme, num_moist),intent(in) :: moist + real(kind_phys), dimension( ims:ime, kms:kme, jms:jme),intent(in) :: rho,dz8w,vvel + real(kind_phys), dimension( ims:ime, kms:kme, jms:jme,1:nchem),intent(inout) :: var + real(kind_phys), dimension( ims:ime, jms:jme),intent(in) :: rain + real(kind_phys), dimension( its:ite, jts:jte) :: var_sum,var_rmv + real(kind_phys), dimension( its:ite, kts:kte, jts:jte) :: var_rmvl + real(kind_phys), dimension( its:ite, jts:jte) :: frc,var_sum_clw,rain_clw + real(kind_phys) :: dvar,factor,clsum + integer :: nv,i,j,k,km,kb,kbeg + !real(kind_phys), parameter :: alpha = .5 ! scavenging factor + + + do nv=1,nchem + do i=its,ite + do j=jts,jte + var_sum_clw(i,j)=0. + var_sum(i,j)=0. + var_rmvl(i,:,j)=0. + frc(i,j)=0. + rain_clw(i,j)=0. + if(rain(i,j).gt.1.e-10)then +! convert rain back to rate +! + rain_clw(i,j)=rain(i,j)/dt +! total cloud water +! + do k=1,kte-1 + dvar=max(0.,moist(i,k,j,p_qc)*rho(i,k,j)*vvel(i,k,j)*dz8w(i,k,j)) + var_sum_clw(i,j)=var_sum_clw(i,j)+dvar + var_sum(i,j)=var_sum(i,j)+var(i,k,j,nv)*rho(i,k,j) + enddo + if(var_sum(i,j).gt.1.e-10 .and. var_sum_clw(i,j).gt.1.e-10 ) then +! assuming that frc is onstant, it is my conversion factor +! (just like in convec. parameterization) + frc(i,j)=rain_clw(i,j)/var_sum_clw(i,j) + frc(i,j)=max(1.e-6,min(frc(i,j),.005)) + endif + endif + enddo + enddo +! +! get rid of it +! + do i=its,ite + do j=jts,jte + if(rain(i,j).gt.1.e-10 .and. var_sum(i,j).gt.1.e-10 .and. var_sum_clw(i,j).gt.1.e-10)then + do k=kts,kte-2 + if(var(i,k,j,nv).gt.1.e-16 .and. moist(i,k,j,p_qc).gt.0.)then + factor = max(0.,frc(i,j)*rho(i,k,j)*dz8w(i,k,j)*vvel(i,k,j)) + dvar=alpha*factor/(1+factor)*var(i,k,j,nv) + var(i,k,j,nv)=max(1.e-16,var(i,k,j,nv)-dvar) + endif + enddo + endif + enddo + enddo + enddo ! nv +end subroutine wetdep_ls +end module module_wetdep_ls diff --git a/smoke/module_zero_plumegen_coms.F90 b/physics/smoke_dust/module_zero_plumegen_coms.F90 similarity index 88% rename from smoke/module_zero_plumegen_coms.F90 rename to physics/smoke_dust/module_zero_plumegen_coms.F90 index 622d6a813..92b9ca2dc 100755 --- a/smoke/module_zero_plumegen_coms.F90 +++ b/physics/smoke_dust/module_zero_plumegen_coms.F90 @@ -9,6 +9,8 @@ module module_zero_plumegen_coms integer, parameter :: nkp = 200, ntime = 200 type plumegen_coms + logical :: initialized = .false. + real(kind=kind_phys),dimension(nkp) :: w,t,qv,qc,qh,qi,sc, & ! blob vth,vti,rho,txs, & est,qsat! never used: ,qpas,qtotal @@ -55,38 +57,28 @@ module module_zero_plumegen_coms procedure :: set_to_zero => plumegen_coms_zero end type plumegen_coms - interface plumegen_coms - procedure :: plumegen_coms_constructor - end interface plumegen_coms - - type(plumegen_coms), private, target :: private_thread_coms - logical, private :: mzpc_initialized = .false. + type(plumegen_coms), private, pointer :: private_thread_coms !$OMP THREADPRIVATE(private_thread_coms) -!$OMP THREADPRIVATE(mzpc_initialized) contains function get_thread_coms() result(coms) implicit none class(plumegen_coms), pointer :: coms - if(.not.mzpc_initialized) then - private_thread_coms = plumegen_coms() - mzpc_initialized = .true. + if(.not.associated(private_thread_coms)) then + allocate(private_thread_coms) + call plumegen_coms_zero(private_thread_coms) endif coms => private_thread_coms end function get_thread_coms - type(plumegen_coms) function plumegen_coms_constructor() result(this) - implicit none - call plumegen_coms_zero(this) - this%testval=3314 - end function plumegen_coms_constructor - subroutine plumegen_coms_zero(this) implicit none class(plumegen_coms) :: this + this%initialized = .false. + this%w=0.0 this%t=0.0 this%qv=0.0 diff --git a/smoke/plume_data_mod.F90 b/physics/smoke_dust/plume_data_mod.F90 similarity index 100% rename from smoke/plume_data_mod.F90 rename to physics/smoke_dust/plume_data_mod.F90 diff --git a/smoke/rrfs_smoke_config.F90 b/physics/smoke_dust/rrfs_smoke_config.F90 similarity index 66% rename from smoke/rrfs_smoke_config.F90 rename to physics/smoke_dust/rrfs_smoke_config.F90 index 43b3aee14..58d4c5846 100755 --- a/smoke/rrfs_smoke_config.F90 +++ b/physics/smoke_dust/rrfs_smoke_config.F90 @@ -16,59 +16,30 @@ module rrfs_smoke_config !-- constant paramters real(kind=kind_phys), parameter :: epsilc = 1.e-12 - !-- chemistyr module configurations + !-- aerosol module configurations integer :: chem_opt = 1 integer :: kemit = 1 integer :: dust_opt = 5 - integer :: dmsemis_opt = 1 integer :: seas_opt = 2 - integer :: biomass_burn_opt=1 logical :: do_plumerise = .true. integer :: addsmoke_flag = 1 - integer :: plumerisefire_frq=60 ! Let's add to the namelist - integer :: chem_conv_tr = 0 - integer :: aer_ra_feedback=1 !0 - integer :: aer_ra_frq = 60 + integer :: plumerisefire_frq=60 integer :: wetdep_ls_opt = 1 integer :: drydep_opt = 1 + integer :: coarsepm_settling = 1 logical :: bb_dcycle = .false. - logical :: smoke_forecast = .false. logical :: aero_ind_fdb = .false. logical :: dbg_opt = .true. - - real(kind=kind_phys), parameter :: depo_fact=0. - integer, parameter :: CHEM_OPT_GOCART= 1 - INTEGER, PARAMETER :: gocartracm_kpp = 301 - integer, parameter :: chem_tune_tracers = 20 - integer, parameter :: DUST_OPT_NONE = 0 - integer, parameter :: SEAS_OPT_NONE = 0 - ! -- DMS emissions - integer, parameter :: DMSE_OPT_NONE = 0 - integer, parameter :: DMSE_OPT_ENABLE = 1 - ! -- subgrid convective transport - integer, parameter :: CTRA_OPT_NONE = 0 - integer, parameter :: CTRA_OPT_GRELL = 2 - ! -- large scale wet deposition - integer, parameter :: WDLS_OPT_NONE = 0 - integer, parameter :: WDLS_OPT_GSD = 1 - integer, parameter :: WDLS_OPT_NGAC = 2 + integer :: smoke_forecast = 0 ! 0 read in ebb_smoke(i,24) + real(kind_phys) :: wetdep_ls_alpha = .5 ! scavenging factor ! -- + integer, parameter :: CHEM_OPT_GOCART= 1 integer, parameter :: call_chemistry = 1 integer, parameter :: num_moist=3, num_chem=20, num_emis_seas=5, num_emis_dust=5 - integer, parameter :: num_emis_ant = 7 - integer, parameter :: SEAS_OPT_DEFAULT = 1 - - integer, parameter :: DUST_OPT_GOCART = 1 - integer, parameter :: DUST_OPT_AFWA = 3 integer, parameter :: DUST_OPT_FENGSHA = 5 - ! -- biomass burning emissions - integer, parameter :: BURN_OPT_ENABLE = 1 - integer, parameter :: FIRE_OPT_MODIS = 1 - integer, parameter :: FIRE_OPT_GBBEPx = 2 - ! -- hydrometeors integer, parameter :: p_qv=1 integer, parameter :: p_qc=2 @@ -77,12 +48,9 @@ module rrfs_smoke_config ! -- FV3 GFDL microphysics integer, parameter :: p_atm_shum = 1 integer, parameter :: p_atm_cldq = 2 - integer, parameter :: p_atm_o3mr = 7 integer :: numgas = 0 - real(kind=kind_phys) :: wetdep_ls_alpha(chem_tune_tracers)=-999. - !-- tracers integer, parameter :: p_so2=1 integer, parameter :: p_sulf=2 @@ -97,7 +65,7 @@ module rrfs_smoke_config integer, parameter :: p_dust_2=11 integer, parameter :: p_dust_3=12 integer, parameter :: p_dust_4=13 - integer, parameter :: p_dust_5=14 + integer, parameter :: p_dust_5=14, p_coarse_pm=14 integer, parameter :: p_seas_1=15 integer, parameter :: p_seas_2=16 integer, parameter :: p_seas_3=17 diff --git a/smoke/rrfs_smoke_postpbl.F90 b/physics/smoke_dust/rrfs_smoke_postpbl.F90 similarity index 68% rename from smoke/rrfs_smoke_postpbl.F90 rename to physics/smoke_dust/rrfs_smoke_postpbl.F90 index f83aaf795..8fbfa7a51 100755 --- a/smoke/rrfs_smoke_postpbl.F90 +++ b/physics/smoke_dust/rrfs_smoke_postpbl.F90 @@ -15,26 +15,22 @@ module rrfs_smoke_postpbl contains -!>\defgroup rrfs_smoke_postpbl GSD Chem emission driver Module -!> \ingroup gsd_chem_group -!! This is the GSD Chem emission driver Module -!! \section arg_table_rrfs_smoke_postpbl_run Argument Table +!> \section arg_table_rrfs_smoke_postpbl_run Argument Table !! \htmlinclude rrfs_smoke_postpbl_run.html !! -!>\section rrfs_smoke_postpbl GSD Chemistry Scheme General Algorithm -!> @{ - subroutine rrfs_smoke_postpbl_run(ite, kte, ntsmoke, ntdust, ntrac, & - qgrs, chem3d, errmsg, errflg) + subroutine rrfs_smoke_postpbl_run(ite, kte, ntsmoke, ntdust, ntcoarsepm, ntrac, & + qgrs, chem3d, rrfs_sd, errmsg, errflg) implicit none - integer, intent(in) :: ite,kte,ntsmoke,ntdust,ntrac + integer, intent(in) :: ite,kte,ntsmoke,ntdust,ntcoarsepm,ntrac integer, parameter :: its=1,kts=1 real(kind_phys), dimension(:,:,:), intent(inout) :: qgrs real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d + logical, intent(in) :: rrfs_sd character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -44,16 +40,20 @@ subroutine rrfs_smoke_postpbl_run(ite, kte, ntsmoke, ntdust, ntrac, & errmsg = '' errflg = 0 + if (.not. rrfs_sd) return + !--- put smoke stuff back into tracer array do k=kts,kte do i=its,ite qgrs(i,k,ntsmoke)= chem3d(i,k,1) qgrs(i,k,ntdust )= chem3d(i,k,2) + qgrs(i,k,ntcoarsepm)= chem3d(i,k,3) enddo enddo - end subroutine rrfs_smoke_postpbl_run + return + + end subroutine rrfs_smoke_postpbl_run -!> @} end module rrfs_smoke_postpbl diff --git a/smoke/rrfs_smoke_postpbl.meta b/physics/smoke_dust/rrfs_smoke_postpbl.meta similarity index 70% rename from smoke/rrfs_smoke_postpbl.meta rename to physics/smoke_dust/rrfs_smoke_postpbl.meta index 99aae69f2..dab56cddc 100755 --- a/smoke/rrfs_smoke_postpbl.meta +++ b/physics/smoke_dust/rrfs_smoke_postpbl.meta @@ -1,11 +1,11 @@ [ccpp-table-properties] - name = rrfs_smoke_wrapper + name = rrfs_smoke_postpbl type = scheme - dependencies = dep_dry_gocart_mod.F90,dep_dry_mod.F90,dep_simple_mod.F90,dep_vertmx_mod.F90,dep_wet_ls_mod.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,rrfs_smoke_data.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90 + dependencies = dep_dry_mod.F90,module_wetdep_ls.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90 ######################################################################## [ccpp-arg-table] - name = rrfs_smoke_wrapper_run + name = rrfs_smoke_postpbl_run type = scheme [ite] standard_name = horizontal_loop_extent @@ -35,6 +35,13 @@ dimensions = () type = integer intent = in +[ntcoarsepm] + standard_name = index_for_coarse_pm_in_tracer_concentration_array + long_name = tracer index for coarse pm + units = index + dimensions = () + type = integer + intent = in [ntrac] standard_name = number_of_tracers long_name = number of tracers @@ -54,10 +61,17 @@ standard_name = chem3d_mynn_pbl_transport long_name = mynn pbl transport of smoke and dust units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension,2) + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_chemical_species_vertically_mixed) type = real kind = kind_phys intent = inout +[rrfs_sd] + standard_name = do_smoke_coupling + long_name = flag controlling rrfs_sd collection (default off) + units = flag + dimensions = () + type = logical + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/smoke/rrfs_smoke_wrapper.F90 b/physics/smoke_dust/rrfs_smoke_wrapper.F90 similarity index 66% rename from smoke/rrfs_smoke_wrapper.F90 rename to physics/smoke_dust/rrfs_smoke_wrapper.F90 index ac32e1ad4..530d875db 100755 --- a/smoke/rrfs_smoke_wrapper.F90 +++ b/physics/smoke_dust/rrfs_smoke_wrapper.F90 @@ -1,5 +1,5 @@ !>\file rrfs_smoke_wrapper.F90 -!! This file is CCPP RRFS smoke driver +!! This file is CCPP driver of RRFS Smoke and Dust !! Haiqin.Li@noaa.gov 02/2021 module rrfs_smoke_wrapper @@ -12,8 +12,9 @@ module rrfs_smoke_wrapper use plume_data_mod use module_plumerise1 !plume_rise_mod use module_add_emiss_burn + use coarsepm_settling_mod use dep_dry_mod - use rrfs_smoke_data + use module_wetdep_ls implicit none @@ -23,36 +24,39 @@ module rrfs_smoke_wrapper contains -!>\defgroup rrfs_smoke_wrapper GSD Chem emission driver Module +!>\defgroup rrfs_smoke_wrapper rrfs-sd emission driver Module !> \ingroup gsd_chem_group -!! This is the GSD Chem emission driver Module +!! This is the rrfs-sd emission driver Module !! \section arg_table_rrfs_smoke_wrapper_run Argument Table !! \htmlinclude rrfs_smoke_wrapper_run.html !! -!>\section rrfs_smoke_wrapper GSD Chemistry Scheme General Algorithm +!>\section rrfs_smoke_wrapper rrfs-sd Scheme General Algorithm !> @{ - subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, & - u10m, v10m, ustar, rlat, rlon, tskin, pb2d, t2m, dpt2m, & - pr3d, ph3d,phl3d, prl3d, tk3d, us3d, vs3d, spechum, w, & - nsoil, smc, vegtype, soiltyp, sigmaf, dswsfc, zorl,snow, & + subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, & + u10m, v10m, ustar, rlat, rlon, tskin, pb2d, t2m, dpt2m, & + pr3d, ph3d,phl3d, prl3d, tk3d, us3d, vs3d, spechum, w, & + nsoil, smc, vegtype, soiltyp, sigmaf, dswsfc, zorl,snow, & julian, idat, rain_cpl, rainc_cpl, exch, hf2d, g, pi, con_cp, con_rd, & - dust12m_in, emi_in, smoke_GBBEPx, ntrac, qgrs, gq0, chem3d, tile_num, & - ntsmoke, ntdust, imp_physics, imp_physics_thompson, & - nwfa, nifa, emanoc, & - emdust, emseas, ebb_smoke_hr, frp_hr, frp_std_hr, & - coef_bb, ebu_smoke,fhist, min_fplume, max_fplume, hwp, & - smoke_ext, dust_ext, & - seas_opt_in, dust_opt_in, biomass_burn_opt_in, drydep_opt_in, & - do_plumerise_in, plumerisefire_frq_in, addsmoke_flag_in, & + dust12m_in, emi_in, smoke_RRFS, ntrac, qgrs, gq0, chem3d, tile_num, & + ntsmoke, ntdust, ntcoarsepm, imp_physics, imp_physics_thompson, & + nwfa, nifa, emanoc, emdust, emseas, & + ebb_smoke_hr, frp_hr, frp_std_hr, & + coef_bb, ebu_smoke,fhist, min_fplume, max_fplume, hwp, wetness, & + smoke_ext, dust_ext, ndvel, ddvel_inout,rrfs_sd, & + dust_alpha_in, dust_gamma_in, fire_in, & + seas_opt_in, dust_opt_in, drydep_opt_in, coarsepm_settling_in, & + do_plumerise_in, plumerisefire_frq_in, addsmoke_flag_in, & + wetdep_ls_opt_in,wetdep_ls_alpha_in, & smoke_forecast_in, aero_ind_fdb_in,dbg_opt_in,errmsg,errflg) implicit none integer, intent(in) :: im,kte,kme,ktau,nsoil,tile_num,jdate(8),idat(8) - integer, intent(in) :: ntrac, ntsmoke, ntdust + integer, intent(in) :: ntrac, ntsmoke, ntdust, ntcoarsepm, ndvel real(kind_phys),intent(in) :: dt, julian, g, pi, con_cp, con_rd - logical, intent(in) :: smoke_forecast_in,aero_ind_fdb_in,dbg_opt_in + logical, intent(in) :: aero_ind_fdb_in,dbg_opt_in + integer, intent(in) :: smoke_forecast_in integer, parameter :: ids=1,jds=1,jde=1, kds=1 integer, parameter :: ims=1,jms=1,jme=1, kms=1 @@ -61,10 +65,10 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, integer, dimension(:), intent(in) :: land, vegtype, soiltyp real(kind_phys), dimension(:,:), intent(in) :: smc real(kind_phys), dimension(:,:,:), intent(in) :: dust12m_in - real(kind_phys), dimension(:,:,:), intent(in) :: smoke_GBBEPx + real(kind_phys), dimension(:,:,:), intent(in) :: smoke_RRFS real(kind_phys), dimension(:,:), intent(in) :: emi_in - real(kind_phys), dimension(:), intent(in) :: u10m, v10m, ustar, dswsfc, & - garea, rlat,rlon, tskin, pb2d, sigmaf, zorl, snow, & + real(kind_phys), dimension(:), intent(in) :: u10m, v10m, ustar, dswsfc, & + garea, rlat,rlon, tskin, pb2d, sigmaf, zorl, snow, & rain_cpl, rainc_cpl, hf2d, t2m, dpt2m real(kind_phys), dimension(:,:), intent(in) :: ph3d, pr3d real(kind_phys), dimension(:,:), intent(in) :: phl3d, prl3d, tk3d, & @@ -75,14 +79,19 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, real(kind_phys), dimension(:), intent(inout) :: ebb_smoke_hr, frp_hr, frp_std_hr real(kind_phys), dimension(:), intent(inout) :: coef_bb, fhist real(kind_phys), dimension(:,:), intent(inout) :: ebu_smoke + real(kind_phys), dimension(:,:), intent(inout) :: fire_in real(kind_phys), dimension(:), intent(inout) :: max_fplume, min_fplume real(kind_phys), dimension(:), intent( out) :: hwp real(kind_phys), dimension(:,:), intent(out) :: smoke_ext, dust_ext real(kind_phys), dimension(:,:), intent(inout) :: nwfa, nifa + real(kind_phys), dimension(:,:), intent(inout) :: ddvel_inout + real (kind=kind_phys), dimension(:), intent(in) :: wetness integer, intent(in ) :: imp_physics, imp_physics_thompson - integer, intent(in) :: seas_opt_in, dust_opt_in, biomass_burn_opt_in, & - drydep_opt_in, plumerisefire_frq_in, addsmoke_flag_in - logical, intent(in ) :: do_plumerise_in + real (kind=kind_phys), intent(in) :: dust_alpha_in, dust_gamma_in, wetdep_ls_alpha_in + integer, intent(in) :: seas_opt_in, dust_opt_in, drydep_opt_in, & + coarsepm_settling_in, plumerisefire_frq_in, & + addsmoke_flag_in, wetdep_ls_opt_in + logical, intent(in ) :: do_plumerise_in, rrfs_sd character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -97,7 +106,6 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_moist) :: moist real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_chem ) :: chem real(kind_phys), dimension(ims:im, 1, jms:jme, 1:num_emis_seas ) :: emis_seas - real(kind_phys), dimension(ims:im, jms:jme, 1:num_chem ) :: dry_fall real(kind_phys), dimension(ims:im, jms:jme) :: seashelp integer :: ide, ime, ite, kde, julday @@ -115,22 +123,18 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, real(kind_phys), dimension(ims:im, jms:jme, num_frp_plume ) :: plume_frp real(kind_phys), dimension(ims:im, jms:jme ) :: coef_bb_dc, flam_frac, & fire_hist, peak_hr - real(kind_phys), dimension(ims:im,kms:kme,jms:jme ) :: aod3d_smoke, aod3d_dust + real(kind_phys), dimension(ims:im,kms:kme,jms:jme ) :: ext3d_smoke, ext3d_dust integer, dimension(ims:im, jms:jme ) :: min_fplume2, max_fplume2 - real(kind_phys) :: dtstep - logical :: call_plume, scale_fire_emiss + logical :: call_fire !>- optical variables real(kind_phys), dimension(ims:im, kms:kme, jms:jme) :: rel_hum + real(kind_phys), dimension(ims:im, jms:jme, ndvel) :: ddvel !>-- anthropogentic variables -! real(kind_phys), dimension(ims:im, kms:kemit, jms:jme, 1:num_emis_ant) :: emis_ant real(kind_phys), dimension(ims:im) :: emis_anoc - - real(kind_phys), dimension(ims:im, kms:kme, jms:jme) :: ac3, ahno3, anh3, asulf, cor3, h2oai, h2oaj, nu3 - real(kind_phys), dimension(ims:im, jms:jme) :: dep_vel_o3, e_co + real(kind_phys), dimension(ims:im, jms:jme, 1) :: sedim real(kind_phys) :: gmt - real(kind_phys), dimension(1:num_chem) :: ppm2ugkg !> -- parameter to caluclate wfa&ifa (m) real(kind_phys), parameter :: mean_diameter1= 4.E-8, sigma1=1.8 @@ -142,26 +146,23 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, real(kind_phys), parameter :: density_dust= 2.6e+3, density_sulfate=1.8e+3 real(kind_phys), parameter :: density_oc = 1.4e+3, density_seasalt=2.2e+3 - real(kind_phys) :: daero_emis_wfa, daero_emis_ifa + real(kind_phys), dimension(im) :: daero_emis_wfa, daero_emis_ifa !>-- local variables real(kind_phys), dimension(im) :: wdgust, snoweq - integer :: current_month, current_hour + integer :: current_month, current_hour, hour_int real(kind_phys) :: curr_secs real(kind_phys) :: factor, factor2, factor3 - integer :: nbegin, nv, nvv - integer :: i, j, jp, k, kp, n - - type(smoke_data), pointer :: data - - data => get_thread_smoke_data() + integer :: nbegin, nv + integer :: i, j, k, kp, n errmsg = '' errflg = 0 + if (.not. rrfs_sd) return + !>-- options to turn on/off sea-salt, dust, plume-rising seas_opt = seas_opt_in dust_opt = dust_opt_in - biomass_burn_opt = biomass_burn_opt_in drydep_opt = drydep_opt_in do_plumerise = do_plumerise_in plumerisefire_frq = plumerisefire_frq_in @@ -169,46 +170,42 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, smoke_forecast = smoke_forecast_in aero_ind_fdb = aero_ind_fdb_in dbg_opt = dbg_opt_in + wetdep_ls_opt = wetdep_ls_opt_in + wetdep_ls_alpha = wetdep_ls_alpha_in + coarsepm_settling = coarsepm_settling_in - !print*,'hli ktau',ktau ! -- set domain ide=im ime=im ite=im kde=kte - h2oai = 0. - h2oaj = 0. - nu3 = 0. - ac3 = 0. - cor3 = 0. - asulf = 0. - ahno3 = 0. - anh3 = 0. - e_co = 0. - dep_vel_o3 = 0. - min_fplume2 = 0 max_fplume2 = 0 emis_seas = 0. emis_dust = 0. peak_hr = 0. flam_frac = 0. - aod3d_smoke = 0. - aod3d_dust = 0. + ext3d_smoke = 0. + ext3d_dust = 0. + daero_emis_wfa = 0. + daero_emis_ifa = 0. rcav = 0. rnav = 0. curr_secs = ktau * dt - current_month=jdate(2) - current_hour =jdate(5)+1 - gmt = real(idat(5)) + current_month=jdate(2) ! needed for the dust input data + current_hour =jdate(5)+1 ! =1 at 00Z + hour_int=ktau*dt/3600. ! hours since the simulation start + gmt = real(mod(idat(5)+hour_int,24)) julday = int(julian) - ! -- volume to mass fraction conversion table (ppm -> ug/kg) - ppm2ugkg = 1._kind_phys - ppm2ugkg(p_sulf) = 1.e+03_kind_phys * mw_so4_aer / mwdry + do nv=1,ndvel + do i=its,ite + ddvel(i,1,nv)=ddvel_inout(i,nv) + enddo + enddo ! -- compute incremental convective and large-scale rainfall do i=its,ite @@ -220,35 +217,24 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, ! plumerise frequency in minutes set up by the namelist input - call_plume = (biomass_burn_opt == BURN_OPT_ENABLE) .and. (plumerisefire_frq > 0) - if (call_plume) & - call_plume = (mod(int(curr_secs), max(1, 60*plumerisefire_frq)) == 0) & - .or. (ktau == 2) + call_fire = (do_plumerise .and. (plumerisefire_frq > 0)) + if (call_fire) call_fire = (mod(int(curr_secs), max(1, 60*plumerisefire_frq)) == 0) .or. (ktau == 2) - !scale_fire_emiss = .false. - - ! -- compute accumulated large-scale and convective rainfall since last call - if (ktau > 1) then - dtstep = call_chemistry * dt - else - dtstep = dt - end if - !>- get ready for chemistry run call rrfs_smoke_prep( & - ktau, current_month, current_hour, & + current_month, current_hour, gmt, & u10m,v10m,ustar,land,garea,rlat,rlon,tskin, & pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,exch,w, & nsoil,smc,vegtype,soiltyp,sigmaf,dswsfc,zorl, & - snow,dust12m_in,emi_in,smoke_GBBEPx, & - hf2d, pb2d, g, pi, & + snow,dust12m_in,emi_in,smoke_RRFS, & + hf2d, pb2d, g, pi, hour_int, & u10,v10,ust,tsk,xland,xlat,xlong,dxy, & rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & t8w,exch_h, & z_at_w,vvel,zmid, & ntrac,gq0, & - num_chem, num_moist, ppm2ugkg, & - ntsmoke, ntdust, & + num_chem,num_moist, & + ntsmoke, ntdust,ntcoarsepm, & moist,chem,plume_frp,ebu_in, & ebb_smoke_hr, frp_hr, frp_std_hr, emis_anoc, & smois,ivgtyp,isltyp,vegfrac,rmol,swdown,znt,hfx,pbl, & @@ -259,25 +245,32 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, ! Make this global, calculate at 1st time step only !>-- for plumerise -- -!IF (ktau==1) THEN + do j=jts,jte do i=its,ite - if (xlong(i,j)<-130.) then + peak_hr(i,j)= fire_in(i,10) + enddo + enddo + + IF (ktau==1) THEN + do j=jts,jte + do i=its,ite + if (xlong(i,j)<230.) then peak_hr(i,j)= 0.0* 3600. ! peak at 24 UTC, fires in Alaska - elseif(xlong(i,j)<-115.) then + elseif(xlong(i,j)<245.) then peak_hr(i,j)= 23.0* 3600. - elseif (xlong(i,j)<-100.) then + elseif (xlong(i,j)<260.) then peak_hr(i,j)= 22.0* 3600. ! peak at 22 UTC, fires in the western US - elseif (xlong(i,j)<-85.) then + elseif (xlong(i,j)<275.) then peak_hr(i,j)= 21.0* 3600. - elseif (xlong(i,j)<-70.) then ! peak at 20 UTC, fires in the eastern US + elseif (xlong(i,j)<290.) then ! peak at 20 UTC, fires in the eastern US peak_hr(i,j)= 20.0* 3600. else peak_hr(i,j)= 19.0* 3600. endif enddo enddo -!END IF + ENDIF IF (ktau==1) THEN ebu = 0. @@ -299,29 +292,30 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !>- compute sea-salt - ! -- compute sea salt - if (seas_opt >= SEAS_OPT_DEFAULT) then - call gocart_seasalt_driver(ktau,dt,rri,t_phy,moist, & + ! -- compute sea salt (opt=2) + if (seas_opt == 2) then + call gocart_seasalt_driver(dt,rri,t_phy, & u_phy,v_phy,chem,rho_phy,dz8w,u10,v10,ust,p8w,tsk, & xland,xlat,xlong,dxy,g,emis_seas,pi, & - seashelp,num_emis_seas,num_moist,num_chem,seas_opt, & + seashelp,num_emis_seas,num_chem,seas_opt, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte) endif - !-- compute dust - select case (dust_opt) - case (DUST_OPT_FENGSHA) + !-- compute dust (opt=5) + if (dust_opt==DUST_OPT_FENGSHA) then ! Set at compile time in dust_data_mod: - call gocart_dust_fengsha_driver(data,dt,chem,rho_phy,smois,p8w,ssm, & + dust_alpha = dust_alpha_in + dust_gamma = dust_gamma_in + call gocart_dust_fengsha_driver(dt,chem,rho_phy,smois,p8w,ssm, & isltyp,vegfrac,snowh,xland,dxy,g,emis_dust,ust,znt, & clayf,sandf,rdrag,uthr, & - num_emis_dust,num_moist,num_chem,nsoil, & + num_emis_dust,num_chem,nsoil, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte) - end select + end if ! compute wild-fire plumes !-- to add a namelist option to turn on/off plume raising @@ -329,13 +323,12 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !-- /scratch2/BMC/ap-fc/Ravan/rapid-refresh/WRFV3.9/smoke ! Every hour (per namelist) the ebu_driver is called to calculate ebu, but ! the plumerise is controlled by the namelist option of plumerise_flag - if (call_plume) then -! WRITE(*,*) 'plumerise is called at ktau= ',ktau + if (call_fire) then call ebu_driver ( & - data,flam_frac,ebu_in,ebu, & + flam_frac,ebu_in,ebu, & t_phy,moist(:,:,:,p_qv), & rho_phy,vvel,u_phy,v_phy,p_phy, & - z_at_w,zmid,ktau,g,con_cp,con_rd, & + z_at_w,zmid,g,con_cp,con_rd, & plume_frp, min_fplume2, max_fplume2, & ! new approach ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & @@ -345,34 +338,52 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, ! -- add biomass burning emissions at every timestep if (addsmoke_flag == 1) then - call add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum,chem, & + call add_emis_burn(dt,dz8w,rho_phy,rel_hum,chem, & julday,gmt,xlat,xlong, & ivgtyp, vegfrac, peak_hr, & ! RAR curr_secs,ebu, & - coef_bb_dc,fire_hist,aod3d_smoke,aod3d_dust, & - ! scalar(ims,kms,jms,P_QNWFA),scalar(ims,kms,jms,P_QNIFA), ! & + coef_bb_dc,fire_hist,ext3d_smoke,ext3d_dust, & rcav, rnav,swdown,smoke_forecast, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte ) endif -! WRITE(*,*) 'after add_emis_burn at ktau= ',ktau + !>-- compute coarsepm setting + if (coarsepm_settling == 1) then + call coarsepm_settling_driver(dt,t_phy,rel_hum, & + chem(:,:,:,p_coarse_pm), & + rho_phy,dz8w,p8w,p_phy,sedim, & + dxy,g,1, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) + endif !>-- compute dry deposition if (drydep_opt == 1) then - call dry_dep_driver(data,ktau,dt,julday,current_month,t_phy,p_phy, & - moist,p8w,rmol,rri,gmt,t8w,rcav, & - chem,rho_phy,dz8w,exch_h,hfx, & - ivgtyp,tsk,swdown,vegfrac,pbl,ust,znt,zmid,z_at_w, & - xland,xlat,xlong,h2oaj,h2oai,nu3,ac3,cor3,asulf,ahno3, & - anh3,dry_fall,dep_vel_o3,g, & - e_co,kemit,snowh,numgas, & - num_chem,num_moist, & + + call dry_dep_driver(rmol,ust,ndvel,ddvel,rel_hum, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte) + + do nv=1,ndvel + do i=its,ite + ddvel_inout(i,nv)=ddvel(i,1,nv) + enddo + enddo + else + ddvel_inout(:,:)=0. + endif + +!>- large-scale wet deposition + if (wetdep_ls_opt == 1) then + call wetdep_ls(dt,chem,rnav,moist, & + rho_phy,num_chem,num_moist,dz8w,vvel, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte) endif -! WRITE(*,*) 'dry depostion is done at ktau= ',ktau do k=kts,kte do i=its,ite @@ -384,95 +395,100 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !---- diagnostic output of hourly wildfire potential (07/2021) hwp = 0. do i=its,ite - wdgust(i)=1.68*sqrt(us3d(i,1)**2+vs3d(i,1)**2) - snoweq(i)=max((25.-snow(i)*1000.)/25.,0.) - !hwp(i)=44.09*wdgust(i)**1.82*max(0.,t2m(i)-dpt2m(i))**0.61*max(0.,1.-smc(i,1))**14.0*snoweq(i)*sigmaf(i) - hwp(i)=44.09*wdgust(i)**1.82*(t2m(i)-dpt2m(i))**0.61*(1.-smc(i,1))**14.0*snoweq(i)*sigmaf(i) + wdgust(i)=max(1.68*sqrt(us3d(i,1)**2+vs3d(i,1)**2),3.) + snoweq(i)=max((25.-snow(i))/25.,0.) + hwp(i)=0.237*wdgust(i)**1.11*max(t2m(i)-dpt2m(i),15.)**0.92*((1.-wetness(i))**6.95)*snoweq(i) ! Eric 08/2022 enddo !---- diagnostic output of smoke & dust optical extinction (12/2021) do k=kts,kte do i=its,ite - smoke_ext(i,k) = aod3d_smoke(i,k,1) - dust_ext (i,k) = aod3d_dust (i,k,1) + smoke_ext(i,k) = ext3d_smoke(i,k,1) + dust_ext (i,k) = ext3d_dust (i,k,1) enddo enddo !------------------------------------- !---- put smoke stuff back into tracer array do k=kts,kte do i=its,ite - gq0(i,k,ntsmoke )=ppm2ugkg(p_smoke ) * max(epsilc,chem(i,k,1,p_smoke)) ! - gq0(i,k,ntdust )=ppm2ugkg(p_dust_1) * max(epsilc,chem(i,k,1,p_dust_1)) + gq0(i,k,ntsmoke ) = min(5000.,max(epsilc,chem(i,k,1,p_smoke ))) + gq0(i,k,ntdust ) = min(100.,max(epsilc,chem(i,k,1,p_dust_1))) + gq0(i,k,ntcoarsepm)= min(1000.,max(epsilc,chem(i,k,1,p_coarse_pm))) enddo enddo do k=kts,kte do i=its,ite - qgrs(i,k,ntsmoke )= gq0(i,k,ntsmoke ) - qgrs(i,k,ntdust )= gq0(i,k,ntdust ) - chem3d(i,k,1 )= gq0(i,k,ntsmoke ) - chem3d(i,k,2 )= gq0(i,k,ntdust ) + qgrs(i,k,ntsmoke )= gq0(i,k,ntsmoke ) + qgrs(i,k,ntdust )= gq0(i,k,ntdust ) + qgrs(i,k,ntcoarsepm)= gq0(i,k,ntcoarsepm) + chem3d(i,k,1 )= gq0(i,k,ntsmoke ) + chem3d(i,k,2 )= gq0(i,k,ntdust ) + chem3d(i,k,3 )= gq0(i,k,ntcoarsepm) enddo enddo !------------------------------------- !-- to output for diagnostics -! WRITE(*,*) 'rrfs nwfa/nifa 1 at ktau= ',ktau do i = 1, im - emseas (i) = emis_seas (i,1,1,1)*1.e+9 ! size bin 1 sea salt emission: ug/m2/s - emdust (i) = emis_dust (i,1,1,1) ! size bin 1 dust emission : ug/m2/s - emanoc (i) = emis_anoc (i) ! anthropogenic organic carbon: ug/m2/s - coef_bb (i) = coef_bb_dc (i,1) - fhist (i) = fire_hist (i,1) + emseas (i) = emis_seas(i,1,1,1)*1.e+9 ! size bin 1 sea salt emission: ug/m2/s + emdust (i) = emis_dust(i,1,1,1) + emis_dust(i,1,1,2) + & + emis_dust(i,1,1,3) + emis_dust(i,1,1,4) ! dust emission: ug/m2/s + emanoc (i) = emis_anoc (i) ! anthropogenic organic carbon: ug/m2/s + coef_bb (i) = coef_bb_dc(i,1) + fhist (i) = fire_hist (i,1) min_fplume (i) = real(min_fplume2(i,1)) max_fplume (i) = real(max_fplume2(i,1)) + emseas (i) = sandf(i,1) ! sand for dust + emanoc (i) = uthr (i,1) ! u threshold for dust + enddo + + do i = 1, im + fire_in(i,10) = peak_hr(i,1) enddo -! WRITE(*,*) 'rrfs nwfa/nifa 2 at ktau= ',ktau !-- to provide real aerosol emission for Thompson MP if (imp_physics == imp_physics_thompson .and. aero_ind_fdb) then fact_wfa = 1.e-9*6.0/pi*exp(4.5*log(sigma1)**2)/mean_diameter1**3 fact_ifa = 1.e-9*6.0/pi*exp(4.5*log(sigma2)**2)/mean_diameter2**3 - do i = its, ite - do k = kts, kte - if (k==1)then - daero_emis_wfa =(emanoc(i)+ebu_smoke(i,k))/density_oc + emseas(i)/density_seasalt - else - daero_emis_wfa = ebu_smoke(i,k)/density_oc - endif - daero_emis_wfa = kappa_oc* daero_emis_wfa*fact_wfa*rri(i,k,1)/dz8w(i,k,1) ! consider using dust tracer + do i = 1, im + daero_emis_wfa(i) =(emanoc(i)+ebu_smoke(i,kemit))/density_oc + emseas(i)/density_seasalt + daero_emis_ifa(i) = emdust(i)/density_dust + + daero_emis_wfa(i) = daero_emis_wfa(i)*fact_wfa*rri(i,kemit,1)/dz8w(i,kemit,1) + daero_emis_ifa(i) = daero_emis_ifa(i)*fact_ifa*rri(i,kemit,1)/dz8w(i,kemit,1) - nwfa(i,k) = nwfa(i,k) + daero_emis_wfa*dt - nifa(i,k) = gq0(i,k,ntdust)/density_dust*fact_ifa*kappa_dust ! Check the formula + nwfa(i,kemit) = nwfa(i,kemit) + daero_emis_wfa(i)*dt + nifa(i,kemit) = nifa(i,kemit) + daero_emis_ifa(i)*dt if(land(i).eq.1)then - nwfa(i,k) = nwfa(i,k)*(1 - 0.10*dt/86400.) !-- mimicking dry deposition + nwfa(i,kemit) = nwfa(i,kemit)*(1. - 0.10*dt/86400.) !-- mimicking dry deposition + nifa(i,kemit) = nifa(i,kemit)*(1. - 0.10*dt/86400.) !-- mimicking dry deposition else - nwfa(i,k) = nwfa(i,k)*(1 - 0.05*dt/86400.) !-- mimicking dry deposition + nwfa(i,kemit) = nwfa(i,kemit)*(1. - 0.05*dt/86400.) !-- mimicking dry deposition + nifa(i,kemit) = nifa(i,kemit)*(1. - 0.05*dt/86400.) !-- mimicking dry deposition endif - enddo + nwfa(i,kemit) = MIN(2.E10,nwfa(i,kemit)) + nifa(i,kemit) = MIN(9999.E6,nifa(i,kemit)) enddo endif -! WRITE(*,*) 'rrfs smoke wrapper is done at ktau= ',ktau end subroutine rrfs_smoke_wrapper_run subroutine rrfs_smoke_prep( & - ktau,current_month,current_hour, & + current_month,current_hour,gmt, & u10m,v10m,ustar,land,garea,rlat,rlon,ts2d, & pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,exch,w, & nsoil,smc,vegtype,soiltyp,sigmaf,dswsfc,zorl, & - snow_cpl,dust12m_in,emi_in,smoke_GBBEPx, & - hf2d, pb2d, g, pi, & + snow_cpl,dust12m_in,emi_in,smoke_RRFS, & + hf2d, pb2d, g, pi, hour_int, & u10,v10,ust,tsk,xland,xlat,xlong,dxy, & rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & t8w,exch_h, & z_at_w,vvel,zmid, & ntrac,gq0, & - num_chem, num_moist, ppm2ugkg, & - ntsmoke, ntdust, & - !num_emis_ant, & - !emis_ant, & + num_chem, num_moist, & + ntsmoke, ntdust, ntcoarsepm, & moist,chem,plume_frp,ebu_in, & ebb_smoke_hr, frp_hr, frp_std_hr, emis_anoc, & smois,ivgtyp,isltyp,vegfrac,rmol,swdown,znt,hfx,pbl, & @@ -482,19 +498,19 @@ subroutine rrfs_smoke_prep( & its,ite, jts,jte, kts,kte) !Chem input configuration - integer, intent(in) :: ktau, current_month, current_hour + integer, intent(in) :: current_month, current_hour, hour_int !FV3 input variables integer, intent(in) :: nsoil integer, dimension(ims:ime), intent(in) :: land, vegtype, soiltyp integer, intent(in) :: ntrac - real(kind=kind_phys), intent(in) :: g, pi + real(kind=kind_phys), intent(in) :: g, pi, gmt real(kind=kind_phys), dimension(ims:ime), intent(in) :: & u10m, v10m, ustar, garea, rlat, rlon, ts2d, sigmaf, dswsfc, & zorl, snow_cpl, pb2d, hf2d real(kind=kind_phys), dimension(ims:ime, nsoil), intent(in) :: smc real(kind=kind_phys), dimension(ims:ime, 12, 5), intent(in) :: dust12m_in - real(kind=kind_phys), dimension(ims:ime, 24, 3), intent(in) :: smoke_GBBEPx + real(kind=kind_phys), dimension(ims:ime, 24, 3), intent(in) :: smoke_RRFS real(kind=kind_phys), dimension(ims:ime, 1), intent(in) :: emi_in real(kind=kind_phys), dimension(ims:ime, kms:kme), intent(in) :: pr3d,ph3d real(kind=kind_phys), dimension(ims:ime, kts:kte), intent(in) :: & @@ -502,16 +518,13 @@ subroutine rrfs_smoke_prep( & real(kind=kind_phys), dimension(ims:ime, kts:kte,ntrac), intent(in) :: gq0 - !GSD Chem variables - !integer,intent(in) :: num_emis_ant - integer,intent(in) :: num_chem, num_moist, ntsmoke, ntdust + !rrfs-sd variables + integer,intent(in) :: num_chem, num_moist, ntsmoke, ntdust, ntcoarsepm integer,intent(in) :: ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte - !real(kind_phys), dimension(ims:ime, kms:kemit, jms:jme, num_emis_ant), intent(inout) :: emis_ant - real(kind_phys), dimension(num_chem), intent(in) :: ppm2ugkg real(kind_phys), dimension(ims:ime, jms:jme),intent(out) :: ebu_in real(kind_phys), dimension(ims:ime, jms:jme, num_frp_plume), intent(out) :: plume_frp @@ -534,7 +547,7 @@ subroutine rrfs_smoke_prep( & real(kind_phys), parameter :: frpc = 1._kind_phys ! FRP conversion factor (Regional) ! -- local variables - integer i,ip,j,jp,k,kp,kk,kkp,nv,l,ll,n + integer i,ip,j,k,kp,kk,kkp,nv,l,ll,n ! -- initialize fire emissions !plume = 0._kind_phys @@ -542,6 +555,8 @@ subroutine rrfs_smoke_prep( & ebu_in = 0._kind_phys ebb_smoke_hr = 0._kind_phys emis_anoc = 0._kind_phys + frp_hr = 0._kind_phys + frp_std_hr = 0._kind_phys ! -- initialize output arrays isltyp = 0._kind_phys @@ -617,75 +632,60 @@ subroutine rrfs_smoke_prep( & enddo enddo - !if (ktau <= 1) then - ! emis_ant = 0. - ! !emis_vol = 0. - !end if - do j=jts,jte - jp = j - jts + 1 - do i=its,ite - ip = i - its + 1 - z_at_w(i,kts,j)=max(0.,ph3d(ip,1)/g) - enddo + do i=its,ite + z_at_w(i,kts,j)=max(0.,ph3d(i,1)/g) + enddo enddo do j=jts,jte - jp = j - jts + 1 - do k=kts,kte - kp = k - kts + 1 - do i=its,ite - ip = i - its + 1 - dz8w(i,k,j)=abs(ph3d(ip,kp+1)-ph3d(ip,kp))/g - z_at_w(i,k+1,j)=z_at_w(i,k,j)+dz8w(i,k,j) - enddo + do k=kts,kte + do i=its,ite + dz8w(i,k,j)=abs(ph3d(i,k+1)-ph3d(i,k))/g + z_at_w(i,k+1,j)=z_at_w(i,k,j)+dz8w(i,k,j) enddo + enddo enddo do j=jts,jte - jp = j - jts + 1 - do k=kts,kte+1 - kp = k - kts + 1 - do i=its,ite - ip = i - its + 1 - p8w(i,k,j)=pr3d(ip,kp) - enddo + do k=kts,kte+1 + do i=its,ite + p8w(i,k,j)=pr3d(i,k) enddo + enddo enddo do j=jts,jte - jp = j - jts + 1 do k=kts,kte+1 kk=min(k,kte) kkp = kk - kts + 1 do i=its,ite - ip = i - its + 1 dz8w(i,k,j)=z_at_w(i,kk+1,j)-z_at_w(i,kk,j) - t_phy(i,k,j)=tk3d(ip,kkp) - p_phy(i,k,j)=prl3d(ip,kkp) - u_phy(i,k,j)=us3d(ip,kkp) - v_phy(i,k,j)=vs3d(ip,kkp) - rho_phy(i,k,j)=p_phy(i,k,j)/(287.04*t_phy(i,k,j)*(1.+.608*spechum(ip,kkp))) + t_phy(i,k,j)=tk3d(i,kkp) + p_phy(i,k,j)=prl3d(i,kkp) + u_phy(i,k,j)=us3d(i,kkp) + v_phy(i,k,j)=vs3d(i,kkp) + rho_phy(i,k,j)=p_phy(i,k,j)/(287.04*t_phy(i,k,j)*(1.+.608*spechum(i,kkp))) rri(i,k,j)=1./rho_phy(i,k,j) - vvel(i,k,j)=-w(ip,kkp)*rri(i,k,j)/g + vvel(i,k,j)=-w(i,kkp)*rri(i,k,j)/g moist(i,k,j,:)=0. - moist(i,k,j,1)=gq0(ip,kkp,p_atm_shum) + moist(i,k,j,1)=gq0(i,kkp,p_atm_shum) if (t_phy(i,k,j) > 265.) then - moist(i,k,j,2)=gq0(ip,kkp,p_atm_cldq) + moist(i,k,j,2)=gq0(i,kkp,p_atm_cldq) moist(i,k,j,3)=0. if (moist(i,k,j,2) < 1.e-8) moist(i,k,j,2)=0. else moist(i,k,j,2)=0. - moist(i,k,j,3)=gq0(ip,kkp,p_atm_cldq) + moist(i,k,j,3)=gq0(i,kkp,p_atm_cldq) if(moist(i,k,j,3) < 1.e-8)moist(i,k,j,3)=0. endif - rel_hum(i,k,j) = .95 - rel_hum(i,k,j) = MIN( .95, moist(i,k,j,1) / & + !rel_hum(i,k,j) = min(0.95,spechum(i,kkp)) + rel_hum(i,k,j) = min(0.95, moist(i,k,j,1) / & (3.80*exp(17.27*(t_phy(i,k,j)-273.)/ & (t_phy(i,k,j)-36.))/(.01*p_phy(i,k,j)))) - rel_hum(i,k,j)=max(0.1,rel_hum(i,k,j)) + rel_hum(i,k,j) = max(0.1,rel_hum(i,k,j)) !-- - zmid(i,k,j)=phl3d(ip,kkp)/g + zmid(i,k,j)=phl3d(i,kkp)/g enddo enddo enddo @@ -705,7 +705,6 @@ subroutine rrfs_smoke_prep( & enddo enddo - ! -- only used in phtolysis.... do j=jts,jte do i=its,ite t8w(i,1,j)=t_phy(i,1,j) @@ -718,27 +717,26 @@ subroutine rrfs_smoke_prep( & emis_anoc(i) = emi_in(i,1) enddo - ! select case (plumerise_flag) - ! case (FIRE_OPT_GBBEPx) + if (hour_int<24) then do j=jts,jte do i=its,ite - ebb_smoke_hr(i) = smoke_GBBEPx(i,current_hour,1) ! smoke - frp_hr (i) = smoke_GBBEPx(i,current_hour,2) ! frp - frp_std_hr (i) = smoke_GBBEPx(i,current_hour,3) ! std frp + ebb_smoke_hr(i) = smoke_RRFS(i,hour_int+1,1) ! smoke + frp_hr (i) = smoke_RRFS(i,hour_int+1,2) ! frp + frp_std_hr (i) = smoke_RRFS(i,hour_int+1,3) ! std frp ebu_in (i,j) = ebb_smoke_hr(i) - plume_frp(i,j,p_frp_hr ) = conv_frp* frp_hr (i) - plume_frp(i,j,p_frp_std ) = conv_frp* frp_std_hr (i) + plume_frp(i,j,p_frp_hr ) = conv_frp* frp_hr (i) + plume_frp(i,j,p_frp_std) = conv_frp* frp_std_hr (i) enddo enddo - ! case default - ! end select + endif ! We will add a namelist variable, real :: flam_frac_global do k=kms,kte do i=ims,ime - chem(i,k,jts,p_smoke )=max(epsilc,gq0(i,k,ntsmoke )/ppm2ugkg(p_smoke)) - chem(i,k,jts,p_dust_1)=max(epsilc,gq0(i,k,ntdust )/ppm2ugkg(p_dust_1)) + chem(i,k,jts,p_smoke )=max(epsilc,gq0(i,k,ntsmoke )) + chem(i,k,jts,p_dust_1 )=max(epsilc,gq0(i,k,ntdust )) + chem(i,k,jts,p_coarse_pm)=max(epsilc,gq0(i,k,ntcoarsepm)) enddo enddo diff --git a/smoke/rrfs_smoke_wrapper.meta b/physics/smoke_dust/rrfs_smoke_wrapper.meta similarity index 85% rename from smoke/rrfs_smoke_wrapper.meta rename to physics/smoke_dust/rrfs_smoke_wrapper.meta index ef46b04ea..2b2be03b6 100755 --- a/smoke/rrfs_smoke_wrapper.meta +++ b/physics/smoke_dust/rrfs_smoke_wrapper.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = rrfs_smoke_wrapper type = scheme - dependencies = dep_dry_gocart_mod.F90,dep_dry_mod.F90,dep_simple_mod.F90,dep_vertmx_mod.F90,dep_wet_ls_mod.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,rrfs_smoke_data.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90 + dependencies = dep_dry_mod.F90,module_wetdep_ls.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90,coarsepm_settling_mod.F90 ######################################################################## [ccpp-arg-table] @@ -263,9 +263,9 @@ kind = kind_phys intent = in [snow] - standard_name = lwe_thickness_of_snow_amount - long_name = snow fall on physics timestep - units = m + standard_name = lwe_surface_snow + long_name = water equivalent snow depth + units = mm dimensions = (horizontal_loop_extent) type = real kind = kind_phys @@ -365,9 +365,9 @@ type = real kind = kind_phys intent = in -[smoke_GBBEPx] - standard_name = emission_smoke_GBBEPx - long_name = emission fire GBBEPx +[smoke_RRFS] + standard_name = emission_smoke_RRFS + long_name = emission fire RRFS units = various dimensions = (horizontal_loop_extent,24,3) type = real @@ -400,7 +400,7 @@ standard_name = chem3d_mynn_pbl_transport long_name = mynn pbl transport of smoke and dust units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension,2) + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_chemical_species_vertically_mixed) type = real kind = kind_phys intent = inout @@ -425,6 +425,13 @@ dimensions = () type = integer intent = in +[ntcoarsepm] + standard_name = index_for_coarse_pm_in_tracer_concentration_array + long_name = tracer index for coarse pm + units = index + dimensions = () + type = integer + intent = in [imp_physics] standard_name = control_for_microphysics_scheme long_name = choice of microphysics scheme @@ -551,6 +558,14 @@ type = real kind = kind_phys intent = out +[wetness] + standard_name = normalized_soil_wetness_for_land_surface_model + long_name = normalized soil wetness + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [smoke_ext] standard_name = extinction_coefficient_in_air_due_to_smoke long_name = extinction coefficient in air due to smoke @@ -567,6 +582,52 @@ type = real kind = kind_phys intent = out +[ndvel] + standard_name = number_of_chemical_species_deposited + long_name = number of chemical pbl deposited + units = count + dimensions = () + type = integer + intent = in +[ddvel_inout] + standard_name = dry_deposition_velocity_mynn_pbl_transport + long_name = dry deposition velocity by mynn pbl transport + units = m s-1 + dimensions = (horizontal_loop_extent,number_of_chemical_species_deposited) + type = real + kind = kind_phys + intent = inout +[rrfs_sd] + standard_name = do_smoke_coupling + long_name = flag controlling rrfs_sd collection (default off) + units = flag + dimensions = () + type = logical + intent = in +[dust_alpha_in] + standard_name = alpha_fengsha_dust_scheme + long_name = alpha paramter for fengsha dust scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[dust_gamma_in] + standard_name = gamma_fengsha_dust_scheme + long_name = gamma paramter for fengsha dust scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[fire_in] + standard_name = smoke_fire_auxiliary_input + long_name = smoke fire auxiliary input variables + units = various + dimensions = (horizontal_loop_extent,fire_auxiliary_data_extent) + type = real + kind = kind_phys + intent = inout [seas_opt_in] standard_name = control_for_smoke_sea_salt long_name = rrfs smoke sea salt emission option @@ -581,20 +642,35 @@ dimensions = () type = integer intent = in -[biomass_burn_opt_in] - standard_name = control_for_smoke_biomass_burn - long_name = rrfs smoke biomass burning option +[drydep_opt_in] + standard_name = control_for_smoke_dry_deposition + long_name = rrfs smoke dry deposition option units = index dimensions = () type = integer intent = in -[drydep_opt_in] - standard_name = control_for_smoke_dry_deposition - long_name = rrfs smoke dry deposition option +[coarsepm_settling_in] + standard_name = control_for_smoke_coarsepm_settling + long_name = rrfs smoke coarsepm settling option units = index dimensions = () type = integer intent = in +[wetdep_ls_opt_in] + standard_name = control_for_smoke_wet_deposition + long_name = rrfs smoke large scale wet deposition option + units = index + dimensions = () + type = integer + intent = in +[wetdep_ls_alpha_in] + standard_name = alpha_for_ls_wet_depoistion + long_name = alpha paramter for ls wet deposition + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [do_plumerise_in] standard_name = do_smoke_plumerise long_name = rrfs smoke plumerise option @@ -618,10 +694,10 @@ intent = in [smoke_forecast_in] standard_name = do_smoke_forecast - long_name = flag for rrfs smoke forecast - units = flag + long_name = index for rrfs smoke forecast + units = index dimensions = () - type = logical + type = integer intent = in [aero_ind_fdb_in] standard_name = do_smoke_aerosol_indirect_feedback diff --git a/smoke/seas_data_mod.F90 b/physics/smoke_dust/seas_data_mod.F90 similarity index 100% rename from smoke/seas_data_mod.F90 rename to physics/smoke_dust/seas_data_mod.F90 diff --git a/smoke/seas_mod.F90 b/physics/smoke_dust/seas_mod.F90 similarity index 96% rename from smoke/seas_mod.F90 rename to physics/smoke_dust/seas_mod.F90 index 85c861156..1d18046ad 100755 --- a/smoke/seas_mod.F90 +++ b/physics/smoke_dust/seas_mod.F90 @@ -13,7 +13,6 @@ module seas_mod implicit none - integer, parameter :: SEAS_OPT_DEFAULT = 1 integer, parameter :: CHEM_OPT_GOCART = 300 integer, parameter :: chem_opt = 300 @@ -22,26 +21,24 @@ module seas_mod private - public :: SEAS_OPT_DEFAULT - public :: gocart_seasalt_driver CONTAINS - subroutine gocart_seasalt_driver(ktau,dt,alt,t_phy,moist,u_phy, & + subroutine gocart_seasalt_driver(dt,alt,t_phy,u_phy, & v_phy,chem,rho_phy,dz8w,u10,v10,ustar,p8w,tsk, & - xland,xlat,xlong,area,g,emis_seas,pi, & - seashelp,num_emis_seas,num_moist,num_chem,seas_opt, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) + xland,xlat,xlong,area,g,emis_seas,pi, & + seashelp,num_emis_seas,num_chem,seas_opt, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) - INTEGER, INTENT(IN ) :: ktau,num_emis_seas,num_moist,num_chem, & + INTEGER, INTENT(IN ) :: num_emis_seas,num_chem, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte,seas_opt - REAL(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & - INTENT(IN ) :: moist +! REAL(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & +! INTENT(IN ) :: moist REAL(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), & INTENT(INOUT ) :: chem REAL(kind=kind_phys), DIMENSION( ims:ime, 1, jms:jme,num_emis_seas), & diff --git a/smoke/seas_ngac_mod.F90 b/physics/smoke_dust/seas_ngac_mod.F90 similarity index 100% rename from smoke/seas_ngac_mod.F90 rename to physics/smoke_dust/seas_ngac_mod.F90 diff --git a/smoke/dep_dry_gocart_mod.F90 b/smoke/dep_dry_gocart_mod.F90 deleted file mode 100755 index 9fb5edfd1..000000000 --- a/smoke/dep_dry_gocart_mod.F90 +++ /dev/null @@ -1,302 +0,0 @@ -!>\file dep_dry_gocart_mod.F90 -!! This file is GOCART dry deposition module to calculate the dry deposition -!! velocities of smoke and dust. - -module dep_dry_gocart_mod - - use machine , only : kind_phys - use rrfs_smoke_data - - implicit none - - private - - public :: gocart_drydep_driver - -CONTAINS - -subroutine gocart_drydep_driver(numgas, & - moist,p8w,chem,rho_phy,dz8w,ddvel,xland,hfx, & - ivgtyp,tsk,pbl,ust,znt,g, & - num_moist,num_chem, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - - IMPLICIT NONE - INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - num_moist,num_chem, & - its,ite, jts,jte, kts,kte,numgas - REAL(kind_phys), INTENT(IN ) :: g - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ),& - INTENT(IN ) :: moist - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ) ,& - INTENT(INOUT) :: chem - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) ,& - INTENT(IN ) :: dz8w, p8w,rho_phy - INTEGER, DIMENSION( ims:ime , jms:jme ) ,& - INTENT(IN ) :: ivgtyp - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) ,& - INTENT(INOUT) :: tsk, & - pbl, & - ust, & - xland,znt,hfx - -!! .. Local Scalars .. - - INTEGER :: iland, iprt, iseason, jce, jcs, & - n, nr, ipr, jpr, nvr, & - idrydep_onoff,imx,jmx,lmx - integer :: ii,jj,kk,i,j,k,nv - integer, dimension (1,1) :: ilwi - real(kind_phys), DIMENSION (5) :: tc,bems - real(kind_phys), dimension (1,1) :: z0,w10m,gwet,airden,airmas,& - delz_sfc,hflux,ts,pblz,ustar,& - ps,dvel,drydf - REAL(kind_phys), DIMENSION( its:ite, jts:jte, num_chem ) :: ddvel - - do nv=1,num_chem - do j=jts,jte - do i=its,ite - ddvel(i,j,nv)=0. - enddo - enddo - enddo - imx=1 - jmx=1 - lmx=1 - do j=jts,jte - do i=its,ite - dvel(1,1)=0. - ilwi(1,1)=0 - if(xland(i,j).gt.1.5)ilwi=1 -! for aerosols, ii=1 or ii=2 - ii=1 - if(ivgtyp(i,j).eq.19.or.ivgtyp(i,j).eq.23)ii=1 - airden(1,1)=rho_phy(i,kts,j) - delz_sfc(1,1)=dz8w(i,kts,j) - ustar(1,1)=ust(i,j) - hflux(1,1)=hfx(i,j) - pblz(1,1)=pbl(i,j) - ps(1,1)=p8w(i,kts,j)*.01 - z0(1,1)=znt(i,j) - ts(1,1)=tsk(i,j) - - call depvel_gocart(ii,imx,jmx,lmx,& - airden, delz_sfc, pblz, ts, ustar, hflux, ilwi, & - ps, z0, dvel, drydf,g) - do nv=1,num_chem - ddvel(i,j,nv)=dvel(1,1) - enddo - enddo - enddo -end subroutine gocart_drydep_driver - - - -SUBROUTINE depvel_gocart( & - ii,imx,jmx,lmx,& - airden, delz_sfc, pblz, ts, ustar, hflux, ilwi, & - ps, z0, dvel, drydf,g0) - -! **************************************************************************** -! * * -! * Calculate dry deposition velocity. * -! * * -! * Input variables: * -! * AEROSOL(k) - Logical, T = aerosol species, F = gas species * -! * IREG(i,j) - # of landtypes in grid square * -! * ILAND(i,j,ldt) - Land type ID for element ldt =1,IREG(i,j) * -! * IUSE(i,j,ldt) - Fraction of gridbox area occupied by land type * -! * element ldt * -! * USTAR(i,j) - Friction velocity (m s-1) * -! * DELZ_SFC(i,j) - Thickness of layer above surface * -! * PBLZ(i,j) - Mixing depth (m) * -! * Z0(i,j) - Roughness height (m) * -! * * -! * Determined in this subroutine (local): * -! * OBK - Monin-Obukhov length (m): set to 1.E5 m under * -! * neutral conditions * -! * Rs(ldt) - Bulk surface resistance(s m-1) for species k to * -! * surface ldt * -! * Ra - Aerodynamic resistance. * -! * Rb - Sublayer resistance. * -! * Rs - Surface resistance. * -! * Rttl - Total deposition resistance (s m-1) for species k * -! * Rttl(k) = Ra + Rb + Rs. * -! * * -! * Returned: * -! * DVEL(i,j,k) - Deposition velocity (m s-1) of species k * -! * DRYDf(i,j,k) - Deposition frequency (s-1) of species k, * -! * = DVEL / DELZ_SFC * -! * * -! **************************************************************************** - - - IMPLICIT NONE - INTEGER, INTENT(IN) :: imx,jmx,lmx - REAL(kind_phys), INTENT(IN) :: airden(imx,jmx), delz_sfc(imx,jmx) - REAL(kind_phys), INTENT(IN) :: hflux(imx,jmx), ts(imx,jmx) - REAL(kind_phys), INTENT(IN) :: ustar(imx,jmx), pblz(imx,jmx) - REAL(kind_phys), INTENT(IN) :: ps(imx,jmx) - INTEGER, INTENT(IN) :: ilwi(imx,jmx) - REAL(kind_phys), INTENT(IN) :: z0(imx,jmx) - REAL(kind=kind_phys), INTENT(IN) :: g0 - REAL(kind_phys), INTENT(OUT) :: dvel(imx,jmx), drydf(imx,jmx) - - REAL(kind_phys) :: obk, vds, czh, rttl, frac, logmfrac, psi_h, cz, eps - REAL(kind_phys) :: vd, ra, rb, rs - INTEGER :: i, j, k, ldt, iolson, ii - CHARACTER(LEN=50) :: msg - REAL(kind_phys) :: prss, tempk, tempc, xnu, ckustr, reyno, aird, diam, xm, z - REAL(kind_phys) :: frpath, speed, dg, dw, rt - REAL(kind_phys) :: rad0, rix, gfact, gfaci, rdc, rixx, rluxx, rgsx, rclx - REAL(kind_phys) :: dtmp1, dtmp2, dtmp3, dtmp4 - REAL(kind_phys) :: biofit,vk - - psi_h=0.0 - ! executable statements - j_loop: DO j = 1,jmx - i_loop: DO i = 1,imx - vk=.4 - vd = 0.0 - ra = 0.0 - rb = 0.0 ! only required for gases (SO2) - rs = 0.0 - -! **************************************************************************** -! * Compute the the Monin-Obhukov length. * -! * The direct computation of the Monin-Obhukov length is: * -! * * -! * - Air density * Cp * T(surface air) * Ustar^3 * -! * OBK = ---------------------------------------------- * -! * vK * g * Sensible Heat flux * -! * * -! * Cp = 1000 J/kg/K = specific heat at constant pressure * -! * vK = 0.4 = von Karman's constant * -! **************************************************************************** - - IF (hflux(i,j) == 0.0) THEN - obk = 1.0E5 - ELSE - ! MINVAL(hflux), MINVAL(airden), MINVAL(ustar) =?? - obk = -airden(i,j) * 1000.0 * ts(i,j) * (ustar(i,j))**3 & - / (vk * g0 * hflux(i,j)) -! -- debug: - IF ( obk == 0.0 ) WRITE(*,211) obk, i, j -211 FORMAT(1X,'OBK=', E11.2, 1X,' i,j = ', 2I4) - - END IF - - cz = delz_sfc(i,j) / 2.0 ! center of the grid box above surface - -! **************************************************************************** -! * (1) Aerosodynamic resistance Ra and sublayer resistance Rb. * -! * * -! * The Reynolds number REYNO diagnoses whether a surface is * -! * aerodynamically rough (REYNO > 10) or smooth. Surface is * -! * rough in all cases except over water with low wind speeds. * -! * * -! * For gas species over land and ice (REYNO >= 10) and for aerosol * -! * species for all surfaces: * -! * * -! * Ra = 1./VT (VT from GEOS Kzz at L=1, m/s). * -! * * -! * The following equations are from Walcek et al, 1986: * -! * * -! * For gas species when REYNO < 10 (smooth), Ra and Rb are combined * -! * as Ra: * -! * * -! * Ra = { ln(ku* z1/Dg) - Sh } / ku* eq.(13) * -! * * -! * where z1 is the altitude at the center of the lowest model layer * -! * (CZ); * -! * Sh is a stability correction function; * -! * k is the von Karman constant (0.4, vK); * -! * u* is the friction velocity (USTAR). * -! * * -! * Sh is computed as a function of z1 and L eq ( 4) and (5)): * -! * * -! * 0 < z1/L <= 1: Sh = -5 * z1/L * -! * z1/L < 0: Sh = exp{ 0.598 + 0.39*ln(E) - 0.09(ln(E))^2 } * -! * where E = min(1,-z1/L) (Balkanski, thesis). * -! * * -! * For gas species when REYNO >= 10, * -! * * -! * Rb = 2/ku* (Dair/Dg)**(2/3) eq.(12) * -! * where Dg is the gas diffusivity, and * -! * Dair is the air diffusivity. * -! * * -! * For aerosol species, Rb is combined with surface resistance as Rs. * -! * * -! **************************************************************************** - - frac = cz / obk - IF (frac > 1.0) frac = 1.0 - IF (frac > 0.0 .AND. frac <= 1.0) THEN - psi_h = -5.0*frac - ELSE IF (frac < 0.0) THEN - eps = MIN(1.0D0, -frac) - logmfrac = LOG(eps) - psi_h = EXP( 0.598 + 0.39 * logmfrac - 0.09 * (logmfrac)**2 ) - END IF - !-------------------------------------------------------------- - ! Aerosol species, Rs here is the combination of Rb and Rs. - - ra = (LOG(cz/z0(i,j)) - psi_h) / (vk*ustar(i,j)) - - vds = 0.002*ustar(i,j) - IF (obk < 0.0) & - vds = vds * (1.0+(-300.0/obk)**0.6667) - - czh = pblz(i,j)/obk - IF (czh < -30.0) vds = 0.0009*ustar(i,j)*(-czh)**0.6667 - - ! --Set Vds to be less than VDSMAX (entry in input file divided -- - ! by 1.E4). VDSMAX is taken from Table 2 of Walcek et al. [1986]. - ! Invert to get corresponding R - if(ii.eq.1)then - rs=1.0/MIN(vds,2.0D-2) - else - rs=1.0/MIN(vds,2.0D-3) - endif - - - ! ------ Set max and min values for bulk surface resistances ------ - - rs= MAX(1.0D0, MIN(rs, 9.9990D+3)) - -! **************************************************************************** -! * * -! * Compute dry deposition velocity. * -! * * -! * IUSE is the fraction of the grid square occupied by surface ldt in * -! * units of per mil (IUSE=500 -> 50% of the grid square). Add the * -! * contribution of surface type ldt to the deposition velocity; this is * -! * a loop over all surface types in the gridbox. * -! * * -! * Total resistance = Ra + Rb + Rs. -! * * -! **************************************************************************** - - rttl = ra + rb + rs - vd = vd + 1./rttl - - ! ------ Load array DVEL ------ - dvel(i,j) = vd * 1.2 - - ! -- Set a minimum value for DVEL - ! MIN(VdSO2) = 2.0e-3 m/s over ice - ! = 3.0e-3 m/s over land - ! MIN(vd_aerosol) = 1.0e-4 m/s - - IF (dvel(i,j) < 1.0E-4) dvel(i,j) = 1.0E-4 - drydf(i,j) = dvel(i,j) / delz_sfc(i,j) - - END DO i_loop - END DO j_loop - -END SUBROUTINE depvel_gocart - -end module dep_dry_gocart_mod diff --git a/smoke/dep_dry_mod.F90 b/smoke/dep_dry_mod.F90 deleted file mode 100755 index 9520d2897..000000000 --- a/smoke/dep_dry_mod.F90 +++ /dev/null @@ -1,303 +0,0 @@ -!>\file dep_dry_mod.F90 -!! This file is for the dry depostion driver. - -module dep_dry_mod - - use machine , only : kind_phys - use rrfs_smoke_config, only : epsilc, GOCART_SIMPLE => CHEM_OPT_GOCART, CTRA_OPT_NONE -! use chem_tracers_mod, only : p_o3,p_dust_1,p_vash_1,p_vash_4,p_vash_10,p_dms, -! & -! config_flags => chem_config - use dep_dry_gocart_mod - use dep_simple_mod - use dep_vertmx_mod -! use aero_soa_vbs_mod, only : soa_vbs_depdriver - - implicit none - - - private - - public :: dry_dep_driver - -contains - - subroutine dry_dep_driver(data,ktau,dtstep,julday,current_month,t_phy,p_phy, & - moist,p8w,rmol,alt,gmt,t8w,raincv, & - chem,rho_phy,dz8w,exch_h,hfx, & - ivgtyp,tsk,gsw,vegfra,pbl,ust,znt,z,z_at_w, & - xland,xlat,xlong,h2oaj,h2oai,nu3,ac3,cor3,asulf,ahno3, & - anh3,ddep,dep_vel_o3,g, & - e_co,kemit,snowh,numgas, & - num_chem,num_moist, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) -!---------------------------------------------------------------------- -! USE module_model_constants -! USE module_configure -! USE module_state_description -! USE module_dep_simple -! USE module_initial_chem_namelists,only:p_o3,p_dust_1,p_vash_1,p_vash_4,p_vash_10,p_dms -! USE module_vertmx_wrf -! USE module_chemvars,only:epsilc -! USE module_data_sorgam -! USE module_aerosols_sorgam -! USE module_gocart_settling -! use module_dep_simple -! USE module_gocart_drydep,only: gocart_drydep_driver -! USE module_aerosols_soa_vbs, only: soa_vbs_depdriver -! USE module_mosaic_drydep, only: mosaic_drydep_driver -! USE module_mixactivate_wrappers, only: mosaic_mixactivate, sorgam_mixactivate - IMPLICIT NONE - type(smoke_data), pointer, intent(inout) :: data - - INTEGER, INTENT(IN ) :: numgas, current_month, & - num_chem,num_moist, julday, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte - INTEGER, INTENT(IN ) :: & - ktau - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & - INTENT(IN ) :: moist - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), & - INTENT(INOUT ) :: chem - - INTEGER, INTENT(IN ) :: kemit - REAL(kind_phys), DIMENSION( ims:ime, kms:kemit, jms:jme ), & - INTENT(IN ) :: & - e_co - - - - - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) , & - INTENT(IN ) :: & - alt, & - t8w, & - dz8w, & - p8w,z_at_w , & - exch_h,rho_phy,z - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) , & - INTENT(INOUT) :: & - h2oaj,h2oai,nu3,ac3,cor3,asulf,ahno3,anh3 - INTEGER,DIMENSION( ims:ime , jms:jme ) , & - INTENT(IN ) :: & - ivgtyp - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) , & - INTENT(INOUT) :: & - tsk, & - gsw, & - vegfra, & - pbl, & - snowh, & - raincv, & - ust, & - hfx, & - xland, & - xlat, & - xlong, & - znt,rmol - REAL(kind_phys), DIMENSION( ims:ime, jms:jme, num_chem ), & - INTENT(OUT ) :: ddep - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) , & - INTENT(OUT) :: & - dep_vel_o3 - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & - INTENT(IN ) :: & - p_phy, & - t_phy - - REAL(kind_phys), INTENT(IN ) :: & - dtstep,g,gmt - -!--- deposition and emissions stuff -! .. Parameters .. -! .. -! .. Local Scalars .. - - REAL(kind_phys) :: cdt, factor - - INTEGER :: idrydep_onoff - -! INTEGER :: chem_conv_tr, chem_opt - -! CHARACTER (4) :: luse_typ,mminlu_loc -! .. -! .. Local Arrays .. - REAL(kind_phys), DIMENSION( its:ite, jts:jte, num_chem ) :: ddvel - -! REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) :: dryrho_phy - REAL(kind_phys), DIMENSION( kts:kte ) :: dryrho_1d - -! turbulent transport - real(kind_phys) :: pblst(kts:kte),ekmfull(kts:kte+1),zzfull(kts:kte+1),zz(kts:kte) - integer :: i,j,k,nv -! -! necessary for aerosols (module dependent) -! - REAL(kind_phys), DIMENSION( its:ite, jts:jte ) :: aer_res - REAL(kind_phys), DIMENSION( its:ite, jts:jte ) :: aer_res_def - REAL(kind_phys), DIMENSION( its:ite, jts:jte ) :: aer_res_zcen - -! .. -! .. Intrinsic Functions .. - INTRINSIC max, min - -! chem_opt = chem_opt -! chem_conv_tr = chem_conv_tr - -! -! compute dry deposition velocities = ddvel -! -! 28-jun-2005 rce - initialize ddvel=0; call aerosol drydep routine -! only when drydep_opt == WESELY -! the wesely_driver routine computes aer_res, and currently -! you cannot compute aerosol drydep without it !! -! 08-jul-2005 rce - pass idrydep_onoff to mixactivate routines -! -! write(6,*)'call dry dep driver' - dep_vel_o3(:,:)=0. - ddvel(:,:,:) = 0.0 - idrydep_onoff = 0 - -! drydep_select: SELECT CASE(drydep_opt) - -! CASE ( WESELY ) -! -! drydep_opt == WESELY means -! wesely for gases -! other (appropriate) routine for aerosols -! -! CALL wrf_debug(15,'DOING DRY DEP VELOCITIES WITH WESELY METHOD') - - IF( chem_opt /= GOCART_SIMPLE ) THEN - call wesely_driver(data,ktau,dtstep, & - current_month, & - gmt,julday,t_phy,moist,p8w,t8w,raincv, & - p_phy,chem,rho_phy,dz8w,ddvel,aer_res_def,aer_res_zcen, & - ivgtyp,tsk,gsw,vegfra,pbl,rmol,ust,znt,xlat,xlong,z,z_at_w,& - snowh,numgas, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - ENDIF - IF (( chem_opt == GOCART_SIMPLE ) .or. & - ( chem_opt == GOCARTRACM_KPP) .or. & - ( chem_opt == 316) .or. & - ( chem_opt == 317) .or. & -! ( chem_opt == 502) .or. & - (chem_opt == 304 )) then -! -! this does aerosol species (dust,seas, bc,oc) for gocart only -! this does aerosol species (dust,seas, bc,oc,sulf) for gocart only -!, - call gocart_drydep_driver(numgas, & - moist,p8w,chem,rho_phy,dz8w,ddvel,xland,hfx, & - ivgtyp,tsk,pbl,ust,znt,g, & - num_moist,num_chem, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - ELSE if (chem_opt == 501 ) then -! for caesium .1cm/s -! - ddvel(:,:,:)=.001 - ELSE if (chem_opt == 108 ) then -!! call soa_vbs_depdriver (ust,t_phy, & -!! moist,p8w,rmol,znt,pbl, & -!! alt,p_phy,chem,rho_phy,dz8w, & -!! h2oaj,h2oai,nu3,ac3,cor3,asulf,ahno3,anh3, & -!! aer_res,ddvel(:,:,numgas+1:num_chem), & -!! num_chem-numgas, & -!! ids,ide, jds,jde, kds,kde, & -!! ims,ime, jms,jme, kms,kme, & -!! its,ite, jts,jte, kts,kte ) -! limit aerosol ddvels to <= 0.5 m/s -! drydep routines occasionally produce unrealistically-large particle -! diameter leading to unrealistically-large sedimentation velocity - ddvel(:,:,numgas+1:num_chem) = min( 0.50, ddvel(:,:,numgas+1:num_chem)) - ELSE - !Set dry deposition velocity to zero when using the - !chemistry tracer mode. - ddvel(:,:,:) = 0. - END IF - idrydep_onoff = 1 - -! -! Compute dry deposition according to NGAC -! - cdt = real(dtstep, kind=kind_phys) - do nv = 1, num_chem - do j = jts, jte - do i = its, ite - factor = 1._kind_phys - exp(-ddvel(i,j,nv)*cdt/dz8w(i,kts,j)) - ddep(i,j,nv) = max(0.0, factor * chem(i,kts,j,nv)) & !ug/m2/s - * (p8w(i,kts,j)-p8w(i,kts+1,j))/g/dtstep - end do - end do - end do - - -! This will be called later from subgrd_transport_driver.F !!!!!!!! -! -! - do 100 j=jts,jte - do 100 i=its,ite - if(p_dust_1.gt.1)dep_vel_o3(i,j)=ddvel(i,j,p_dust_1) - pblst=0. -! -! -!-- start with vertical mixing -! - do k=kts,kte+1 - zzfull(k)=z_at_w(i,k,j)-z_at_w(i,kts,j) - enddo - - if (chem_conv_tr == CTRA_OPT_NONE) then - ekmfull = 0. - else - ekmfull(kts)=0. - do k=kts+1,kte - ekmfull(k)=max(1.e-6,exch_h(i,k,j)) - enddo - ekmfull(kte+1)=0. - end if - -!!$! UNCOMMENT THIS AND FINE TUNE LEVELS TO YOUR DOMAIN IF YOU WANT TO -!!$! FORCE MIXING TO A CERTAIN DEPTH: -!!$! -!!$! --- Mix the emissions up several layers -! - do k=kts,kte - zz(k)=z(i,k,j)-z_at_w(i,kts,j) - enddo -! vertical mixing routine (including deposition) -! need to be careful here with that dumm tracer in spot 1 -! do not need lho,lho2 -! (03-may-2006 rce - calc dryrho_1d and pass it to vertmx) -! -! if(p_o3.gt.1)dep_vel_o3(i,j)=ddvel(i,j,p_o3) - do nv=1,num_chem-0 - do k=kts,kte - pblst(k)=max(epsilc,chem(i,k,j,nv)) - dryrho_1d(k) = 1./alt(i,k,j) - enddo - - !mix_select: SELECT CASE(chem_opt) - !CASE DEFAULT - call vertmx(data,dtstep,pblst,ekmfull,dryrho_1d, & - zzfull,zz,ddvel(i,j,nv),kts,kte) - - !END SELECT mix_select - - do k=kts,kte - chem(i,k,j,nv)=max(epsilc,pblst(k)) - enddo - enddo -100 continue - -END SUBROUTINE dry_dep_driver - -end module dep_dry_mod diff --git a/smoke/dep_simple_mod.F90 b/smoke/dep_simple_mod.F90 deleted file mode 100755 index 37a8189b5..000000000 --- a/smoke/dep_simple_mod.F90 +++ /dev/null @@ -1,766 +0,0 @@ -!>\file dep_simple_mod.F90 -!! This file contains the Wesely dry deposition module. - -module dep_simple_mod - - use rrfs_smoke_data - use rrfs_smoke_config, GOCART_SIMPLE => CHEM_OPT_GOCART, chem_opt=>chem_opt -! use chem_tracers_mod, config_flags => chem_config - -! USE module_data_sorgam - - implicit none - -!-------------------------------------------------- -! .. Default Accessibility .. -!-------------------------------------------------- - PUBLIC - - - CONTAINS - -SUBROUTINE wesely_driver( data, ktau, dtstep, current_month, & - gmt, julday, t_phy,moist, p8w, t8w, raincv, & - p_phy, chem, rho_phy, dz8w, ddvel, aer_res_def, & - aer_res_zcen, ivgtyp, tsk, gsw, vegfra, pbl, & - rmol, ust, znt, xlat, xlong, & - z, z_at_w, snowh, numgas, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - implicit none -!-------------------------------------------------- -! Wesely dry dposition driver -!-------------------------------------------------- - -! USE module_model_constants -! USE module_wrf_control,only:num_moist,num_chem -! USE module_state_description -! USE module_initial_chem_namelists -! USE module_data_sorgam -! USE module_state_description, only: param_first_scalar - type(smoke_data), intent(inout), pointer :: data - INTEGER, INTENT(IN ) :: julday, & - numgas, current_month, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte - INTEGER, INTENT(IN ) :: ktau - REAL(kind_phys), INTENT(IN ) :: dtstep,gmt - -!-------------------------------------------------- -! advected moisture variables -!-------------------------------------------------- - REAL(KIND_PHYS), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), INTENT(IN ) :: & - moist -!-------------------------------------------------- -! advected chemical species -!-------------------------------------------------- - REAL(KIND_PHYS), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), INTENT(INOUT ) :: & - chem -!-------------------------------------------------- -! deposition velocities -!-------------------------------------------------- - REAL(KIND_PHYS), DIMENSION( its:ite, jts:jte, num_chem ), INTENT(INOUT ) :: & - ddvel -!-------------------------------------------------- -! input from met model -!-------------------------------------------------- - REAL(KIND_PHYS), DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: & - t_phy, & - p_phy, & - dz8w, & - z, & - t8w, & - p8w, & - z_at_w, & - rho_phy - INTEGER,DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: & - ivgtyp - REAL(KIND_PHYS), DIMENSION( ims:ime , jms:jme ), INTENT(INOUT ) :: & - tsk, & - gsw, & - vegfra, & - pbl, & - rmol, & - ust, & - xlat, & - xlong, & - raincv, & - znt - REAL(KIND_PHYS), intent(inout) :: aer_res_def(its:ite,jts:jte) - REAL(KIND_PHYS), intent(inout) :: aer_res_zcen(its:ite,jts:jte) - REAL(KIND_PHYS), INTENT(IN) :: snowh(ims:ime,jms:jme) - -!-------------------------------------------------- -! .. Local Scalars -!-------------------------------------------------- - REAL(kind_phys) :: clwchem, dvfog, dvpart, pa, rad, dep_vap - REAL(KIND_PHYS) :: rhchem, ta, ustar, vegfrac, z1, zntt - INTEGER :: i, iland, iprt, iseason, j, jce, jcs, n, nr, ipr,jpr,nvr - LOGICAL :: highnh3, rainflag, vegflag, wetflag -!-------------------------------------------------- -! .. Local Arrays -!-------------------------------------------------- - REAL(KIND_PHYS) :: p(kts:kte) - REAL(KIND_PHYS) :: srfres(numgas) - REAL(KIND_PHYS) :: ddvel0d(numgas) - -!----------------------------------------------------------- -! necessary for aerosols (module dependent) -!----------------------------------------------------------- - real(kind_phys) :: rcx(numgas) - - -!----------------------------------------------------------- -! .. Intrinsic Functions -!----------------------------------------------------------- -! integer :: chem_opt - - INTRINSIC max, min - - data => get_thread_smoke_data() - -! chem_opt = chem_opt - - dep_vap = depo_fact - !print*,'hli simple chem_opt',chem_opt - -! CALL wrf_debug(15,'in dry_dep_wesely') - - if( julday < 90 .or. julday > 270 ) then - iseason = 2 -! CALL wrf_debug(15,'setting iseason to 2') - else - iseason = 1 - endif - - -tile_lat_loop : & - do j = jts,jte -tile_lon_loop : & - do i = its,ite - iprt = 0 - - iland = luse2usgs( ivgtyp(i,j) ) -!-- - - ta = tsk(i,j) - rad = gsw(i,j) - vegfrac = vegfra(i,j) - pa = .01*p_phy(i,kts,j) - clwchem = moist(i,kts,j,p_qc) - ustar = ust(i,j) - zntt = znt(i,j) - z1 = z_at_w(i,kts+1,j) - z_at_w(i,kts,j) -!----------------------------------------------------------- -! Set logical default values -!----------------------------------------------------------- - rainflag = .FALSE. - wetflag = .FALSE. - highnh3 = .FALSE. -! if(p_qr > 1) then -! if(moist(i,kts,j,p_qr) > 1.e-18 .or. raincv(i,j) > 0.) then -! rainflag = .true. -! endif -! endif - rhchem = MIN( 100.,100. * moist(i,kts,j,p_qv) / & - (3.80*exp(17.27*(t_phy(i,kts,j)-273.)/(t_phy(i,kts,j)-36.))/pa)) - rhchem = MAX(5.,RHCHEM) - if (rhchem >= 95.) wetflag = .true. - -!----------------------------------------------------------- -!--- deposition -!----------------------------------------------------------- -! if(snowc(i,j).gt.0.)iseason=4 - CALL rc( data, rcx, ta, rad, rhchem, iland, & - iseason, numgas, wetflag, rainflag, highnh3, & - iprt, moist(i,kts,j,p_qv), p8w(i,kts,j) ) - srfres(1:numgas-2) = rcx(1:numgas-2) - srfres(numgas-1:numgas) = 0. - CALL deppart( data, rmol(i,j), ustar, rhchem, clwchem, iland, dvpart, dvfog ) - ddvel0d(1:numgas) = 0. - aer_res_def(i,j) = 0. - aer_res_zcen(i,j) = 0. - CALL landusevg( data, ddvel0d, ustar, rmol(i,j), zntt, z1, dvpart, iland, & - numgas, srfres, aer_res_def(i,j), aer_res_zcen(i,j), p_sulf ) - -!----------------------------------------------------------- -!wig: CBMZ does not have HO and HO2 last so need to copy all species -! ddvel(i,j,1:numgas-2)=ddvel0d(1:numgas-2) -!----------------------------------------------------------- - ddvel(i,j,1:numgas) = ddvel0d(1:numgas) - end do tile_lon_loop - end do tile_lat_loop - -!----------------------------------------------------------- -! For the additional CBMZ species, assign similar RADM counter parts for -! now. Short lived species get a zero velocity since dry dep should be -! unimportant. **ALSO**, treat p_sulf as h2so4 vapor, not aerosol sulfate -!----------------------------------------------------------- -! - -!----------------------------------------------------------- -! For gocartsimple : need msa. On the other hand sulf comes from aerosol routine -!----------------------------------------------------------- - if (chem_opt == GOCART_SIMPLE ) then - do j=jts,jte - do i=its,ite - ddvel(i,j,p_msa) = ddvel(i,j,p_sulf) - ddvel(i,j,p_sulf) = 0. - ddvel(i,j,p_dms) = 0. - end do - end do - end if - -END SUBROUTINE wesely_driver - - SUBROUTINE rc( data, rcx, t, rad, rh, iland, & - iseason, numgas, wetflag, rainflag, highnh3, & - iprt, spec_hum, p_srf ) -!---------------------------------------------------------------------- -! THIS SUBROUTINE CALCULATES SURFACE RESISTENCES ACCORDING -! TO THE MODEL OF -! M. L. WESELY, -! ATMOSPHERIC ENVIRONMENT 23 (1989), 1293-1304 -! WITH SOME ADDITIONS ACCORDING TO -! J. W. ERISMAN, A. VAN PUL, AND P. WYERS, -! ATMOSPHERIC ENVIRONMENT 28 (1994), 2595-2607 -! WRITTEN BY WINFRIED SEIDL, APRIL 1997 -! MODYFIED BY WINFRIED SEIDL, MARCH 2000 -! FOR MM5 VERSION 3 -!---------------------------------------------------------------------- - -! USE module_state_description -! USE module_initial_chem_namelists - implicit none - type(smoke_data), pointer, intent(inout) :: data -!---------------------------------------------------------------------- -! ... dummy arguments -!---------------------------------------------------------------------- - INTEGER, intent(in) :: iland, iseason, numgas - INTEGER, intent(in) :: iprt - REAL(KIND_PHYS), intent(in) :: rad, rh - REAL(KIND_PHYS), intent(in) :: t ! surface temp (K) - REAL(KIND_PHYS), intent(in) :: p_srf ! surface pressure (Pa) - REAL(KIND_PHYS), intent(in) :: spec_hum ! surface specific humidity (kg/kg) - real(kind_phys), intent(out) :: rcx(numgas) - LOGICAL, intent(in) :: highnh3, rainflag, wetflag - -!---------------------------------------------------------------------- -! .. Local Scalars .. -!---------------------------------------------------------------------- - REAL(KIND_PHYS), parameter :: t0 = 298. - REAL(KIND_PHYS), parameter :: tmelt = 273.16 - INTEGER :: lt, n - INTEGER :: chem_opt - REAL(KIND_PHYS) :: rclx, rdc, resice, rgsx, rluo1, rluo2 - REAL(KIND_PHYS) :: rlux, rmx, rs, rsmx, rdtheta, z, wrk - REAL(KIND_PHYS) :: qs, es, ws, dewm, dv_pan, drat - REAL(KIND_PHYS) :: crs, tc - REAL(KIND_PHYS) :: rs_pan, tc_pan - LOGICAL :: has_dew -!---------------------------------------------------------------------- -! .. Local Arrays .. -!---------------------------------------------------------------------- - REAL(KIND_PHYS) :: hstary(numgas) - -!---------------------------------------------------------------------- -! .. Intrinsic Functions .. -!---------------------------------------------------------------------- - INTRINSIC exp - - chem_opt = chem_opt - - rcx(1:numgas) = 1. - - tc = t - 273.15 - rdtheta = 0. - - z = 200./(rad+0.1) - -!!! HARDWIRE VALUES FOR TESTING -! z=0.4727409 -! tc=22.76083 -! t=tc+273.15 -! rad = 412.8426 -! rainflag=.false. -! wetflag=.false. - - IF ( tc<=0. .OR. tc>=40. ) THEN - rs = 9999. - ELSE - rs = data%ri(iland,iseason)*(1+z*z)*(400./(tc*(40.-tc))) - END IF - rdc = 100.*(1. + 1000./(rad + 10.))/(1. + 1000.*rdtheta) - rluo1 = 1./(1./3000. + 3./data%rlu(iland,iseason)) - rluo2 = 1./(1./1000. + 3./data%rlu(iland,iseason)) - resice = 1000.*exp( -(tc + 4.) ) - wrk = (t0 - t)/(t0*t) - - - DO n = 1, numgas - IF( data%hstar(n) /= 0. ) then - hstary(n) = data%hstar(n)*exp( data%dhr(n)*wrk ) -!---------------------------------------------------------------------- -! SPECIAL TREATMENT FOR HNO3, HNO4, H2O2, PAA -!---------------------------------------------------------------------- - rmx = 1./(hstary(n)/3000. + 100.*data%f0(n)) - rsmx = rs*data%dratio(n) + rmx - rclx = 1./(1.e-5*hstary(n)/data%rcls(iland,iseason) & - + data%f0(n)/data%rclo(iland,iseason)) + resice - rgsx = 1./(1.e-5*hstary(n)/data%rgss(iland,iseason) & - + data%f0(n)/data%rgso(iland,iseason)) + resice - rlux = data%rlu(iland,iseason)/(1.e-5*hstary(n) + data%f0(n)) + resice - IF( wetflag ) THEN - rlux = 1./(1./(3.*data%rlu(iland,iseason)) + 1.e-7*hstary(n) + data%f0(n)/rluo1) - END IF - IF( rainflag ) THEN - rlux = 1./(1./(3.*data%rlu(iland,iseason)) + 1.e-7*hstary(n) + data%f0(n)/rluo2) - END IF - rcx(n) = 1./(1./rsmx + 1./rlux + 1./(rdc + rclx) + 1./(data%rac(iland,iseason) + rgsx)) - rcx(n) = max( 1.,rcx(n) ) - end IF - END DO - -!-------------------------------------------------- -! SPECIAL TREATMENT FOR OZONE -!-------------------------------------------------- -! SPECIAL TREATMENT FOR SO2 (Wesely) -! HSTARY(P_SO2)=DATA%HSTAR(P_SO2)*EXP(DATA%DHR(P_SO2)*(1./T-1./298.)) -! RMX=1./(HSTARY(P_SO2)/3000.+100.*DATA%F0(P_SO2)) -! RSMX=RS*DATA%DRATIO(P_SO2)+RMX -! RLUX=DATA%RLU(ILAND,ISEASON)/(1.E-5*HSTARY(P_SO2)+DATA%F0(P_SO2)) -! & +RESICE -! RCLX=DATA%RCLS(ILAND,ISEASON)+RESICE -! RGSX=DATA%RGSS(ILAND,ISEASON)+RESICE -! IF ((wetflag).OR.(RAINFLAG)) THEN -! IF (ILAND.EQ.1) THEN -! RLUX=50. -! ELSE -! RLUX=100. -! END IF -! END IF -! RCX(P_SO2)=1./(1./RSMX+1./RLUX+1./(RDC+RCLX) -! & +1./(DATA%RAC(ILAND,ISEASON)+RGSX)) -! IF (RCX(P_SO2).LT.1.) RCX(P_SO2)=1. - -!-------------------------------------------------- -! SO2 according to Erisman et al. 1994 -! R_STOM -!-------------------------------------------------- -is_so2 : & - if( p_so2 > 1 ) then - rsmx = rs*data%dratio(p_so2) -!-------------------------------------------------- -! R_EXT -!-------------------------------------------------- - IF (tc> -1. ) THEN - IF (rh<81.3) THEN - rlux = 25000.*exp(-0.0693*rh) - ELSE - rlux = 0.58E12*exp(-0.278*rh) - END IF - END IF - IF (((wetflag) .OR. (rainflag)) .AND. (tc> -1. )) THEN - rlux = 1. - END IF - IF ((tc>= -5. ) .AND. (tc<= -1. )) THEN - rlux = 200. - END IF - IF (tc< -5. ) THEN - rlux = 500. - END IF -!-------------------------------------------------- -! INSTEAD OF R_INC R_CL and R_DC of Wesely are used -!-------------------------------------------------- - rclx = data%rcls(iland,iseason) -!-------------------------------------------------- -! DRY SURFACE -!-------------------------------------------------- - rgsx = 1000. -!-------------------------------------------------- -! WET SURFACE -!-------------------------------------------------- - IF ((wetflag) .OR. (rainflag)) THEN - IF (highnh3) THEN - rgsx = 0. - ELSE - rgsx = 500. - END IF - END IF -!-------------------------------------------------- -! WATER -!-------------------------------------------------- - IF (iland==iswater_temp) THEN - rgsx = 0. - END IF -!-------------------------------------------------- -! SNOW -!-------------------------------------------------- - IF( iseason==4 .OR. iland==isice_temp ) THEN - IF( tc > 2. ) THEN - rgsx = 0. - else IF ( tc >= -1. .AND. tc <= 2. ) THEN - rgsx = 70.*(2. - tc) - else IF ( tc < -1. ) THEN - rgsx = 500. - END IF - END IF -!-------------------------------------------------- -! TOTAL SURFACE RESISTENCE -!-------------------------------------------------- - IF ((iseason/=4) .AND. (data%ixxxlu(iland)/=1) .AND. (iland/=iswater_temp) .AND. & - (iland/=isice_temp)) THEN - rcx(p_so2) = 1./(1./rsmx+1./rlux+1./(rclx+rdc+rgsx)) - ELSE - rcx(p_so2) = rgsx - END IF - rcx(p_so2) = max( 1.,rcx(p_so2) ) - end if is_so2 -!-------------------------------------------------- -! NH3 according to Erisman et al. 1994 -! R_STOM -!-------------------------------------------------- - END SUBROUTINE rc - - SUBROUTINE deppart( data, rmol, ustar, rh, clw, iland, & - dvpart, dvfog ) -!-------------------------------------------------- -! THIS SUBROUTINE CALCULATES SURFACE DEPOSITION VELOCITIES -! FOR FINE AEROSOL PARTICLES ACCORDING TO THE MODEL OF -! J. W. ERISMAN, A. VAN PUL, AND P. WYERS, -! ATMOSPHERIC ENVIRONMENT 28 (1994), 2595-2607 -! WRITTEN BY WINFRIED SEIDL, APRIL 1997 -! MODIFIED BY WINFRIED SEIDL, MARCH 2000 -! FOR MM5 VERSION 3 -!-------------------------------------------------- - implicit none - type(smoke_data), pointer, intent(inout) :: data - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - INTEGER, intent(in) :: iland - REAL(KIND_PHYS), intent(in) :: clw, rh, rmol, ustar - REAL(KIND_PHYS), intent(out) :: dvfog, dvpart - -!-------------------------------------------------- -! .. Intrinsic Functions .. -!-------------------------------------------------- - INTRINSIC exp - - dvpart = ustar/data%kpart(iland) - IF (rmol<0.) THEN -!-------------------------------------------------- -! UNSTABLE LAYERING CORRECTION -!-------------------------------------------------- - dvpart = dvpart*(1.+(-300.*rmol)**0.66667) - END IF - IF (rh>80.) THEN -!-------------------------------------------------- -! HIGH RELATIVE HUMIDITY CORRECTION -! ACCORDING TO J. W. ERISMAN ET AL. -! ATMOSPHERIC ENVIRONMENT 31 (1997), 321-332 -!-------------------------------------------------- - dvpart = dvpart*(1.+0.37*exp((rh-80.)/20.)) - END IF - -!-------------------------------------------------- -! SEDIMENTATION VELOCITY OF FOG WATER ACCORDING TO -! R. FORKEL, W. SEIDL, R. DLUGI AND E. DEIGELE -! J. GEOPHYS. RES. 95D (1990), 18501-18515 -!-------------------------------------------------- - dvfog = 0.06*clw - IF (data%ixxxlu(iland)==5) THEN -!-------------------------------------------------- -! TURBULENT DEPOSITION OF FOG WATER IN CONIFEROUS FOREST ACCORDI -! A. T. VERMEULEN ET AL. -! ATMOSPHERIC ENVIRONMENT 31 (1997), 375-386 -!-------------------------------------------------- - dvfog = dvfog + 0.195*ustar*ustar - END IF - - END SUBROUTINE deppart - - SUBROUTINE landusevg( data, vgs, ustar, rmol, z0, zz, & - dvparx, iland, numgas, srfres, aer_res_def, & - aer_res_zcen, p_sulf ) -!-------------------------------------------------- -! This subroutine calculates the species specific deposition velocit -! as a function of the local meteorology and land use. The depositi -! Velocity is also landuse specific. -! Reference: Hsieh, C.M., Wesely, M.L. and Walcek, C.J. (1986) -! A Dry Deposition Module for Regional Acid Deposition -! EPA report under agreement DW89930060-01 -! Revised version by Darrell Winner (January 1991) -! Environmental Engineering Science 138-78 -! California Institute of Technology -! Pasadena, CA 91125 -! Modified by Winfried Seidl (August 1997) -! Fraunhofer-Institut fuer Atmosphaerische Umweltforschung -! Garmisch-Partenkirchen, D-82467 -! for use of Wesely and Erisman surface resistances -! Inputs: -! Ustar : The grid average friction velocity (m/s) -! Rmol : Reciprocal of the Monin-Obukhov length (1/m) -! Z0 : Surface roughness height for the grid square (m) -! SrfRes : Array of landuse/atmospheric/species resistances (s/m) -! Slist : Array of chemical species codes -! Dvparx : Array of surface deposition velocity of fine aerosol p -! Outputs: -! Vgs : Array of species and landuse specific deposition -! velocities (m/s) -! Vg : Cell-average deposition velocity by species (m/s) -! Variables used: -! SCPR23 : (Schmidt #/Prandtl #)**(2/3) Diffusion correction fac -! Zr : Reference Height (m) -! Iatmo : Parameter specifying the stabilty class (Function of -! Z0 : Surface roughness height (m) -! karman : Von Karman constant (from module_model_constants) -!-------------------------------------------------- - -! USE module_model_constants, only: karman - implicit none - - type(smoke_data), pointer, intent(inout) :: data - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - INTEGER, intent(in) :: iland, numgas, p_sulf - REAL(KIND_PHYS), intent(in) :: dvparx, ustar, z0, zz - REAL(KIND_PHYS), intent(inout) :: rmol - REAL(KIND_PHYS), intent(inout) :: aer_res_def - REAL(KIND_PHYS), intent(inout) :: aer_res_zcen -!-------------------------------------------------- -! .. Array Arguments .. -!-------------------------------------------------- - REAL(KIND_PHYS), intent(in) :: srfres(numgas) - REAL(KIND_PHYS), intent(out) :: vgs(numgas) - -!-------------------------------------------------- -! .. Local Scalars .. -!-------------------------------------------------- - INTEGER :: jspec - REAL(KIND_PHYS) :: vgp, vgpart, zr - REAL(KIND_PHYS) :: rmol_tmp -!-------------------------------------------------- -! .. Local Arrays .. -!-------------------------------------------------- - REAL(KIND_PHYS) :: vgspec(numgas) - -!-------------------------------------------------- -! Calculate aerodynamic resistance for reference -! height = layer center -!-------------------------------------------------- - zr = zz*.5 - rmol_tmp = rmol - CALL depvel( data, numgas, rmol_tmp, zr, z0, ustar, & - vgspec, vgpart, aer_res_zcen ) -!-------------------------------------------------- -! Set the reference height (2.0 m) -!-------------------------------------------------- -! zr = 10.0 - zr = 2.0 - -!-------------------------------------------------- -! CALCULATE THE DEPOSITION VELOCITY without any surface -! resistance term, i.e. 1 / (ra + rb) -!-------------------------------------------------- - CALL depvel( data, numgas, rmol, zr, z0, ustar, & - vgspec, vgpart, aer_res_def ) - -!-------------------------------------------------- -! Calculate the deposition velocity for each species -! and grid cell by looping through all the possibile combinations -! of the two -!-------------------------------------------------- - vgp = 1.0/((1.0/vgpart)+(1.0/dvparx)) -!-------------------------------------------------- -! Loop through the various species -!-------------------------------------------------- - DO jspec = 1, numgas -!-------------------------------------------------- -! Add in the surface resistance term, rc (SrfRes) -!-------------------------------------------------- - vgs(jspec) = 1.0/(1.0/vgspec(jspec) + srfres(jspec)) - END DO - vgs(p_sulf) = vgp - - CALL cellvg( data, vgs, ustar, zz, zr, rmol, numgas ) - - END SUBROUTINE landusevg - - SUBROUTINE cellvg( data, vgtemp, ustar, dz, zr, rmol, nspec ) -!-------------------------------------------------- -! THIS PROGRAM HAS BEEN DESIGNED TO CALCULATE THE CELL AVERAGE -! DEPOSITION VELOCITY GIVEN THE VALUE OF VG AT SOME REFERENCE -! HEIGHT ZR WHICH IS MUCH SMALLER THAN THE CELL HEIGHT DZ. -! PROGRAM WRITTEN BY GREGORY J.MCRAE (NOVEMBER 1977) -! Modified by Darrell A. Winner (February 1991) -!.....PROGRAM VARIABLES... -! VgTemp - DEPOSITION VELOCITY AT THE REFERENCE HEIGHT -! USTAR - FRICTION VELOCITY -! RMOL - RECIPROCAL OF THE MONIN-OBUKHOV LENGTH -! ZR - REFERENCE HEIGHT -! DZ - CELL HEIGHT -! CELLVG - CELL AVERAGE DEPOSITION VELOCITY -! VK - VON KARMAN CONSTANT -!-------------------------------------------------- - -! USE module_model_constants, only: karman - implicit none - type(smoke_data), pointer, intent(inout) :: data - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - INTEGER, intent(in) :: nspec - REAL(KIND_PHYS), intent(in) :: dz, rmol, ustar, zr -!-------------------------------------------------- -! .. Array Arguments .. -!-------------------------------------------------- - REAL(KIND_PHYS), intent(out) :: vgtemp(nspec) -!-------------------------------------------------- -! .. Local Scalars .. -!-------------------------------------------------- - INTEGER :: nss - REAL(KIND_PHYS) :: a, fac, pdz, pzr, vk -!-------------------------------------------------- -! .. Intrinsic Functions .. -!-------------------------------------------------- - INTRINSIC alog, sqrt - -!-------------------------------------------------- -! Set the von Karman constant -!-------------------------------------------------- - vk = karman - -!-------------------------------------------------- -! DETERMINE THE STABILITY BASED ON THE CONDITIONS -! 1/L < 0 UNSTABLE -! 1/L = 0 NEUTRAL -! 1/L > 0 STABLE -!-------------------------------------------------- - DO nss = 1, nspec - IF (rmol < 0.) THEN - pdz = sqrt(1.0 - 9.0*dz*rmol) - pzr = sqrt(1.0 - 9.0*zr*rmol) - fac = ((pdz - 1.0)/(pzr - 1.0))*((pzr + 1.0)/(pdz + 1.0)) - a = 0.74*dz*alog(fac) + (0.164/rmol)*(pdz-pzr) - ELSE IF (rmol == 0.) THEN - a = 0.74*(dz*alog(dz/zr) - dz + zr) - ELSE - a = 0.74*(dz*alog(dz/zr) - dz + zr) + (2.35*rmol)*(dz - zr)**2 - END IF -!-------------------------------------------------- -! CALCULATE THE DEPOSITION VELOCITIY -!-------------------------------------------------- - vgtemp(nss) = vgtemp(nss)/(1.0 + vgtemp(nss)*a/(vk*ustar*(dz - zr))) - END DO - - END SUBROUTINE cellvg - - SUBROUTINE depvel( data, numgas, rmol, zr, z0, ustar, & - depv, vgpart, aer_res ) -!-------------------------------------------------- -! THIS FUNCTION HAS BEEN DESIGNED TO EVALUATE AN UPPER LIMIT -! FOR THE POLLUTANT DEPOSITION VELOCITY AS A FUNCTION OF THE -! SURFACE ROUGHNESS AND METEOROLOGICAL CONDITIONS. -! PROGRAM WRITTEN BY GREGORY J.MCRAE (NOVEMBER 1977) -! Modified by Darrell A. Winner (Feb. 1991) -! by Winfried Seidl (Aug. 1997) -!.....PROGRAM VARIABLES... -! RMOL - RECIPROCAL OF THE MONIN-OBUKHOV LENGTH -! ZR - REFERENCE HEIGHT -! Z0 - SURFACE ROUGHNESS HEIGHT -! SCPR23 - (Schmidt #/Prandtl #)**(2/3) Diffusion correction fact -! UBAR - ABSOLUTE VALUE OF SURFACE WIND SPEED -! DEPVEL - POLLUTANT DEPOSITION VELOCITY -! Vk - VON KARMAN CONSTANT -! USTAR - FRICTION VELOCITY U* -! POLINT - POLLUTANT INTEGRAL -! AER_RES - AERODYNAMIC RESISTANCE -!.....REFERENCES... -! MCRAE, G.J. ET AL. (1983) MATHEMATICAL MODELING OF PHOTOCHEMICAL -! AIR POLLUTION, ENVIRONMENTAL QUALITY LABORATORY REPORT 18, -! CALIFORNIA INSTITUTE OF TECHNOLOGY, PASADENA, CALIFORNIA. -!.....RESTRICTIONS... -! 1. THE MODEL EDDY DIFFUSIVITIES ARE BASED ON MONIN-OBUKHOV -! SIMILARITY THEORY AND SO ARE ONLY APPLICABLE IN THE -! SURFACE LAYER, A HEIGHT OF O(30M). -! 2. ALL INPUT UNITS MUST BE CONSISTENT -! 3. THE PHI FUNCTIONS USED TO CALCULATE THE FRICTION -! VELOCITY U* AND THE POLLUTANT INTEGRALS ARE BASED -! ON THE WORK OF BUSINGER ET AL.(1971). -! 4. THE MOMENTUM AND POLLUTANT DIFFUSIVITIES ARE NOT -! THE SAME FOR THE CASES L<0 AND L>0. -!-------------------------------------------------- - -! USE module_model_constants, only: karman - implicit none - type(smoke_data), pointer, intent(inout) :: data - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - INTEGER, intent(in) :: numgas - REAL(KIND_PHYS), intent(in) :: ustar, z0, zr - REAL(KIND_PHYS), intent(out) :: vgpart, aer_res - REAL(KIND_PHYS), intent(inout) :: rmol -!-------------------------------------------------- -! .. Array Arguments .. -!-------------------------------------------------- - REAL(KIND_PHYS), intent(out) :: depv(numgas) -!-------------------------------------------------- -! .. Local Scalars .. -!-------------------------------------------------- - INTEGER :: l - REAL(KIND_PHYS) :: ao, ar, polint, vk -!-------------------------------------------------- -! .. Intrinsic Functions .. -!-------------------------------------------------- - INTRINSIC alog -!-------------------------------------------------- -! Set the von Karman constant -!-------------------------------------------------- - vk = karman - -!-------------------------------------------------- -! Calculate the diffusion correction factor -! SCPR23 is calculated as (Sc/Pr)**(2/3) using Sc= 1.15 and Pr= 1.0 -! DATA%SCPR23 = 1.10 -!-------------------------------------------------- -! DETERMINE THE STABILITY BASED ON THE CONDITIONS -! 1/L < 0 UNSTABLE -! 1/L = 0 NEUTRAL -! 1/L > 0 STABLE -!-------------------------------------------------- - - if(abs(rmol) < 1.E-6 ) rmol = 0. - - IF (rmol<0) THEN - ar = ((1.0-9.0*zr*rmol)**(0.25)+0.001)**2 - ao = ((1.0-9.0*z0*rmol)**(0.25)+0.001)**2 - polint = 0.74*(alog((ar-1.0)/(ar+1.0))-alog((ao-1.0)/(ao+1.0))) - ELSE IF (rmol==0.) THEN - polint = 0.74*alog(zr/z0) - ELSE - polint = 0.74*alog(zr/z0) + 4.7*rmol*(zr-z0) - END IF - -!-------------------------------------------------- -! CALCULATE THE Maximum DEPOSITION VELOCITY -!-------------------------------------------------- - DO l = 1, numgas - depv(l) = ustar*vk/(2.0*data%scpr23(l)+polint) - END DO - vgpart = ustar*vk/polint - aer_res = polint/(karman*max(ustar,1.0e-4)) - - END SUBROUTINE depvel - - ! NOTE: dep_init is now in rrfs_smoke_data - -end module dep_simple_mod diff --git a/smoke/dep_vertmx_mod.F90 b/smoke/dep_vertmx_mod.F90 deleted file mode 100755 index d56b1b87e..000000000 --- a/smoke/dep_vertmx_mod.F90 +++ /dev/null @@ -1,212 +0,0 @@ -!>\file dep_vertmx_mod.F90 -!! This file calculates change in time of phi due to vertical mixing and dry deposition. - -MODULE dep_vertmx_mod - use rrfs_smoke_data - use machine , only : kind_phys - -CONTAINS - -!----------------------------------------------------------------------- - SUBROUTINE vertmx( data, dt, phi, kt_turb, dryrho, & - zsigma, zsigma_half, vd, kts, ktem1 ) -! !! purpose - calculate change in time of phi due to vertical mixing -! !! and dry deposition (for 1 species, 1 vertical column, 1 time step) -! !! Mariusz Pagowski, March 2001 -! !! conventions used: -! !! input is lower case -! !! output is upper case -! -! !! modifications by R Easter, May 2006 -! !! added dryrho so this routine conserves column mass burde -! !! when dry deposition velocity is zero -! !! changed "kte" to "ktem1" for consistency with the kte in WRF -! -! ARGUMENTS -! -! dt = time step (s) -! phi = initial/final (at input/output) species mixing ratios at "T" points -! kt_turb = turbulent exchange coefficients (m^2/s) at "W" points -! dryrho = dry air density (kg/m^3) at "T" points -! zsigma = heights (m) at "W" points -! zsigma_half = heights (m) at "T" points -! vd = dry deposition velocity (m/s) -! kts, ktem1 = vertical indices of bottom and top "T" points -! - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - -! .. Scalar Arguments .. - INTEGER, INTENT(IN) :: kts,ktem1 - REAL(KIND=KIND_PHYS), INTENT(IN) :: dt, vd -! .. -! .. Array Arguments .. - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1+1) :: kt_turb, zsigma - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: dryrho, zsigma_half - REAL(KIND=KIND_PHYS), INTENT(INOUT), DIMENSION (kts:ktem1) :: phi -! .. -! .. Local Scalars .. - INTEGER :: k -! .. -! .. Local Arrays .. - REAL(KIND=KIND_PHYS), DIMENSION (kts+1:ktem1) :: a_coeff - REAL(KIND=KIND_PHYS), DIMENSION (kts:ktem1) :: b_coeff, lhs1, lhs2, lhs3, rhs -! .. -! .. External Subroutines .. -! EXTERNAL coeffs, rlhside, tridiag -! .. - CALL coeffs( data, kts, ktem1, dryrho, zsigma, zsigma_half, a_coeff, b_coeff ) - - CALL rlhside( data, kts, ktem1, kt_turb, dryrho, a_coeff, b_coeff, & - phi, dt, vd, rhs, lhs1, lhs2, lhs3 ) - - CALL tridiag( data, kts, ktem1, lhs1, lhs2, lhs3, rhs ) - - DO k = kts,ktem1 - phi(k) = rhs(k) - END DO - - END SUBROUTINE vertmx - - -!----------------------------------------------------------------------- - SUBROUTINE rlhside( data, kts, ktem1, k_turb, dryrho, a_coeff, b_coeff, & - phi, dt, vd, rhs, lhs1, lhs2, lhs3 ) - !! to calculate right and left hand sides in diffusion equation - !! for the tridiagonal solver - !! Mariusz Pagowski, March 2001 - !! conventions used: - !! input is lower case - !! output is upper case - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - -! .. Scalar Arguments .. - INTEGER, INTENT(IN) :: kts,ktem1 - REAL(KIND=KIND_PHYS), INTENT(IN) :: dt, vd -! .. -! .. Array Arguments .. - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1+1) :: k_turb - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts+1:ktem1) :: a_coeff - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: b_coeff, dryrho - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: phi - REAL(KIND=KIND_PHYS), INTENT(OUT), DIMENSION (kts:ktem1) :: lhs1, lhs2, lhs3, rhs -! .. -! .. Local Scalars .. - !REAL(KIND_PHYS) :: a1, a2, alfa_explicit = .25, beta_implicit = .75 - REAL(KIND_PHYS) :: a1, a2, alfa_explicit = .0, beta_implicit = 1. - INTEGER :: i - -! .. - i = kts - a2 = a_coeff(i+1)*k_turb(i+1) - rhs(i) = (1./(dt*b_coeff(i)) - alfa_explicit*(vd*dryrho(i)+a2))*phi(i) + & - alfa_explicit*(a2*phi(i+1)) - lhs1(i) = 0. - lhs2(i) = 1./(dt*b_coeff(i)) + beta_implicit*(vd*dryrho(i)+a2) - lhs3(i) = -beta_implicit*a2 - - DO i = kts+1, ktem1-1 - a1 = a_coeff(i)*k_turb(i) - a2 = a_coeff(i+1)*k_turb(i+1) - - rhs(i) = (1./(dt*b_coeff(i)) - alfa_explicit*(a1+a2))*phi(i) + & - alfa_explicit*(a1*phi(i-1) + a2*phi(i+1)) - - lhs1(i) = -beta_implicit*a1 - lhs2(i) = 1./(dt*b_coeff(i)) + beta_implicit*(a1+a2) - lhs3(i) = -beta_implicit*a2 - END DO - - i = ktem1 - a1 = a_coeff(i)*k_turb(i) - rhs(i) = (1./(dt*b_coeff(i)) - alfa_explicit*(a1 ))*phi(i) + & - alfa_explicit*(a1*phi(i-1)) - lhs1(i) = -beta_implicit*a1 - lhs2(i) = 1./(dt*b_coeff(i)) + beta_implicit*(a1 ) - lhs3(i) = 0. - - END SUBROUTINE rlhside - - -!----------------------------------------------------------------------- - SUBROUTINE tridiag( data, kts, ktem1, a, b, c, f ) - !! to solve system of linear eqs on tridiagonal matrix n times n - !! after Peaceman and Rachford, 1955 - !! a,b,c,F - are vectors of order n - !! a,b,c - are coefficients on the LHS - !! F - is initially RHS on the output becomes a solution vector - !! Mariusz Pagowski, March 2001 - !! conventions used: - !! input is lower case - !! output is upper case - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - -! .. Scalar Arguments .. - INTEGER, INTENT(IN) :: kts,ktem1 -! .. -! .. Array Arguments .. - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: a, b, c - REAL(KIND=KIND_PHYS), INTENT(INOUT), DIMENSION (kts:ktem1) :: f -! .. -! .. Local Scalars .. - REAL(KIND_PHYS) :: p - INTEGER :: i -! .. -! .. Local Arrays .. - REAL(KIND=KIND_PHYS), DIMENSION (kts:ktem1) :: q -! .. - q(kts) = -c(kts)/b(kts) - f(kts) = f(kts)/b(kts) - - DO i = kts+1, ktem1 - p = 1./(b(i)+a(i)*q(i-1)) - q(i) = -c(i)*p - f(i) = (f(i)-a(i)*f(i-1))*p - END DO - - DO i = ktem1 - 1, kts, -1 - f(i) = f(i) + q(i)*f(i+1) - END DO - - END SUBROUTINE tridiag - - -!----------------------------------------------------------------------- - SUBROUTINE coeffs( data, kts, ktem1, dryrho, & - z_sigma, z_sigma_half, a_coeff, b_coeff ) -! !! to calculate coefficients in diffusion equation -! !! Mariusz Pagowski, March 2001 -! !! conventions used: -! !! input is lower case -! !! output is upper case -! .. Scalar Arguments .. - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - - INTEGER, INTENT(IN) :: kts,ktem1 -! .. -! .. Array Arguments .. - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1+1) :: z_sigma - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: z_sigma_half, dryrho - REAL(KIND=KIND_PHYS), INTENT(OUT), DIMENSION (kts+1:ktem1) :: a_coeff - REAL(KIND=KIND_PHYS), INTENT(OUT), DIMENSION (kts:ktem1) :: b_coeff -! .. -! .. Local Scalars .. - INTEGER :: i - REAL(KIND=KIND_PHYS) :: dryrho_at_w -! .. - DO i = kts, ktem1 - b_coeff(i) = 1./(dryrho(i)*(z_sigma(i+1)-z_sigma(i))) - END DO - - DO i = kts+1, ktem1 - dryrho_at_w = 0.5*(dryrho(i)+dryrho(i-1)) - a_coeff(i) = dryrho_at_w/(z_sigma_half(i)-z_sigma_half(i-1)) - END DO - - END SUBROUTINE coeffs - -!----------------------------------------------------------------------- -END MODULE dep_vertmx_mod diff --git a/smoke/dep_wet_ls_mod.F90 b/smoke/dep_wet_ls_mod.F90 deleted file mode 100755 index 3a7a186ea..000000000 --- a/smoke/dep_wet_ls_mod.F90 +++ /dev/null @@ -1,562 +0,0 @@ -!>\file dep_wet_ls_mod.F90 -!! This file contains aerosol wet deposition module. - -module dep_wet_ls_mod - use rrfs_smoke_data - use machine , only : kind_phys - use rrfs_smoke_config -! use chem_tracers_mod -! use chem_rc_mod -! use chem_tracers_mod -! use chem_const_mod, only : grav => grvity - - implicit none - - ! -- large scale wet deposition scavenging factors - - private - - public :: dep_wet_ls_init - public :: wetdep_ls - public :: WetRemovalGOCART - -contains - -! subroutine dep_wet_ls_init(config, rc) - subroutine dep_wet_ls_init(data) - implicit none - type(smoke_data), intent(inout) :: data - - ! -- I/O arguments -! type(chem_config_type), intent(in) :: config -! integer, intent(out) :: rc - - ! -- local variables - integer :: ios, n - - ! -- begin - !rc = CHEM_RC_SUCCESS - - ! -- set aerosol wet scavenging coefficients - if (associated(data%alpha)) then - deallocate(data%alpha, stat=ios) - !if (chem_rc_test((ios /= 0), msg="Failed to deallocate memory", & - ! file=__FILE__, line=__LINE__, rc=rc)) return - end if - - allocate(data%alpha(num_chem), stat=ios) - !if (chem_rc_test((ios /= 0), msg="Failed to allocate memory", & - ! file=__FILE__, line=__LINE__, rc=rc)) return - - data%alpha = 0. - - select case (wetdep_ls_opt) - case (WDLS_OPT_GSD) - - select case (chem_opt) - case (CHEM_OPT_GOCART) - data%alpha = 1.0 - end select - - case (WDLS_OPT_NGAC) - - select case (chem_opt) - case (CHEM_OPT_GOCART) - data%alpha(p_so2 ) = 0. - data%alpha(p_sulf ) = 1.5 - data%alpha(p_dms ) = 0. - data%alpha(p_msa ) = 0. - data%alpha(p_p25 ) = 1. - data%alpha(p_bc1 ) = 0.7 - data%alpha(p_bc2 ) = 0.7 - data%alpha(p_oc1 ) = 1. - data%alpha(p_oc2 ) = 1. - data%alpha(p_dust_1) = 1. - data%alpha(p_dust_2) = 1. - data%alpha(p_dust_3) = 1. - data%alpha(p_dust_4) = 1. - data%alpha(p_dust_5) = 1. - data%alpha(p_seas_1) = 1. - data%alpha(p_seas_2) = 1. - data%alpha(p_seas_3) = 1. - data%alpha(p_seas_4) = 1. - data%alpha(p_seas_5) = 1. - data%alpha(p_p10 ) = 1. - case default - ! -- NGAC large scale wet deposition only works with GOCART - end select - - case default - end select - - ! -- replace first default wet scavenging coefficients with input values if - ! available - if (any(wetdep_ls_alpha > 0._kind_phys)) then - n = min(size(data%alpha), size(wetdep_ls_alpha)) - data%alpha(1:n) = real(wetdep_ls_alpha(1:n)) - end if - - end subroutine dep_wet_ls_init - - - - subroutine wetdep_ls(data,dt,var,rain,moist,rho,var_rmv, & - num_moist,num_chem,p_qc,p_qi,dz8w,vvel, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - - INTEGER, INTENT(IN ) :: num_chem,num_moist,p_qc, p_qi, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte - real(kind_phys), INTENT(IN ) :: dt - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & - INTENT(IN ) :: moist - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & - INTENT(IN ) :: rho,dz8w,vvel - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ,1:num_chem), & - INTENT(INOUT) :: var - REAL(kind_phys), DIMENSION( ims:ime, jms:jme ), & - INTENT(IN ) :: rain - REAL(kind_phys), DIMENSION( ims:ime , jms:jme,num_chem ), & - INTENT(INOUT ) :: var_rmv - REAL(kind_phys), DIMENSION( its:ite , jts:jte ) :: var_sum - REAL(kind_phys), DIMENSION( its:ite , kts:kte, jts:jte ) :: var_rmvl - REAL(kind_phys), DIMENSION( its:ite , jts:jte ) :: frc,var_sum_clw,rain_clw - real(kind_phys) :: dvar,factor,rho_water - integer :: nv,i,j,k - - rho_water = 1000. - var_rmv (:,:,:)=0. - - do nv=1,num_chem -! -! simple LS removal -! - -! -! proportionality constant -! - frc(:,:)=0.1 - do i=its,ite - do j=jts,jte - var_sum_clw(i,j)=0. - var_sum(i,j)=0. - var_rmvl(i,:,j)=0. - rain_clw(i,j)=0. - if(rain(i,j).gt.1.e-6)then -! convert rain back to rate -! - rain_clw(i,j)=rain(i,j)/dt -! total cloud water -! - do k=1,kte - dvar=max(0.,(moist(i,k,j,p_qc)+moist(i,k,j,p_qi))) - var_sum_clw(i,j)=var_sum_clw(i,j)+dvar - enddo - endif - enddo - enddo -! -! get rid of it -! - do i=its,ite - do j=jts,jte - if(rain(i,j).gt.1.e-6 .and. var_sum_clw(i,j).gt.1.e-10 ) then - do k=kts,kte - if(var(i,k,j,nv).gt.1.e-08 .and. (moist(i,k,j,p_qc)+moist(i,k,j,p_qi)).gt.1.e-8)then - factor = max(0.,frc(i,j)*rho(i,k,j)*dz8w(i,k,j)*vvel(i,k,j)) - dvar=max(0.,data%alpha(nv)*factor/(1+factor)*var(i,k,j,nv)) - dvar=min(dvar,var(i,k,j,nv)) - var_rmvl(i,k,j)=dvar - if((var(i,k,j,nv)-dvar).lt.1.e-16)then - dvar=var(i,k,j,nv)-1.e-16 - var_rmvl(i,k,j)=dvar !lzhang - var(i,k,j,nv)=var(i,k,j,nv)-dvar - else - var(i,k,j,nv)=var(i,k,j,nv)-dvar - endif - !var_rmv(i,j,nv)=var_rmv(i,j,nv)+var_rmvl(i,k,j) - !!convert wetdeposition into ug/m2/s - var_rmv(i,j,nv)=var_rmv(i,j,nv)+(var_rmvl(i,k,j)*rho(i,k,j)*dz8w(i,k,j)/dt) !lzhang - endif - enddo - var_rmv(i,j,nv)=max(0.,var_rmv(i,j,nv)) - endif - enddo - enddo - enddo - - end subroutine wetdep_ls - -!------------------------------------------------------------------------- -! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 ! -!------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: WetRemovalGOCART - Calculate aerosol wet removal due -! to large scale processes. -! -! !INTERFACE: -! - - subroutine WetRemovalGOCART ( data,i1, i2, j1, j2, k1, k2, n1, n2, cdt, & - num_chem, var_rmv, chem, ple, tmpu, & - rhoa, dqcond, precc, precl, grav, & - ims, ime, jms, jme, kms, kme) -! ims, ime, jms, jme, kms, kme, rc ) - -! !USES: - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - -! !INPUT PARAMETERS: - integer, intent(in) :: i1, i2, j1, j2, k1, k2, n1, n2, num_chem, & - ims, ime, jms, jme, kms, kme - real(kind_phys), intent(in) :: cdt, grav - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ,1:num_chem),& - INTENT(INOUT) :: chem - REAL(kind_phys), DIMENSION( ims:ime , jms:jme,num_chem ), & - INTENT(INOUT ) :: var_rmv !! tracer loss flux [kg m-2 s-1] - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme),& - INTENT(IN) :: ple, tmpu, rhoa, dqcond - real(kind_phys), dimension(ims:ime , jms:jme) , & - INTENT(IN) :: precc, precl ! cv, ls precip [mm day-1] - -! !OUTPUT PARAMETERS: -! integer, intent(out) :: rc ! Error return code: - ! 0 - all is well - ! 1 - - -! !DESCRIPTION: Calculates the updated species concentration due to wet -! removal. As written, intended to function for large -! scale (not convective) wet removal processes - -! -! !REVISION HISTORY: -! -! 08Jan2010 - Colarco, based on GOCART implementation, does not -! include any size dependent term -! -!EOP -!------------------------------------------------------------------------- - -! !Local Variables - character(len=*), parameter :: myname = 'WetRemovalGOCART' - integer :: i, j, k, n, nbins, LH, kk, ios,nv - real(kind_phys) :: pdog(i1:i2,k1:k2,j1:j2) ! air mass factor dp/g [kg m-2] - real(kind_phys) :: pls, pcv, pac ! ls, cv, tot precip [mm day-1] - real(kind_phys) :: qls(k1:k2), qcv(k1:k2) ! ls, cv portion dqcond [kg m-3 s-1] - real(kind_phys) :: qmx, qd, A ! temporary variables on moisture - real(kind_phys) :: F, B, BT ! temporary variables on cloud, freq. - real(kind_phys), allocatable :: fd(:,:) ! flux across layers [kg m-2] - real(kind_phys), allocatable :: DC(:) ! scavenge change in mass mixing ratio -! Rain parameters from Liu et al. - real(kind_phys), parameter :: B0_ls = 1.0e-4 - real(kind_phys), parameter :: F0_ls = 1.0 - real(kind_phys), parameter :: XL_ls = 5.0e-4 - real(kind_phys), parameter :: B0_cv = 1.5e-3 - real(kind_phys), parameter :: F0_cv = 0.3 - real(kind_phys), parameter :: XL_cv = 2.0e-3 -! Duration of rain: ls = model timestep, cv = 1800 s (<= cdt) - real(kind_phys) :: Td_ls - real(kind_phys) :: Td_cv - - -! Efficiency of dust wet removal (since dust is really not too hygroscopic) -! Applied only to in-cloud scavenging - real(kind_phys) :: effRemoval -! real(kind_phys),dimension(20) ::fwet -! tracer: p_so2=1 p_sulf=2 p_dms=3 p_msa=4 p_p25=5 p_bc1=6 p_bc2=7 p_oc1=8 -! p_oc2=9 p_dust_1=10 p_dust_2=11 p_dust_3=12 p_dust_4=13 p_dust_5=14 -! p_seas_1=15 p_seas_2=16 p_seas_3=17 p_seas_4=18 p_seas_5=19 p_p10 =20 -! data fwet /0.,1.5,0.,0.,1.,0.7,0.7,0.4,0.4,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1./ -! rc=0. - -! Initialize local variables -! -------------------------- -! rc = CHEM_RC_SUCCESS - - Td_ls = cdt - Td_cv = cdt - nbins = n2-n1+1 - var_rmv = 0.0 - -! Allocate the dynamic arrays - allocate(fd(k1:k2,nbins),stat=ios) -! if (chem_rc_test((ios .ne. 0), msg="Failed to allocate memory", & -! file=__FILE__, line=__LINE__, rc=rc)) return - allocate(dc(nbins),stat=ios) -! if (chem_rc_test((ios .ne. 0), msg="Failed to allocate memory", & -! file=__FILE__, line=__LINE__, rc=rc)) return - -! Accumulate the 3-dimensional arrays of rhoa and pdog - do j = j1, j2 - do i = i1, i2 - !pdog(i,k1:k2,j) = (ple(i,k1+1:k2+1,j)-ple(i,k1:k2,j)) / grav - pdog(i,k1:k2,j) = (ple(i,k1:k2,j)-ple(i,k1+1:k2+1,j)) / grav !lzhang - enddo - enddo - - do nv=1, num_chem -! Loop over spatial indices - do j = j1, j2 - big_i_loop: do i = i1, i2 - -! Check for total precipitation amount -! Assume no precip in column if precl+precc = 0 - pac = precl(i,j) + precc(i,j) - if(pac .le. 0.) cycle big_i_loop - pls = precl(i,j) - pcv = precc(i,j) - -! Initialize the precipitation fields - qls(:) = 0. - qcv(:) = 0. - fd(:,:) = 0. - -! Find the highest model layer experiencing rainout. Assumes no -! scavenging if T < 258 K - !LH = 0 - LH = k2+1 !lzhang - !do k = k1, k2 - do k = k2, k1,-1 !lzhang - if(dqcond(i,k,j) .lt. 0. .and. tmpu(i,k,j) .gt. 258.) then - LH = k - exit - endif - end do - if(LH .gt. k2) cycle big_i_loop !lzhang - -! convert dqcond from kg water/kg air/s to kg water/m3/s and reverse -! sign so that dqcond < 0. (positive precip) means qls and qcv > 0. - !do k = LH, k2 - do k = LH, k1, -1 !lzhang - qls(k) = -dqcond(i,k,j)*pls/pac*rhoa(i,k,j) - qcv(k) = -dqcond(i,k,j)*pcv/pac*rhoa(i,k,j) - end do - -! Loop over vertical to do the scavenging! - !do k = LH, k2 - do k = LH, k1, -1 !lzhang - -!----------------------------------------------------------------------------- -! (1) LARGE-SCALE RAINOUT: -! Tracer loss by rainout = TC0 * F * exp(-B*dt) -! where B = precipitation frequency, -! F = fraction of grid box covered by precipitating clouds. -! We assume that tracer scavenged by rain is falling down to the -! next level, where a fraction could be re-evaporated to gas phase -! if Qls is less then 0 in that level. -!----------------------------------------------------------------------------- - if (qls(k) .gt. 0.) then - F = F0_ls / (1. + F0_ls*B0_ls*XL_ls/(qls(k)*cdt/Td_ls)) - B = B0_ls/F0_ls +1./(F0_ls*XL_ls/qls(k)) - BT = B * Td_ls - if (BT.gt.10.) BT = 10. !< Avoid overflow > -! Adjust du level: - do n = 1, nbins - effRemoval = data%alpha(nv) - DC(n) = chem(i,k,j,nv) * F * effRemoval *(1.-exp(-BT)) - if (DC(n).lt.0.) DC(n) = 0. - chem(i,k,j,nv) = chem(i,k,j,nv)-DC(n) - if (chem(i,k,j,nv) .lt. 1.0E-32) chem(i,k,j,nv) = 1.0E-32 - end do -! Flux down: unit is kg m-2 -! Formulated in terms of production in the layer. In the revaporation step -! we consider possibly adding flux from above... - do n = 1, nbins - Fd(k,n) = DC(n)*pdog(i,k,j) - end do - - end if ! if Qls > 0 >>> - -!----------------------------------------------------------------------------- -! * (2) LARGE-SCALE WASHOUT: -! * Occurs when rain at this level is less than above. -!----------------------------------------------------------------------------- - !if(k .gt. LH .and. qls(k) .ge. 0.) then - if(k .lt. LH .and. qls(k) .ge. 0.) then !lzhang - !if(qls(k) .lt. qls(k-1)) then - if(qls(k) .lt. qls(k+1)) then !lzhang -! Find a maximum F overhead until the level where Qls<0. - Qmx = 0. - !do kk = k-1,LH,-1 - do kk = k+1,LH !lzhang - if (Qls(kk).gt.0.) then - Qmx = max(Qmx,Qls(kk)) - else - exit - end if - end do - - F = F0_ls / (1. + F0_ls*B0_ls*XL_ls/(Qmx*cdt/Td_ls)) - if (F.lt.0.01) F = 0.01 -!----------------------------------------------------------------------------- -! The following is to convert Q(k) from kgH2O/m3/sec to mm/sec in order -! to use the Harvard formula. Convert back to mixing ratio by multiplying -! by rhoa. Multiply by pdog gives kg/m2/s of precip. Divide by density -! of water (=1000 kg/m3) gives m/s of precip and multiply by 1000 gives -! units of mm/s (omit the multiply and divide by 1000). -!----------------------------------------------------------------------------- - - Qd = Qmx /rhoa(i,k,j)*pdog(i,k,j) - if (Qd.ge.50.) then - B = 0. - else - B = Qd * 0.1 - end if - BT = B * cdt - if (BT.gt.10.) BT = 10. - -! Adjust du level: - do n = 1, nbins - DC(n) = chem(i,k,j,nv) * F * (1.-exp(-BT)) - if (DC(n).lt.0.) DC(n) = 0. - chem(i,k,j,nv) = chem(i,k,j,nv)-DC(n) - if (chem(i,k,j,nv) .lt. 1.0E-32) & - chem(i,k,j,nv) = 1.0E-32 - var_rmv(i,j,nv) = var_rmv(i,j,nv)+DC(n)*pdog(i,k,j)/cdt !ug/m2/s - end do - - end if - end if ! if ls washout >>> -#if 0 -!----------------------------------------------------------------------------- -! (3) CONVECTIVE RAINOUT: -! Tracer loss by rainout = dd0 * F * exp(-B*dt) -! where B = precipitation frequency, -! F = fraction of grid box covered by precipitating clouds. -!----------------------------------------------------------------------------- - - if (qcv(k) .gt. 0.) then - F = F0_cv / (1. + F0_cv*B0_cv*XL_cv/(Qcv(k)*cdt/Td_cv)) - B = B0_cv - BT = B * Td_cv - if (BT.gt.10.) BT = 10. !< Avoid overflow > - -! Adjust du level: - do n = 1, nbins - effRemoval = data%alpha(nv) - DC(n) = chem(i,k,j,nv) * F * effRemoval * (1.-exp(-BT)) - if (DC(n).lt.0.) DC(n) = 0. - chem(i,k,j,nv) = chem(i,k,j,nv)-DC(n) - if (chem(i,k,j,nv) .lt. 1.0E-32) chem(i,k,j,nv) = 1.0E-32 - end do - -!------ Flux down: unit is kg. Including both ls and cv. - do n = 1, nbins - Fd(k,n) = Fd(k,n) + DC(n)*pdog(i,k,j) - end do - - end if ! if Qcv > 0 >>> - -!----------------------------------------------------------------------------- -! (4) CONVECTIVE WASHOUT: -! Occurs when rain at this level is less than above. -!----------------------------------------------------------------------------- - - !if (k.gt.LH .and. Qcv(k).ge.0.) then - if (k.lt.LH .and. Qcv(k).ge.0.) then !lzhang - !if (Qcv(k).lt.Qcv(k-1)) then - if (Qcv(k).lt.Qcv(k+1)) then !lzhang -!----- Find a maximum F overhead until the level where Qls<0. - Qmx = 0. - !do kk = k-1, LH, -1 - do kk = k+1, LH !lzhang - if (Qcv(kk).gt.0.) then - Qmx = max(Qmx,Qcv(kk)) - else - exit - end if - end do - - F = F0_cv / (1. + F0_cv*B0_cv*XL_cv/(Qmx*cdt/Td_cv)) - if (F.lt.0.01) F = 0.01 -!----------------------------------------------------------------------------- -! The following is to convert Q(k) from kgH2O/m3/sec to mm/sec in order -! to use the Harvard formula. Convert back to mixing ratio by multiplying -! by rhoa. Multiply by pdog gives kg/m2/s of precip. Divide by density -! of water (=1000 kg/m3) gives m/s of precip and multiply by 1000 gives -! units of mm/s (omit the multiply and divide by 1000). -!----------------------------------------------------------------------------- - - Qd = Qmx / rhoa(i,k,j)*pdog(i,k,j) - if (Qd.ge.50.) then - B = 0. - else - B = Qd * 0.1 - end if - BT = B * cdt - if (BT.gt.10.) BT = 10. - -! Adjust du level: - do n = 1, nbins - DC(n) = chem(i,k,j,nv) * F * (1.-exp(-BT)) - if (DC(n).lt.0.) DC(n) = 0. - chem(i,k,j,nv) = chem(i,k,j,nv)-DC(n) - if (chem(i,k,j,nv) .lt. 1.0E-32) & - chem(i,k,j,nv) = 1.0E-32 - var_rmv(i,j,nv) = var_rmv(i,j,nv)+DC(n)*pdog(i,k,j)/cdt !ug/m2/s - end do - - end if - end if ! if cv washout >>> -#endif -!----------------------------------------------------------------------------- -! (5) RE-EVAPORATION. Assume that SO2 is re-evaporated as SO4 since it -! has been oxidized by H2O2 at the level above. -!----------------------------------------------------------------------------- -! Add in the flux from above, which will be subtracted if reevaporation occurs - !if(k .gt. LH) then - if(k .lt. LH) then !lzhang - do n = 1, nbins - !Fd(k,n) = Fd(k,n) + Fd(k-1,n) - Fd(k,n) = Fd(k,n) + Fd(k+1,n) !lzhang - end do - -! Is there evaporation in the currect layer? - if (-dqcond(i,k,j) .lt. 0.) then -! Fraction evaporated = H2O(k)evap / H2O(next condensation level). - !if (-dqcond(i,k-1,j) .gt. 0.) then - if (-dqcond(i,k+1,j) .gt. 0.) then !lzhang - - A = abs( dqcond(i,k,j) * pdog(i,k,j) & - !/ ( dqcond(i,k-1,j) * pdog(i,k-1,j)) ) - / ( dqcond(i,k+1,j) * pdog(i,k+1,j)) ) !lzhang - if (A .gt. 1.) A = 1. - -! Adjust tracer in the level - do n = 1, nbins - !DC(n) = Fd(k-1,n) / pdog(i,k,j) * A - DC(n) = Fd(k+1,n) / pdog(i,k,j) * A !lzhang - chem(i,k,j,nv) = chem(i,k,j,nv) + DC(n) - chem(i,k,j,nv) = max(chem(i,k,j,nv),1.e-32) -! Adjust the flux out of the bottom of the layer - Fd(k,n) = Fd(k,n) - DC(n)*pdog(i,k,j) - end do - - endif - endif ! if -moistq < 0 - endif - end do ! k - - do n = 1, nbins - !var_rmv(i,j,nv) = var_rmv(i,j,nv)+Fd(k2,n)/cdt !lzhang - var_rmv(i,j,nv) = var_rmv(i,j,nv)+Fd(k1,n)/cdt ! ug/m2/s - end do - - end do big_i_loop ! i - end do ! j - end do !nv for num_chem - - deallocate(fd,DC,stat=ios) -! if (chem_rc_test((ios .ne. 0), msg="Failed to deallocate memory", & -! file=__FILE__, line=__LINE__, rc=rc)) return - - end subroutine WetRemovalGOCART - -end module dep_wet_ls_mod diff --git a/smoke/dust_fengsha_mod.F90 b/smoke/dust_fengsha_mod.F90 deleted file mode 100755 index fbf87aa56..000000000 --- a/smoke/dust_fengsha_mod.F90 +++ /dev/null @@ -1,601 +0,0 @@ -!>\file dust_fengsha_mod.F90 -!! This file contains the FENGSHA dust scheme. - -module dust_fengsha_mod -! -! This module developed by Barry Baker (NOAA ARL) -! For serious questions contact barry.baker@noaa.gov -! -! 07/16/2019 - Adapted for NUOPC/GOCART, R. Montuoro -! 02/01/2020 - Adapted for FV3/CCPP, Haiqin Li - - use rrfs_smoke_data - use machine , only : kind_phys - use dust_data_mod - - implicit none - - private - - public :: gocart_dust_fengsha_driver - -contains - - subroutine gocart_dust_fengsha_driver(data, dt, & - chem,rho_phy,smois,p8w,ssm, & - isltyp,vegfra,snowh,xland,area,g,emis_dust, & - ust,znt,clay,sand,rdrag,uthr, & - num_emis_dust,num_moist,num_chem,num_soil_layers, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - INTEGER, INTENT(IN ) :: & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte, & - num_emis_dust,num_moist,num_chem,num_soil_layers - INTEGER,DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: isltyp - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), INTENT(INOUT) :: chem - REAL(kind_phys), DIMENSION( ims:ime, 1, jms:jme,num_emis_dust),OPTIONAL, INTENT(INOUT) :: emis_dust - REAL(kind_phys), DIMENSION( ims:ime, num_soil_layers, jms:jme ), INTENT(IN) :: smois - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: ssm - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: vegfra, & - snowh, & - xland, & - area, & - ust, & - znt, & - clay, & - sand, & - rdrag, & - uthr - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: & - p8w, & - rho_phy - REAL(kind_phys), INTENT(IN) :: dt,g - - ! Local variables - - integer :: nmx,smx,i,j,k,imx,jmx,lmx - integer,dimension (1,1) :: ilwi - real(kind_phys), DIMENSION (1,1) :: erodtot - REAL(kind_phys), DIMENSION (1,1) :: gravsm - REAL(kind_phys), DIMENSION (1,1) :: drylimit - real(kind_phys), DIMENSION (5) :: tc,bems - real(kind_phys), dimension (1,1) :: airden,airmas,ustar - real(kind_phys), dimension (1) :: dxy - real(kind_phys), dimension (3) :: massfrac - real(kind_phys) :: conver,converi - real(kind_phys) :: R - - ! threshold values - conver=1.e-9 - converi=1.e9 - - ! Number of dust bins - - imx=1 - jmx=1 - lmx=1 - nmx=ndust - smx=nsalt - - k=kts - do j=jts,jte - do i=its,ite - - ! Don't do dust over water!!! - - ilwi(1,1)=0 - if(xland(i,j).lt.1.5)then - ilwi(1,1)=1 - - ! Total concentration at lowest model level. This is still hardcoded for 5 bins. - - ! if(config_flags%chem_opt == 2 .or. config_flags%chem_opt == 11 ) then - ! tc(:)=1.e-16*conver - ! else - tc(1)=chem(i,kts,j,p_dust_1)*conver - tc(2)=chem(i,kts,j,p_dust_2)*conver - tc(3)=chem(i,kts,j,p_dust_3)*conver - tc(4)=chem(i,kts,j,p_dust_4)*conver - tc(5)=chem(i,kts,j,p_dust_5)*conver - ! endif - - ! Air mass and density at lowest model level. - - airmas(1,1)=-(p8w(i,kts+1,j)-p8w(i,kts,j))*area(i,j)/g - airden(1,1)=rho_phy(i,kts,j) - ustar(1,1)=ust(i,j) - dxy(1)=area(i,j) - - ! Mass fractions of clay, silt, and sand. - massfrac(1)=clay(i,j) - massfrac(2)=1-(clay(i,j)+sand(i,j)) - massfrac(3)=sand(i,j) - - - ! Total erodibility. - - erodtot(1,1) = ssm(i,j) ! SUM(erod(i,j,:)) - - ! Don't allow roughness lengths greater than 20 cm to be lofted. - ! This kludge accounts for land use types like urban areas and - ! forests which would otherwise show up as high dust emitters. - ! This is a placeholder for a more widely accepted kludge - ! factor in the literature, which reduces lofting for rough areas. - ! Forthcoming... - - IF (znt(i,j) .gt. 0.2) then - ilwi(1,1)=0 - endif - - ! limit where there is lots of vegetation - if (vegfra(i,j) .gt. .17) then - ilwi(1,1) = 0 - endif - - ! limit where there is snow on the ground - if (snowh(i,j) .gt. 0) then - ilwi(1,1) = 0 - endif - - ! Do not allow areas with bedrock, lava, or land-ice to loft - - IF (isltyp(i,j) .eq. 15 .or. isltyp(i,j) .eq. 16. .or. & - isltyp(i,j) .eq. 18) then - ilwi(1,1)=0 - ENDIF - IF (isltyp(i,j) .eq. 0)then - ilwi(1,1)=0 - endif - if(ilwi(1,1) == 0 ) cycle - - ! Calculate gravimetric soil moisture and drylimit. - gravsm(1,1)=100.*smois(i,1,j)/((1.-maxsmc(isltyp(i,j)))*(2.65*(1.-clay(i,j))+2.50*clay(i,j))) - drylimit(1,1)=14.0*clay(i,j)*clay(i,j)+17.0*clay(i,j) - - ! get drag partition - ! FENGSHA uses the drag partition correction of MacKinnon et al 2004 - ! doi:10.1016/j.geomorph.2004.03.009 - if (dust_calcdrag .ne. 1) then - call fengsha_drag(data,znt(i,j),R) - else - ! use the precalculated version derived from ASCAT; Prigent et al. (2012,2015) - ! doi:10.1109/TGRS.2014.2338913 & doi:10.5194/amt-5-2703-2012 - ! pick only valid values - if (rdrag(i,j) > 0.) then - R = real(rdrag(i,j), kind=kind_phys) - else - cycle - endif - endif - - ! Call dust emission routine. - call source_dust(data, imx, jmx, lmx, nmx, smx, dt, tc, ustar, massfrac, & - erodtot, dxy, gravsm, airden, airmas, & - bems, g, drylimit, dust_alpha, dust_gamma, R, uthr(i,j)) - - ! if(config_flags%chem_opt == 2 .or. config_flags%chem_opt == 11 ) then - ! dustin(i,j,1:5)=tc(1:5)*converi - ! else - chem(i,kts,j,p_dust_1)=tc(1)*converi - chem(i,kts,j,p_dust_2)=tc(2)*converi - chem(i,kts,j,p_dust_3)=tc(3)*converi - chem(i,kts,j,p_dust_4)=tc(4)*converi - chem(i,kts,j,p_dust_5)=tc(5)*converi - ! endif - - ! chem(i,kts,j,p_dust_1)=tc(1)*converi - ! chem(i,kts,j,p_dust_2)=tc(2)*converi - ! chem(i,kts,j,p_dust_3)=tc(3)*converi - ! chem(i,kts,j,p_dust_4)=tc(4)*converi - ! chem(i,kts,j,p_dust_5)=tc(5)*converi - - ! For output diagnostics - - emis_dust(i,1,j,p_edust1)=bems(1) - emis_dust(i,1,j,p_edust2)=bems(2) - emis_dust(i,1,j,p_edust3)=bems(3) - emis_dust(i,1,j,p_edust4)=bems(4) - emis_dust(i,1,j,p_edust5)=bems(5) - endif - enddo - enddo - ! - - end subroutine gocart_dust_fengsha_driver - - - SUBROUTINE source_dust(data, imx, jmx, lmx, nmx, smx, dt1, tc, ustar, massfrac, & - erod, dxy, gravsm, airden, airmas, bems, g0, drylimit, alpha, & - gamma, R, uthres) - - ! **************************************************************************** - ! * Evaluate the source of each dust particles size bin by soil emission - ! * - ! * Input: - ! * EROD Fraction of erodible grid cell (-) - ! * GRAVSM Gravimetric soil moisture (g/g) - ! * DRYLIMIT Upper GRAVSM limit for air-dry soil (g/g) - ! * ALPHA Constant to fudge the total emission of dust (1/m) - ! * GAMMA Tuning constant for erodibility (-) - ! * DXY Surface of each grid cell (m2) - ! * AIRMAS Mass of air for each grid box (kg) - ! * AIRDEN Density of air for each grid box (kg/m3) - ! * USTAR Friction velocity (m/s) - ! * DT1 Time step (s) - ! * NMX Number of dust bins (-) - ! * SMX Number of saltation bins (-) - ! * IMX Number of I points (-) - ! * JMX Number of J points (-) - ! * LMX Number of L points (-) - ! * R Drag Partition (-) - ! * UTHRES FENGSHA Dry Threshold Velocities (m/s) - ! * - ! * Data: - ! * MASSFRAC Fraction of mass in each of 3 soil classes (-) - ! * SPOINT Pointer to 3 soil classes (-) - ! * DEN_DUST Dust density (kg/m3) - ! * DEN_SALT Saltation particle density (kg/m3) - ! * REFF_SALT Reference saltation particle diameter (m) - ! * REFF_DUST Reference dust particle diameter (m) - ! * LO_DUST Lower diameter limits for dust bins (m) - ! * UP_DUST Upper diameter limits for dust bins (m) - ! * FRAC_SALT Soil class mass fraction for saltation bins (-) - ! * - ! * Parameters: - ! * CMB Constant of proportionality (-) - ! * MMD_DUST Mass median diameter of dust (m) - ! * GSD_DUST Geometric standard deviation of dust (-) - ! * LAMBDA Side crack propagation length (m) - ! * CV Normalization constant (-) - ! * G0 Gravitational acceleration (m/s2) - ! * G Gravitational acceleration in cgs (cm/s2) - ! * - ! * Working: - ! * U_TS0 "Dry" threshold friction velocity (m/s) - ! * U_TS Moisture-adjusted threshold friction velocity (m/s) - ! * RHOA Density of air in cgs (g/cm3) - ! * DEN Dust density in cgs (g/cm3) - ! * DIAM Dust diameter in cgs (cm) - ! * DMASS Saltation mass distribution (-) - ! * DSURFACE Saltation surface area per unit mass (m2/kg) - ! * DS_REL Saltation surface area distribution (-) - ! * SALT Saltation flux (kg/m/s) - ! * DLNDP Dust bin width (-) - ! * EMIT Total vertical mass flux (kg/m2/s) - ! * EMIT_VOL Total vertical volume flux (m/s) - ! * DSRC Mass of emitted dust (kg/timestep/cell) - ! * - ! * Output: - ! * TC Total concentration of dust (kg/kg/timestep/cell) - ! * BEMS Source of each dust type (kg/timestep/cell) - ! * - ! **************************************************************************** - implicit none - type(smoke_data), intent(inout) :: data - - INTEGER, INTENT(IN) :: imx,jmx,lmx,nmx,smx - REAL(kind_phys), INTENT(IN) :: dt1 - REAL(kind_phys), INTENT(INOUT) :: tc(imx,jmx,lmx,nmx) - REAL(kind_phys), INTENT(IN) :: ustar(imx,jmx) - REAL(kind_phys), INTENT(IN) :: massfrac(3) - REAL(kind_phys), INTENT(IN) :: erod(imx,jmx) - REAL(kind_phys), INTENT(IN) :: dxy(jmx) - REAL(kind_phys), INTENT(IN) :: gravsm(imx,jmx) - REAL(kind_phys), INTENT(IN) :: airden(imx,jmx,lmx) - REAL(kind_phys), INTENT(IN) :: airmas(imx,jmx,lmx) - REAL(kind_phys), INTENT(OUT) :: bems(imx,jmx,nmx) - REAL(kind_phys), INTENT(IN) :: g0 - REAL(kind_phys), INTENT(IN) :: drylimit(imx,jmx) - !! Sandblasting mass efficiency, aka "fudge factor" (based on Tegen et al, - !! 2006 and Hemold et al, 2007) - ! - ! REAL, PARAMETER :: alpha=1.8E-8 ! (m^-1) - REAL(kind_phys), INTENT(IN) :: alpha - ! Experimental optional exponential tuning constant for erodibility. - ! 0 < gamma < 1 -> more relative impact by low erodibility regions. - REAL(kind_phys), INTENT(IN) :: gamma - REAL(kind_phys), INTENT(IN) :: R - REAL(kind_phys), INTENT(IN) :: uthres - - REAL(kind_phys) :: den(smx), diam(smx) - REAL(kind_phys) :: dvol(nmx), distr_dust(nmx), dlndp(nmx) - REAL(kind_phys) :: dsurface(smx), ds_rel(smx) - REAL(kind_phys) :: u_ts0, u_ts, dsrc, dmass, dvol_tot - REAL(kind_phys) :: salt,emit, emit_vol, stotal - REAL(kind_phys) :: rhoa, g - INTEGER :: i, j, n - - ! Sandblasting mass efficiency, beta. - ! Beta maxes out for clay fractions above 0.2 = betamax. - - REAL(kind_phys), PARAMETER :: betamax=5.25E-4 - REAL(kind_phys) :: beta - integer :: styp - - ! Constant of proportionality from Marticorena et al, 1997 (unitless) - ! Arguably more ~consistent~ fudge than alpha, which has many walnuts - ! sprinkled throughout the literature. - GC - - REAL(kind_phys), PARAMETER :: cmb=1.0 - ! REAL, PARAMETER :: cmb=2.61 ! from White,1979 - - ! Parameters used in Kok distribution function. Advise not to play with - ! these without the expressed written consent of someone who knows what - ! they're doing. - GC - - REAL(kind_phys), PARAMETER :: mmd_dust=3.4D-6 ! median mass diameter (m) - REAL(kind_phys), PARAMETER :: gsd_dust=3.0 ! geom. std deviation - REAL(kind_phys), PARAMETER :: lambda=12.0D-6 ! crack propagation length (m) - REAL(kind_phys), PARAMETER :: cv=12.62D-6 ! normalization constant - - ! Calculate saltation surface area distribution from sand, silt, and clay - ! mass fractions and saltation bin fraction. This will later become a - ! modifier to the total saltation flux. The reasoning here is that the - ! size and availability of saltators affects saltation efficiency. Based - ! on Eqn. (32) in Marticorena & Bergametti, 1995 (hereon, MB95). - - DO n=1,smx - dmass=massfrac(spoint(n))*frac_salt(n) - dsurface(n)=0.75*dmass/(den_salt(n)*reff_salt(n)) - ENDDO - - ! The following equation yields relative surface area fraction. It will only - ! work if you are representing the "full range" of all three soil classes. - ! For this reason alone, we have incorporated particle sizes that encompass - ! the clay class, to account for the its relative area over the basal - ! surface, even though these smaller bins would be unlikely to play any large - ! role in the actual saltation process. - GC - - stotal=SUM(dsurface(:)) - DO n=1,smx - ds_rel(n)=dsurface(n)/stotal - ENDDO - - ! Calculate total dust emission due to saltation of sand sized particles. - ! Begin by calculating DRY threshold friction velocity (u_ts0). Next adjust - ! u_ts0 for moisture to get threshold friction velocity (u_ts). Then - ! calculate saltation flux (salt) where ustar has exceeded u_ts. Finally, - ! calculate total dust emission (tot_emit), taking into account erodibility. - - ! Set DRY threshold friction velocity to input value - u_ts0 = uthres - - g = g0*1.0E2 - emit=0.0 - - DO n = 1, smx - den(n) = den_salt(n)*1.0D-3 ! (g cm^-3) - diam(n) = 2.0*reff_salt(n)*1.0D2 ! (cm) - DO i = 1,imx - DO j = 1,jmx - rhoa = airden(i,j,1)*1.0D-3 ! (g cm^-3) - - ! FENGSHA uses the 13 category soil type from the USDA - ! call calc_fengsha_styp(massfrac(1),massfrac(3),massfrac(2),styp) - ! Fengsha uses threshold velocities based on dale gilletes data - ! call fengsha_utst(styp,uthres,u_ts0) - - ! Friction velocity threshold correction function based on physical - ! properties related to moisture tension. Soil moisture greater than - ! dry limit serves to increase threshold friction velocity (making - ! it more difficult to loft dust). When soil moisture has not reached - ! dry limit, treat as dry - - IF (gravsm(i,j) > drylimit(i,j)) THEN - u_ts = MAX(0.0D+0,u_ts0*(sqrt(1.0+1.21*(gravsm(i,j)-drylimit(i,j))**0.68)) / R) - ELSE - u_ts = u_ts0 / R - END IF - - ! Calculate total vertical mass flux (note beta has units of m^-1) - ! Beta acts to tone down dust in areas with so few dust-sized particles that the - ! lofting efficiency decreases. Otherwise, super sandy zones would be huge dust - ! producers, which is generally not the case. Equation derived from wind-tunnel - ! experiments (see MB95). - - beta=10**(13.6*massfrac(1)-6.0) ! (unitless) - if (massfrac(1) <= 0.2) then - beta=10**(13.4*massfrac(1)-6.0) - else - beta = 2.E-4 - endif - - !--------------------------------------------------------------------- - ! formula of Draxler & Gillette (2001) Atmos. Environ. - ! F = K A (r/g) U* ( U*^2 - Ut*^2 ) - ! - ! where: - ! F = vertical emission flux [g/m**2-s] - ! K = constant 2.0E-04 [1/m] - ! A = 0~3.5 mean = 2.8 (fudge factor) - ! U* = friction velocity [m/s] - ! Ut* = threshold friction velocity [m/s] - ! - !-------------------------------------------------------------------- - - IF (ustar(i,j) .gt. u_ts) then - call fengsha_hflux(data,ustar(i,j),u_ts,beta, salt) - salt = alpha * cmb * ds_rel(n) * airden(i,j,1) / g0 * salt * (erod(i,j)**gamma) * beta - else - salt = 0. - endif - ! EROD is taken into account above - emit = emit + salt - END DO - END DO - END DO - - ! Now that we have the total dust emission, distribute into dust bins using - ! lognormal distribution (Dr. Jasper Kok, in press), and - ! calculate total mass emitted over the grid box over the timestep. - ! - ! In calculating the Kok distribution, we assume upper and lower limits to each bin. - ! For reff_dust=(/0.73D-6,1.4D-6,2.4D-6,4.5D-6,8.0D-6/) (default), - ! lower limits were ASSUMED at lo_dust=(/0.1D-6,1.0D-6,1.8D-6,3.0D-6,6.0D-6/) - ! upper limits were ASSUMED at up_dust=(/1.0D-6,1.8D-6,3.0D-6,6.0D-6,10.0D-6/) - ! These may be changed within module_data_gocart_dust.F, but make sure it is - ! consistent with reff_dust values. These values were taken from the original - ! GOCART bin configuration. We use them here to calculate dust bin width, dlndp. - ! dVol is the volume distribution. You know...if you were wondering. GC - - dvol_tot=0. - DO n=1,nmx - dlndp(n)=LOG(up_dust(n)/lo_dust(n)) - dvol(n)=(2.0*reff_dust(n)/cv)*(1.+ERF(LOG(2.0*reff_dust(n)/mmd_dust)/(SQRT(2.)*LOG(gsd_dust))))*& - EXP(-(2.0*reff_dust(n)/lambda)**3.0)*dlndp(n) - dvol_tot=dvol_tot+dvol(n) - ! Convert mass flux to volume flux - !emit_vol=emit/den_dust(n) ! (m s^-1) - END DO - DO n=1,nmx - distr_dust(n)=dvol(n)/dvol_tot - !print *,"distr_dust(",n,")=",distr_dust(n) - END DO - - ! Now distribute total vertical emission into dust bins and update concentration. - - DO n=1,nmx - DO i=1,imx - DO j=1,jmx - ! Calculate total mass emitted - dsrc = emit*distr_dust(n)*dxy(j)*dt1 ! (kg) - IF (dsrc < 0.0) dsrc = 0.0 - - ! Update dust mixing ratio at first model level. - tc(i,j,1,n) = tc(i,j,1,n) + dsrc / airmas(i,j,1) ! (kg/kg) - ! bems(i,j,n) = dsrc ! diagnostic - !bems(i,j,n) = 1000.*dsrc/(dxy(j)*dt1) ! diagnostic (g/m2/s) - bems(i,j,n) = 1.e+9*dsrc/(dxy(j)*dt1) ! diagnostic (ug/m2/s) !lzhang - END DO - END DO - END DO - - END SUBROUTINE source_dust - - subroutine fengsha_utst(data,styp,uth, ut) - implicit none - type(smoke_data), intent(inout) :: data - - integer, intent(in) :: styp - real(kind_phys), dimension(fengsha_maxstypes), intent(in) :: uth - real(kind_phys), intent(out) :: ut - ut = uth(styp) -! real (kind_phys) :: uth(13) = & -! (/ 0.08, & ! Sand - 1 -! 0.20, & ! Loamy Sand - 2 -! 0.30, & ! Sandy Loam - 3 -! 0.30, & ! Silt Loam - 4 -! 0.35, & ! Silt - 5 -! 0.60, & ! Loam - 6 -! 0.30, & ! Sandy Clay Loam - 7 -! 0.35, & ! Silty Clay Loam - 8 -! 0.45, & ! Clay Loam - 9 -! 0.45, & ! Sandy Clay - 10 -! 0.45, & ! Silty Clay - 11 -! 0.60, & ! Clay - 12 -! 9.999 /) ! Other - 13 - return - end subroutine fengsha_utst - - subroutine calc_fengsha_styp(data, clay, sand, silt, type) - implicit none - type(smoke_data), intent(inout) :: data - - !--------------------------------------------------------------- - ! Function: calculate soil type based on USDA definition. - ! Source: USDA soil texture calculator - ! - ! Defintion of soil types: - ! - ! - ! NOAH 1 2 3 4 5 6 7 8 9 10 11 12 - ! PX 1 2 3 4 - 5 6 7 8 9 10 11 - ! Soil "Sand" "Loamy Sand" "Sandy Loam" "Silt Loam" "Silt" "Loam" "Sandy Clay Loam" "Silt Clay Loam" "Clay Loam" "Sandy Clay" "Silty Clay" "Clay" - !--------------------------------------------------------------- - REAL(kind_phys), intent(in) :: clay, sand, silt - integer, intent(out) :: type - real(kind_phys) :: cly, snd, slt - - type = 0 - - snd = sand * 100. - cly = clay * 100. - slt = silt * 100. - if (slt+1.5*cly .lt. 15) type = 1 ! snd - if (slt+1.5*cly .ge. 15 .and.slt+1.5*cly .lt. 30) type = 2 ! loamy snd - if (cly .ge. 7 .and. cly .lt. 20 .and. snd .gt. 52 .and. slt+2*cly .ge. 30) type = 3 ! sndy loam (cond 1) - if (cly .lt. 7 .and. slt .lt. 50 .and. slt+2*cly .ge. 30) type = 3 ! sndy loam (cond 2) - if (slt .ge. 50 .and. cly .ge. 12 .and.cly .lt. 27 ) type = 4 ! slt loam (cond 1) - if (slt .ge. 50 .and. slt .lt. 80 .and.cly .lt. 12) type = 4 ! slt loam (cond 2) - if (slt .ge. 80 .and. cly .lt. 12) type = 5 ! slt - if (cly .ge. 7 .and. cly .lt. 27 .and.slt .ge. 28 .and. slt .lt. 50 .and.snd .le. 52) type = 6 ! loam - if (cly .ge. 20 .and. cly .lt. 35 .and.slt .lt. 28 .and. snd .gt. 45) type = 7 ! sndy cly loam - if (cly .ge. 27 .and. cly .lt. 40 .and.snd .lt. 20) type = 8 ! slt cly loam - if (cly .ge. 27 .and. cly .lt. 40 .and.snd .ge. 20 .and. snd .le. 45) type = 9 ! cly loam - if (cly .ge. 35 .and. snd .gt. 45) type = 10 ! sndy cly - if (cly .ge. 40 .and. slt .ge. 40) type = 11 ! slty cly - if (cly .ge. 40 .and. snd .le. 45 .and.slt .lt. 40) type = 12 ! clay - return - end subroutine calc_fengsha_styp - - subroutine fengsha_drag(data,z0,R) - implicit none - type(smoke_data), intent(inout) :: data - - real(kind_phys), intent(in) :: z0 - real(kind_phys), intent(out) :: R - real(kind_phys), parameter :: z0s = 1.0e-04 !Surface roughness for ideal bare surface [m] - ! ------------------------------------------------------------------------ - ! Function: Calculates the MacKinnon et al. 2004 Drag Partition Correction - ! - ! R = 1.0 - log(z0 / z0s) / log( 0.7 * (12255./z0s) ** 0.8) - ! - !-------------------------------------------------------------------------- - ! Drag partition correction. See MacKinnon et al. (2004), - ! doi:10.1016/j.geomorph.2004.03.009 - R = 1.0 - log(z0 / z0s) / log( 0.7 * (12255./z0s) ** 0.8) - - ! Drag partition correction. See Marticorena et al. (1997), - ! doi:10.1029/96JD02964 - !R = 1.0 - log(z0 / z0s) / log( 0.7 * (10./z0s) ** 0.8) - - return - end subroutine fengsha_drag - - subroutine fengsha_hflux(data,ust,utst, kvh, salt) - !--------------------------------------------------------------------- - ! Function: Calculates the Horizontal Saltation Flux, Q, and then - ! calculates the vertical flux. - ! - ! formula of Draxler & Gillette (2001) Atmos. Environ. - ! F = K A (r/g) U* ( U*^2 - Ut*^2 ) - ! - ! where: - ! F = vertical emission flux [g/m**2-s] - ! K = constant 2.0E-04 [1/m] - ! A = 0~3.5 mean = 2.8 (fudge factor) - ! U* = friction velocity [m/s] - ! Ut* = threshold friction velocity [m/s] - ! - !-------------------------------------------------------------------- - implicit none - type(smoke_data), intent(inout) :: data - real(kind_phys), intent(in) :: ust, & ! friction velocity - utst, & ! threshold friction velocity - kvh ! vertical to horizontal mass flux ratio - - real(kind_phys), intent(out) :: salt - real(kind_phys) :: Q - Q = ust * (ust * ust - utst * utst) - salt = Q ! sdep * kvh * Q - - return - end subroutine fengsha_hflux - - -end module dust_fengsha_mod diff --git a/smoke/rrfs_smoke_data.F90 b/smoke/rrfs_smoke_data.F90 deleted file mode 100755 index cb9cc25e6..000000000 --- a/smoke/rrfs_smoke_data.F90 +++ /dev/null @@ -1,651 +0,0 @@ -!>\file rrfs_smoke_data.F90 -!! This file contains data for the RRFS-Smoke modules. - -module rrfs_smoke_data - use machine , only : kind_phys - implicit none - INTEGER, PARAMETER :: dep_seasons = 5 - INTEGER, PARAMETER :: nlu = 25 - - type wesely_pft - integer :: npft - integer :: months - INTEGER, pointer :: seasonal_wes(:,:,:,:) => NULL() - contains - final :: wesely_pft_destructor - end type wesely_pft - - interface wesely_pft - procedure :: wesely_pft_constructor - end interface wesely_pft - -!-------------------------------------------------- -! many of these parameters will depend on the RADM mechanism! -! if you change it, lets talk about it and get it done!!! -!-------------------------------------------------- - - REAL(kind_phys), parameter :: small_value = 1.e-36 - REAL(kind_phys), parameter :: large_value = 1.e36 - -!-------------------------------------------------- -! following currently hardwired to USGS -!-------------------------------------------------- - integer, parameter :: isice_temp = 24 - integer, parameter :: iswater_temp = 16 - integer, parameter :: wrf2mz_lt_map(nlu) = (/ 1, 2, 2, 2, 2, & - 4, 3, 3, 3, 3, & - 4, 5, 4, 5, 6, & - 7, 9, 6, 8, 9, & - 6, 6, 8, 0, 0 /) - real(kind_phys), parameter :: wh2o = 18.0153 - real(kind_phys), parameter :: wpan = 121.04793 - real(kind_phys), PARAMETER :: KARMAN=0.4 - INTEGER, parameter :: luse2usgs(21) = (/14,13,12,11,15,8,9,10,10,7, & - 17,4,1,5,24,19,16,21,22,23,16 /) - character(len=4), parameter :: mminlu = 'USGS' - - ! integer, parameter :: pan_seasons = 5 - ! integer, parameter :: pan_lands = 11 - - type smoke_data - ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Taken from dep_simple_mod - INTEGER :: ixxxlu(nlu) - REAL(KIND_PHYS) :: kpart(nlu) - REAL(KIND_PHYS) :: rac(nlu,dep_seasons), rclo(nlu,dep_seasons), rcls(nlu,dep_seasons) - REAL(KIND_PHYS) :: rgso(nlu,dep_seasons), rgss(nlu,dep_seasons) - REAL(KIND_PHYS) :: ri(nlu,dep_seasons), rlu(nlu,dep_seasons) - ! REAL(KIND_PHYS) :: ri_pan(pan_seasons,pan_lands) - ! never used: real(kind_phys) :: c0_pan(pan_lands) - ! never used: real(kind_phys) :: k_pan (pan_lands) - - ! never used: integer :: month - REAL(KIND_PHYS) :: dratio(1000), hstar(1000), hstar4(1000) - REAL(KIND_PHYS) :: f0(1000), dhr(1000), scpr23(1000) - - ! Note: scpr23 is only read, never written - - ! never used: type(wesely_pft) :: seasonal_pft - - ! never used: logical, pointer :: is_aerosol(:) => NULL() - - ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Taken from dep_wet_ls_mod - real(kind_phys), dimension(:), pointer :: alpha => NULL() - contains - final :: smoke_data_destructor - procedure :: dep_init - end type smoke_data - - interface smoke_data - procedure :: smoke_data_constructor - end interface smoke_data - - type(smoke_data), target, private :: private_thread_data - logical, private :: rrfs_smoke_data_initialized = .false. - - !$OMP THREADPRIVATE(private_thread_data) - !$OMP THREADPRIVATE(rrfs_smoke_data_initialized) - -contains - - function get_thread_smoke_data() result(data) - implicit none - class(smoke_data), pointer :: data - if(.not. rrfs_smoke_data_initialized) then - private_thread_data = smoke_data() - rrfs_smoke_data_initialized = .true. - endif - data => private_thread_data - end function get_thread_smoke_data - - subroutine wesely_pft_destructor(this) - implicit none - type(wesely_pft) :: this - if(associated(this%seasonal_wes)) then - deallocate(this%seasonal_wes) - nullify(this%seasonal_wes) - endif - end subroutine wesely_pft_destructor - - function wesely_pft_constructor() result(this) - implicit none - class(wesely_pft), pointer :: this - nullify(this%seasonal_wes) - end function wesely_pft_constructor - - function smoke_data_constructor() result(this) - implicit none - type(smoke_data) :: this - ! These are never used: - ! this%c0_pan = (/ 0.000, 0.006, 0.002, 0.009, 0.015, & - ! 0.006, 0.000, 0.000, 0.000, 0.002, 0.002 /) - ! this%k_pan = (/ 0.000, 0.010, 0.005, 0.004, 0.003, & - ! 0.005, 0.000, 0.000, 0.000, 0.075, 0.002 /) - ! this%month = 0 - ! this%seasonal_pft = wesely_pft() - ! nullify(this%is_aerosol) - nullify(this%alpha) - ! This is not called in the original non-thread-safe code: - ! call this%dep_init() - end function smoke_data_constructor - - subroutine smoke_data_destructor(this) - implicit none - type(smoke_data) :: this - if(associated(this%alpha)) then - deallocate(this%alpha) - nullify(this%alpha) - endif - ! Never used: - ! if(associated(this%is_aerosol)) then - ! deallocate(this%is_aerosol) - ! nullify(this%is_aerosolo) - ! endif - end subroutine smoke_data_destructor - - -! SUBROUTINE dep_init( id, numgas, mminlu_loc, & -! ips, ipe, jps, jpe, ide, jde ) - SUBROUTINE dep_init(this,errmsg,errflg) - ! Lifted out of dep_simple_mod, this initializes - ! member variables that were module variables in - ! that module. -!-- - implicit none - class(smoke_data) :: this - character(*), intent(inout) :: errmsg - integer, intent(inout) :: errflg - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - ! Unused: - ! integer, intent(in) :: numgas - ! integer, intent(in) :: ips, ipe, jps, jpe - ! integer, intent(in) :: ide, jde - ! mmin_lu_loc had no definition, but is also unused - -!-------------------------------------------------- -! .. Local Scalars -!-------------------------------------------------- - INTEGER :: iland, iseason, l - integer :: iprt - integer :: astat - integer :: ncid - integer :: dimid - integer :: varid - integer :: cpos, slen - integer :: lon_e, lat_e - integer :: iend, jend - integer :: chem_opt - integer, allocatable :: input_wes_seasonal(:,:,:,:) - REAL(KIND_PHYS) :: sc - character(len=128) :: err_msg - character(len=128) :: filename - character(len=3) :: id_num -!-------------------------------------------------- -! .. Local Arrays -!-------------------------------------------------- - REAL(KIND_PHYS) :: dat1(nlu,dep_seasons), dat2(nlu,dep_seasons), & - dat3(nlu,dep_seasons), dat4(nlu,dep_seasons), & - dat5(nlu,dep_seasons), dat6(nlu,dep_seasons), & - dat7(nlu,dep_seasons) - ! REAL(KIND_PHYS) :: dat8(pan_seasons,pan_lands) - chem_opt = chem_opt - -!-------------------------------------------------- -! .. Data Statements .. -! THIS%RI for stomatal resistance -! data ((this%ri(ILAND,ISEASON),ILAND=1,nlu),ISEASON=1,dep_seasons)/0.10E+11, & - DATA ((dat1(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+11, & - 0.60E+02, 0.60E+02, 0.60E+02, 0.60E+02, 0.70E+02, 0.12E+03, & - 0.12E+03, 0.12E+03, 0.12E+03, 0.70E+02, 0.13E+03, 0.70E+02, & - 0.13E+03, 0.10E+03, 0.10E+11, 0.80E+02, 0.10E+03, 0.10E+11, & - 0.80E+02, 0.10E+03, 0.10E+03, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.12E+03, 0.10E+11, 0.10E+11, & - 0.70E+02, 0.25E+03, 0.50E+03, 0.10E+11, 0.10E+11, 0.50E+03, & - 0.10E+11, 0.10E+11, 0.50E+03, 0.50E+03, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.12E+03, 0.10E+11, & - 0.10E+11, 0.70E+02, 0.25E+03, 0.50E+03, 0.10E+11, 0.10E+11, & - 0.50E+03, 0.10E+11, 0.10E+11, 0.50E+03, 0.50E+03, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.70E+02, 0.40E+03, 0.80E+03, 0.10E+11, & - 0.10E+11, 0.80E+03, 0.10E+11, 0.10E+11, 0.80E+03, 0.80E+03, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.12E+03, 0.12E+03, & - 0.12E+03, 0.12E+03, 0.14E+03, 0.24E+03, 0.24E+03, 0.24E+03, & - 0.12E+03, 0.14E+03, 0.25E+03, 0.70E+02, 0.25E+03, 0.19E+03, & - 0.10E+11, 0.16E+03, 0.19E+03, 0.10E+11, 0.16E+03, 0.19E+03, & - 0.19E+03, 0.10E+11, 0.10E+11, 0.10E+11/ -! .. - IF (nlu/=25) THEN - errmsg='number of land use classifications not correct ' - errflg=1 - return - END IF - IF (dep_seasons/=5) THEN - errmsg='number of dep_seasons not correct ' - errflg=1 - return - END IF - -! SURFACE RESISTANCE DATA FOR DEPOSITION MODEL OF -! M. L. WESELY, ATMOSPHERIC ENVIRONMENT 23 (1989) 1293-1304 - -! Seasonal categories: -! 1: midsummer with lush vegetation -! 2: autumn with unharvested cropland -! 3: late autumn with frost, no snow -! 4: winter, snow on ground and subfreezing -! 5: transitional spring with partially green short annuals - -! Land use types: -! USGS type Wesely type -! 1: Urban and built-up land 1 -! 2: Dryland cropland and pasture 2 -! 3: Irrigated cropland and pasture 2 -! 4: Mix. dry/irrg. cropland and pasture 2 -! 5: Cropland/grassland mosaic 2 -! 6: Cropland/woodland mosaic 4 -! 7: Grassland 3 -! 8: Shrubland 3 -! 9: Mixed shrubland/grassland 3 -! 10: Savanna 3, always summer -! 11: Deciduous broadleaf forest 4 -! 12: Deciduous needleleaf forest 5, autumn and winter modi -! 13: Evergreen broadleaf forest 4, always summer -! 14: Evergreen needleleaf forest 5 -! 15: Mixed Forest 6 -! 16: Water Bodies 7 -! 17: Herbaceous wetland 9 -! 18: Wooded wetland 6 -! 19: Barren or sparsely vegetated 8 -! 20: Herbaceous Tundra 9 -! 21: Wooded Tundra 6 -! 22: Mixed Tundra 6 -! 23: Bare Ground Tundra 8 -! 24: Snow or Ice -, always winter -! 25: No data 8 - - -! Order of data: -! | -! | seasonal category -! \|/ -! ---> landuse type -! 1 2 3 4 5 6 7 8 9 -! THIS%RLU for outer surfaces in the upper canopy - DO iseason = 1, dep_seasons - this%ri(1:nlu,iseason) = dat1(1:nlu,iseason) - END DO -! data ((this%rlu(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.10E+11, & - DATA ((dat2(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+11, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.10E+11, 0.25E+04, 0.20E+04, 0.10E+11, & - 0.25E+04, 0.20E+04, 0.20E+04, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, & - 0.90E+04, 0.90E+04, 0.90E+04, 0.20E+04, 0.90E+04, 0.90E+04, & - 0.20E+04, 0.40E+04, 0.80E+04, 0.10E+11, 0.90E+04, 0.80E+04, & - 0.10E+11, 0.90E+04, 0.80E+04, 0.80E+04, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, & - 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, 0.20E+04, 0.90E+04, & - 0.90E+04, 0.20E+04, 0.40E+04, 0.80E+04, 0.10E+11, 0.90E+04, & - 0.80E+04, 0.10E+11, 0.90E+04, 0.80E+04, 0.80E+04, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.20E+04, 0.60E+04, 0.90E+04, 0.10E+11, & - 0.90E+04, 0.90E+04, 0.10E+11, 0.90E+04, 0.90E+04, 0.90E+04, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.40E+04, 0.40E+04, & - 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, & - 0.20E+04, 0.40E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.30E+04, & - 0.10E+11, 0.40E+04, 0.30E+04, 0.10E+11, 0.40E+04, 0.30E+04, & - 0.30E+04, 0.10E+11, 0.10E+11, 0.10E+11/ - DO iseason = 1, dep_seasons - this%rlu(1:nlu,iseason) = dat2(1:nlu,iseason) - END DO -! THIS%RAC for transfer that depends on canopy height and density -! data ((this%rac(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.10E+03, & - DATA ((dat3(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+04, 0.10E+03, & - 0.10E+03, 0.10E+03, 0.10E+03, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.00E+00, 0.30E+03, 0.20E+04, 0.00E+00, & - 0.30E+03, 0.20E+04, 0.20E+04, 0.00E+00, 0.00E+00, 0.00E+00, & - 0.10E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+04, & - 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, 0.15E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.17E+04, 0.00E+00, 0.20E+03, 0.17E+04, & - 0.00E+00, 0.20E+03, 0.17E+04, 0.17E+04, 0.00E+00, 0.00E+00, & - 0.00E+00, 0.10E+03, 0.10E+02, 0.10E+02, 0.10E+02, 0.10E+02, & - 0.10E+04, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+04, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.15E+04, 0.00E+00, 0.10E+03, & - 0.15E+04, 0.00E+00, 0.10E+03, 0.15E+04, 0.15E+04, 0.00E+00, & - 0.00E+00, 0.00E+00, 0.10E+03, 0.10E+02, 0.10E+02, 0.10E+02, & - 0.10E+02, 0.10E+04, 0.10E+02, 0.10E+02, 0.10E+02, 0.10E+02, & - 0.10E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.15E+04, 0.00E+00, & - 0.50E+02, 0.15E+04, 0.00E+00, 0.50E+02, 0.15E+04, 0.15E+04, & - 0.00E+00, 0.00E+00, 0.00E+00, 0.10E+03, 0.50E+02, 0.50E+02, & - 0.50E+02, 0.50E+02, 0.12E+04, 0.80E+02, 0.80E+02, 0.80E+02, & - 0.10E+03, 0.12E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.15E+04, & - 0.00E+00, 0.20E+03, 0.15E+04, 0.00E+00, 0.20E+03, 0.15E+04, & - 0.15E+04, 0.00E+00, 0.00E+00, 0.00E+00/ - DO iseason = 1, dep_seasons - this%rac(1:nlu,iseason) = dat3(1:nlu,iseason) - END DO -! THIS%RGSS for ground surface SO2 -! data ((this%rgss(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.40E+03, & - DATA ((dat4(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.40E+03, & - 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.50E+03, 0.35E+03, & - 0.35E+03, 0.35E+03, 0.35E+03, 0.50E+03, 0.50E+03, 0.50E+03, & - 0.50E+03, 0.10E+03, 0.10E+01, 0.10E+01, 0.10E+03, 0.10E+04, & - 0.10E+01, 0.10E+03, 0.10E+03, 0.10E+04, 0.10E+03, 0.10E+04, & - 0.40E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.50E+03, & - 0.35E+03, 0.35E+03, 0.35E+03, 0.35E+03, 0.50E+03, 0.50E+03, & - 0.50E+03, 0.50E+03, 0.10E+03, 0.10E+01, 0.10E+01, 0.10E+03, & - 0.10E+04, 0.10E+01, 0.10E+03, 0.10E+03, 0.10E+04, 0.10E+03, & - 0.10E+04, 0.40E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, & - 0.50E+03, 0.35E+03, 0.35E+03, 0.35E+03, 0.35E+03, 0.50E+03, & - 0.50E+03, 0.50E+03, 0.50E+03, 0.20E+03, 0.10E+01, 0.10E+01, & - 0.20E+03, 0.10E+04, 0.10E+01, 0.20E+03, 0.20E+03, 0.10E+04, & - 0.10E+03, 0.10E+04, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, & - 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, & - 0.10E+03, 0.10E+03, 0.50E+03, 0.10E+03, 0.10E+03, 0.10E+01, & - 0.10E+03, 0.10E+03, 0.10E+04, 0.10E+03, 0.10E+03, 0.10E+03, & - 0.10E+04, 0.10E+03, 0.10E+04, 0.50E+03, 0.15E+03, 0.15E+03, & - 0.15E+03, 0.15E+03, 0.50E+03, 0.35E+03, 0.35E+03, 0.35E+03, & - 0.35E+03, 0.50E+03, 0.50E+03, 0.50E+03, 0.50E+03, 0.20E+03, & - 0.10E+01, 0.10E+01, 0.20E+03, 0.10E+04, 0.10E+01, 0.20E+03, & - 0.20E+03, 0.10E+04, 0.10E+03, 0.10E+04/ - DO iseason = 1, dep_seasons - this%rgss(1:nlu,iseason) = dat4(1:nlu,iseason) - END DO -! THIS%RGSO for ground surface O3 -! data ((this%rgso(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.30E+03, & - DATA ((dat5(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.30E+03, & - 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.30E+03, 0.20E+04, 0.10E+04, 0.30E+03, 0.40E+03, & - 0.10E+04, 0.30E+03, 0.30E+03, 0.40E+03, 0.35E+04, 0.40E+03, & - 0.30E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.30E+03, 0.20E+04, 0.80E+03, 0.30E+03, & - 0.40E+03, 0.80E+03, 0.30E+03, 0.30E+03, 0.40E+03, 0.35E+04, & - 0.40E+03, 0.30E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.30E+03, 0.20E+04, 0.10E+04, & - 0.30E+03, 0.40E+03, 0.10E+04, 0.30E+03, 0.30E+03, 0.40E+03, & - 0.35E+04, 0.40E+03, 0.60E+03, 0.35E+04, 0.35E+04, 0.35E+04, & - 0.35E+04, 0.35E+04, 0.35E+04, 0.35E+04, 0.35E+04, 0.35E+04, & - 0.35E+04, 0.35E+04, 0.20E+03, 0.35E+04, 0.35E+04, 0.20E+04, & - 0.35E+04, 0.35E+04, 0.40E+03, 0.35E+04, 0.35E+04, 0.35E+04, & - 0.40E+03, 0.35E+04, 0.40E+03, 0.30E+03, 0.15E+03, 0.15E+03, & - 0.15E+03, 0.15E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.30E+03, & - 0.20E+04, 0.10E+04, 0.30E+03, 0.40E+03, 0.10E+04, 0.30E+03, & - 0.30E+03, 0.40E+03, 0.35E+04, 0.40E+03/ - DO iseason = 1, dep_seasons - this%rgso(1:nlu,iseason) = dat5(1:nlu,iseason) - END DO -! THIS%RCLS for exposed surfaces in the lower canopy SO2 -! data ((this%rcls(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.10E+11, & - DATA ((dat6(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+11, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.10E+11, 0.25E+04, 0.20E+04, 0.10E+11, & - 0.25E+04, 0.20E+04, 0.20E+04, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, & - 0.90E+04, 0.90E+04, 0.90E+04, 0.20E+04, 0.90E+04, 0.90E+04, & - 0.20E+04, 0.20E+04, 0.40E+04, 0.10E+11, 0.90E+04, 0.40E+04, & - 0.10E+11, 0.90E+04, 0.40E+04, 0.40E+04, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, 0.20E+04, 0.90E+04, & - 0.90E+04, 0.20E+04, 0.30E+04, 0.60E+04, 0.10E+11, 0.90E+04, & - 0.60E+04, 0.10E+11, 0.90E+04, 0.60E+04, 0.60E+04, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.90E+04, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.90E+04, 0.90E+04, 0.20E+04, 0.20E+03, 0.40E+03, 0.10E+11, & - 0.90E+04, 0.40E+03, 0.10E+11, 0.90E+04, 0.40E+03, 0.40E+03, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.40E+04, 0.40E+04, & - 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, & - 0.20E+04, 0.40E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.30E+04, & - 0.10E+11, 0.40E+04, 0.30E+04, 0.10E+11, 0.40E+04, 0.30E+04, & - 0.30E+04, 0.10E+11, 0.10E+11, 0.10E+11/ - DO iseason = 1, dep_seasons - this%rcls(1:nlu,iseason) = dat6(1:nlu,iseason) - END DO -! THIS%RCLO for exposed surfaces in the lower canopy O3 -! data ((this%rclo(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.10E+11, & - DATA ((dat7(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+11, & - 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.10E+04, 0.10E+04, 0.10E+11, 0.10E+04, 0.10E+04, 0.10E+11, & - 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.40E+03, 0.40E+03, 0.40E+03, 0.40E+03, 0.40E+03, & - 0.40E+03, 0.40E+03, 0.40E+03, 0.10E+04, 0.40E+03, 0.40E+03, & - 0.10E+04, 0.10E+04, 0.60E+03, 0.10E+11, 0.40E+03, 0.60E+03, & - 0.10E+11, 0.40E+03, 0.60E+03, 0.60E+03, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.40E+03, 0.40E+03, 0.40E+03, 0.40E+03, 0.10E+04, 0.40E+03, & - 0.40E+03, 0.10E+04, 0.10E+04, 0.60E+03, 0.10E+11, 0.80E+03, & - 0.60E+03, 0.10E+11, 0.80E+03, 0.60E+03, 0.60E+03, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.10E+04, 0.40E+03, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.40E+03, 0.40E+03, 0.10E+04, 0.15E+04, 0.60E+03, 0.10E+11, & - 0.80E+03, 0.60E+03, 0.10E+11, 0.80E+03, 0.60E+03, 0.60E+03, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+04, 0.10E+04, & - 0.10E+04, 0.10E+04, 0.50E+03, 0.50E+03, 0.50E+03, 0.50E+03, & - 0.10E+04, 0.50E+03, 0.15E+04, 0.10E+04, 0.15E+04, 0.70E+03, & - 0.10E+11, 0.60E+03, 0.70E+03, 0.10E+11, 0.60E+03, 0.70E+03, & - 0.70E+03, 0.10E+11, 0.10E+11, 0.10E+11/ - - DO iseason = 1, dep_seasons - this%rclo(1:nlu,iseason) = dat7(1:nlu,iseason) - END DO - - ! data ((dat8(iseason,iland),iseason=1,pan_seasons),iland=1,pan_lands) / & - ! 1.e36, 60., 120., 70., 130., 100.,1.e36,1.e36, 80., 100., 150., & - ! 1.e36,1.e36,1.e36,1.e36, 250., 500.,1.e36,1.e36,1.e36,1.e36,1.e36, & - ! 1.e36,1.e36,1.e36,1.e36, 250., 500.,1.e36,1.e36,1.e36,1.e36,1.e36, & - ! 1.e36,1.e36,1.e36,1.e36, 400., 800.,1.e36,1.e36,1.e36,1.e36,1.e36, & - ! 1.e36, 120., 240., 140., 250., 190.,1.e36,1.e36, 160., 200., 300. / - ! this%ri_pan(:,:) = dat8(:,:) - -!-------------------------------------------------- -! Initialize parameters -!-------------------------------------------------- - this%hstar = 0. - this%hstar4 = 0. - this%dhr = 0. - this%f0 = 0. - this%dratio = 1.0 ! FIXME: IS THIS RIGHT? - this%scpr23 = 1.0 ! FIXME: IS THIS RIGHT? - -!-------------------------------------------------- -! HENRY''S LAW COEFFICIENTS -! Effective Henry''s law coefficient at pH 7 -! [KH298]=mole/(l atm) -!-------------------------------------------------- - -! DATA FOR AEROSOL PARTICLE DEPOSITION FOR THE MODEL OF -! J. W. ERISMAN, A. VAN PUL AND P. WYERS -! ATMOSPHERIC ENVIRONMENT 28 (1994), 2595-2607 - -! vd = (u* / k) * CORRECTION FACTORS - -! CONSTANT K FOR LANDUSE TYPES: -! urban and built-up land - this%kpart(1) = 500. -! dryland cropland and pasture - this%kpart(2) = 500. -! irrigated cropland and pasture - this%kpart(3) = 500. -! mixed dryland/irrigated cropland and past - this%kpart(4) = 500. -! cropland/grassland mosaic - this%kpart(5) = 500. -! cropland/woodland mosaic - this%kpart(6) = 100. -! grassland - this%kpart(7) = 500. -! shrubland - this%kpart(8) = 500. -! mixed shrubland/grassland - this%kpart(9) = 500. -! savanna - this%kpart(10) = 500. -! deciduous broadleaf forest - this%kpart(11) = 100. -! deciduous needleleaf forest - this%kpart(12) = 100. -! evergreen broadleaf forest - this%kpart(13) = 100. -! evergreen needleleaf forest - this%kpart(14) = 100. -! mixed forest - this%kpart(15) = 100. -! water bodies - this%kpart(16) = 500. -! herbaceous wetland - this%kpart(17) = 500. -! wooded wetland - this%kpart(18) = 500. -! barren or sparsely vegetated - this%kpart(19) = 500. -! herbaceous tundra - this%kpart(20) = 500. -! wooded tundra - this%kpart(21) = 100. -! mixed tundra - this%kpart(22) = 500. -! bare ground tundra - this%kpart(23) = 500. -! snow or ice - this%kpart(24) = 500. -! Comments: - this%kpart(25) = 500. -! Erisman et al. (1994) give -! k = 500 for low vegetation and k = 100 for forests. - -! For desert k = 500 is taken according to measurements -! on bare soil by -! J. Fontan, A. Lopez, E. Lamaud and A. Druilhet (1997) -! Vertical Flux Measurements of the Submicronic Aerosol Particles -! and Parametrisation of the Dry Deposition Velocity -! in: Biosphere-Atmosphere Exchange of Pollutants -! and Trace Substances -! Editor: S. Slanina. Springer-Verlag Berlin, Heidelberg, 1997 -! pp. 381-390 - -! For coniferous forest the Erisman value of k = 100 is taken. -! Measurements of Erisman et al. (1997) in a coniferous forest -! in the Netherlands, lead to values of k between 20 and 38 -! (Atmospheric Environment 31 (1997), 321-332). -! However, these high values of vd may be reached during -! instable cases. The eddy correlation measurements -! of Gallagher et al. (1997) made during the same experiment -! show for stable cases (L>0) values of k between 200 and 250 -! at minimum (Atmospheric Environment 31 (1997), 359-373). -! Fontan et al. (1997) found k = 250 in a forest -! of maritime pine in southwestern France. - -! For gras, model calculations of Davidson et al. support -! the value of 500. -! C. I. Davidson, J. M. Miller and M. A. Pleskov -! The Influence of Surface Structure on Predicted Particles -! Dry Deposition to Natural Gras Canopies -! Water, Air, and Soil Pollution 18 (1982) 25-43 - -! Snow covered surface: The experiment of Ibrahim et al. (1983) -! gives k = 436 for 0.7 um diameter particles. -! The deposition velocity of Milford and Davidson (1987) -! gives k = 154 for continental sulfate aerosol. -! M. Ibrahim, L. A. Barrie and F. Fanaki -! Atmospheric Environment 17 (1983), 781-788 - -! J. B. Milford and C. I. Davidson -! The Sizes of Particulate Sulfate and Nitrate in the Atmosphere -! - A Review -! JAPCA 37 (1987), 125-134 -! no data -! WRITE (0,*) ' return from rcread ' -! ********************************************************* - -! Simplified landuse scheme for deposition and biogenic emission -! subroutines -! (ISWATER and ISICE are already defined elsewhere, -! therefore water and ice are not considered here) - -! 1 urban or bare soil -! 2 agricultural -! 3 grassland -! 4 deciduous forest -! 5 coniferous and mixed forest -! 6 other natural landuse categories - - - IF (mminlu=='OLD ') THEN - this%ixxxlu(1) = 1 - this%ixxxlu(2) = 2 - this%ixxxlu(3) = 3 - this%ixxxlu(4) = 4 - this%ixxxlu(5) = 5 - this%ixxxlu(6) = 5 - this%ixxxlu(7) = 0 - this%ixxxlu(8) = 6 - this%ixxxlu(9) = 1 - this%ixxxlu(10) = 6 - this%ixxxlu(11) = 0 - this%ixxxlu(12) = 4 - this%ixxxlu(13) = 6 - END IF - IF (mminlu=='USGS') THEN - this%ixxxlu(1) = 1 - this%ixxxlu(2) = 2 - this%ixxxlu(3) = 2 - this%ixxxlu(4) = 2 - this%ixxxlu(5) = 2 - this%ixxxlu(6) = 4 - this%ixxxlu(7) = 3 - this%ixxxlu(8) = 6 - this%ixxxlu(9) = 3 - this%ixxxlu(10) = 6 - this%ixxxlu(11) = 4 - this%ixxxlu(12) = 5 - this%ixxxlu(13) = 4 - this%ixxxlu(14) = 5 - this%ixxxlu(15) = 5 - this%ixxxlu(16) = 0 - this%ixxxlu(17) = 6 - this%ixxxlu(18) = 4 - this%ixxxlu(19) = 1 - this%ixxxlu(20) = 6 - this%ixxxlu(21) = 4 - this%ixxxlu(22) = 6 - this%ixxxlu(23) = 1 - this%ixxxlu(24) = 0 - this%ixxxlu(25) = 1 - END IF - IF (mminlu=='SiB ') THEN - this%ixxxlu(1) = 4 - this%ixxxlu(2) = 4 - this%ixxxlu(3) = 4 - this%ixxxlu(4) = 5 - this%ixxxlu(5) = 5 - this%ixxxlu(6) = 6 - this%ixxxlu(7) = 3 - this%ixxxlu(8) = 6 - this%ixxxlu(9) = 6 - this%ixxxlu(10) = 6 - this%ixxxlu(11) = 1 - this%ixxxlu(12) = 2 - this%ixxxlu(13) = 6 - this%ixxxlu(14) = 1 - this%ixxxlu(15) = 0 - this%ixxxlu(16) = 0 - this%ixxxlu(17) = 1 - END IF - - END SUBROUTINE dep_init -end module rrfs_smoke_data diff --git a/smoke/rrfs_smoke_lsdep_wrapper.F90 b/smoke/rrfs_smoke_lsdep_wrapper.F90 deleted file mode 100644 index 1fd7a2d3f..000000000 --- a/smoke/rrfs_smoke_lsdep_wrapper.F90 +++ /dev/null @@ -1,323 +0,0 @@ -!>\file rrfs_smoke_lsdep_wrapper.F90 -!! This file is RRFS-smoke large-scale wet deposition wrapper with CCPP -!! Haiqin.Li@noaa.gov 04/2021 - - module rrfs_smoke_lsdep_wrapper - - use machine , only : kind_phys - use rrfs_smoke_config - use dep_wet_ls_mod - use dust_data_mod - use rrfs_smoke_data - - implicit none - - private - - public :: rrfs_smoke_lsdep_wrapper_run - -contains - -!>\defgroup rrfs_smoke_lsdep_wrapper GSD Chem driver Module -!> \ingroup gsd_chem_group -!! This is the GSD Chem driver Module -!! \section arg_table_rrfs_smoke_lsdep_wrapper_run Argument Table -!! \htmlinclude rrfs_smoke_lsdep_wrapper_run.html -!! -!>\section rrfs_smoke_lsdep_wrapper GSD Chemistry Scheme General Algorithm -!> @{ - subroutine rrfs_smoke_lsdep_wrapper_run(im, kte, kme, ktau, dt, & - rain_cpl, rainc_cpl, g, & - pr3d, ph3d,phl3d, prl3d, tk3d, us3d, vs3d, spechum, & - w, dqdt, ntrac,ntsmoke,ntdust, & - gq0,qgrs,wetdep_ls_opt_in, & - errmsg,errflg) - - implicit none - - - integer, intent(in) :: im,kte,kme,ktau - integer, intent(in) :: ntrac,ntsmoke,ntdust - real(kind_phys),intent(in) :: dt,g - - integer, parameter :: ids=1,jds=1,jde=1, kds=1 - integer, parameter :: ims=1,jms=1,jme=1, kms=1 - integer, parameter :: its=1,jts=1,jte=1, kts=1 - - real(kind_phys), dimension(:), intent(in) :: rain_cpl, rainc_cpl - real(kind_phys), dimension(:,:), intent(in) :: ph3d, pr3d - real(kind_phys), dimension(:,:), intent(in) :: phl3d, prl3d, tk3d, & - us3d, vs3d, spechum, w, dqdt - real(kind_phys), dimension(:,:,:), intent(inout) :: gq0, qgrs - integer, intent(in) :: wetdep_ls_opt_in - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - real(kind_phys), dimension(1:im, 1:kme,jms:jme) :: rri, t_phy, u_phy, v_phy, & - p_phy, z_at_w, dz8w, p8w, t8w, rho_phy, vvel, dqdti - - real(kind_phys), dimension(ims:im, jms:jme) :: rcav, rnav - -!>- vapor & chemistry variables - real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_moist) :: moist - real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_chem ) :: chem - real(kind_phys), dimension(ims:im, jms:jme, 1:num_chem ) :: var_rmv - - integer :: ide, ime, ite, kde - - real(kind_phys) :: dtstep - real(kind_phys), dimension(1:num_chem) :: ppm2ugkg - - type(smoke_data), pointer :: data - -!>-- local variables - integer :: i, j, jp, k, kp, n - - data=>get_thread_smoke_data() - - errmsg = '' - errflg = 0 - - wetdep_ls_opt = wetdep_ls_opt_in - !print*,'hli wetdep_ls_opt',wetdep_ls_opt - - ! -- set domain - ide=im - ime=im - ite=im - kde=kte - - ! -- volume to mass fraction conversion table (ppm -> ug/kg) - ppm2ugkg = 1._kind_phys - !ppm2ugkg(p_so2 ) = 1.e+03_kind_phys * mw_so2_aer / mwdry - ppm2ugkg(p_sulf) = 1.e+03_kind_phys * mw_so4_aer / mwdry - - ! -- initialize large-sacle wet depostion - if (ktau==1) then - call dep_wet_ls_init(data) - endif - - ! -- set control flags - - ! -- compute accumulated large-scale and convective rainfall since last call - if (ktau > 1) then - dtstep = call_chemistry * dt - else - dtstep = dt - end if - - ! -- compute incremental convective and large-scale rainfall - do i=its,ite - rcav(i,1)=max(rainc_cpl(i)*1000. , 0.) ! meter to mm - rnav(i,1)=max((rain_cpl(i)-rainc_cpl(i))*1000., 0.) ! meter to mm - enddo - -!!! - -!>- get ready for chemistry run - call rrfs_smoke_prep_lsdep(data,ktau,dtstep, & - pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,w, dqdt, & - rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & - t8w,dqdti,z_at_w,vvel,g, & - ntsmoke,ntdust, & - ntrac,gq0,num_chem, num_moist, & - ppm2ugkg,moist,chem, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - - ! -- ls wet deposition - select case (wetdep_ls_opt) - case (WDLS_OPT_GSD) - call wetdep_ls(data,dt,chem,rnav,moist,rho_phy,var_rmv, & - num_moist,num_chem,p_qc,p_qi,dz8w,vvel, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - case (WDLS_OPT_NGAC) - call WetRemovalGOCART(data,its,ite, jts,jte, kts,kte, 1,1, dt, & - num_chem,var_rmv,chem,p_phy,t_phy, & - rho_phy,dqdti,rcav,rnav, g, & - ims,ime, jms,jme, kms,kme) - !if (chem_rc_check(localrc, msg="Failure in NGAC wet removal scheme", & - ! file=__FILE__, line=__LINE__, rc=rc)) return - case default - ! -- no further option implemented - end select - - - ! -- put chem stuff back into tracer array - do k=kts,kte - do i=its,ite - gq0(i,k,ntsmoke)=ppm2ugkg(p_oc1 ) * max(epsilc,chem(i,k,1,p_oc1)) - gq0(i,k,ntdust )=ppm2ugkg(p_dust_1) * max(epsilc,chem(i,k,1,p_dust_1)) - enddo - enddo - - do k=kts,kte - do i=its,ite - qgrs(i,k,ntsmoke)=gq0(i,k,ntsmoke) - qgrs(i,k,ntdust )=gq0(i,k,ntdust ) - enddo - enddo - - -! - end subroutine rrfs_smoke_lsdep_wrapper_run -!> @} - - subroutine rrfs_smoke_prep_lsdep(data,ktau,dtstep, & - pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,w,dqdt, & - rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & - t8w,dqdti,z_at_w,vvel,g, & - ntsmoke,ntdust, & - ntrac,gq0,num_chem, num_moist, & - ppm2ugkg,moist,chem, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - implicit none - type(smoke_data), intent(inout) :: data - - !Chem input configuration - integer, intent(in) :: ktau - real(kind=kind_phys), intent(in) :: dtstep,g - - !FV3 input variables - integer, intent(in) :: ntrac,ntsmoke,ntdust - real(kind=kind_phys), dimension(ims:ime, kms:kme), intent(in) :: pr3d,ph3d - real(kind=kind_phys), dimension(ims:ime, kts:kte), intent(in) :: & - phl3d,tk3d,prl3d,us3d,vs3d,spechum,w,dqdt - real(kind=kind_phys), dimension(ims:ime, kts:kte,ntrac), intent(in) :: gq0 - - - !GSD Chem variables - integer,intent(in) :: num_chem, num_moist - integer,intent(in) :: ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte - - real(kind_phys), dimension(num_chem), intent(in) :: ppm2ugkg - - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme), intent(out) :: & - rri, t_phy, u_phy, v_phy, p_phy, rho_phy, dz8w, p8w, t8w, vvel, dqdti - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme, num_moist), intent(out) :: moist - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme, num_chem), intent(out) :: chem - - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme), intent(out) :: z_at_w - - ! -- local variables -! real(kind=kind_phys), dimension(ims:ime, kms:kme, jms:jme) :: p_phy - real(kind_phys) :: factor,factor2,pu,pl,aln,pwant - real(kind_phys) :: xhour,xmin,xlonn,xtime,real_time - real(kind_phys), DIMENSION (1,1) :: sza,cosszax - integer i,ip,j,jp,k,kp,kk,kkp,nv,jmax,jmaxi,l,ll,n,ndystep,ixhour - - ! -- initialize output arrays - rri = 0._kind_phys - t_phy = 0._kind_phys - u_phy = 0._kind_phys - v_phy = 0._kind_phys - p_phy = 0._kind_phys - rho_phy = 0._kind_phys - dz8w = 0._kind_phys - p8w = 0._kind_phys - t8w = 0._kind_phys - vvel = 0._kind_phys - dqdti = 0._kind_phys - moist = 0._kind_phys - chem = 0._kind_phys - z_at_w = 0._kind_phys - - - do j=jts,jte - jp = j - jts + 1 - do i=its,ite - ip = i - its + 1 - z_at_w(i,kts,j)=max(0.,ph3d(ip,1)/g) - enddo - enddo - - do j=jts,jte - jp = j - jts + 1 - do k=kts,kte - kp = k - kts + 1 - do i=its,ite - ip = i - its + 1 - dz8w(i,k,j)=abs(ph3d(ip,kp+1)-ph3d(ip,kp))/g - z_at_w(i,k+1,j)=z_at_w(i,k,j)+dz8w(i,k,j) - enddo - enddo - enddo - - do j=jts,jte - jp = j - jts + 1 - do k=kts,kte+1 - kp = k - kts + 1 - do i=its,ite - ip = i - its + 1 - p8w(i,k,j)=pr3d(ip,kp) - enddo - enddo - enddo - - do j=jts,jte - jp = j - jts + 1 - do k=kts,kte+1 - kk=min(k,kte) - kkp = kk - kts + 1 - do i=its,ite - ip = i - its + 1 - dz8w(i,k,j)=z_at_w(i,kk+1,j)-z_at_w(i,kk,j) - t_phy(i,k,j)=tk3d(ip,kkp) - p_phy(i,k,j)=prl3d(ip,kkp) - u_phy(i,k,j)=us3d(ip,kkp) - dqdti(i,k,j)=dqdt(ip,kkp) - v_phy(i,k,j)=vs3d(ip,kkp) - rho_phy(i,k,j)=p_phy(i,k,j)/(287.04*t_phy(i,k,j)*(1.+.608*spechum(ip,kkp))) - rri(i,k,j)=1./rho_phy(i,k,j) - vvel(i,k,j)=-w(ip,kkp)*rri(i,k,j)/g - moist(i,k,j,:)=0. - moist(i,k,j,1)=gq0(ip,kkp,p_atm_shum) - if (t_phy(i,k,j) > 265.) then - moist(i,k,j,2)=gq0(ip,kkp,p_atm_cldq) - moist(i,k,j,3)=0. - if (moist(i,k,j,2) < 1.e-8) moist(i,k,j,2)=0. - else - moist(i,k,j,2)=0. - moist(i,k,j,3)=gq0(ip,kkp,p_atm_cldq) - if(moist(i,k,j,3) < 1.e-8)moist(i,k,j,3)=0. - endif - !-- - enddo - enddo - enddo - - do j=jts,jte - do k=2,kte - do i=its,ite - t8w(i,k,j)=.5*(t_phy(i,k,j)+t_phy(i,k-1,j)) - enddo - enddo - enddo - - ! -- only used in phtolysis.... - do j=jts,jte - do i=its,ite - t8w(i,1,j)=t_phy(i,1,j) - t8w(i,kte+1,j)=t_phy(i,kte,j) - enddo - enddo - - - do k=kms,kte - do i=ims,ime - chem(i,k,jts,p_oc1 )=max(epsilc,gq0(i,k,ntsmoke)/ppm2ugkg(p_oc1)) - chem(i,k,jts,p_dust_1)=max(epsilc,gq0(i,k,ntdust )/ppm2ugkg(p_dust_1)) - enddo - enddo - - - end subroutine rrfs_smoke_prep_lsdep -!> @} - end module rrfs_smoke_lsdep_wrapper diff --git a/smoke/rrfs_smoke_lsdep_wrapper.meta b/smoke/rrfs_smoke_lsdep_wrapper.meta deleted file mode 100755 index 23c71fce8..000000000 --- a/smoke/rrfs_smoke_lsdep_wrapper.meta +++ /dev/null @@ -1,208 +0,0 @@ -[ccpp-table-properties] - name = rrfs_smoke_lsdep_wrapper - type = scheme - dependencies = dep_dry_gocart_mod.F90,dep_dry_mod.F90,dep_simple_mod.F90,dep_vertmx_mod.F90,dep_wet_ls_mod.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,rrfs_smoke_data.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90 - -######################################################################## -[ccpp-arg-table] - name = rrfs_smoke_lsdep_wrapper_run - type = scheme -[im] - standard_name = horizontal_loop_extent - long_name = horizontal loop extent - units = count - dimensions = () - type = integer - intent = in -[kte] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[kme] - standard_name = vertical_interface_dimension - long_name = number of vertical levels plus one - units = count - dimensions = () - type = integer - intent = in -[ktau] - standard_name = index_of_timestep - long_name = current forecast iteration - units = index - dimensions = () - type = integer - intent = in -[dt] - standard_name = timestep_for_physics - long_name = physics time step - units = s - dimensions = () - type = real - kind = kind_phys - intent = in -[rain_cpl] - standard_name = lwe_thickness_of_precipitation_amount_on_dynamics_timestep - long_name = total rain at this time step - units = m - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[rainc_cpl] - standard_name = lwe_thickness_of_convective_precipitation_amount_on_dynamics_timestep - long_name = convective rain at this time step - units = m - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[g] - standard_name = gravitational_acceleration - long_name = gravitational acceleration - units = m s-2 - dimensions = () - type = real - kind = kind_phys - intent = in -[pr3d] - standard_name = air_pressure_at_interface - long_name = air pressure at model layer interfaces - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[ph3d] - standard_name = geopotential_at_interface - long_name = geopotential at model layer interfaces - units = m2 s-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[phl3d] - standard_name = geopotential - long_name = geopotential at model layer centers - units = m2 s-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[prl3d] - standard_name = air_pressure - long_name = mean layer pressure - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[tk3d] - standard_name = air_temperature_of_new_state - long_name = updated temperature - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[us3d] - standard_name = x_wind_of_new_state - long_name = updated x-direction wind - units = m s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[vs3d] - standard_name = y_wind_of_new_state - long_name = updated y-direction wind - units = m s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[spechum] - standard_name = specific_humidity_of_new_state - long_name = water vapor specific humidity updated by physics - units = kg kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[w] - standard_name = lagrangian_tendency_of_air_pressure - long_name = layer mean vertical velocity - units = Pa s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[dqdt] - standard_name = instantaneous_water_vapor_specific_humidity_tendency_due_to_convection - long_name = instantaneous moisture tendency due to convection - units = kg kg-1 s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[ntrac] - standard_name = number_of_tracers - long_name = number of tracers - units = count - dimensions = () - type = integer - intent = in -[ntsmoke] - standard_name = index_for_smoke_in_tracer_concentration_array - long_name = tracer index for smoke - units = index - dimensions = () - type = integer - intent = in -[ntdust] - standard_name = index_for_dust_in_tracer_concentration_array - long_name = tracer index for dust - units = index - dimensions = () - type = integer - intent = in -[gq0] - standard_name = tracer_concentration_of_new_state - long_name = tracer concentration updated by physics - units = kg kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) - type = real - kind = kind_phys - intent = inout -[qgrs] - standard_name = tracer_concentration - long_name = model layer mean tracer concentration - units = kg kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) - type = real - kind = kind_phys - intent = inout -[wetdep_ls_opt_in] - standard_name = control_for_smoke_wet_deposition - long_name = rrfs smoke large scale wet deposition option - units = index - dimensions = () - type = integer - intent = in -[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 From 40f93615293f648b8473ffff101a372c4ad781f1 Mon Sep 17 00:00:00 2001 From: "Haiqin.Li" Date: Mon, 13 Mar 2023 17:20:01 +0000 Subject: [PATCH 06/19] "include the MYNN-EDMF update from PR #43" --- physics/module_bl_mynn.F90 | 3172 ++++++++++++++++----------------- physics/mynnedmf_wrapper.F90 | 424 ++--- physics/mynnedmf_wrapper.meta | 60 +- physics/sgscloud_radpre.F90 | 132 +- physics/sgscloud_radpre.meta | 38 + 5 files changed, 1965 insertions(+), 1861 deletions(-) diff --git a/physics/module_bl_mynn.F90 b/physics/module_bl_mynn.F90 index d1fae478d..51a906faf 100644 --- a/physics/module_bl_mynn.F90 +++ b/physics/module_bl_mynn.F90 @@ -121,7 +121,7 @@ ! Hybrid PBL height diagnostic, which blends a theta-v-based ! definition in neutral/convective BL and a TKE-based definition ! in stable conditions. -! TKE budget output option (bl_mynn_tkebudget) +! TKE budget output option ! v3.5.0: TKE advection option (bl_mynn_tkeadvect) ! v3.5.1: Fog deposition related changes. ! v3.6.0: Removed fog deposition from the calculation of tendencies @@ -216,14 +216,14 @@ ! Misc small-impact bugfixes: ! 1) dz was incorrectly indexed in mym_condensation ! 2) configurations with icloud_bl = 0 were using uninitialized arrays -! v4.4 / CCPP +! v4.5 / CCPP ! This version includes many modifications that proved valuable in the global ! framework and removes some key lingering bugs in the mixing of chemical species. ! TKE Budget output fixed (Puhales, 2020-12) ! New option for stability function: (Puhales, 2020-12) ! bl_mynn_stfunc = 0 (original, Kansas-type function, Paulson, 1970 ) ! bl_mynn_stfunc = 1 (expanded range, same as used for Jimenez et al (MWR) -! see the Technical Note for this implementation. +! see the Technical Note for this implementation (small impact). ! Improved conservation of momentum and higher-order moments. ! Important bug fixes for mixing of chemical species. ! Addition of pressure-gradient effects on updraft momentum transport. @@ -253,58 +253,48 @@ MODULE module_bl_mynn IMPLICIT NONE -!get rid - INTEGER , PARAMETER :: param_first_scalar = 1, & - & p_qc = 2, & - & p_qr = 0, & - & p_qi = 2, & - & p_qs = 0, & - & p_qg = 0, & - & p_qnc= 0, & - & p_qni= 0 - !=================================================================== ! From here on, these are MYNN-specific parameters: ! The parameters below depend on stability functions of module_sf_mynn. - REAL, PARAMETER :: cphm_st=5.0, cphm_unst=16.0, & - cphh_st=5.0, cphh_unst=16.0 + real(kind_phys), PARAMETER :: cphm_st=5.0, cphm_unst=16.0, & + cphh_st=5.0, cphh_unst=16.0 ! Closure constants - REAL, PARAMETER :: & - &pr = 0.74, & - &g1 = 0.235, & ! NN2009 = 0.235 - &b1 = 24.0, & - &b2 = 15.0, & ! CKmod NN2009 - &c2 = 0.729, & ! 0.729, & !0.75, & - &c3 = 0.340, & ! 0.340, & !0.352, & - &c4 = 0.0, & - &c5 = 0.2, & + real(kind_phys), PARAMETER :: & + &pr = 0.74, & + &g1 = 0.235, & ! NN2009 = 0.235 + &b1 = 24.0, & + &b2 = 15.0, & ! CKmod NN2009 + &c2 = 0.729, & ! 0.729, & !0.75, & + &c3 = 0.340, & ! 0.340, & !0.352, & + &c4 = 0.0, & + &c5 = 0.2, & &a1 = b1*( 1.0-3.0*g1 )/6.0, & ! &c1 = g1 -1.0/( 3.0*a1*b1**(1.0/3.0) ), & &c1 = g1 -1.0/( 3.0*a1*2.88449914061481660), & &a2 = a1*( g1-c1 )/( g1*pr ), & &g2 = b2/b1*( 1.0-c3 ) +2.0*a1/b1*( 3.0-2.0*c2 ) - REAL, PARAMETER :: & - &cc2 = 1.0-c2, & - &cc3 = 1.0-c3, & - &e1c = 3.0*a2*b2*cc3, & - &e2c = 9.0*a1*a2*cc2, & + real(kind_phys), PARAMETER :: & + &cc2 = 1.0-c2, & + &cc3 = 1.0-c3, & + &e1c = 3.0*a2*b2*cc3, & + &e2c = 9.0*a1*a2*cc2, & &e3c = 9.0*a2*a2*cc2*( 1.0-c5 ), & - &e4c = 12.0*a1*a2*cc2, & + &e4c = 12.0*a1*a2*cc2, & &e5c = 6.0*a1*a1 ! Constants for min tke in elt integration (qmin), max z/L in els (zmax), ! and factor for eddy viscosity for TKE (Kq = Sqfac*Km): - REAL, PARAMETER :: qmin=0.0, zmax=1.0, Sqfac=3.0 + real(kind_phys), PARAMETER :: qmin=0.0, zmax=1.0, Sqfac=3.0 ! Note that the following mixing-length constants are now specified in mym_length ! &cns=3.5, alp1=0.23, alp2=0.3, alp3=3.0, alp4=10.0, alp5=0.2 - REAL, PARAMETER :: gpw=5./3., qcgmin=1.e-8, qkemin=1.e-12 - REAL, PARAMETER :: tliq = 269. !all hydrometeors are liquid when T > tliq + real(kind_phys), PARAMETER :: gpw=5./3., qcgmin=1.e-8, qkemin=1.e-12 + real(kind_phys), PARAMETER :: tliq = 269. !all hydrometeors are liquid when T > tliq ! Constants for cloud PDF (mym_condensation) - REAL, PARAMETER :: rr2=0.7071068, rrp=0.3989423 + real(kind_phys), PARAMETER :: rr2=0.7071068, rrp=0.3989423 !>Use Canuto/Kitamura mod (remove Ric and negative TKE) (1:yes, 0:no) !!For more info, see Canuto et al. (2008 JAS) and Kitamura (Journal of the @@ -314,12 +304,12 @@ MODULE module_bl_mynn !!(above) back to NN2009 values (see commented out lines next to the !!parameters above). This only removes the negative TKE problem !!but does not necessarily improve performance - neutral impact. - REAL, PARAMETER :: CKmod=1. + real(kind_phys), PARAMETER :: CKmod=1. !>Use Ito et al. (2015, BLM) scale-aware (0: no, 1: yes). Note that this also has impacts !!on the cloud PDF and mass-flux scheme, using Honnert et al. (2011) similarity function !!for TKE in the upper PBL/cloud layer. - REAL, PARAMETER :: scaleaware=1. + real(kind_phys), PARAMETER :: scaleaware=1. !>Of the following the options, use one OR the other, not both. !>Adding top-down diffusion driven by cloud-top radiative cooling @@ -341,32 +331,6 @@ MODULE module_bl_mynn LOGICAL, PARAMETER :: debug_code = .false. INTEGER, PARAMETER :: idbg = 23 !specific i-point to write out -! JAYMES- -!> Constants used for empirical calculations of saturation -!! vapor pressures (in function "esat") and saturation mixing ratios -!! (in function "qsat"), reproduced from module_mp_thompson.F, -!! v3.6 - REAL, PARAMETER:: J0= .611583699E03 - REAL, PARAMETER:: J1= .444606896E02 - REAL, PARAMETER:: J2= .143177157E01 - REAL, PARAMETER:: J3= .264224321E-1 - REAL, PARAMETER:: J4= .299291081E-3 - REAL, PARAMETER:: J5= .203154182E-5 - REAL, PARAMETER:: J6= .702620698E-8 - REAL, PARAMETER:: J7= .379534310E-11 - REAL, PARAMETER:: J8=-.321582393E-13 - - REAL, PARAMETER:: K0= .609868993E03 - REAL, PARAMETER:: K1= .499320233E02 - REAL, PARAMETER:: K2= .184672631E01 - REAL, PARAMETER:: K3= .402737184E-1 - REAL, PARAMETER:: K4= .565392987E-3 - REAL, PARAMETER:: K5= .521693933E-5 - REAL, PARAMETER:: K6= .307839583E-7 - REAL, PARAMETER:: K7= .105785160E-9 - REAL, PARAMETER:: K8= .161444444E-12 -! end- - ! Used in WRF-ARW module_physics_init.F INTEGER :: mynn_level @@ -385,13 +349,12 @@ SUBROUTINE mynn_bl_driver( & &initflag,restart,cycling, & &delt,dz,dx,znt, & &u,v,w,th,sqv3d,sqc3d,sqi3d, & - &qnc,qni, & - &qnwfa,qnifa,ozone, & + &sqs3d,qnc,qni, & + &qnwfa,qnifa,qnbca,ozone, & &p,exner,rho,t3d, & &xland,ts,qsfc,ps, & &ust,ch,hfx,qfx,rmol,wspd, & &uoce,voce, & !ocean current - &vdfg, & !Katata-added for fog dep &qke,qke_adv, & &sh3d,sm3d, & &nchem,kdvel,ndvel, & !Smoke/Chem variables @@ -401,16 +364,16 @@ SUBROUTINE mynn_bl_driver( & &tsq,qsq,cov, & &rublten,rvblten,rthblten, & &rqvblten,rqcblten,rqiblten, & - &rqncblten,rqniblten, & + &rqncblten,rqniblten,rqsblten, & &rqnwfablten,rqnifablten, & - &dozone, & + &rqnbcablten,dozone, & &exch_h,exch_m, & &pblh,kpbl, & &el_pbl, & &dqke,qwt,qshear,qbuoy,qdiss, & &qc_bl,qi_bl,cldfra_bl, & &bl_mynn_tkeadvect, & - &bl_mynn_tkebudget, & + &tke_budget, & &bl_mynn_cloudpdf, & &bl_mynn_mixlength, & &icloud_bl, & @@ -429,18 +392,19 @@ SUBROUTINE mynn_bl_driver( & &spp_pbl,pattern_spp_pbl, & &rthraten, & &FLAG_QC,FLAG_QI,FLAG_QNC, & - &FLAG_QNI,FLAG_QNWFA,FLAG_QNIFA, & - &FLAG_OZONE & - &,IDS,IDE,JDS,JDE,KDS,KDE & - &,IMS,IME,JMS,JME,KMS,KME & - &,ITS,ITE,JTS,JTE,KTS,KTE) + &FLAG_QNI,FLAG_QS, & + &FLAG_QNWFA,FLAG_QNIFA, & + &FLAG_QNBCA,FLAG_OZONE, & + &IDS,IDE,JDS,JDE,KDS,KDE, & + &IMS,IME,JMS,JME,KMS,KME, & + &ITS,ITE,JTS,JTE,KTS,KTE ) !------------------------------------------------------------------- INTEGER, INTENT(in) :: initflag !INPUT NAMELIST OPTIONS: - LOGICAL, INTENT(IN) :: restart,cycling - LOGICAL, INTENT(in) :: bl_mynn_tkebudget + LOGICAL, INTENT(in) :: restart,cycling + INTEGER, INTENT(in) :: tke_budget INTEGER, INTENT(in) :: bl_mynn_cloudpdf INTEGER, INTENT(in) :: bl_mynn_mixlength INTEGER, INTENT(in) :: bl_mynn_edmf @@ -452,17 +416,18 @@ SUBROUTINE mynn_bl_driver( & INTEGER, INTENT(in) :: bl_mynn_cloudmix INTEGER, INTENT(in) :: bl_mynn_mixqt INTEGER, INTENT(in) :: icloud_bl - REAL(kind=kind_phys), INTENT(in) :: closure + real(kind_phys), INTENT(in) :: closure LOGICAL, INTENT(in) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QNC,& - FLAG_QNWFA,FLAG_QNIFA,FLAG_OZONE + FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & + FLAG_OZONE,FLAG_QS LOGICAL, INTENT(IN) :: mix_chem,enh_mix,rrfs_sd,smoke_dbg - INTEGER, INTENT(in) :: & - & IDS,IDE,JDS,JDE,KDS,KDE & - &,IMS,IME,JMS,JME,KMS,KME & - &,ITS,ITE,JTS,JTE,KTS,KTE + INTEGER, INTENT(in) :: & + & IDS,IDE,JDS,JDE,KDS,KDE & + &,IMS,IME,JMS,JME,KMS,KME & + &,ITS,ITE,JTS,JTE,KTS,KTE #ifdef HARDCODE_VERTICAL # define kts 1 @@ -479,120 +444,129 @@ SUBROUTINE mynn_bl_driver( & ! to prevent a crash on Cheyenne. Do not change it back without testing if the code runs ! on Cheyenne with the GNU compiler. - REAL(kind=kind_phys), INTENT(in) :: delt - REAL(kind=kind_phys), DIMENSION(:), INTENT(in) :: dx - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: dz, & + real(kind_phys), INTENT(in) :: delt + real(kind_phys), DIMENSION(:), INTENT(in) :: dx + real(kind_phys), DIMENSION(:,:), INTENT(in) :: dz, & &u,v,w,th,sqv3D,p,exner,rho,T3D - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: & - &sqc3D,sqi3D,qni,qnc,qnwfa,qnifa - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in):: ozone - REAL(kind=kind_phys), DIMENSION(:), INTENT(in):: ust, & + real(kind_phys), DIMENSION(:,:), INTENT(in) :: & + &sqc3D,sqi3D,sqs3D,qni,qnc,qnwfa,qnifa,qnbca + real(kind_phys), DIMENSION(:,:), INTENT(in):: ozone + real(kind_phys), DIMENSION(:), INTENT(in):: ust, & &ch,qsfc,ps,wspd - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & &Qke,Tsq,Qsq,Cov,qke_adv - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & - &rublten,rvblten,rthblten,rqvblten,rqcblten, & - &rqiblten,rqniblten,rqncblten, & - &rqnwfablten,rqnifablten - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: dozone - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(in) :: rthraten + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & + &rublten,rvblten,rthblten,rqvblten,rqcblten, & + &rqiblten,rqsblten,rqniblten,rqncblten, & + &rqnwfablten,rqnifablten,rqnbcablten + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: dozone + real(kind_phys), DIMENSION(:,:), INTENT(in) :: rthraten - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(out) :: exch_h,exch_m - REAL, DIMENSION(:), INTENT(in) :: xland,ts,znt,hfx,qfx, & - &uoce,voce + real(kind_phys), DIMENSION(:,:), INTENT(out) :: exch_h,exch_m + real(kind_phys), DIMENSION(:), INTENT(in) :: xland, & + &ts,znt,hfx,qfx,uoce,voce !These 10 arrays are only allocated when bl_mynn_output > 0 - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & - & edmf_a,edmf_w,edmf_qt,edmf_thl,edmf_ent,edmf_qc, & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & + & edmf_a,edmf_w,edmf_qt,edmf_thl,edmf_ent,edmf_qc, & & sub_thl3D,sub_sqv3D,det_thl3D,det_sqv3D -! REAL, DIMENSION(IMS:IME,KMS:KME) :: & +! real, DIMENSION(IMS:IME,KMS:KME) :: & ! & edmf_a_dd,edmf_w_dd,edmf_qt_dd,edmf_thl_dd,edmf_ent_dd,edmf_qc_dd - REAL(kind=kind_phys), DIMENSION(:), INTENT(inout) :: Pblh - REAL, DIMENSION(:), INTENT(inout) :: rmol + real(kind_phys), DIMENSION(:), INTENT(inout) :: Pblh + real(kind_phys), DIMENSION(:), INTENT(inout) :: rmol - REAL, DIMENSION(IMS:IME) :: Psig_bl,Psig_shcu + real(kind_phys), DIMENSION(IMS:IME) :: psig_bl,psig_shcu - INTEGER,DIMENSION(:),INTENT(INOUT) :: & + INTEGER,DIMENSION(:),INTENT(INOUT) :: & &KPBL,nupdraft,ktop_plume - REAL(kind=kind_phys), DIMENSION(:), INTENT(out) :: maxmf + real(kind_phys), DIMENSION(:), INTENT(out) :: maxmf - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: el_pbl + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: el_pbl - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(out) :: & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & &qWT,qSHEAR,qBUOY,qDISS,dqke - ! 3D budget arrays are not allocated when bl_mynn_tkebudget == .false. + ! 3D budget arrays are not allocated when tke_budget == 0 ! 1D (local) budget arrays are used for passing between subroutines. - REAL, DIMENSION(kts:kte) :: qWT1,qSHEAR1,qBUOY1,qDISS1,dqke1,diss_heat + real(kind_phys), DIMENSION(kts:kte) :: & + &qwt1,qshear1,qbuoy1,qdiss1,dqke1,diss_heat - REAL(kind=kind_phys), DIMENSION(:,:), intent(out) :: Sh3D,Sm3D + real(kind_phys), DIMENSION(:,:), intent(out) :: Sh3D,Sm3D - REAL(kind=kind_phys), DIMENSION(:,:), INTENT(inout) :: & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & &qc_bl,qi_bl,cldfra_bl - REAL, DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D,cldfra_bl1D, & - qc_bl1D_old,qi_bl1D_old,cldfra_bl1D_old + real(kind_phys), DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D, & + &cldfra_bl1D,qc_bl1D_old,qi_bl1D_old,cldfra_bl1D_old ! smoke/chemical arrays INTEGER, INTENT(IN ) :: nchem, kdvel, ndvel -! REAL, DIMENSION( ims:ime, kms:kme, nchem ), INTENT(INOUT), optional :: chem3d -! REAL, DIMENSION( ims:ime, kdvel, ndvel ), INTENT(IN), optional :: vdep - REAL(kind=kind_phys), DIMENSION(:, :, :), INTENT(INOUT) :: chem3d - REAL(kind=kind_phys), DIMENSION(:, :), INTENT(IN) :: vdep - REAL(kind=kind_phys), DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO + real(kind_phys), DIMENSION(:,:,:), INTENT(INOUT) :: chem3d + real(kind_phys), DIMENSION(:,:), INTENT(IN) :: vdep + real(kind_phys), DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO !local - REAL, DIMENSION(kts:kte ,nchem) :: chem1 - REAL, DIMENSION(kts:kte+1,nchem) :: s_awchem1 - REAL, DIMENSION(ndvel) :: vd1 + real(kind_phys), DIMENSION(kts:kte ,nchem) :: chem1 + real(kind_phys), DIMENSION(kts:kte+1,nchem) :: s_awchem1 + real(kind_phys), DIMENSION(ndvel) :: vd1 INTEGER :: ic !local vars INTEGER :: ITF,JTF,KTF, IMD,JMD INTEGER :: i,j,k,kproblem - REAL, DIMENSION(KTS:KTE) :: thl,thvl,tl,qv1,qc1,qi1,sqw, & - &El, Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, & - &Vt, Vq, sgm, thlsg, sqwsg, vdfg - REAL, DIMENSION(KTS:KTE) :: thetav,sh,sm,u1,v1,w1,p1, & - &ex1,dz1,th1,tk1,rho1,qke1,tsq1,qsq1,cov1, & - &sqv,sqi,sqc,du1,dv1,dth1,dqv1,dqc1,dqi1,ozone1, & - &k_m1,k_h1,qni1,dqni1,qnc1,dqnc1,qnwfa1,qnifa1, & - &dqnwfa1,dqnifa1,dozone1 + real(kind_phys), DIMENSION(KTS:KTE) :: & + &thl,tl,qv1,qc1,qi1,qs1,sqw, & + &el, dfm, dfh, dfq, tcd, qcd, pdk, pdt, pdq, pdc, & + &vt, vq, sgm + real(kind_phys), DIMENSION(KTS:KTE) :: & + &thetav,sh,sm,u1,v1,w1,p1, & + &ex1,dz1,th1,tk1,rho1,qke1,tsq1,qsq1,cov1, & + &sqv,sqi,sqc,sqs, & + &du1,dv1,dth1,dqv1,dqc1,dqi1,dqs1,ozone1, & + &k_m1,k_h1,qni1,dqni1,qnc1,dqnc1,qnwfa1,qnifa1, & + &qnbca1,dqnwfa1,dqnifa1,dqnbca1,dozone1 !mass-flux variables - REAL, DIMENSION(KTS:KTE) :: dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf - REAL, DIMENSION(KTS:KTE) :: edmf_a1,edmf_w1,edmf_qt1, & - &edmf_thl1,edmf_ent1,edmf_qc1 - REAL, DIMENSION(KTS:KTE) :: edmf_a_dd1,edmf_w_dd1, & - &edmf_qt_dd1,edmf_thl_dd1, & + real(kind_phys), DIMENSION(KTS:KTE) :: & + &dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf + real(kind_phys), DIMENSION(KTS:KTE) :: & + &edmf_a1,edmf_w1,edmf_qt1,edmf_thl1, & + &edmf_ent1,edmf_qc1 + real(kind_phys), DIMENSION(KTS:KTE) :: & + &edmf_a_dd1,edmf_w_dd1,edmf_qt_dd1,edmf_thl_dd1, & &edmf_ent_dd1,edmf_qc_dd1 - REAL, DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v, & - det_thl,det_sqv,det_sqc,det_u,det_v - REAL,DIMENSION(KTS:KTE+1) :: s_aw1,s_awthl1,s_awqt1, & - s_awqv1,s_awqc1,s_awu1,s_awv1,s_awqke1, & - s_awqnc1,s_awqni1,s_awqnwfa1,s_awqnifa1 - REAL,DIMENSION(KTS:KTE+1) :: sd_aw1,sd_awthl1,sd_awqt1, & - sd_awqv1,sd_awqc1,sd_awu1,sd_awv1,sd_awqke1 - - REAL, DIMENSION(KTS:KTE+1) :: zw - REAL :: cpm,sqcg,flt,fltv,flq,flqv,flqc,pmz,phh,exnerg,zet,phi_m,& - & afk,abk,ts_decay, qc_bl2, qi_bl2, & - & th_sfc,ztop_plume,sqc9,sqi9,wsp + real(kind_phys), DIMENSION(KTS:KTE) :: & + &sub_thl,sub_sqv,sub_u,sub_v, & + &det_thl,det_sqv,det_sqc,det_u,det_v + real(kind_phys), DIMENSION(KTS:KTE+1) :: & + &s_aw1,s_awthl1,s_awqt1, & + &s_awqv1,s_awqc1,s_awu1,s_awv1,s_awqke1, & + &s_awqnc1,s_awqni1,s_awqnwfa1,s_awqnifa1, & + &s_awqnbca1 + real(kind_phys), DIMENSION(KTS:KTE+1) :: & + &sd_aw1,sd_awthl1,sd_awqt1, & + &sd_awqv1,sd_awqc1,sd_awu1,sd_awv1,sd_awqke1 + + real(kind_phys), DIMENSION(KTS:KTE+1) :: zw + real(kind_phys) :: cpm,sqcg,flt,fltv,flq,flqv,flqc, & + &pmz,phh,exnerg,zet,phi_m, & + &afk,abk,ts_decay, qc_bl2, qi_bl2, & + &th_sfc,ztop_plume,wsp !top-down diffusion - REAL, DIMENSION(ITS:ITE) :: maxKHtopdown - REAL,DIMENSION(KTS:KTE) :: KHtopdown,TKEprodTD + real(kind_phys), DIMENSION(ITS:ITE) :: maxKHtopdown + real(kind_phys), DIMENSION(KTS:KTE) :: KHtopdown,TKEprodTD LOGICAL :: INITIALIZE_QKE,problem ! Stochastic fields - INTEGER, INTENT(IN) :: spp_pbl - REAL(kind=kind_phys), DIMENSION( :, :), INTENT(IN) :: pattern_spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(:,:), INTENT(IN) :: pattern_spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col ! Substepping TKE INTEGER :: nsub - real(kind=kind_phys) :: delt2 + real(kind_phys) :: delt2 if (debug_code) then !check incoming values @@ -629,7 +603,7 @@ SUBROUTINE mynn_bl_driver( & !*** Begin debugging IMD=(IMS+IME)/2 JMD=(JMS+JME)/2 -!*** End debugging +!*** End debugging JTF=JTE ITF=ITE @@ -701,6 +675,7 @@ SUBROUTINE mynn_bl_driver( & dqnc1(kts:kte)=0.0 dqnwfa1(kts:kte)=0.0 dqnifa1(kts:kte)=0.0 + dqnbca1(kts:kte)=0.0 dozone1(kts:kte)=0.0 qc_bl1D_old(kts:kte)=0.0 cldfra_bl1D_old(kts:kte)=0.0 @@ -721,7 +696,7 @@ SUBROUTINE mynn_bl_driver( & ENDDO ENDDO - IF ( bl_mynn_tkebudget ) THEN + IF (tke_budget .eq. 1) THEN DO k=KTS,KTE DO i=ITS,ITF qWT(i,k)=0. @@ -734,7 +709,23 @@ SUBROUTINE mynn_bl_driver( & ENDIF DO i=ITS,ITF - DO k=KTS,KTE !KTF + if (FLAG_QI ) then + sqi(:)=sqi3D(i,:) + else + sqi = 0.0 + endif + if (FLAG_QS ) then + sqs(:)=sqs3D(i,:) + else + sqs = 0.0 + endif + if (icloud_bl > 0) then + cldfra_bl1d(:)=cldfra_bl(i,:) + qc_bl1d(:)=qc_bl(i,:) + qi_bl1d(:)=qi_bl(i,:) + endif + + do k=KTS,KTE !KTF dz1(k)=dz(i,k) u1(k) = u(i,k) v1(k) = v(i,k) @@ -745,52 +736,15 @@ SUBROUTINE mynn_bl_driver( & rho1(k)=rho(i,k) sqc(k)=sqc3D(i,k) !/(1.+qv(i,k)) sqv(k)=sqv3D(i,k) !/(1.+qv(i,k)) - thetav(k)=th(i,k)*(1.+0.608*sqv(k)) - IF (icloud_bl > 0) THEN - CLDFRA_BL1D(k)=CLDFRA_BL(i,k) - QC_BL1D(k)=QC_BL(i,k) - QI_BL1D(k)=QI_BL(i,k) - ENDIF - IF (FLAG_QI ) THEN - sqi(k)=sqi3D(i,k) !/(1.+qv(i,k)) - sqw(k)=sqv(k)+sqc(k)+sqi(k) - thl(k)=th1(k) - xlvcp/ex1(k)*sqc(k) & - & - xlscp/ex1(k)*sqi(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & - ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. sqi(k)<1e-8 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=QI_BL1D(k)*CLDFRA_BL1D(k) - ELSE - sqc9=sqc(k) - sqi9=sqi(k) - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - sqwsg(k)=sqv(k)+sqc9+sqi9 - ELSE - sqi(k)=0.0 - sqw(k)=sqv(k)+sqc(k) - thl(k)=th1(k)-xlvcp/ex1(k)*sqc(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=0.0 - ELSE - sqc9=sqc(k) - sqi9=0.0 - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - sqwsg(k)=sqv(k)+sqc9+sqi9 - ENDIF - thvl(k)=thlsg(k)*(1.+0.61*sqv(k)) + thetav(k)=th(i,k)*(1.+p608*sqv(k)) + !keep snow out for now - increases ceiling bias + sqw(k)=sqv(k)+sqc(k)+sqi(k)!+sqs(k) + thl(k)=th1(k) - xlvcp/ex1(k)*sqc(k) & + & - xlscp/ex1(k)*(sqi(k)+sqs(k)) + !Use form from Tripoli and Cotton (1981) with their + !suggested min temperature to improve accuracy. + !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & + ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) IF (k==kts) THEN zw(k)=0. @@ -821,9 +775,8 @@ SUBROUTINE mynn_bl_driver( & zw(kte+1)=zw(kte)+dz(i,kte) -!> - Call get_pblh() to calculate hybrid (\f$\theta_{vli}-TKE\f$) PBL height. -! CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& - CALL GET_PBLH(KTS,KTE,PBLH(i),thvl, & +!> - Call get_pblh() to calculate hybrid (\f$\theta_{v}-TKE\f$) PBL height. + CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& & Qke1,zw,dz1,xland(i),KPBL(i)) !> - Call scale_aware() to calculate similarity functions for scale-adaptive control @@ -841,18 +794,17 @@ SUBROUTINE mynn_bl_driver( & !! obtaining prerequisite variables by calling the following subroutines from !! within mym_initialize(): mym_level2() and mym_length(). CALL mym_initialize ( & - &kts,kte, & + &kts,kte,xland(i), & &dz1, dx(i), zw, & &u1, v1, thl, sqv, & - &thlsg, sqwsg, & &PBLH(i), th1, thetav, sh, sm, & &ust(i), rmol(i), & &el, Qke1, Tsq1, Qsq1, Cov1, & &Psig_bl(i), cldfra_bl1D, & &bl_mynn_mixlength, & - &edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf,& + &edmf_w1,edmf_a1, & &INITIALIZE_QKE, & - &spp_pbl,rstoch_col ) + &spp_pbl,rstoch_col ) IF (.not.restart) THEN !UPDATE 3D VARIABLES @@ -895,647 +847,582 @@ SUBROUTINE mynn_bl_driver( & ENDIF DO i=ITS,ITF - DO k=KTS,KTE !KTF - !JOE-TKE BUDGET - IF ( bl_mynn_tkebudget ) THEN - dqke(i,k)=qke(i,k) - END IF - IF (icloud_bl > 0) THEN - CLDFRA_BL1D(k)=CLDFRA_BL(i,k) - QC_BL1D(k)=QC_BL(i,k) - QI_BL1D(k)=QI_BL(i,k) - cldfra_bl1D_old(k)=cldfra_bl(i,k) - qc_bl1D_old(k)=qc_bl(i,k) - qi_bl1D_old(k)=qi_bl(i,k) - else - CLDFRA_BL1D(k)=0.0 - QC_BL1D(k)=0.0 - QI_BL1D(k)=0.0 - cldfra_bl1D_old(k)=0.0 - qc_bl1D_old(k)=0.0 - qi_bl1D_old(k)=0.0 - ENDIF - dz1(k)= dz(i,k) - u1(k) = u(i,k) - v1(k) = v(i,k) - w1(k) = w(i,k) - th1(k)= th(i,k) - tk1(k)=T3D(i,k) - p1(k) = p(i,k) - ex1(k)= exner(i,k) - rho1(k)=rho(i,k) - sqv(k)= sqv3D(i,k) !/(1.+qv(i,k)) - sqc(k)= sqc3D(i,k) !/(1.+qv(i,k)) - qv1(k)= sqv(k)/(1.-sqv(k)) - qc1(k)= sqc(k)/(1.-sqv(k)) - dqc1(k)=0.0 - dqi1(k)=0.0 - dqni1(k)=0.0 - dqnc1(k)=0.0 - dqnwfa1(k)=0.0 - dqnifa1(k)=0.0 - dozone1(k)=0.0 - IF(FLAG_QI)THEN - sqi(k)= sqi3D(i,k) !/(1.+qv(i,k)) - qi1(k)= sqi(k)/(1.-sqv(k)) - sqw(k)= sqv(k)+sqc(k)+sqi(k) - thl(k)= th1(k) - xlvcp/ex1(k)*sqc(k) & - & - xlscp/ex1(k)*sqi(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & - ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. sqi(k)<1e-8 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=QI_BL1D(k)*CLDFRA_BL1D(k) - ELSE - sqc9=sqc(k) - sqi9=sqi(k) - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - sqwsg(k)=sqv(k)+sqc9+sqi9 - ELSE - qi1(k)=0.0 - sqi(k)=0.0 - sqw(k)= sqv(k)+sqc(k) - thl(k)= th1(k)-xlvcp/ex1(k)*sqc(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=QI_BL1D(k)*CLDFRA_BL1D(k) - ELSE - sqc9=sqc(k) - sqi9=0.0 - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - ENDIF - thetav(k)=th1(k)*(1.+0.608*sqv(k)) - thvl(k) =thlsg(k) *(1.+0.608*sqv(k)) - - IF (FLAG_QNI ) THEN - qni1(k)=qni(i,k) - ELSE - qni1(k)=0.0 - ENDIF - IF (FLAG_QNC ) THEN - qnc1(k)=qnc(i,k) - ELSE - qnc1(k)=0.0 - ENDIF - IF (FLAG_QNWFA ) THEN - qnwfa1(k)=qnwfa(i,k) - ELSE - qnwfa1(k)=0.0 - ENDIF - IF (FLAG_QNIFA ) THEN - qnifa1(k)=qnifa(i,k) - ELSE - qnifa1(k)=0.0 - ENDIF - IF (FLAG_OZONE) THEN - ozone1(k)=ozone(i,k) - ELSE - ozone1(k)=0.0 - ENDIF - el(k) = el_pbl(i,k) - qke1(k)=qke(i,k) - sh(k) =sh3d(i,k) - sm(k) =sm3d(i,k) - tsq1(k)=tsq(i,k) - qsq1(k)=qsq(i,k) - cov1(k)=cov(i,k) - if (spp_pbl==1) then - rstoch_col(k)=pattern_spp_pbl(i,k) - else - rstoch_col(k)=0.0 - endif - - !edmf - edmf_a1(k)=0.0 - edmf_w1(k)=0.0 - edmf_qc1(k)=0.0 - s_aw1(k)=0. - s_awthl1(k)=0. - s_awqt1(k)=0. - s_awqv1(k)=0. - s_awqc1(k)=0. - s_awu1(k)=0. - s_awv1(k)=0. - s_awqke1(k)=0. - s_awqnc1(k)=0. - s_awqni1(k)=0. - s_awqnwfa1(k)=0. - s_awqnifa1(k)=0. - ![EWDD] - edmf_a_dd1(k)=0.0 - edmf_w_dd1(k)=0.0 - edmf_qc_dd1(k)=0.0 - sd_aw1(k)=0. - sd_awthl1(k)=0. - sd_awqt1(k)=0. - sd_awqv1(k)=0. - sd_awqc1(k)=0. - sd_awu1(k)=0. - sd_awv1(k)=0. - sd_awqke1(k)=0. - sub_thl(k)=0. - sub_sqv(k)=0. - sub_u(k)=0. - sub_v(k)=0. - det_thl(k)=0. - det_sqv(k)=0. - det_sqc(k)=0. - det_u(k)=0. - det_v(k)=0. - - IF (k==kts) THEN - zw(k)=0. - ELSE - zw(k)=zw(k-1)+dz(i,k-1) - ENDIF - ENDDO ! end k - - !initialize smoke/chem arrays (if used): - IF ( mix_chem ) then - do ic = 1,ndvel - vd1(ic) = vdep(i,ic) ! dry deposition velocity - chem1(kts,ic) = chem3d(i,kts,ic) - s_awchem1(kts,ic)=0. - enddo - do k = kts+1,kte - DO ic = 1,nchem - chem1(k,ic) = chem3d(i,k,ic) - s_awchem1(k,ic)=0. - ENDDO - enddo - ELSE - do ic = 1,ndvel - vd1(ic) = 0. ! dry deposition velocity - chem1(kts,ic) = 0. - s_awchem1(kts,ic)=0. - enddo - do k = kts+1,kte - do ic = 1,nchem - chem1(k,ic) = 0. - s_awchem1(k,ic)=0. - enddo - enddo - ENDIF - - zw(kte+1)=zw(kte)+dz(i,kte) - !EDMF - s_aw1(kte+1)=0. - s_awthl1(kte+1)=0. - s_awqt1(kte+1)=0. - s_awqv1(kte+1)=0. - s_awqc1(kte+1)=0. - s_awu1(kte+1)=0. - s_awv1(kte+1)=0. - s_awqke1(kte+1)=0. - s_awqnc1(kte+1)=0. - s_awqni1(kte+1)=0. - s_awqnwfa1(kte+1)=0. - s_awqnifa1(kte+1)=0. - sd_aw1(kte+1)=0. - sd_awthl1(kte+1)=0. - sd_awqt1(kte+1)=0. - sd_awqv1(kte+1)=0. - sd_awqc1(kte+1)=0. - sd_awu1(kte+1)=0. - sd_awv1(kte+1)=0. - sd_awqke1(kte+1)=0. - IF ( mix_chem ) THEN - DO ic = 1,nchem - s_awchem1(kte+1,ic)=0. - ENDDO - ENDIF + !Initialize some arrays + if (tke_budget .eq. 1) then + dqke(i,:)=qke(i,:) + endif + if (FLAG_QI ) then + sqi(:)=sqi3D(i,:) + else + sqi = 0.0 + endif + if (FLAG_QS ) then + sqs(:)=sqs3D(i,:) + else + sqs = 0.0 + endif + if (icloud_bl > 0) then + CLDFRA_BL1D(:)=CLDFRA_BL(i,:) + QC_BL1D(:) =QC_BL(i,:) + QI_BL1D(:) =QI_BL(i,:) + cldfra_bl1D_old(:)=cldfra_bl(i,:) + qc_bl1D_old(:)=qc_bl(i,:) + qi_bl1D_old(:)=qi_bl(i,:) + else + CLDFRA_BL1D =0.0 + QC_BL1D =0.0 + QI_BL1D =0.0 + cldfra_bl1D_old=0.0 + qc_bl1D_old =0.0 + qi_bl1D_old =0.0 + endif + dz1(kts:kte) =dz(i,kts:kte) + u1(kts:kte) =u(i,kts:kte) + v1(kts:kte) =v(i,kts:kte) + w1(kts:kte) =w(i,kts:kte) + th1(kts:kte) =th(i,kts:kte) + tk1(kts:kte) =T3D(i,kts:kte) + p1(kts:kte) =p(i,kts:kte) + ex1(kts:kte) =exner(i,kts:kte) + rho1(kts:kte) =rho(i,kts:kte) + sqv(kts:kte) =sqv3D(i,kts:kte) !/(1.+qv(i,kts:kte)) + sqc(kts:kte) =sqc3D(i,kts:kte) !/(1.+qv(i,kts:kte)) + qv1(kts:kte) =sqv(kts:kte)/(1.-sqv(kts:kte)) + qc1(kts:kte) =sqc(kts:kte)/(1.-sqv(kts:kte)) + qi1(kts:kte) =sqi(kts:kte)/(1.-sqv(kts:kte)) + qs1(kts:kte) =sqs(kts:kte)/(1.-sqv(kts:kte)) + dqc1(kts:kte) =0.0 + dqi1(kts:kte) =0.0 + dqs1(kts:kte) =0.0 + dqni1(kts:kte) =0.0 + dqnc1(kts:kte) =0.0 + dqnwfa1(kts:kte)=0.0 + dqnifa1(kts:kte)=0.0 + dqnbca1(kts:kte)=0.0 + dozone1(kts:kte)=0.0 + IF (FLAG_QNI ) THEN + qni1(kts:kte)=qni(i,kts:kte) + ELSE + qni1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNC ) THEN + qnc1(kts:kte)=qnc(i,kts:kte) + ELSE + qnc1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNWFA ) THEN + qnwfa1(kts:kte)=qnwfa(i,kts:kte) + ELSE + qnwfa1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNIFA ) THEN + qnifa1(kts:kte)=qnifa(i,kts:kte) + ELSE + qnifa1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNBCA ) THEN + qnbca1(kts:kte)=qnbca(i,kts:kte) + ELSE + qnbca1(kts:kte)=0.0 + ENDIF + IF (FLAG_OZONE ) THEN + ozone1(kts:kte)=ozone(i,kts:kte) + ELSE + ozone1(kts:kte)=0.0 + ENDIF + el(kts:kte) =el_pbl(i,kts:kte) + qke1(kts:kte)=qke(i,kts:kte) + sh(kts:kte) =sh3d(i,kts:kte) + sm(kts:kte) =sm3d(i,kts:kte) + tsq1(kts:kte)=tsq(i,kts:kte) + qsq1(kts:kte)=qsq(i,kts:kte) + cov1(kts:kte)=cov(i,kts:kte) + if (spp_pbl==1) then + rstoch_col(kts:kte)=pattern_spp_pbl(i,kts:kte) + else + rstoch_col(kts:kte)=0.0 + endif + !edmf + edmf_a1 =0.0 + edmf_w1 =0.0 + edmf_qc1 =0.0 + s_aw1 =0.0 + s_awthl1 =0.0 + s_awqt1 =0.0 + s_awqv1 =0.0 + s_awqc1 =0.0 + s_awu1 =0.0 + s_awv1 =0.0 + s_awqke1 =0.0 + s_awqnc1 =0.0 + s_awqni1 =0.0 + s_awqnwfa1 =0.0 + s_awqnifa1 =0.0 + s_awqnbca1 =0.0 + ![EWDD] + edmf_a_dd1 =0.0 + edmf_w_dd1 =0.0 + edmf_qc_dd1=0.0 + sd_aw1 =0.0 + sd_awthl1 =0.0 + sd_awqt1 =0.0 + sd_awqv1 =0.0 + sd_awqc1 =0.0 + sd_awu1 =0.0 + sd_awv1 =0.0 + sd_awqke1 =0.0 + sub_thl =0.0 + sub_sqv =0.0 + sub_u =0.0 + sub_v =0.0 + det_thl =0.0 + det_sqv =0.0 + det_sqc =0.0 + det_u =0.0 + det_v =0.0 + + do k = kts,kte + if (k==kts) then + zw(k)=0. + else + zw(k)=zw(k-1)+dz(i,k-1) + endif + !keep snow out for now - increases ceiling bias + sqw(k)= sqv(k)+sqc(k)+sqi(k)!+sqs(k) + thl(k)= th1(k) - xlvcp/ex1(k)*sqc(k) & + & - xlscp/ex1(k)*(sqi(k)+sqs(k)) + !Use form from Tripoli and Cotton (1981) with their + !suggested min temperature to improve accuracy. + !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & + ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) + thetav(k)=th1(k)*(1.+p608*sqv(k)) + enddo ! end k + zw(kte+1)=zw(kte)+dz(i,kte) + + !initialize smoke/chem arrays (if used): + if ( mix_chem ) then + do ic = 1,ndvel + vd1(ic) = vdep(i,ic) ! dry deposition velocity + chem1(kts,ic) = chem3d(i,kts,ic) + enddo + do k = kts+1,kte + do ic = 1,nchem + chem1(k,ic) = chem3d(i,k,ic) + enddo + enddo + else + do ic = 1,ndvel + vd1(ic) = 0. ! dry deposition velocity + chem1(kts,ic) = 0. + enddo + do k = kts+1,kte + do ic = 1,nchem + chem1(k,ic) = 0. + enddo + enddo + endif + s_awchem1 = 0.0 !> - Call get_pblh() to calculate the hybrid \f$\theta_{vli}-TKE\f$ !! PBL height diagnostic. -! CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& - CALL GET_PBLH(KTS,KTE,PBLH(i),thvl,& - & Qke1,zw,dz1,xland(i),KPBL(i)) + CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& + & Qke1,zw,dz1,xland(i),KPBL(i)) !> - Call scale_aware() to calculate the similarity functions, !! \f$P_{\sigma-PBL}\f$ and \f$P_{\sigma-shcu}\f$, to control !! the scale-adaptive behaviour for the local and nonlocal !! components, respectively. - IF (scaleaware > 0.) THEN - CALL SCALE_AWARE(dx(i),PBLH(i),Psig_bl(i),Psig_shcu(i)) - ELSE - Psig_bl(i)=1.0 - Psig_shcu(i)=1.0 - ENDIF + if (scaleaware > 0.) then + call SCALE_AWARE(dx(i),PBLH(i),Psig_bl(i),Psig_shcu(i)) + else + Psig_bl(i)=1.0 + Psig_shcu(i)=1.0 + endif - sqcg= 0.0 !ill-defined variable; qcg has been removed - cpm=cp*(1.+0.84*qv1(kts)) - exnerg=(ps(i)/p1000mb)**rcp - - !----------------------------------------------------- - !ORIGINAL CODE - !flt = hfx(i)/( rho(i,kts)*cpm ) & - ! +xlvcp*ch(i)*(sqc(kts)/exner(i,kts) -sqcg/exnerg) - !flq = qfx(i)/ rho(i,kts) & - ! -ch(i)*(sqc(kts) -sqcg ) - !----------------------------------------------------- - ! Katata-added - The deposition velocity of cloud (fog) - ! water is used instead of CH. - !flt = hfx(i)/( rho(i,kts)*cpm ) & - ! & +xlvcp*vdfg(i)*(sqc(kts)/exner(i,kts)- sqcg/exnerg) - !flq = qfx(i)/ rho(i,kts) & - ! & -vdfg(i)*(sqc(kts) - sqcg ) - !----------------------------------------------------- - flqv = qfx(i)/rho1(kts) - flqc = -vdfg(i)*(sqc(kts) - sqcg ) - th_sfc = ts(i)/ex1(kts) - - ! TURBULENT FLUX FOR TKE BOUNDARY CONDITIONS - flq =flqv+flqc !! LATENT - flt =hfx(i)/(rho1(kts)*cpm )-xlvcp*flqc/ex1(kts) !! Temperature flux - fltv=flt + flqv*p608*th_sfc !! Virtual temperature flux - - ! Update 1/L using updated sfc heat flux and friction velocity - rmol(i) = -karman*gtr*fltv/max(ust(i)**3,1.0e-6) - zet = 0.5*dz(i,kts)*rmol(i) - zet = MAX(zet, -20.) - zet = MIN(zet, 20.) - !if(i.eq.idbg)print*,"updated z/L=",zet - if (bl_mynn_stfunc == 0) then - !Original Kansas-type stability functions - if ( zet >= 0.0 ) then - pmz = 1.0 + (cphm_st-1.0) * zet - phh = 1.0 + cphh_st * zet - else - pmz = 1.0/ (1.0-cphm_unst*zet)**0.25 - zet - phh = 1.0/SQRT(1.0-cphh_unst*zet) - end if + sqcg= 0.0 !ill-defined variable; qcg has been removed + cpm=cp*(1.+0.84*qv1(kts)) + exnerg=(ps(i)/p1000mb)**rcp + + !----------------------------------------------------- + !ORIGINAL CODE + !flt = hfx(i)/( rho(i,kts)*cpm ) & + ! +xlvcp*ch(i)*(sqc(kts)/exner(i,kts) -sqcg/exnerg) + !flq = qfx(i)/ rho(i,kts) & + ! -ch(i)*(sqc(kts) -sqcg ) + !----------------------------------------------------- + flqv = qfx(i)/rho1(kts) + flqc = 0.0 !currently no sea-spray fluxes, fog settling handled elsewhere + th_sfc = ts(i)/ex1(kts) + + ! TURBULENT FLUX FOR TKE BOUNDARY CONDITIONS + flq =flqv+flqc !! LATENT + flt =hfx(i)/(rho1(kts)*cpm )-xlvcp*flqc/ex1(kts) !! Temperature flux + fltv=flt + flqv*p608*th_sfc !! Virtual temperature flux + + ! Update 1/L using updated sfc heat flux and friction velocity + rmol(i) = -karman*gtr*fltv/max(ust(i)**3,1.0e-6) + zet = 0.5*dz(i,kts)*rmol(i) + zet = MAX(zet, -20.) + zet = MIN(zet, 20.) + !if(i.eq.idbg)print*,"updated z/L=",zet + if (bl_mynn_stfunc == 0) then + !Original Kansas-type stability functions + if ( zet >= 0.0 ) then + pmz = 1.0 + (cphm_st-1.0) * zet + phh = 1.0 + cphh_st * zet else - !Updated stability functions (Puhales, 2020) - phi_m = phim(zet) - pmz = phi_m - zet - phh = phih(zet) + pmz = 1.0/ (1.0-cphm_unst*zet)**0.25 - zet + phh = 1.0/SQRT(1.0-cphh_unst*zet) end if + else + !Updated stability functions (Puhales, 2020) + phi_m = phim(zet) + pmz = phi_m - zet + phh = phih(zet) + end if !> - Call mym_condensation() to calculate the nonconvective component !! of the subgrid cloud fraction and mixing ratio as well as the functions !! used to calculate the buoyancy flux. Different cloud PDFs can be !! selected by use of the namelist parameter \p bl_mynn_cloudpdf. - CALL mym_condensation ( kts,kte, & - &dx(i),dz1,zw,u1,v1,xland(i), & - &thl,sqw,sqv,sqc,sqi, & - &p1,ex1,tsq1,qsq1,cov1, & - &Sh,el,bl_mynn_cloudpdf, & - &qc_bl1D,qi_bl1D,cldfra_bl1D, & - &PBLH(i),HFX(i), & - &Vt, Vq, th1, sgm, rmol(i), & - &spp_pbl, rstoch_col ) + call mym_condensation (kts,kte, & + &dx(i),dz1,zw,xland(i), & + &thl,sqw,sqv,sqc,sqi,sqs, & + &p1,ex1,tsq1,qsq1,cov1, & + &Sh,el,bl_mynn_cloudpdf, & + &qc_bl1D,qi_bl1D,cldfra_bl1D, & + &PBLH(i),HFX(i), & + &Vt, Vq, th1, sgm, rmol(i), & + &spp_pbl, rstoch_col ) !> - Add TKE source driven by cloud top cooling !! Calculate the buoyancy production of TKE from cloud-top cooling when !! \p bl_mynn_topdown =1. - IF (bl_mynn_topdown.eq.1)then - CALL topdown_cloudrad(kts,kte,dz1,zw, & - &xland(i),kpbl(i),PBLH(i), & - &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & - &cldfra_bl1D,rthraten(i,:), & - &maxKHtopdown(i),KHtopdown,TKEprodTD ) - ELSE - maxKHtopdown(i) = 0.0 - KHtopdown(kts:kte) = 0.0 - TKEprodTD(kts:kte) = 0.0 - ENDIF + if (bl_mynn_topdown.eq.1) then + call topdown_cloudrad(kts,kte,dz1,zw, & + &xland(i),kpbl(i),PBLH(i), & + &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & + &cldfra_bl1D,rthraten(i,:), & + &maxKHtopdown(i),KHtopdown,TKEprodTD ) + else + maxKHtopdown(i) = 0.0 + KHtopdown(kts:kte) = 0.0 + TKEprodTD(kts:kte) = 0.0 + endif - IF (bl_mynn_edmf > 0) THEN - !PRINT*,"Calling DMP Mass-Flux: i= ",i - CALL DMP_mf( & - &kts,kte,delt,zw,dz1,p1,rho1, & - &bl_mynn_edmf_mom, & - &bl_mynn_edmf_tke, & - &bl_mynn_mixscalars, & - &u1,v1,w1,th1,thl,thetav,tk1, & - &sqw,sqv,sqc,qke1, & - &qnc1,qni1,qnwfa1,qnifa1, & - &ex1,Vt,Vq,sgm, & - &ust(i),flt,fltv,flq,flqv, & - &PBLH(i),KPBL(i),DX(i), & - &xland(i),th_sfc, & + if (bl_mynn_edmf > 0) then + !PRINT*,"Calling DMP Mass-Flux: i= ",i + call DMP_mf( & + &kts,kte,delt,zw,dz1,p1,rho1, & + &bl_mynn_edmf_mom, & + &bl_mynn_edmf_tke, & + &bl_mynn_mixscalars, & + &u1,v1,w1,th1,thl,thetav,tk1, & + &sqw,sqv,sqc,qke1, & + &qnc1,qni1,qnwfa1,qnifa1,qnbca1, & + &ex1,Vt,Vq,sgm, & + &ust(i),flt,fltv,flq,flqv, & + &PBLH(i),KPBL(i),DX(i), & + &xland(i),th_sfc, & ! now outputs - tendencies - ! &,dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf & + ! &,dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf & ! outputs - updraft properties - & edmf_a1,edmf_w1,edmf_qt1, & - & edmf_thl1,edmf_ent1,edmf_qc1, & + &edmf_a1,edmf_w1,edmf_qt1, & + &edmf_thl1,edmf_ent1,edmf_qc1, & ! for the solver - & s_aw1,s_awthl1,s_awqt1, & - & s_awqv1,s_awqc1, & - & s_awu1,s_awv1,s_awqke1, & - & s_awqnc1,s_awqni1, & - & s_awqnwfa1,s_awqnifa1, & - & sub_thl,sub_sqv, & - & sub_u,sub_v, & - & det_thl,det_sqv,det_sqc, & - & det_u,det_v, & + &s_aw1,s_awthl1,s_awqt1, & + &s_awqv1,s_awqc1, & + &s_awu1,s_awv1,s_awqke1, & + &s_awqnc1,s_awqni1, & + &s_awqnwfa1,s_awqnifa1,s_awqnbca1, & + &sub_thl,sub_sqv, & + &sub_u,sub_v, & + &det_thl,det_sqv,det_sqc, & + &det_u,det_v, & ! chem/smoke mixing - & nchem,chem1,s_awchem1, & - & mix_chem, & - & qc_bl1D,cldfra_bl1D, & - & qc_bl1D_old,cldfra_bl1D_old, & - & FLAG_QC,FLAG_QI, & - & FLAG_QNC,FLAG_QNI, & - & FLAG_QNWFA,FLAG_QNIFA, & - & Psig_shcu(i), & - & nupdraft(i),ktop_plume(i), & - & maxmf(i),ztop_plume, & - & spp_pbl,rstoch_col ) - ENDIF + &nchem,chem1,s_awchem1, & + &mix_chem, & + &qc_bl1D,cldfra_bl1D, & + &qc_bl1D_old,cldfra_bl1D_old, & + &FLAG_QC,FLAG_QI, & + &FLAG_QNC,FLAG_QNI, & + &FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & + &Psig_shcu(i), & + &nupdraft(i),ktop_plume(i), & + &maxmf(i),ztop_plume, & + &spp_pbl,rstoch_col ) + endif - IF (bl_mynn_edmf_dd == 1) THEN - CALL DDMF_JPL(kts,kte,delt,zw,dz1,p1, & - &u1,v1,th1,thl,thetav,tk1, & - sqw,sqv,sqc,rho1,ex1, & - &ust(i),flt,flq, & - &PBLH(i),KPBL(i), & - &edmf_a_dd1,edmf_w_dd1,edmf_qt_dd1, & - &edmf_thl_dd1,edmf_ent_dd1, & - &edmf_qc_dd1, & - &sd_aw1,sd_awthl1,sd_awqt1, & - &sd_awqv1,sd_awqc1,sd_awu1,sd_awv1, & - &sd_awqke1, & - &qc_bl1d,cldfra_bl1d, & - &rthraten(i,:) ) - ENDIF + if (bl_mynn_edmf_dd == 1) then + call DDMF_JPL(kts,kte,delt,zw,dz1,p1, & + &u1,v1,th1,thl,thetav,tk1, & + &sqw,sqv,sqc,rho1,ex1, & + &ust(i),flt,flq, & + &PBLH(i),KPBL(i), & + &edmf_a_dd1,edmf_w_dd1,edmf_qt_dd1, & + &edmf_thl_dd1,edmf_ent_dd1, & + &edmf_qc_dd1, & + &sd_aw1,sd_awthl1,sd_awqt1, & + &sd_awqv1,sd_awqc1,sd_awu1,sd_awv1, & + &sd_awqke1, & + &qc_bl1d,cldfra_bl1d, & + &rthraten(i,:) ) + endif - !Capability to substep the eddy-diffusivity portion - !do nsub = 1,2 - delt2 = delt !*0.5 !only works if topdown=0 - - CALL mym_turbulence ( & - &kts,kte,closure, & - &dz1, DX(i), zw, & - &u1, v1, thl, thetav, sqc, sqw, & - &thlsg, sqwsg, & - &qke1, tsq1, qsq1, cov1, & - &vt, vq, & - &rmol(i), flt, flq, & - &PBLH(i),th1, & - &Sh,Sm,el, & - &Dfm,Dfh,Dfq, & - &Tcd,Qcd,Pdk, & - &Pdt,Pdq,Pdc, & - &qWT1,qSHEAR1,qBUOY1,qDISS1, & - &bl_mynn_tkebudget, & - &Psig_bl(i),Psig_shcu(i), & - &cldfra_bl1D,bl_mynn_mixlength, & - &edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & - &TKEprodTD, & - &spp_pbl,rstoch_col) + !Capability to substep the eddy-diffusivity portion + !do nsub = 1,2 + delt2 = delt !*0.5 !only works if topdown=0 + + call mym_turbulence( & + &kts,kte,xland(i),closure, & + &dz1, DX(i), zw, & + &u1, v1, thl, thetav, sqc, sqw, & + &qke1, tsq1, qsq1, cov1, & + &vt, vq, & + &rmol(i), flt, fltv, flq, & + &PBLH(i),th1, & + &Sh,Sm,el, & + &Dfm,Dfh,Dfq, & + &Tcd,Qcd,Pdk, & + &Pdt,Pdq,Pdc, & + &qWT1,qSHEAR1,qBUOY1,qDISS1, & + &tke_budget, & + &Psig_bl(i),Psig_shcu(i), & + &cldfra_bl1D,bl_mynn_mixlength, & + &edmf_w1,edmf_a1, & + &TKEprodTD, & + &spp_pbl,rstoch_col ) !> - Call mym_predict() to solve TKE and !! \f$\theta^{'2}, q^{'2}, and \theta^{'}q^{'}\f$ !! for the following time step. - CALL mym_predict (kts,kte,closure, & - &delt2, dz1, & - &ust(i), flt, flq, pmz, phh, & - &el, dfq, rho1, pdk, pdt, pdq, pdc,& - &Qke1, Tsq1, Qsq1, Cov1, & - &s_aw1, s_awqke1, bl_mynn_edmf_tke,& - &qWT1, qDISS1,bl_mynn_tkebudget) !! TKE budget (Puhales, 2020) - - if (dheat_opt > 0) then - DO k=kts,kte-1 - ! Set max dissipative heating rate to 7.2 K per hour - diss_heat(k) = MIN(MAX(1.0*(qke1(k)**1.5)/(b1*MAX(0.5*(el(k)+el(k+1)),1.))/cp, 0.0),0.002) - ! Limit heating above 100 mb: - diss_heat(k) = diss_heat(k) * exp(-10000./MAX(p1(k),1.)) - ENDDO - diss_heat(kte) = 0. - else - diss_heat(1:kte) = 0. - endif + call mym_predict(kts,kte,closure, & + &delt2, dz1, & + &ust(i), flt, flq, pmz, phh, & + &el, dfq, rho1, pdk, pdt, pdq, pdc, & + &Qke1, Tsq1, Qsq1, Cov1, & + &s_aw1, s_awqke1, bl_mynn_edmf_tke, & + &qWT1, qDISS1, tke_budget ) + + if (dheat_opt > 0) then + do k=kts,kte-1 + ! Set max dissipative heating rate to 7.2 K per hour + diss_heat(k) = MIN(MAX(1.0*(qke1(k)**1.5)/(b1*MAX(0.5*(el(k)+el(k+1)),1.))/cp, 0.0),0.002) + ! Limit heating above 100 mb: + diss_heat(k) = diss_heat(k) * exp(-10000./MAX(p1(k),1.)) + enddo + diss_heat(kte) = 0. + else + diss_heat(1:kte) = 0. + endif !> - Call mynn_tendencies() to solve for tendencies of !! \f$U, V, \theta, q_{v}, q_{c}, and q_{i}\f$. - CALL mynn_tendencies(kts,kte,i, & - &delt, dz1, rho1, & - &u1, v1, th1, tk1, qv1, & - &qc1, qi1, qnc1, qni1, & - &ps(i), p1, ex1, thl, & - &sqv, sqc, sqi, sqw, & - &qnwfa1, qnifa1, ozone1, & - &ust(i),flt,flq,flqv,flqc, & - &wspd(i),uoce(i),voce(i), & - &tsq1, qsq1, cov1, & - &tcd, qcd, & - &dfm, dfh, dfq, & - &Du1, Dv1, Dth1, Dqv1, & - &Dqc1, Dqi1, Dqnc1, Dqni1, & - &Dqnwfa1, Dqnifa1, Dozone1, & - &diss_heat, & + call mynn_tendencies(kts,kte,i, & + &delt, dz1, rho1, & + &u1, v1, th1, tk1, qv1, & + &qc1, qi1, qs1, qnc1, qni1, & + &ps(i), p1, ex1, thl, & + &sqv, sqc, sqi, sqs, sqw, & + &qnwfa1, qnifa1, qnbca1, ozone1, & + &ust(i),flt,flq,flqv,flqc, & + &wspd(i),uoce(i),voce(i), & + &tsq1, qsq1, cov1, & + &tcd, qcd, & + &dfm, dfh, dfq, & + &Du1, Dv1, Dth1, Dqv1, & + &Dqc1, Dqi1, Dqs1, Dqnc1, Dqni1, & + &Dqnwfa1, Dqnifa1, Dqnbca1, & + &Dozone1, & + &diss_heat, & ! mass flux components - &s_aw1,s_awthl1,s_awqt1, & - &s_awqv1,s_awqc1,s_awu1,s_awv1, & - &s_awqnc1,s_awqni1, & - &s_awqnwfa1,s_awqnifa1, & - &sd_aw1,sd_awthl1,sd_awqt1, & - &sd_awqv1,sd_awqc1, & - sd_awu1,sd_awv1, & - &sub_thl,sub_sqv, & - &sub_u,sub_v, & - &det_thl,det_sqv,det_sqc, & - &det_u,det_v, & - &FLAG_QC,FLAG_QI,FLAG_QNC, & - &FLAG_QNI,FLAG_QNWFA,FLAG_QNIFA, & - &cldfra_bl1d, & - &bl_mynn_cloudmix, & - &bl_mynn_mixqt, & - &bl_mynn_edmf, & - &bl_mynn_edmf_mom, & - &bl_mynn_mixscalars ) - - - IF ( mix_chem ) THEN - IF ( rrfs_sd ) THEN - CALL mynn_mix_chem(kts,kte,i, & - &delt, dz1, pblh(i), & - &nchem, kdvel, ndvel, & - &chem1, vd1, & - &rho1,flt, & - &tcd, qcd, & - &dfh, & - &s_aw1,s_awchem1, & - &emis_ant_no(i), & - &frp(i), rrfs_sd, & - &enh_mix, smoke_dbg ) - ELSE - CALL mynn_mix_chem(kts,kte,i, & - &delt, dz1, pblh(i), & - &nchem, kdvel, ndvel, & - &chem1, vd1, & - &rho1,flt, & - &tcd, qcd, & - &dfh, & - &s_aw1,s_awchem1, & - &zero, & - &zero, rrfs_sd, & - &enh_mix, smoke_dbg ) - ENDIF - DO ic = 1,nchem - DO k = kts,kte - chem3d(i,k,ic) = max(1.e-12, chem1(k,ic)) - ENDDO - ENDDO - ENDIF + &s_aw1,s_awthl1,s_awqt1, & + &s_awqv1,s_awqc1,s_awu1,s_awv1, & + &s_awqnc1,s_awqni1, & + &s_awqnwfa1,s_awqnifa1,s_awqnbca1, & + &sd_aw1,sd_awthl1,sd_awqt1, & + &sd_awqv1,sd_awqc1, & + &sd_awu1,sd_awv1, & + &sub_thl,sub_sqv, & + &sub_u,sub_v, & + &det_thl,det_sqv,det_sqc, & + &det_u,det_v, & + &FLAG_QC,FLAG_QI,FLAG_QNC, & + &FLAG_QNI,FLAG_QS, & + &FLAG_QNWFA,FLAG_QNIFA, & + &FLAG_QNBCA, & + &cldfra_bl1d, & + &bl_mynn_cloudmix, & + &bl_mynn_mixqt, & + &bl_mynn_edmf, & + &bl_mynn_edmf_mom, & + &bl_mynn_mixscalars ) + + + if ( mix_chem ) then + if ( rrfs_sd ) then + call mynn_mix_chem(kts,kte,i, & + &delt, dz1, pblh(i), & + &nchem, kdvel, ndvel, & + &chem1, vd1, & + &rho1,flt, & + &tcd, qcd, & + &dfh, & + &s_aw1,s_awchem1, & + &emis_ant_no(i), & + &frp(i), rrfs_sd, & + &enh_mix, smoke_dbg ) + else + call mynn_mix_chem(kts,kte,i, & + &delt, dz1, pblh(i), & + &nchem, kdvel, ndvel, & + &chem1, vd1, & + &rho1,flt, & + &tcd, qcd, & + &dfh, & + &s_aw1,s_awchem1, & + &zero, & + &zero, rrfs_sd, & + &enh_mix, smoke_dbg ) + endif + do ic = 1,nchem + do k = kts,kte + chem3d(i,k,ic) = max(1.e-12, chem1(k,ic)) + enddo + enddo + endif - CALL retrieve_exchange_coeffs(kts,kte,& - &dfm, dfh, dz1, K_m1, K_h1) - - !UPDATE 3D ARRAYS - do k=kts,kte - exch_m(i,k)=K_m1(k) - exch_h(i,k)=K_h1(k) - rublten(i,k)=du1(k) - rvblten(i,k)=dv1(k) - rthblten(i,k)=dth1(k) - rqvblten(i,k)=dqv1(k) - if (bl_mynn_cloudmix > 0) then - if (FLAG_QC) rqcblten(i,k)=dqc1(k) - if (FLAG_QI) rqiblten(i,k)=dqi1(k) - else - if (FLAG_QC) rqcblten(i,k)=0. - if (FLAG_QI) rqiblten(i,k)=0. - endif - if (bl_mynn_cloudmix > 0 .and. bl_mynn_mixscalars > 0) then - if (FLAG_QNC) rqncblten(i,k)=dqnc1(k) - if (FLAG_QNI) rqniblten(i,k)=dqni1(k) - if (FLAG_QNWFA) rqnwfablten(i,k)=dqnwfa1(k) - if (FLAG_QNIFA) rqnifablten(i,k)=dqnifa1(k) - else - if (FLAG_QNC) rqncblten(i,k)=0. - if (FLAG_QNI) rqniblten(i,k)=0. - if (FLAG_QNWFA) rqnwfablten(i,k)=0. - if (FLAG_QNIFA) rqnifablten(i,k)=0. - endif - dozone(i,k)=dozone1(k) - - if (icloud_bl > 0) then - qc_bl(i,k)=qc_bl1D(k) - qi_bl(i,k)=qi_bl1D(k) - cldfra_bl(i,k)=cldfra_bl1D(k) - endif - - el_pbl(i,k)=el(k) - qke(i,k)=qke1(k) - tsq(i,k)=tsq1(k) - qsq(i,k)=qsq1(k) - cov(i,k)=cov1(k) - sh3d(i,k)=sh(k) - sm3d(i,k)=sm(k) - enddo !end-k + call retrieve_exchange_coeffs(kts,kte, & + &dfm, dfh, dz1, K_m1, K_h1 ) + + !UPDATE 3D ARRAYS + exch_m(i,:) =k_m1(:) + exch_h(i,:) =k_h1(:) + rublten(i,:) =du1(:) + rvblten(i,:) =dv1(:) + rthblten(i,:)=dth1(:) + rqvblten(i,:)=dqv1(:) + if (bl_mynn_cloudmix > 0) then + if (flag_qc) rqcblten(i,:)=dqc1(:) + if (flag_qi) rqiblten(i,:)=dqi1(:) + if (flag_qs) rqsblten(i,:)=dqs1(:) + else + if (flag_qc) rqcblten(i,:)=0. + if (flag_qi) rqiblten(i,:)=0. + if (flag_qs) rqsblten(i,:)=0. + endif + if (bl_mynn_cloudmix > 0 .and. bl_mynn_mixscalars > 0) then + if (flag_qnc) rqncblten(i,:) =dqnc1(:) + if (flag_qni) rqniblten(i,:) =dqni1(:) + if (flag_qnwfa) rqnwfablten(i,:)=dqnwfa1(:) + if (flag_qnifa) rqnifablten(i,:)=dqnifa1(:) + if (flag_qnbca) rqnbcablten(i,:)=dqnbca1(:) + else + if (flag_qnc) rqncblten(i,:) =0. + if (flag_qni) rqniblten(i,:) =0. + if (flag_qnwfa) rqnwfablten(i,:)=0. + if (flag_qnifa) rqnifablten(i,:)=0. + if (flag_qnbca) rqnbcablten(i,:)=0. + endif + dozone(i,:)=dozone1(:) + if (icloud_bl > 0) then + qc_bl(i,:) =qc_bl1D(:) + qi_bl(i,:) =qi_bl1D(:) + cldfra_bl(i,:)=cldfra_bl1D(:) + endif + el_pbl(i,:)=el(:) + qke(i,:) =qke1(:) + tsq(i,:) =tsq1(:) + qsq(i,:) =qsq1(:) + cov(i,:) =cov1(:) + sh3d(i,:) =sh(:) + sm3d(i,:) =sm(:) + + if (tke_budget .eq. 1) then + !! TKE budget is now given in m**2/s**-3 (Puhales, 2020) + !! Lower boundary condtions (using similarity relationships such as the prognostic equation for Qke) + k=kts + qSHEAR1(k) =4.*(ust(i)**3*phi_m/(karman*dz(i,k)))-qSHEAR1(k+1) !! staggered + qBUOY1(k) =4.*(-ust(i)**3*zet/(karman*dz(i,k)))-qBUOY1(k+1) !! staggered + !! unstaggering SHEAR and BUOY and trasfering all TKE budget to 3D array + do k = kts,kte-1 + qSHEAR(i,k)=0.5*(qSHEAR1(k)+qSHEAR1(k+1)) !!! unstaggering in z + qBUOY(i,k) =0.5*(qBUOY1(k)+qBUOY1(k+1)) !!! unstaggering in z + qWT(i,k) =qWT1(k) + qDISS(i,k) =qDISS1(k) + dqke(i,k) =(qke1(k)-dqke(i,k))*0.5/delt + enddo + !! Upper boundary conditions + k=kte + qSHEAR(i,k) =0. + qBUOY(i,k) =0. + qWT(i,k) =0. + qDISS(i,k) =0. + dqke(i,k) =0. + endif - if ( bl_mynn_tkebudget ) then - !! TKE budget is now given in m**2/s**-3 (Puhales, 2020) - !! Lower boundary condtions (using similarity relationships such as the prognostic equation for Qke) - k=kts - qSHEAR1(k)=4.*(ust(i)**3*phi_m/(karman*dz(i,k)))-qSHEAR1(k+1) !! staggered - qBUOY1(k)=4.*(-ust(i)**3*zet/(karman*dz(i,k)))-qBUOY1(k+1) !! staggered - !! unstaggering SHEAR and BUOY and trasfering all TKE budget to 3D array - do k = kts,kte-1 - qSHEAR(i,k)=0.5*(qSHEAR1(k)+qSHEAR1(k+1)) !!! unstaggering in z - qBUOY(i,k)=0.5*(qBUOY1(k)+qBUOY1(k+1)) !!! unstaggering in z - qWT(i,k)=qWT1(k) - qDISS(i,k)=qDISS1(k) - dqke(i,k)=(qke1(k)-dqke(i,k))*0.5/delt - enddo - !! Upper boundary conditions - k=kte - qSHEAR(i,k)=0. - qBUOY(i,k)=0. - qWT(i,k)=0. - qDISS(i,k)=0. - dqke(i,k)=0. + !update updraft/downdraft properties + if (bl_mynn_output > 0) then !research mode == 1 + if (bl_mynn_edmf > 0) then + edmf_a(i,:) =edmf_a1(:) + edmf_w(i,:) =edmf_w1(:) + edmf_qt(i,:) =edmf_qt1(:) + edmf_thl(i,:) =edmf_thl1(:) + edmf_ent(i,:) =edmf_ent1(:) + edmf_qc(i,:) =edmf_qc1(:) + sub_thl3D(i,:)=sub_thl(:) + sub_sqv3D(i,:)=sub_sqv(:) + det_thl3D(i,:)=det_thl(:) + det_sqv3D(i,:)=det_sqv(:) endif + !if (bl_mynn_edmf_dd > 0) THEN + ! edmf_a_dd(i,:) =edmf_a_dd1(:) + ! edmf_w_dd(i,:) =edmf_w_dd1(:) + ! edmf_qt_dd(i,:) =edmf_qt_dd1(:) + ! edmf_thl_dd(i,:)=edmf_thl_dd1(:) + ! edmf_ent_dd(i,:)=edmf_ent_dd1(:) + ! edmf_qc_dd(i,:) =edmf_qc_dd1(:) + !endif + endif - !update updraft/downdraft properties - if (bl_mynn_output > 0) THEN !research mode == 1 - if (bl_mynn_edmf > 0) THEN - DO k = kts,kte - edmf_a(i,k)=edmf_a1(k) - edmf_w(i,k)=edmf_w1(k) - edmf_qt(i,k)=edmf_qt1(k) - edmf_thl(i,k)=edmf_thl1(k) - edmf_ent(i,k)=edmf_ent1(k) - edmf_qc(i,k)=edmf_qc1(k) - sub_thl3D(i,k)=sub_thl(k) - sub_sqv3D(i,k)=sub_sqv(k) - det_thl3D(i,k)=det_thl(k) - det_sqv3D(i,k)=det_sqv(k) - ENDDO - endif -! if (bl_mynn_edmf_dd > 0) THEN -! DO k = kts,kte -! edmf_a_dd(i,k)=edmf_a_dd1(k) -! edmf_w_dd(i,k)=edmf_w_dd1(k) -! edmf_qt_dd(i,k)=edmf_qt_dd1(k) -! edmf_thl_dd(i,k)=edmf_thl_dd1(k) -! edmf_ent_dd(i,k)=edmf_ent_dd1(k) -! edmf_qc_dd(i,k)=edmf_qc_dd1(k) -! ENDDO -! ENDIF - ENDIF - - !*** Begin debug prints - IF ( debug_code .and. (i .eq. idbg)) THEN - IF ( ABS(QFX(i))>.001)print*,& - "SUSPICIOUS VALUES AT: i=",i," QFX=",QFX(i) - IF ( ABS(HFX(i))>1100.)print*,& - "SUSPICIOUS VALUES AT: i=",i," HFX=",HFX(i) - DO k = kts,kte - IF ( sh(k) < 0. .OR. sh(k)> 200.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," sh=",sh(k) - IF ( ABS(vt(k)) > 2.0 )print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," vt=",vt(k) - IF ( ABS(vq(k)) > 7000.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," vq=",vq(k) - IF ( qke(i,k) < -1. .OR. qke(i,k)> 200.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," qke=",qke(i,k) - IF ( el_pbl(i,k) < 0. .OR. el_pbl(i,k)> 1500.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," el_pbl=",el_pbl(i,k) - IF ( exch_m(i,k) < 0. .OR. exch_m(i,k)> 2000.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," exxch_m=",exch_m(i,k) - IF (icloud_bl > 0) then - IF( cldfra_bl(i,k) < 0.0 .OR. cldfra_bl(i,k)> 1.)THEN - PRINT*,"SUSPICIOUS VALUES: CLDFRA_BL=",cldfra_bl(i,k)," qc_bl=",QC_BL(i,k) - ENDIF - ENDIF - - !IF (I==IMD .AND. J==JMD) THEN - ! PRINT*,"MYNN DRIVER END: k=",k," sh=",sh(k) - ! PRINT*," sqw=",sqw(k)," thl=",thl(k)," exch_m=",exch_m(i,k) - ! PRINT*," xland=",xland(i)," rmol=",rmol(i)," ust=",ust(i) - ! PRINT*," qke=",qke(i,k)," el=",el_pbl(i,k)," tsq=",tsq(i,k) - ! PRINT*," PBLH=",PBLH(i)," u=",u(i,k)," v=",v(i,k) - ! PRINT*," vq=",vq(k)," vt=",vt(k)," vdfg=",vdfg(i) - !ENDIF - ENDDO !end-k - ENDIF - !*** End debug prints + !*** Begin debug prints + if ( debug_code .and. (i .eq. idbg)) THEN + if ( ABS(QFX(i))>.001)print*,& + "SUSPICIOUS VALUES AT: i=",i," QFX=",QFX(i) + if ( ABS(HFX(i))>1100.)print*,& + "SUSPICIOUS VALUES AT: i=",i," HFX=",HFX(i) + do k = kts,kte + IF ( sh(k) < 0. .OR. sh(k)> 200.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," sh=",sh(k) + IF ( ABS(vt(k)) > 2.0 )print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," vt=",vt(k) + IF ( ABS(vq(k)) > 7000.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," vq=",vq(k) + IF ( qke(i,k) < -1. .OR. qke(i,k)> 200.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," qke=",qke(i,k) + IF ( el_pbl(i,k) < 0. .OR. el_pbl(i,k)> 1500.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," el_pbl=",el_pbl(i,k) + IF ( exch_m(i,k) < 0. .OR. exch_m(i,k)> 2000.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," exxch_m=",exch_m(i,k) + IF (icloud_bl > 0) then + IF ( cldfra_bl(i,k) < 0.0 .OR. cldfra_bl(i,k)> 1.)THEN + PRINT*,"SUSPICIOUS VALUES: CLDFRA_BL=",cldfra_bl(i,k)," qc_bl=",QC_BL(i,k) + ENDIF + ENDIF - !JOE-add tke_pbl for coupling w/shallow-cu schemes (TKE_PBL = QKE/2.) - ! TKE_PBL is defined on interfaces, while QKE is at middle of layer. - !tke_pbl(i,kts) = 0.5*MAX(qke(i,kts),1.0e-10) - !DO k = kts+1,kte - ! afk = dz1(k)/( dz1(k)+dz1(k-1) ) - ! abk = 1.0 -afk - ! tke_pbl(i,k) = 0.5*MAX(qke(i,k)*abk+qke(i,k-1)*afk,1.0e-3) - !ENDDO + !IF (I==IMD .AND. J==JMD) THEN + ! PRINT*,"MYNN DRIVER END: k=",k," sh=",sh(k) + ! PRINT*," sqw=",sqw(k)," thl=",thl(k)," exch_m=",exch_m(i,k) + ! PRINT*," xland=",xland(i)," rmol=",rmol(i)," ust=",ust(i) + ! PRINT*," qke=",qke(i,k)," el=",el_pbl(i,k)," tsq=",tsq(i,k) + ! PRINT*," PBLH=",PBLH(i)," u=",u(i,k)," v=",v(i,k) + ! PRINT*," vq=",vq(k)," vt=",vt(k) + !ENDIF + enddo !end-k + endif - ENDDO !end i-loop + enddo !end i-loop !ACF copy qke into qke_adv if using advection IF (bl_mynn_tkeadvect) THEN @@ -1610,40 +1497,40 @@ END SUBROUTINE mynn_bl_driver !!\section gen_mym_ini GSD MYNN-EDMF mym_initialize General Algorithm !> @{ SUBROUTINE mym_initialize ( & - & kts,kte, & + & kts,kte,xland, & & dz, dx, zw, & & u, v, thl, qw, & - & thlsg, qwsg, & ! & ust, rmo, pmz, phh, flt, flq, & & zi, theta, thetav, sh, sm, & & ust, rmo, el, & & Qke, Tsq, Qsq, Cov, Psig_bl, cldfra_bl1D, & & bl_mynn_mixlength, & - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & + & edmf_w1,edmf_a1, & & INITIALIZE_QKE, & & spp_pbl,rstoch_col) ! !------------------------------------------------------------------- - - INTEGER, INTENT(IN) :: kts,kte - INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf - LOGICAL, INTENT(IN) :: INITIALIZE_QKE -! REAL, INTENT(IN) :: ust, rmo, pmz, phh, flt, flq - REAL, INTENT(IN) :: rmo, Psig_bl - REAL(kind=kind_phys), INTENT(IN) :: dx, ust, zi - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,cldfra_bl1D,& - edmf_w1,edmf_a1,edmf_qc1 - REAL, DIMENSION(kts:kte), INTENT(out) :: tsq,qsq,cov - REAL, DIMENSION(kts:kte), INTENT(inout) :: el,qke - REAL, DIMENSION(kts:kte) :: & - &ql,pdk,pdt,pdq,pdc,dtl,dqw,dtv,& + + integer, INTENT(IN) :: kts,kte + integer, INTENT(IN) :: bl_mynn_mixlength + logical, INTENT(IN) :: INITIALIZE_QKE +! real(kind_phys), INTENT(IN) :: ust, rmo, pmz, phh, flt, flq + real(kind_phys), INTENT(IN) :: rmo, Psig_bl, xland + real(kind_phys), INTENT(IN) :: dx, ust, zi + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v,thl,& + &qw,cldfra_bl1D,edmf_w1,edmf_a1 + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: tsq,qsq,cov + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: el,qke + real(kind_phys), DIMENSION(kts:kte) :: & + &ql,pdk,pdt,pdq,pdc,dtl,dqw,dtv, & &gm,gh,sm,sh,qkw,vt,vq INTEGER :: k,l,lmax - REAL :: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1.,flt=0.,flq=0.,tmpq - REAL, DIMENSION(kts:kte) :: theta,thetav,thlsg,qwsg - REAL, DIMENSION(kts:kte) :: rstoch_col + real(kind_phys):: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1., & + &flt=0.,fltv=0.,flq=0.,tmpq + real(kind_phys), DIMENSION(kts:kte) :: theta,thetav + real(kind_phys), DIMENSION(kts:kte) :: rstoch_col INTEGER ::spp_pbl !> - At first ql, vt and vq are set to zero. @@ -1657,7 +1544,6 @@ SUBROUTINE mym_initialize ( & CALL mym_level2 ( kts,kte, & & dz, & & u, v, thl, thetav, qw, & - & thlsg, qwsg, & & ql, vt, vq, & & dtl, dqw, dtv, gm, gh, sm, sh ) ! @@ -1696,17 +1582,18 @@ SUBROUTINE mym_initialize ( & DO l = 1,lmax ! !> - call mym_length() to calculate the master length scale. - CALL mym_length ( & - & kts,kte, & - & dz, dx, zw, & - & rmo, flt, flq, & - & vt, vq, & - & u, v, qke, & - & dtv, & - & el, & - & zi,theta, & - & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength,& - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf) + CALL mym_length ( & + & kts,kte,xland, & + & dz, dx, zw, & + & rmo, flt, fltv, flq, & + & vt, vq, & + & u, v, qke, & + & dtv, & + & el, & + & zi,theta, & + & qkw,Psig_bl,cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1 ) ! DO k = kts+1,kte elq = el(k)*qkw(k) @@ -1816,7 +1703,6 @@ END SUBROUTINE mym_initialize SUBROUTINE mym_level2 (kts,kte, & & dz, & & u, v, thl, thetav, qw, & - & thlsg, qwsg, & & ql, vt, vq, & & dtl, dqw, dtv, gm, gh, sm, sh ) ! @@ -1829,18 +1715,19 @@ SUBROUTINE mym_level2 (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,ql,vt,vq,& - thetav,thlsg,qwsg - REAL, DIMENSION(kts:kte), INTENT(out) :: & + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v, & + &thl,qw,ql,vt,vq,thetav + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: & &dtl,dqw,dtv,gm,gh,sm,sh - INTEGER :: k + integer :: k - REAL :: rfc,f1,f2,rf1,rf2,smc,shc,& - &ri1,ri2,ri3,ri4,duz,dtz,dqz,vtt,vqq,dtq,dzk,afk,abk,ri,rf + real(kind_phys):: rfc,f1,f2,rf1,rf2,smc,shc, & + &ri1,ri2,ri3,ri4,duz,dtz,dqz,vtt,vqq,dtq,dzk, & + &afk,abk,ri,rf - REAL :: a2fac + real(kind_phys):: a2fac ! ev = 2.5e6 ! tv0 = 0.61*tref @@ -1868,11 +1755,7 @@ SUBROUTINE mym_level2 (kts,kte, & duz = ( u(k)-u(k-1) )**2 +( v(k)-v(k-1) )**2 duz = duz /dzk**2 dtz = ( thl(k)-thl(k-1) )/( dzk ) - !Alternatively, use SGS clouds for thl - !dtz = ( thlsg(k)-thlsg(k-1) )/( dzk ) dqz = ( qw(k)-qw(k-1) )/( dzk ) - !Alternatively, use SGS clouds for qw - !dqz = ( qwsg(k)-qwsg(k-1) )/( dzk ) ! vtt = 1.0 +vt(k)*abk +vt(k-1)*afk ! Beta-theta in NN09, Eq. 39 vqq = tv0 +vq(k)*abk +vq(k-1)*afk ! Beta-q @@ -1949,16 +1832,17 @@ END SUBROUTINE mym_level2 !>\ingroup gsd_mynn_edmf !! This subroutine calculates the mixing lengths. SUBROUTINE mym_length ( & - & kts,kte, & + & kts,kte,xland, & & dz, dx, zw, & - & rmo, flt, flq, & + & rmo, flt, fltv, flq, & & vt, vq, & & u1, v1, qke, & & dtv, & & el, & - & zi,theta, & - & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength,& - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf) + & zi, theta, qkw, & + & Psig_bl, cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1 ) !------------------------------------------------------------------- @@ -1969,53 +1853,50 @@ SUBROUTINE mym_length ( & # define kte HARDCODE_VERTICAL #endif - INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,flq,Psig_bl - REAL(kind=kind_phys), INTENT(IN) :: dx,zi - REAL, DIMENSION(kts:kte), INTENT(IN) :: u1,v1,qke,vt,vq,cldfra_bl1D,& - edmf_w1,edmf_a1,edmf_qc1 - REAL, DIMENSION(kts:kte), INTENT(out) :: qkw, el - REAL, DIMENSION(kts:kte), INTENT(in) :: dtv - - REAL :: elt,vsc - - REAL, DIMENSION(kts:kte), INTENT(IN) :: theta - REAL, DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg,thetaw - REAL :: wt,wt2,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg + INTEGER, INTENT(IN) :: bl_mynn_mixlength + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: zw + real(kind_phys), INTENT(in) :: rmo,flt,fltv,flq,Psig_bl,xland + real(kind_phys), INTENT(IN) :: dx,zi + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: u1,v1, & + &qke,vt,vq,cldfra_bl1D,edmf_w1,edmf_a1 + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: qkw, el + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dtv + real(kind_phys):: elt,vsc + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: theta + real(kind_phys), DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg,thetaw + real(kind_phys):: wt,wt2,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg ! THE FOLLOWING CONSTANTS ARE IMPORTANT FOR REGULATING THE ! MIXING LENGTHS: - REAL :: cns, & !< for surface layer (els) in stable conditions - alp1, & !< for turbulent length scale (elt) - alp2, & !< for buoyancy length scale (elb) - alp3, & !< for buoyancy enhancement factor of elb - alp4, & !< for surface layer (els) in unstable conditions - alp5, & !< for BouLac mixing length or above PBLH - alp6 !< for mass-flux/ + real(kind_phys):: cns, & !< for surface layer (els) in stable conditions + alp1, & !< for turbulent length scale (elt) + alp2, & !< for buoyancy length scale (elb) + alp3, & !< for buoyancy enhancement factor of elb + alp4, & !< for surface layer (els) in unstable conditions + alp5, & !< for BouLac mixing length or above PBLH + alp6 !< for mass-flux/ !THE FOLLOWING LIMITS DO NOT DIRECTLY AFFECT THE ACTUAL PBLH. !THEY ONLY IMPOSE LIMITS ON THE CALCULATION OF THE MIXING LENGTH !SCALES SO THAT THE BOULAC MIXING LENGTH (IN FREE ATMOS) DOES !NOT ENCROACH UPON THE BOUNDARY LAYER MIXING LENGTH (els, elb & elt). - REAL, PARAMETER :: minzi = 300. !< min mixed-layer height - REAL, PARAMETER :: maxdz = 750. !< max (half) transition layer depth + real(kind_phys), PARAMETER :: minzi = 300. !< min mixed-layer height + real(kind_phys), PARAMETER :: maxdz = 750. !< max (half) transition layer depth !! =0.3*2500 m PBLH, so the transition !! layer stops growing for PBLHs > 2.5 km. - REAL, PARAMETER :: mindz = 300. !< 300 !min (half) transition layer depth + real(kind_phys), PARAMETER :: mindz = 300. !< 300 !min (half) transition layer depth !SURFACE LAYER LENGTH SCALE MODS TO REDUCE IMPACT IN UPPER BOUNDARY LAYER - REAL, PARAMETER :: ZSLH = 100. !< Max height correlated to surface conditions (m) - REAL, PARAMETER :: CSL = 2. !< CSL = constant of proportionality to L O(1) - REAL :: z_m + real(kind_phys), PARAMETER :: ZSLH = 100. !< Max height correlated to surface conditions (m) + real(kind_phys), PARAMETER :: CSL = 2. !< CSL = constant of proportionality to L O(1) INTEGER :: i,j,k - REAL :: afk,abk,zwk,zwk1,dzk,qdz,vflx,bv,tau_cloud,wstar,elb,els, & - & els1,elf,el_stab,el_unstab,el_mf,el_stab_mf,elb_mf, & - & PBLH_PLUS_ENT,Uonset,Ugrid,el_les - REAL, PARAMETER :: ctau = 1000. !constant for tau_cloud + real(kind_phys):: afk,abk,zwk,zwk1,dzk,qdz,vflx,bv,tau_cloud, & + & wstar,elb,els,elf,el_stab,el_mf,el_stab_mf,elb_mf, & + & PBLH_PLUS_ENT,Uonset,Ugrid,wt_u,el_les + real(kind_phys), PARAMETER :: ctau = 1000. !constant for tau_cloud ! tv0 = 0.61*tref ! gtr = 9.81/tref @@ -2083,15 +1964,11 @@ SUBROUTINE mym_length ( & elf = elb ENDIF - z_m = MAX(0.,zwk - 4.) - ! ** Length scale in the surface layer ** IF ( rmo .GT. 0.0 ) THEN els = karman*zwk/(1.0+cns*MIN( zwk*rmo, zmax )) - els1 = karman*z_m/(1.0+cns*MIN( zwk*rmo, zmax )) ELSE els = karman*zwk*( 1.0 - alp4* zwk*rmo )**0.2 - els1 = karman*z_m*( 1.0 - alp4* zwk*rmo )**0.2 END IF ! ** HARMONC AVERGING OF MIXING LENGTH SCALES: @@ -2106,18 +1983,21 @@ SUBROUTINE mym_length ( & CASE (1) !NONLOCAL (using BouLac) FORM OF MIXING LENGTH - cns = 3.5 - alp1 = 0.22 !0.21 + ugrid = sqrt(u1(kts)**2 + v1(kts)**2) + uonset= 15. + wt_u = (1.0 - min(max(ugrid - uonset, 0.0)/30.0, 0.5)) + cns = 2.7 !was 3.5 + alp1 = 0.22 alp2 = 0.3 - alp3 = 2.0 !1.5 + alp3 = 2.0 * wt_u !taper off bouyancy enhancement in shear-driven pbls alp4 = 5.0 alp5 = 0.3 alp6 = 50. ! Impose limits on the height integration for elt and the transition layer depth - zi2=MAX(zi,200.) !minzi) - h1=MAX(0.3*zi2,200.) - h1=MIN(h1,500.) ! 1/2 transition layer depth + zi2=MAX(zi,300.) !minzi) + h1=MAX(0.3*zi2,300.) + h1=MIN(h1,600.) ! 1/2 transition layer depth h2=h1/2.0 ! 1/4 transition layer depth qtke(kts)=MAX(0.5*qke(kts), 0.01) !tke at full sigma levels @@ -2148,7 +2028,9 @@ SUBROUTINE mym_length ( & END DO elt = MIN( MAX( alp1*elt/vsc, 10.), 400.) - vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq + !avoid use of buoyancy flux functions which are ill-defined at the surface + !vflx = ( vt(kts)+1.0 )*flt + ( vq(kts)+tv0 )*flq + vflx = fltv vsc = ( gtr*elt*MAX( vflx, 0.0 ) )**onethird ! ** Strictly, el(i,j,1) is not zero. ** @@ -2163,31 +2045,23 @@ SUBROUTINE mym_length ( & ! ** Length scale limited by the buoyancy effect ** IF ( dtv(k) .GT. 0.0 ) THEN - alp2 = 0.3 !test+ 0.15*0.5*(cldfra_bl1D(k)+cldfra_bl1D(k-1)) bv = max( sqrt( gtr*dtv(k) ), 0.001) - !elb = alp2*qkw(k) / bv & ! formulation, - ! & *( 1.0 + alp3/alp2*& ! except keep - ! &SQRT( vsc/( bv*elt ) ) ) ! elb bounded by zwk elb = MAX(alp2*qkw(k), & & alp6*edmf_a1(k-1)*edmf_w1(k-1)) / bv & & *( 1.0 + alp3*SQRT( vsc/(bv*elt) ) ) elb = MIN(elb, zwk) - elf = 0.65 * qkw(k)/bv + elf = 0.80 * qkw(k)/bv elBLavg(k) = MAX(elBLavg(k), alp6*edmf_a1(k-1)*edmf_w1(k-1)/bv) ELSE elb = 1.0e10 elf = elb ENDIF - z_m = MAX(0.,zwk - 4.) - ! ** Length scale in the surface layer ** IF ( rmo .GT. 0.0 ) THEN els = karman*zwk/(1.0+cns*MIN( zwk*rmo, zmax )) - els1 = karman*z_m/(1.0+cns*MIN( zwk*rmo, zmax )) ELSE els = karman*zwk*( 1.0 - alp4* zwk*rmo )**0.2 - els1 = karman*z_m*( 1.0 - alp4* zwk*rmo )**0.2 END IF ! ** NOW BLEND THE MIXING LENGTH SCALES: @@ -2197,8 +2071,7 @@ SUBROUTINE mym_length ( & !defined relative to the PBLH (zi) + transition layer (h1) !el(k) = MIN(elb/( elb/elt+elb/els+1.0 ),elf) !try squared-blending - !el_unstab = SQRT( els**2/(1. + (els1**2/elt**2) )) - el(k) = SQRT( els**2/(1. + (els1**2/elt**2) +(els1**2/elb**2))) + el(k) = SQRT( els**2/(1. + (els**2/elt**2) +(els**2/elb**2))) el(k) = MIN (el(k), elf) el(k) = el(k)*(1.-wt) + alp5*elBLavg(k)*wt @@ -2212,20 +2085,20 @@ SUBROUTINE mym_length ( & Uonset = 3.5 + dz(kts)*0.1 Ugrid = sqrt(u1(kts)**2 + v1(kts)**2) cns = 3.5 !JOE-test * (1.0 - MIN(MAX(Ugrid - Uonset, 0.0)/10.0, 1.0)) - alp1 = 0.22 !0.21 + alp1 = 0.22 alp2 = 0.30 - alp3 = 2.0 !1.5 + alp3 = 2.0 alp4 = 5.0 alp5 = alp2 !like alp2, but for free atmosphere alp6 = 50.0 !used for MF mixing length ! Impose limits on the height integration for elt and the transition layer depth !zi2=MAX(zi,minzi) - zi2=MAX(zi, 200.) + zi2=MAX(zi, 300.) !h1=MAX(0.3*zi2,mindz) !h1=MIN(h1,maxdz) ! 1/2 transition layer depth - h1=MAX(0.3*zi2,200.) - h1=MIN(h1,500.) + h1=MAX(0.3*zi2,300.) + h1=MIN(h1,600.) h2=h1*0.5 ! 1/4 transition layer depth qtke(kts)=MAX(0.5*qke(kts),0.01) !tke at full sigma levels @@ -2255,7 +2128,9 @@ SUBROUTINE mym_length ( & END DO elt = MIN( MAX(alp1*elt/vsc, 10.), 400.) - vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq + !avoid use of buoyancy flux functions which are ill-defined at the surface + !vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq + vflx = fltv vsc = ( gtr*elt*MAX( vflx, 0.0 ) )**onethird ! ** Strictly, el(i,j,1) is not zero. ** @@ -2318,33 +2193,24 @@ SUBROUTINE mym_length ( & elb_mf = elb END IF elf = elf/(1. + (elf/800.)) !bound free-atmos mixing length to < 800 m. -! elb_mf = elb_mf/(1. + (elb_mf/800.)) !bound buoyancy mixing length to < 800 m. elb_mf = MAX(elb_mf, 0.01) !to avoid divide-by-zero below - z_m = MAX(0.,zwk - 4.) - ! ** Length scale in the surface layer ** IF ( rmo .GT. 0.0 ) THEN els = karman*zwk/(1.0+cns*MIN( zwk*rmo, zmax )) - els1 = karman*z_m/(1.0+cns*MIN( zwk*rmo, zmax )) ELSE els = karman*zwk*( 1.0 - alp4* zwk*rmo )**0.2 - els1 = karman*z_m*( 1.0 - alp4* zwk*rmo )**0.2 END IF ! ** NOW BLEND THE MIXING LENGTH SCALES: wt=.5*TANH((zwk - (zi2+h1))/h2) + .5 - ! "el_unstab" = blended els-elt - !el_unstab = els/(1. + (els1/elt)) !try squared-blending - !el(k) = SQRT( els**2/(1. + (els1**2/elt**2) )) - el(k) = SQRT( els**2/(1. + (els1**2/elt**2) +(els1**2/elb_mf**2))) - !el(k) = MIN(el_unstab, elb_mf) + el(k) = SQRT( els**2/(1. + (els**2/elt**2) +(els**2/elb_mf**2))) el(k) = el(k)*(1.-wt) + elf*wt - ! include scale-awareness. For now, use simple asymptotic kz -> 12 m. - el_les= MIN(els/(1. + (els1/12.)), elb_mf) + ! include scale-awareness. For now, use simple asymptotic kz -> 12 m (should be ~dz). + el_les= MIN(els/(1. + (els/12.)), elb_mf) el(k) = el(k)*Psig_bl + (1.-Psig_bl)*el_les END DO @@ -2391,14 +2257,14 @@ SUBROUTINE boulac_length0(k,kts,kte,zw,dz,qtke,theta,lb1,lb2) !------------------------------------------------------------------- INTEGER, INTENT(IN) :: k,kts,kte - REAL, DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta - REAL, INTENT(OUT) :: lb1,lb2 - REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta + real(kind_phys), INTENT(OUT) :: lb1,lb2 + real(kind_phys), DIMENSION(kts:kte+1), INTENT(IN) :: zw !LOCAL VARS INTEGER :: izz, found - REAL :: dlu,dld - REAL :: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz + real(kind_phys):: dlu,dld + real(kind_phys):: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz !---------------------------------- @@ -2541,15 +2407,15 @@ SUBROUTINE boulac_length(kts,kte,zw,dz,qtke,theta,lb1,lb2) !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte - REAL, DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta - REAL, DIMENSION(kts:kte), INTENT(OUT) :: lb1,lb2 - REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta + real(kind_phys), DIMENSION(kts:kte), INTENT(OUT):: lb1,lb2 + real(kind_phys), DIMENSION(kts:kte+1), INTENT(IN) :: zw !LOCAL VARS INTEGER :: iz, izz, found - REAL, DIMENSION(kts:kte) :: dlu,dld - REAL, PARAMETER :: Lmax=2000. !soft limit - REAL :: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz + real(kind_phys), DIMENSION(kts:kte) :: dlu,dld + real(kind_phys), PARAMETER :: Lmax=2000. !soft limit + real(kind_phys):: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz !print*,"IN MYNN-BouLac",kts, kte @@ -2730,30 +2596,30 @@ END SUBROUTINE boulac_length !! - Production terms of TKE,\f$\theta^{'2}\f$,\f$q^{'2}\f$, and \f$\theta^{'}q^{'}\f$ !! are calculated. !! - Eddy diffusivity \f$K_h\f$ and eddy viscosity \f$K_m\f$ are calculated. -!! - TKE budget terms are calculated (if the namelist parameter \p bl_mynn_tkebudget +!! - TKE budget terms are calculated (if the namelist parameter \p tke_budget !! is set to True) SUBROUTINE mym_turbulence ( & & kts,kte, & - & closure, & + & xland,closure, & & dz, dx, zw, & & u, v, thl, thetav, ql, qw, & - & thlsg, qwsg, & & qke, tsq, qsq, cov, & & vt, vq, & - & rmo, flt, flq, & + & rmo, flt, fltv, flq, & & zi,theta, & & sh, sm, & & El, & & Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, & & qWT1D,qSHEAR1D,qBUOY1D,qDISS1D, & - & bl_mynn_tkebudget, & - & Psig_bl,Psig_shcu,cldfra_bl1D,bl_mynn_mixlength,& - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & + & tke_budget, & + & Psig_bl,Psig_shcu,cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1, & & TKEprodTD, & - & spp_pbl,rstoch_col) + & spp_pbl,rstoch_col ) !------------------------------------------------------------------- -! + INTEGER, INTENT(IN) :: kts,kte #ifdef HARDCODE_VERTICAL @@ -2761,40 +2627,38 @@ SUBROUTINE mym_turbulence ( & # define kte HARDCODE_VERTICAL #endif - INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf - REAL(kind=kind_phys), INTENT(IN) :: closure - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,flq,Psig_bl,Psig_shcu - REAL(kind=kind_phys), INTENT(IN) :: dx,zi - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,thetav,qw,& - &ql,vt,vq,qke,tsq,qsq,cov,cldfra_bl1D,edmf_w1,edmf_a1,edmf_qc1,& - &TKEprodTD,thlsg,qwsg - - REAL, DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq,& + INTEGER, INTENT(IN) :: bl_mynn_mixlength,tke_budget + real(kind_phys), INTENT(IN) :: closure + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: zw + real(kind_phys), INTENT(in) :: rmo,flt,fltv,flq, & + &Psig_bl,Psig_shcu,xland,dx,zi + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v,thl,thetav,qw, & + &ql,vt,vq,qke,tsq,qsq,cov,cldfra_bl1D,edmf_w1,edmf_a1, & + &TKEprodTD + + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq, & &pdk,pdt,pdq,pdc,tcd,qcd,el - REAL, DIMENSION(kts:kte), INTENT(inout) :: & + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: & qWT1D,qSHEAR1D,qBUOY1D,qDISS1D - REAL :: q3sq_old,dlsq1,qWTP_old,qWTP_new - REAL :: dudz,dvdz,dTdz,& - upwp,vpwp,Tpwp - LOGICAL, INTENT(in) :: bl_mynn_tkebudget + real(kind_phys):: q3sq_old,dlsq1,qWTP_old,qWTP_new + real(kind_phys):: dudz,dvdz,dTdz,upwp,vpwp,Tpwp - REAL, DIMENSION(kts:kte) :: qkw,dtl,dqw,dtv,gm,gh,sm,sh + real(kind_phys), DIMENSION(kts:kte) :: qkw,dtl,dqw,dtv,gm,gh,sm,sh INTEGER :: k -! REAL :: cc2,cc3,e1c,e2c,e3c,e4c,e5c - REAL :: e6c,dzk,afk,abk,vtt,vqq,& +! real(kind_phys):: cc2,cc3,e1c,e2c,e3c,e4c,e5c + real(kind_phys):: e6c,dzk,afk,abk,vtt,vqq, & &cw25,clow,cupp,gamt,gamq,smd,gamv,elq,elh - REAL :: cldavg - REAL, DIMENSION(kts:kte), INTENT(in) :: theta + real(kind_phys):: cldavg + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: theta - REAL :: a2fac, duz, ri !JOE-Canuto/Kitamura mod + real(kind_phys):: a2fac, duz, ri !JOE-Canuto/Kitamura mod - REAL:: auh,aum,adh,adm,aeh,aem,Req,Rsl,Rsl2,& - gmelq,sm20,sh20,sm25max,sh25max,sm25min,sh25min,& + real:: auh,aum,adh,adm,aeh,aem,Req,Rsl,Rsl2, & + gmelq,sm20,sh20,sm25max,sh25max,sm25min,sh25min, & sm_pbl,sh_pbl,zi2,wt,slht,wtpr DOUBLE PRECISION q2sq, t2sq, r2sq, c2sq, elsq, gmel, ghel @@ -2802,11 +2666,10 @@ SUBROUTINE mym_turbulence ( & DOUBLE PRECISION e1, e2, e3, e4, enum, eden, wden ! Stochastic - INTEGER, INTENT(IN) :: spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col - REAL :: Prnum, Prlim - REAL, PARAMETER :: Prlimit = 5.0 - + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col + real(kind_phys):: Prnum, shb + real(kind_phys), PARAMETER :: Prlimit = 5.0 ! ! tv0 = 0.61*tref @@ -2824,21 +2687,21 @@ SUBROUTINE mym_turbulence ( & CALL mym_level2 (kts,kte, & & dz, & & u, v, thl, thetav, qw, & - & thlsg, qwsg, & & ql, vt, vq, & & dtl, dqw, dtv, gm, gh, sm, sh ) ! CALL mym_length ( & - & kts,kte, & + & kts,kte,xland, & & dz, dx, zw, & - & rmo, flt, flq, & + & rmo, flt, fltv, flq, & & vt, vq, & & u, v, qke, & & dtv, & & el, & & zi,theta, & - & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength, & - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf ) + & qkw,Psig_bl,cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1 ) ! DO k = kts+1,kte @@ -3002,10 +2865,16 @@ SUBROUTINE mym_turbulence ( & !IF ( sm(k) > sm25max ) sm(k) = sm25max !IF ( sm(k) < sm25min ) sm(k) = sm25min !sm(k) = Prnum*sh(k) - slht = zi*0.1 - wtpr = min( max( (slht - zw(k))/slht, 0.0), 1.0) ! 1 at z=0, 0 above sfc layer - Prlim = 1.0*wtpr + (1.0 - wtpr)*Prlimit - sm(k) = MIN(sm(k), Prlimit*Sh(k)) + + !surface layer PR + !slht = zi*0.1 + !wtpr = min( max( (slht - zw(k))/slht, 0.0), 1.0) ! 1 at z=0, 0 above sfc layer + !Prlim = 1.0*wtpr + (1.0 - wtpr)*Prlimit + !Prlim = 2.0*wtpr + (1.0 - wtpr)*Prlimit + !sm(k) = MIN(sm(k), Prlim*Sh(k)) + !Pending more testing, keep same Pr limit in sfc layer + shb = max(sh(k), 0.002) + sm(k) = MIN(sm(k), Prlimit*shb) ! ** Level 3 : start ** IF ( closure .GE. 3.0 ) THEN @@ -3160,11 +3029,6 @@ SUBROUTINE mym_turbulence ( & ! with active plumes and clouds. cldavg = 0.5*(cldfra_bl1D(k-1) + cldfra_bl1D(k)) IF (edmf_a1(k) > 0.001 .OR. cldavg > 0.02) THEN - !sm(k) = MAX(sm(k), MAX(1.0 - 2.0*cldavg, 0.0)**0.33 * 0.03 * & - ! & MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) - !sh(k) = MAX(sh(k), MAX(1.0 - 2.0*cldavg, 0.0)**0.33 * 0.03 * & - ! & MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) - ! for mass-flux columns sm(k) = MAX(sm(k), 0.03*MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) sh(k) = MAX(sh(k), 0.03*MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) @@ -3178,14 +3042,14 @@ SUBROUTINE mym_turbulence ( & ! Production of TKE (pdk), T-variance (pdt), ! q-variance (pdq), and covariance (pdc) - pdk(k) = elq*( sm(k)*gm(k) & - & +sh(k)*gh(k)+gamv ) + & + pdk(k) = elq*( sm(k)*gm(k) & + & +sh(k)*gh(k)+gamv ) + & & TKEprodTD(k) pdt(k) = elh*( sh(k)*dtl(k)+gamt )*dtl(k) pdq(k) = elh*( sh(k)*dqw(k)+gamq )*dqw(k) - pdc(k) = elh*( sh(k)*dtl(k)+gamt )& - &*dqw(k)*0.5 & - &+elh*( sh(k)*dqw(k)+gamq )*dtl(k)*0.5 + pdc(k) = elh*( sh(k)*dtl(k)+gamt ) & + & *dqw(k)*0.5 & + & + elh*( sh(k)*dqw(k)+gamq )*dtl(k)*0.5 ! Contergradient terms tcd(k) = elq*gamt @@ -3200,7 +3064,7 @@ SUBROUTINE mym_turbulence ( & dfq(k) = dfm(k) ! Modified: Dec/22/2005, up to here - IF ( bl_mynn_tkebudget ) THEN + IF (tke_budget .eq. 1) THEN !TKE BUDGET ! dudz = ( u(k)-u(k-1) )/dzk ! dvdz = ( v(k)-v(k-1) )/dzk @@ -3229,7 +3093,7 @@ SUBROUTINE mym_turbulence ( & !!!Dissipation Term (now it evaluated on mym_predict) !qDISS1D(k) = (q3sq**(3./2.))/(b1*MAX(el(k),1.)) !! ORIGINAL CODE - !! >> EOB + !! >> EOB ENDIF END DO @@ -3323,7 +3187,7 @@ SUBROUTINE mym_predict (kts,kte, & & pdk, pdt, pdq, pdc, & & qke, tsq, qsq, cov, & & s_aw,s_awqke,bl_mynn_edmf_tke, & - & qWT1D, qDISS1D,bl_mynn_tkebudget) !! TKE budget (Puhales, 2020) + & qWT1D, qDISS1D,tke_budget) !! TKE budget (Puhales, 2020) !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte @@ -3333,30 +3197,29 @@ SUBROUTINE mym_predict (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL(kind=kind_phys), INTENT(IN) :: closure - INTEGER, INTENT(IN) :: bl_mynn_edmf_tke - REAL, DIMENSION(kts:kte), INTENT(IN) :: dz, dfq, el, rho - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc - REAL, INTENT(IN) :: flt, flq, pmz, phh - REAL(kind=kind_phys), INTENT(IN) :: ust, delt - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov + real(kind_phys), INTENT(IN) :: closure + INTEGER, INTENT(IN) :: bl_mynn_edmf_tke,tke_budget + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: dz, dfq, el, rho + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc + real(kind_phys), INTENT(IN) :: flt, flq, pmz, phh + real(kind_phys), INTENT(IN) :: ust, delt + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov ! WA 8/3/15 - REAL, DIMENSION(kts:kte+1), INTENT(INOUT) :: s_awqke,s_aw + real(kind_phys), DIMENSION(kts:kte+1), INTENT(INOUT) :: s_awqke,s_aw !! TKE budget (Puhales, 2020, WRF 4.2.1) << EOB - REAL, DIMENSION(kts:kte), INTENT(OUT) :: qWT1D, qDISS1D - LOGICAL, INTENT(IN) :: bl_mynn_tkebudget - REAL, DIMENSION(kts:kte) :: tke_up,dzinv + real(kind_phys), DIMENSION(kts:kte), INTENT(OUT) :: qWT1D, qDISS1D + real(kind_phys), DIMENSION(kts:kte) :: tke_up,dzinv !! >> EOB INTEGER :: k - REAL, DIMENSION(kts:kte) :: qkw, bp, rp, df3q - REAL :: vkz,pdk1,phm,pdt1,pdq1,pdc1,b1l,b2l,onoff - REAL, DIMENSION(kts:kte) :: dtz - REAL, DIMENSION(kts:kte) :: a,b,c,d,x + real(kind_phys), DIMENSION(kts:kte) :: qkw, bp, rp, df3q + real(kind_phys):: vkz,pdk1,phm,pdt1,pdq1,pdc1,b1l,b2l,onoff + real(kind_phys), DIMENSION(kts:kte) :: dtz + real(kind_phys), DIMENSION(kts:kte) :: a,b,c,d,x - REAL, DIMENSION(kts:kte) :: rhoinv - REAL, DIMENSION(kts:kte+1) :: rhoz,kqdz,kmdz + real(kind_phys), DIMENSION(kts:kte) :: rhoinv + real(kind_phys), DIMENSION(kts:kte+1) :: rhoz,kqdz,kmdz ! REGULATE THE MOMENTUM MIXING FROM THE MASS-FLUX SCHEME (on or off) IF (bl_mynn_edmf_tke == 0) THEN @@ -3486,7 +3349,7 @@ SUBROUTINE mym_predict (kts,kte, & !! TKE budget (Puhales, 2020, WRF 4.2.1) << EOB - IF (bl_mynn_tkebudget) THEN + IF (tke_budget .eq. 1) THEN !! TKE Vertical transport << EOBvt tke_up=0.5*qke dzinv=1./dz @@ -3722,8 +3585,8 @@ END SUBROUTINE mym_predict !! calculate the buoyancy flux. Different cloud PDFs can be selected by !! use of the namelist parameter \p bl_mynn_cloudpdf . SUBROUTINE mym_condensation (kts,kte, & - & dx, dz, zw, u1, v1, xland,& - & thl, qw, qv, qc, qi, & + & dx, dz, zw, xland, & + & thl, qw, qv, qc, qi, qs, & & p,exner, & & tsq, qsq, cov, & & Sh, el, bl_mynn_cloudpdf, & @@ -3742,45 +3605,45 @@ SUBROUTINE mym_condensation (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(IN) :: HFX1,rmo,xland - REAL(kind=kind_phys), INTENT(IN) :: dx,pblh1 - REAL, DIMENSION(kts:kte), INTENT(IN) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw - REAL, DIMENSION(kts:kte), INTENT(IN) :: p,exner,thl,qw,qv,qc,qi, & - &tsq, qsq, cov, th, u1, v1 + real(kind_phys), INTENT(IN) :: HFX1,rmo,xland + real(kind_phys), INTENT(IN) :: dx,pblh1 + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(IN) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: p,exner,thl,qw, & + &qv,qc,qi,qs,tsq,qsq,cov,th - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: vt,vq,sgm + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: vt,vq,sgm - REAL, DIMENSION(kts:kte) :: alp,a,bet,b,ql,q1,RH - REAL, DIMENSION(kts:kte), INTENT(OUT) :: qc_bl1D,qi_bl1D, & - cldfra_bl1D + real(kind_phys), DIMENSION(kts:kte) :: alp,a,bet,b,ql,q1,RH + real(kind_phys), DIMENSION(kts:kte), INTENT(OUT) :: qc_bl1D,qi_bl1D, & + &cldfra_bl1D DOUBLE PRECISION :: t3sq, r3sq, c3sq - REAL :: qsl,esat,qsat,dqsl,cld0,q1k,qlk,eq1,qll,& - &q2p,pt,rac,qt,t,xl,rsl,cpm,Fng,qww,alpha,beta,bb,& - &ls,wt,cld_factor,fac_damp,liq_frac,ql_ice,ql_water,& - &qmq,qsat_tk,wsp,wspfac + real(kind_phys):: qsl,esat,qsat,dqsl,cld0,q1k,qlk,eq1,qll, & + &q2p,pt,rac,qt,t,xl,rsl,cpm,Fng,qww,alpha,beta,bb, & + &ls,wt,cld_factor,fac_damp,liq_frac,ql_ice,ql_water, & + &qmq,qsat_tk,q1_rh,rh_hack + real(kind_phys), PARAMETER :: rhcrit=0.83 !for hom pdf min sigma INTEGER :: i,j,k - REAL :: erf + real(kind_phys):: erf !VARIABLES FOR ALTERNATIVE SIGMA - REAL::dth,dtl,dqw,dzk,els - REAL, DIMENSION(kts:kte), INTENT(IN) :: Sh,el + real:: dth,dtl,dqw,dzk,els + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: Sh,el !variables for SGS BL clouds - REAL :: zagl,damp,PBLH2 - REAL :: cfmax - INTEGER, PARAMETER :: buoy_opt=1 ! 0: traditional SD77, 1: CB02,CB05 + real(kind_phys) :: zagl,damp,PBLH2 + real(kind_phys) :: cfmax !JAYMES: variables for tropopause-height estimation - REAL :: theta1, theta2, ht1, ht2 - INTEGER :: k_tropo + real(kind_phys) :: theta1, theta2, ht1, ht2 + INTEGER :: k_tropo ! Stochastic - INTEGER, INTENT(IN) :: spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col - REAL :: qw_pert + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col + real(kind_phys) :: qw_pert ! First, obtain an estimate for the tropopause height (k), using the method employed in the ! Thompson subgrid-cloud scheme. This height will be a consideration later when determining @@ -3856,9 +3719,6 @@ SUBROUTINE mym_condensation (kts,kte, & qc_bl1D(k) = liq_frac*ql(k) qi_bl1D(k) = (1.0 - liq_frac)*ql(k) - if(cldfra_bl1D(k)>0.01 .and. qc_bl1D(k)<1.E-6)qc_bl1D(k)=1.E-6 - if(cldfra_bl1D(k)>0.01 .and. qi_bl1D(k)<1.E-8)qi_bl1D(k)=1.E-8 - !Now estimate the buoyancy flux functions q2p = xlvcp/exner(k) pt = thl(k) +q2p*ql(k) ! potential temp @@ -3916,9 +3776,6 @@ SUBROUTINE mym_condensation (kts,kte, & qc_bl1D(k) = liq_frac*ql(k) qi_bl1D(k) = (1.0 - liq_frac)*ql(k) - if(cldfra_bl1D(k)>0.01 .and. qc_bl1D(k)<1.E-6)qc_bl1D(k)=1.E-6 - if(cldfra_bl1D(k)>0.01 .and. qi_bl1D(k)<1.E-8)qi_bl1D(k)=1.E-8 - !Now estimate the buoyancy flux functions q2p = xlvcp/exner(k) pt = thl(k) +q2p*ql(k) ! potential temp @@ -3947,7 +3804,7 @@ SUBROUTINE mym_condensation (kts,kte, & xl = xl_blend(t) ! obtain latent heat qsat_tk = qsat_blend(t, p(k)) ! saturation water vapor mixing ratio at tk and p - rh(k)=MAX(MIN(1.0,qw(k)/MAX(1.E-8,qsat_tk)),0.001) + rh(k)=MAX(MIN(1.00,qw(k)/MAX(1.E-10,qsat_tk)),0.001) !dqw/dT: Clausius-Clapeyron dqsl = qsat_tk*ep_2*xlv/( r_d*t**2 ) @@ -3968,35 +3825,53 @@ SUBROUTINE mym_condensation (kts,kte, & !Use the form of Eq. (6) in Chaboureau and Bechtold (2002) !except neglect all but the first term for sig_r - r3sq = MAX( qsq(k), 0.0 ) + r3sq = max( qsq(k), 0.0 ) !Calculate sigma using higher-order moments: sgm(k) = SQRT( r3sq ) !Set limits on sigma relative to saturation water vapor - sgm(k) = MIN( sgm(k), qsat_tk*0.666 ) !500 ) - sgm(k) = MAX( sgm(k), qsat_tk*0.035 ) !Note: 0.02 results in SWDOWN similar - !to the first-order version of sigma - q1(k) = qmq / sgm(k) ! Q1, the normalized saturation + sgm(k) = min( sgm(k), qsat_tk*0.666 ) + sgm(k) = max( sgm(k), qsat_tk*0.035 ) + q1(k) = qmq / sgm(k) ! Q1, the normalized saturation + + !Add condition for falling/settling into low-RH layers, so at least + !some cloud fraction is applied for all qc and qi. + rh_hack = rh(k) + !ensure adequate RH & q1 when qi is at least 1e-9 + if (qi(k)>1.e-9) then + rh_hack =min(1.0, rhcrit + 0.06*(9.0 + log10(qi(k)))) + rh(k) =max(rh(k), rh_hack) + !add rh-based q1 + q1_rh =-3. + 3.*(rh_hack-rhcrit)/(1.-rhcrit) + q1(k) =max(q1_rh, q1(k) ) + endif + !ensure adequate RH & q1 when qc is at least 1e-6 + if (qc(k)>1.e-6) then + rh_hack =min(1.0, rhcrit + 0.09*(6.0 + log10(qc(k)))) + rh(k) =max(rh(k), rh_hack) + !add rh-based q1 + q1_rh =-3. + 3.*(rh_hack-rhcrit)/(1.-rhcrit) + q1(k) =max(q1_rh, q1(k) ) + endif + q1k = q1(k) ! backup Q1 for later modification ! Specify cloud fraction !Original C-B cloud fraction, allows cloud fractions out to q1 = -3.5 !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.55*q1(k)))) ! Eq. 7 in CB02 - !wayne's - over-diffuse, when limits removed from vt & vq & fng + !Waynes LES fit - over-diffuse, when limits removed from vt & vq & fng !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.2*(q1(k)+0.4)))) - !effort to reduce rh-dependency - !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(2.9*(q1(k)+0.4)))) - cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.8*(q1(k)+0.4)))) - !moderate - best compromise?? - !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.55*(q1(k)+0.2)))) - !closer to original for Q1 < -1, best for holding onto stratus, not good flowers - !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.9*(q1(k)+0.4)))) - + !Best compromise: Improves marine stratus without adding much cold bias. + cldfra_bl1D(k) = max(0., min(1., 0.5+0.36*atan(1.8*(q1(k)+0.2)))) ! Specify hydrometeors ! JAYMES- this option added 8 May 2015 ! The cloud water formulations are taken from CB02, Eq. 8. IF (q1k < 0.) THEN !unsaturated - ql_water = sgm(k)*EXP(1.2*q1k-1) +#ifdef SINGLE_PREC + ql_water = sgm(k)*EXP(1.2*q1k-1.) +#else + ql_water = sgm(k)*EXP(1.2*q1k-1.) +#endif ql_ice = sgm(k)*EXP(1.2*q1k-1.) ELSE IF (q1k > 2.) THEN !supersaturated ql_water = sgm(k)*q1k @@ -4007,41 +3882,23 @@ SUBROUTINE mym_condensation (kts,kte, & ENDIF !In saturated grid cells, use average of SGS and resolved values - if ( qc(k) > 1.e-7 ) ql_water = 0.5 * ( ql_water + qc(k) ) - if ( qi(k) > 1.e-9 ) ql_ice = 0.5 * ( ql_ice + qi(k) ) + !if ( qc(k) > 1.e-6 ) ql_water = 0.5 * ( ql_water + qc(k) ) + !ql_ice is actually the total frozen condensate (snow+ice), + !if ( (qi(k)+qs(k)) > 1.e-9 ) ql_ice = 0.5 * ( ql_ice + (qi(k)+qs(k)) ) - if (cldfra_bl1D(k) < 0.01) then + if (cldfra_bl1D(k) < 0.001) then ql_ice = 0.0 ql_water = 0.0 cldfra_bl1D(k) = 0.0 endif - !PHASE PARTITIONING: Make some inferences about the relative amounts of - !subgrid cloud water vs. ice based on collocated explicit clouds. Otherise, - !use a simple temperature-dependent partitioning. - ! IF ( qc(k) + qi(k) > 0.0 ) THEN ! explicit condensate exists, retain its phase partitioning - ! IF ( qi(k) == 0.0 ) THEN ! explicit contains no ice; assume subgrid liquid - ! liq_frac = 1.0 - ! ELSE IF ( qc(k) == 0.0 ) THEN ! explicit contains no liquid; assume subgrid ice - ! liq_frac = 0.0 - ! ELSE IF ( (qc(k) >= 1.E-10) .AND. (qi(k) >= 1.E-10) ) THEN ! explicit contains mixed phase of workably - ! ! large amounts; assume subgrid follows - ! ! same partioning - ! liq_frac = qc(k) / ( qc(k) + qi(k) ) - ! ELSE - ! liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(t0c-tice))) ! explicit contains mixed phase, but at least one - ! ! species is very small, so make a temperature- - ! ! depedent guess - ! ENDIF - ! ELSE ! no explicit condensate, so make a temperature-dependent guess - liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(tliq-tice))) - ! ENDIF - + liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(tliq-tice))) qc_bl1D(k) = liq_frac*ql_water ! apply liq_frac to ql_water and ql_ice qi_bl1D(k) = (1.0-liq_frac)*ql_ice - !Above tropopause: eliminate subgrid clouds from CB scheme - if (k .ge. k_tropo-1) then + !Above tropopause: eliminate subgrid clouds from CB scheme. Note that this was + !"k_tropo - 1" as of 20 Feb 2023. Changed to allow more high-level clouds. + if (k .ge. k_tropo) then cldfra_bl1D(K) = 0. qc_bl1D(k) = 0. qi_bl1D(k) = 0. @@ -4049,6 +3906,7 @@ SUBROUTINE mym_condensation (kts,kte, & !Buoyancy-flux-related calculations follow... !limiting Q1 to avoid too much diffusion in cloud layers + !q1k=max(Q1(k),-2.0) if ((xland-1.5).GE.0) then ! water q1k=max(Q1(k),-2.5) else ! land @@ -4076,64 +3934,30 @@ SUBROUTINE mym_condensation (kts,kte, & Fng = MIN(23.9 + EXP(-1.6*(q1k+2.5)), 60.) ENDIF - if (buoy_opt .eq. 1) then - cfmax= min(cldfra_bl1D(K), 0.6) - bb = b(k)*t/th(k) ! bb is "b" in BCMT95. Their "b" differs from - ! "b" in CB02 (i.e., b(k) above) by a factor - ! of T/theta. Strictly, b(k) above is formulated in - ! terms of sat. mixing ratio, but bb in BCMT95 is - ! cast in terms of sat. specific humidity. The - ! conversion is neglected here. - qww = 1.+0.61*qw(k) - alpha = 0.61*th(k) - beta = (th(k)/t)*(xl/cp) - 1.61*th(k) - vt(k) = qww - cfmax*beta*bb*Fng - 1. - vq(k) = alpha + cfmax*beta*a(k)*Fng - tv0 - ! vt and vq correspond to beta-theta and beta-q, respectively, - ! in NN09, Eq. B8. They also correspond to the bracketed - ! expressions in BCMT95, Eq. 15, since (s*ql/sigma^2) = cldfra*Fng - ! The "-1" and "-tv0" terms are included for consistency with - ! the legacy vt and vq formulations (above). - else - - !original buoyancy flux functions from SD77 - eq1 = rrp*exp( -0.5*q1k*q1k ) - qll = max( cldfra_bl1D(k)*q1k + eq1, 0.0 ) - q2p = xl/cp/exner(k) - - !qt is a THETA-V CONVERSION FOR TOTAL WATER - cfmax= min(cldfra_bl1D(K), 0.6) - qt = 1.0 +p608*qw(k) -(1.+p608)*(qc_bl1D(k)+qi_bl1D(k))*cfmax - rac = alp(k)*( cfmax-qll*eq1 )*( q2p*qt-(1.+p608)*th(k) ) - - !BUOYANCY FACTORS: wherever vt and vq are used, there is a - !"+1" and "+tv0", respectively, so these are subtracted out here. - !vt is unitless and vq has units of K. - vt(k) = qt-1.0 -rac*bet(k) - vq(k) = p608*th(k)-tv0 +rac - endif - - ! dampen the amplification factor (cld_factor) with height in order - ! to limit excessively large cloud fractions aloft - !fac_damp = 1.! -MIN(MAX( zagl-(PBLH2+1000.),0.0)/ & - ! MAX((zw(k_tropo)-(PBLH2+1000.)),500.), 1.) - !fac_damp = min(zagl * 0.01, 1.0) - wsp =sqrt(u1(k)**2 + v1(k)**2) - wspfac = 1.0 - min(max(0.,wsp-15),10.)/10. ! reduce as winds go from 15 to 25 m/s. - fac_damp = min(zagl * 0.0025, 1.0)*wspfac - !cld_factor = 1.0 + fac_damp*MAX(0.0, ( RH(k) - 0.5 ) / 0.51 )**3.3 + cfmax= min(cldfra_bl1D(k), 0.6) + bb = b(k)*t/th(k) ! bb is "b" in BCMT95. Their "b" differs from + ! "b" in CB02 (i.e., b(k) above) by a factor + ! of T/theta. Strictly, b(k) above is formulated in + ! terms of sat. mixing ratio, but bb in BCMT95 is + ! cast in terms of sat. specific humidity. The + ! conversion is neglected here. + qww = 1.+0.61*qw(k) + alpha = 0.61*th(k) + beta = (th(k)/t)*(xl/cp) - 1.61*th(k) + vt(k) = qww - cfmax*beta*bb*Fng - 1. + vq(k) = alpha + cfmax*beta*a(k)*Fng - tv0 + ! vt and vq correspond to beta-theta and beta-q, respectively, + ! in NN09, Eq. B8. They also correspond to the bracketed + ! expressions in BCMT95, Eq. 15, since (s*ql/sigma^2) = cldfra*Fng + ! The "-1" and "-tv0" terms are included for consistency with + ! the legacy vt and vq formulations (above). + + ! dampen amplification factor where need be + fac_damp = min(zagl * 0.0025, 1.0) !cld_factor = 1.0 + fac_damp*MAX(0.0, ( RH(k) - 0.75 ) / 0.26 )**1.9 !HRRRv4 - !cld_factor = 1.0 + fac_damp*(MAX(0.0, ( RH(k) - 0.80 )) / 0.22 )**2 - !cld_factor = 1.0 + fac_damp*(MAX(0.0, ( RH(k) - 0.90 )) / 0.11 )**2 - !cld_factor = 1.0 + fac_damp*1.8*(max(0.0, q1k + 0.2 ))**2 !too low of albedo - !cld_factor = 1.0 + fac_damp*1.8*(max(0.0, q1k + 0.2 ))**2 - !make this enhancement over water only? - !if ((xland-1.5).GE.0) then ! water - cld_factor = 1.0 + fac_damp*min((max(0.0, ( RH(k) - 0.92 )) / 0.25 )**2, 0.3) - !else - ! cld_factor = 1.0 - !endif - cldfra_bl1D(K) = MIN( 1., cld_factor*cldfra_bl1D(K) ) + !cld_factor = 1.0 + fac_damp*min((max(0.0, ( RH(k) - 0.92 )) / 0.25 )**2, 0.3) + cld_factor = 1.0 + fac_damp*min((max(0.0, ( RH(k) - 0.92 )) / 0.145)**2, 0.35) + cldfra_bl1D(K) = min( 1., cld_factor*cldfra_bl1D(K) ) enddo END SELECT !end cloudPDF option @@ -4166,38 +3990,39 @@ END SUBROUTINE mym_condensation !>\ingroup gsd_mynn_edmf !! This subroutine solves for tendencies of U, V, \f$\theta\f$, qv, !! qc, and qi - SUBROUTINE mynn_tendencies(kts,kte,i, & - &delt,dz,rho, & - &u,v,th,tk,qv,qc,qi,qnc,qni, & - &psfc,p,exner, & - &thl,sqv,sqc,sqi,sqw, & - &qnwfa,qnifa,ozone, & - &ust,flt,flq,flqv,flqc,wspd, & - &uoce,voce, & - &tsq,qsq,cov, & - &tcd,qcd, & - &dfm,dfh,dfq, & - &Du,Dv,Dth,Dqv,Dqc,Dqi,Dqnc,Dqni, & - &Dqnwfa,Dqnifa,Dozone, & - &diss_heat, & - &s_aw,s_awthl,s_awqt,s_awqv,s_awqc, & - &s_awu,s_awv, & - &s_awqnc,s_awqni, & - &s_awqnwfa,s_awqnifa, & - &sd_aw,sd_awthl,sd_awqt,sd_awqv, & - &sd_awqc,sd_awu,sd_awv, & - &sub_thl,sub_sqv, & - &sub_u,sub_v, & - &det_thl,det_sqv,det_sqc, & - &det_u,det_v, & - &FLAG_QC,FLAG_QI,FLAG_QNC,FLAG_QNI, & - &FLAG_QNWFA,FLAG_QNIFA, & - &cldfra_bl1d, & - &bl_mynn_cloudmix, & - &bl_mynn_mixqt, & - &bl_mynn_edmf, & - &bl_mynn_edmf_mom, & - &bl_mynn_mixscalars ) + SUBROUTINE mynn_tendencies(kts,kte,i, & + &delt,dz,rho, & + &u,v,th,tk,qv,qc,qi,qs,qnc,qni, & + &psfc,p,exner, & + &thl,sqv,sqc,sqi,sqs,sqw, & + &qnwfa,qnifa,qnbca,ozone, & + &ust,flt,flq,flqv,flqc,wspd, & + &uoce,voce, & + &tsq,qsq,cov, & + &tcd,qcd, & + &dfm,dfh,dfq, & + &Du,Dv,Dth,Dqv,Dqc,Dqi,Dqs,Dqnc,Dqni, & + &Dqnwfa,Dqnifa,Dqnbca,Dozone, & + &diss_heat, & + &s_aw,s_awthl,s_awqt,s_awqv,s_awqc, & + &s_awu,s_awv, & + &s_awqnc,s_awqni, & + &s_awqnwfa,s_awqnifa,s_awqnbca, & + &sd_aw,sd_awthl,sd_awqt,sd_awqv, & + &sd_awqc,sd_awu,sd_awv, & + &sub_thl,sub_sqv, & + &sub_u,sub_v, & + &det_thl,det_sqv,det_sqc, & + &det_u,det_v, & + &FLAG_QC,FLAG_QI,FLAG_QNC,FLAG_QNI, & + &FLAG_QS, & + &FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & + &cldfra_bl1d, & + &bl_mynn_cloudmix, & + &bl_mynn_mixqt, & + &bl_mynn_edmf, & + &bl_mynn_edmf_mom, & + &bl_mynn_mixscalars ) !------------------------------------------------------------------- INTEGER, INTENT(in) :: kts,kte,i @@ -4207,11 +4032,11 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & # define kte HARDCODE_VERTICAL #endif - INTEGER, INTENT(in) :: bl_mynn_cloudmix,bl_mynn_mixqt,& - bl_mynn_edmf,bl_mynn_edmf_mom, & + INTEGER, INTENT(in) :: bl_mynn_cloudmix,bl_mynn_mixqt, & + bl_mynn_edmf,bl_mynn_edmf_mom, & bl_mynn_mixscalars - LOGICAL, INTENT(IN) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QNC,& - FLAG_QNWFA,FLAG_QNIFA + LOGICAL, INTENT(IN) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QS, & + &FLAG_QNC,FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA ! thl - liquid water potential temperature ! qw - total water @@ -4220,46 +4045,47 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ! flq - surface flux of qw ! mass-flux plumes - REAL, DIMENSION(kts:kte+1), INTENT(in) :: s_aw,s_awthl,s_awqt,& - &s_awqnc,s_awqni,s_awqv,s_awqc,s_awu,s_awv, & - &s_awqnwfa,s_awqnifa, & + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: s_aw, & + &s_awthl,s_awqt,s_awqnc,s_awqni,s_awqv,s_awqc,s_awu,s_awv, & + &s_awqnwfa,s_awqnifa,s_awqnbca, & &sd_aw,sd_awthl,sd_awqt,sd_awqv,sd_awqc,sd_awu,sd_awv ! tendencies from mass-flux environmental subsidence and detrainment - REAL, DIMENSION(kts:kte), INTENT(in) :: sub_thl,sub_sqv, & + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: sub_thl,sub_sqv, & &sub_u,sub_v,det_thl,det_sqv,det_sqc,det_u,det_v - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,th,tk,qv,qc,qi,qni,qnc,& - &rho,p,exner,dfq,dz,tsq,qsq,cov,tcd,qcd,cldfra_bl1d,diss_heat - REAL, DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc,sqi,& - &qnwfa,qnifa,ozone,dfm,dfh - REAL, DIMENSION(kts:kte), INTENT(inout) :: du,dv,dth,dqv,dqc,dqi,& - &dqni,dqnc,dqnwfa,dqnifa,dozone - REAL, INTENT(IN) :: flt,flq,flqv,flqc,uoce,voce - REAL(kind=kind_phys), INTENT(IN) :: ust,delt,psfc,wspd + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v,th,tk,qv,qc,qi,& + &qs,qni,qnc,rho,p,exner,dfq,dz,tsq,qsq,cov,tcd,qcd, & + &cldfra_bl1d,diss_heat + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc,& + &sqi,sqs,qnwfa,qnifa,qnbca,ozone,dfm,dfh + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: du,dv,dth,dqv, & + &dqc,dqi,dqs,dqni,dqnc,dqnwfa,dqnifa,dqnbca,dozone + real(kind_phys), INTENT(IN) :: flt,flq,flqv,flqc,uoce,voce + real(kind_phys), INTENT(IN) :: ust,delt,psfc,wspd !debugging - REAL ::wsp,wsp2,tk2,th2 + real(kind_phys):: wsp,wsp2,tk2,th2 LOGICAL :: problem integer :: kproblem -! REAL, INTENT(IN) :: gradu_top,gradv_top,gradth_top,gradqv_top +! real(kind_phys), INTENT(IN) :: gradu_top,gradv_top,gradth_top,gradqv_top !local vars - REAL, DIMENSION(kts:kte) :: dtz,dfhc,dfmc,delp - REAL, DIMENSION(kts:kte) :: sqv2,sqc2,sqi2,sqw2,qni2,qnc2, & !AFTER MIXING - qnwfa2,qnifa2,ozone2 - REAL, DIMENSION(kts:kte) :: zfac,plumeKh,rhoinv - REAL, DIMENSION(kts:kte) :: a,b,c,d,x - REAL, DIMENSION(kts:kte+1) :: rhoz, & !rho on model interface - & khdz, kmdz - REAL :: rhs,gfluxm,gfluxp,dztop,maxdfh,mindfh,maxcf,maxKh,zw - REAL :: t,esat,qsl,onoff,kh,km,dzk,rhosfc - REAL :: ustdrag,ustdiff,qvflux - REAL :: th_new,portion_qc,portion_qi,condensate,qsat + real(kind_phys), DIMENSION(kts:kte) :: dtz,dfhc,dfmc,delp + real(kind_phys), DIMENSION(kts:kte) :: sqv2,sqc2,sqi2,sqs2,sqw2, & + &qni2,qnc2,qnwfa2,qnifa2,qnbca2,ozone2 + real(kind_phys), DIMENSION(kts:kte) :: zfac,plumeKh,rhoinv + real(kind_phys), DIMENSION(kts:kte) :: a,b,c,d,x + real(kind_phys), DIMENSION(kts:kte+1) :: rhoz, & !rho on model interface + &khdz,kmdz + real(kind_phys):: rhs,gfluxm,gfluxp,dztop,maxdfh,mindfh,maxcf,maxKh,zw + real(kind_phys):: t,esat,qsl,onoff,kh,km,dzk,rhosfc + real(kind_phys):: ustdrag,ustdiff,qvflux + real(kind_phys):: th_new,portion_qc,portion_qi,condensate,qsat INTEGER :: k,kk !Activate nonlocal mixing from the mass-flux scheme for !number concentrations and aerosols (0.0 = no; 1.0 = yes) - REAL, PARAMETER :: nonloc = 1.0 + real(kind_phys), PARAMETER :: nonloc = 1.0 dztop=.5*(dz(kte)+dz(kte-1)) @@ -4716,19 +4542,6 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & IF (bl_mynn_cloudmix > 0 .AND. FLAG_QI) THEN k=kts - -! a(k)=0. -! b(k)=1.+dtz(k)*dfh(k+1) -! c(k)= -dtz(k)*dfh(k+1) -! d(k)=sqi(k) !+ qcd(k)*delt !should we have qcd for ice? -! -! DO k=kts+1,kte-1 -! a(k)= -dtz(k)*dfh(k) -! b(k)=1.+dtz(k)*(dfh(k)+dfh(k+1)) -! c(k)= -dtz(k)*dfh(k+1) -! d(k)=sqi(k) !+ qcd(k)*delt -! ENDDO - !rho-weighted: a(k)= -dtz(k)*khdz(k)*rhoinv(k) b(k)=1.+dtz(k)*(khdz(k+1)+khdz(k))*rhoinv(k) @@ -4772,6 +4585,42 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & sqi2=sqi ENDIF +!============================================ +! MIX SNOW ( sqs ) +!============================================ +IF (bl_mynn_cloudmix > 0 .AND. FLAG_QS) THEN + + k=kts +!rho-weighted: + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + b(k)=1.+dtz(k)*(khdz(k+1)+khdz(k))*rhoinv(k) + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) + d(k)=sqs(k) + + DO k=kts+1,kte-1 + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + b(k)=1.+dtz(k)*(khdz(k)+khdz(k+1))*rhoinv(k) + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) + d(k)=sqs(k) + ENDDO + +!! prescribed value + a(kte)=0. + b(kte)=1. + c(kte)=0. + d(kte)=sqs(kte) + +! CALL tridiag(kte,a,b,c,d) + CALL tridiag2(kte,a,b,c,d,sqs2) +! CALL tridiag3(kte,a,b,c,d,sqs2) + +! DO k=kts,kte +! sqs2(k)=d(k-kts+1) +! ENDDO +ELSE + sqs2=sqs +ENDIF + !!============================================ !! cloud ice number concentration (qni) !!============================================ @@ -4937,6 +4786,48 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & qnifa2=qnifa ENDIF +!============================================ +! Black-carbon aerosols ( qnbca ). +!============================================ +IF (bl_mynn_cloudmix > 0 .AND. FLAG_QNBCA .AND. & + bl_mynn_mixscalars > 0) THEN + + k=kts + + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + b(k)=1.+dtz(k)*(khdz(k) + khdz(k+1))*rhoinv(k) - & + & 0.5*dtz(k)*rhoinv(k)*s_aw(k+1)*nonloc + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1)*nonloc + d(k)=qnbca(k) - dtz(k)*rhoinv(k)*s_awqnbca(k+1)*nonloc + + DO k=kts+1,kte-1 + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + 0.5*dtz(k)*rhoinv(k)*s_aw(k)*nonloc + b(k)=1.+dtz(k)*(khdz(k) + khdz(k+1))*rhoinv(k) + & + & 0.5*dtz(k)*rhoinv(k)*(s_aw(k)-s_aw(k+1))*nonloc + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1)*nonloc + d(k)=qnbca(k) + dtz(k)*rhoinv(k)*(s_awqnbca(k)-s_awqnbca(k+1))*nonloc + ENDDO + +! prescribed value + a(kte)=0. + b(kte)=1. + c(kte)=0. + d(kte)=qnbca(kte) + +! CALL tridiag(kte,a,b,c,d) +! CALL tridiag2(kte,a,b,c,d,x) + CALL tridiag3(kte,a,b,c,d,x) + + DO k=kts,kte + !qnbca2(k)=d(k-kts+1) + qnbca2(k)=x(k) + ENDDO + +ELSE + !If not mixing aerosols, set "updated" array equal to original array + qnbca2=qnbca +ENDIF + !============================================ ! Ozone - local mixing only !============================================ @@ -5061,6 +4952,19 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ENDDO ENDIF + !=================== + ! CLOUD SNOW TENDENCY + !=================== + IF (FLAG_QS) THEN + DO k=kts,kte + Dqs(k)=(sqs2(k)/(1.-sqs2(k)) - qs(k))/delt + ENDDO + ELSE + DO k=kts,kte + Dqs(k) = 0. + ENDDO + ENDIF + !=================== ! CLOUD ICE NUM CONC TENDENCY !=================== @@ -5085,9 +4989,9 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ENDIF !ensure non-negative moist species - CALL moisture_check(kte, delt, delp, exner, & - sqv2, sqc2, sqi2, thl, & - dqv, dqc, dqi, dth ) + CALL moisture_check(kte, delt, delp, exner, & + sqv2, sqc2, sqi2, sqs2, thl, & + dqv, dqc, dqi, dqs, dth ) !===================== ! OZONE TENDENCY CHECK @@ -5103,8 +5007,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & !=================== IF (FLAG_QI) THEN DO k=kts,kte - Dth(k)=(thl(k) + xlvcp/exner(k)*sqc2(k) & - & + xlscp/exner(k)*sqi2(k) & + Dth(k)=(thl(k) + xlvcp/exner(k)*sqc2(k) & + & + xlscp/exner(k)*(sqi2(k)+sqs(k)) & & - th(k))/delt !Use form from Tripoli and Cotton (1981) with their !suggested min temperature to improve accuracy: @@ -5144,6 +5048,19 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ENDDO ENDIF + !======================== + ! BLACK-CARBON TENDENCIES + !======================== + IF (FLAG_QNBCA .AND. bl_mynn_mixscalars > 0) THEN + DO k=kts,kte + Dqnbca(k)=(qnbca2(k) - qnbca(k))/delt + ENDDO + ELSE + DO k=kts,kte + Dqnbca(k)=0. + ENDDO + ENDIF + !ensure non-negative moist species !note: if called down here, dth needs to be updated, but ! if called before the theta-tendency calculation, do not compute dth @@ -5189,9 +5106,9 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & END SUBROUTINE mynn_tendencies ! ================================================================== - SUBROUTINE moisture_check(kte, delt, dp, exner, & - qv, qc, qi, th, & - dqv, dqc, dqi, dth ) + SUBROUTINE moisture_check(kte, delt, dp, exner, & + qv, qc, qi, qs, th, & + dqv, dqc, dqi, dqs, dth ) ! This subroutine was adopted from the CAM-UW ShCu scheme and ! adapted for use here. @@ -5207,33 +5124,36 @@ SUBROUTINE moisture_check(kte, delt, dp, exner, & ! applying corresponding input tendencies and corrective tendencies. implicit none - integer, intent(in) :: kte - real(kind=kind_phys), intent(in) :: delt - real, dimension(kte), intent(in) :: dp, exner - real, dimension(kte), intent(inout) :: qv, qc, qi, th - real, dimension(kte), intent(inout) :: dqv, dqc, dqi, dth + integer, intent(in) :: kte + real(kind_phys), intent(in) :: delt + real(kind_phys), dimension(kte), intent(in) :: dp, exner + real(kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, qs, th + real(kind_phys), dimension(kte), intent(inout) :: dqv, dqc, dqi, dqs, dth integer k - real :: dqc2, dqi2, dqv2, sum, aa, dum - real, parameter :: qvmin = 1e-20, & - qcmin = 0.0, & - qimin = 0.0 + real(kind_phys):: dqc2, dqi2, dqs2, dqv2, sum, aa, dum + real(kind_phys), parameter :: qvmin = 1e-20, & + qcmin = 0.0, & + qimin = 0.0 do k = kte, 1, -1 ! From the top to the surface dqc2 = max(0.0, qcmin-qc(k)) !qc deficit (>=0) dqi2 = max(0.0, qimin-qi(k)) !qi deficit (>=0) + dqs2 = max(0.0, qimin-qs(k)) !qs deficit (>=0) !fix tendencies dqc(k) = dqc(k) + dqc2/delt dqi(k) = dqi(k) + dqi2/delt - dqv(k) = dqv(k) - (dqc2+dqi2)/delt + dqs(k) = dqs(k) + dqs2/delt + dqv(k) = dqv(k) - (dqc2+dqi2+dqs2)/delt dth(k) = dth(k) + xlvcp/exner(k)*(dqc2/delt) + & - xlscp/exner(k)*(dqi2/delt) + xlscp/exner(k)*((dqi2+dqs2)/delt) !update species qc(k) = qc(k) + dqc2 qi(k) = qi(k) + dqi2 - qv(k) = qv(k) - dqc2 - dqi2 + qs(k) = qs(k) + dqs2 + qv(k) = qv(k) - dqc2 - dqi2 - dqs2 th(k) = th(k) + xlvcp/exner(k)*dqc2 + & - xlscp/exner(k)*dqi2 + xlscp/exner(k)*(dqi2+dqs2) !then fix qv dqv2 = max(0.0, qvmin-qv(k)) !qv deficit (>=0) @@ -5246,6 +5166,7 @@ SUBROUTINE moisture_check(kte, delt, dp, exner, & qv(k) = max(qv(k),qvmin) qc(k) = max(qc(k),qcmin) qi(k) = max(qi(k),qimin) + qs(k) = max(qs(k),qimin) end do ! Extra moisture used to satisfy 'qv(1)>=qvmin' is proportionally ! extracted from all the layers that has 'qv > 2*qvmin'. This fully @@ -5289,36 +5210,35 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & !------------------------------------------------------------------- INTEGER, INTENT(in) :: kts,kte,i - - REAL, DIMENSION(kts:kte), INTENT(IN) :: dfh,dz,tcd,qcd - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: rho - REAL, INTENT(IN) :: flt - REAL(kind=kind_phys), INTENT(IN) :: delt,pblh + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: dfh,dz,tcd,qcd + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: rho + real(kind_phys), INTENT(IN) :: flt + real(kind_phys), INTENT(IN) :: delt,pblh INTEGER, INTENT(IN) :: nchem, kdvel, ndvel - REAL, DIMENSION( kts:kte+1), INTENT(IN) :: s_aw - REAL, DIMENSION( kts:kte, nchem ), INTENT(INOUT) :: chem1 - REAL, DIMENSION( kts:kte+1,nchem), INTENT(IN) :: s_awchem - REAL, DIMENSION( ndvel ), INTENT(IN) :: vd1 - REAL(kind=kind_phys), INTENT(IN) :: emis_ant_no,frp + real(kind_phys), DIMENSION( kts:kte+1), INTENT(IN) :: s_aw + real(kind_phys), DIMENSION( kts:kte, nchem ), INTENT(INOUT) :: chem1 + real(kind_phys), DIMENSION( kts:kte+1,nchem), INTENT(IN) :: s_awchem + real(kind_phys), DIMENSION( ndvel ), INTENT(IN) :: vd1 + real(kind_phys), INTENT(IN) :: emis_ant_no,frp LOGICAL, INTENT(IN) :: rrfs_sd,enh_mix,smoke_dbg !local vars - REAL, DIMENSION(kts:kte) :: dtz - REAL, DIMENSION(kts:kte) :: a,b,c,d,x - REAL :: rhs,dztop - REAL :: t,dzk - REAL :: hght - REAL :: khdz_old, khdz_back + real(kind_phys), DIMENSION(kts:kte) :: dtz + real(kind_phys), DIMENSION(kts:kte) :: a,b,c,d,x + real(kind_phys):: rhs,dztop + real(kind_phys):: t,dzk + real(kind_phys):: hght + real(kind_phys):: khdz_old, khdz_back INTEGER :: k,kk,kmaxfire ! JLS 12/21/21 INTEGER :: ic ! Chemical array loop index INTEGER, SAVE :: icall - REAL, DIMENSION(kts:kte) :: rhoinv - REAL, DIMENSION(kts:kte+1) :: rhoz,khdz - REAL, PARAMETER :: NO_threshold = 0.1 ! For anthropogenic sources - REAL, PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing over big fires - REAL, PARAMETER :: pblh_threshold = 250.0 + real(kind_phys), DIMENSION(kts:kte) :: rhoinv + real(kind_phys), DIMENSION(kts:kte+1) :: rhoz,khdz + real(kind_phys), PARAMETER :: NO_threshold = 10.0 ! For anthropogenic sources + real(kind_phys), PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing over big fires + real(kind_phys), PARAMETER :: pblh_threshold = 100.0 dztop=.5*(dz(kte)+dz(kte-1)) @@ -5419,13 +5339,13 @@ SUBROUTINE retrieve_exchange_coeffs(kts,kte,& INTEGER , INTENT(in) :: kts,kte - REAL, DIMENSION(KtS:KtE), INTENT(in) :: dz,dfm,dfh + real(kind_phys), DIMENSION(KtS:KtE), INTENT(in) :: dz,dfm,dfh - REAL, DIMENSION(KtS:KtE), INTENT(out) :: K_m, K_h + real(kind_phys), DIMENSION(KtS:KtE), INTENT(out) :: K_m, K_h INTEGER :: k - REAL :: dzk + real(kind_phys):: dzk K_m(kts)=0. K_h(kts)=0. @@ -5451,12 +5371,12 @@ SUBROUTINE tridiag(n,a,b,c,d) !------------------------------------------------------------------- INTEGER, INTENT(in):: n - REAL, DIMENSION(n), INTENT(in) :: a,b - REAL, DIMENSION(n), INTENT(inout) :: c,d + real(kind_phys), DIMENSION(n), INTENT(in) :: a,b + real(kind_phys), DIMENSION(n), INTENT(inout) :: c,d INTEGER :: i - REAL :: p - REAL, DIMENSION(n) :: q + real(kind_phys):: p + real(kind_phys), DIMENSION(n) :: q c(n)=0. q(1)=-c(1)/b(1) @@ -5486,10 +5406,10 @@ subroutine tridiag2(n,a,b,c,d,x) ! n - number of unknowns (levels) integer,intent(in) :: n - real, dimension(n),intent(in) :: a,b,c,d - real ,dimension(n),intent(out) :: x - real ,dimension(n) :: cp,dp - real :: m + real(kind_phys), dimension(n), intent(in) :: a,b,c,d + real(kind_phys), dimension(n), intent(out):: x + real(kind_phys), dimension(n) :: cp,dp + real(kind_phys):: m integer :: i ! initialize c-prime and d-prime @@ -5528,12 +5448,12 @@ subroutine tridiag3(kte,a,b,c,d,x) implicit none integer,intent(in) :: kte integer, parameter :: kts=1 - real, dimension(kte) :: a,b,c,d - real ,dimension(kte),intent(out) :: x + real(kind_phys), dimension(kte) :: a,b,c,d + real(kind_phys), dimension(kte), intent(out) :: x integer :: in ! integer kms,kme,kts,kte,in -! real a(kms:kme,3),c(kms:kme),x(kms:kme) +! real(kind_phys)a(kms:kme,3),c(kms:kme),x(kms:kme) do in=kte-1,kts,-1 d(in)=d(in)-c(in)*d(in+1)/b(in+1) @@ -5551,63 +5471,6 @@ subroutine tridiag3(kte,a,b,c,d,x) return end subroutine tridiag3 -! ================================================================== - -!>\ingroup gsd_mynn_edmf - SUBROUTINE mynn_bl_init_driver( & - &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN, & - &RQCBLTEN,RQIBLTEN & !,RQNIBLTEN,RQNCBLTEN & - &,QKE, & - &EXCH_H & - !&,icloud_bl,qc_bl,cldfra_bl & - &,RESTART,ALLOWED_TO_READ,LEVEL & - &,IDS,IDE,JDS,JDE,KDS,KDE & - &,IMS,IME,JMS,JME,KMS,KME & - &,ITS,ITE,JTS,JTE,KTS,KTE) - - !--------------------------------------------------------------- - LOGICAL,INTENT(IN) :: ALLOWED_TO_READ,RESTART - INTEGER,INTENT(IN) :: LEVEL !,icloud_bl - - INTEGER,INTENT(IN) :: IDS,IDE,JDS,JDE,KDS,KDE, & - & IMS,IME,JMS,JME,KMS,KME, & - & ITS,ITE,JTS,JTE,KTS,KTE - - - REAL,DIMENSION(IMS:IME,KMS:KME),INTENT(INOUT) :: & - &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN, & - &RQCBLTEN,RQIBLTEN,& !RQNIBLTEN,RQNCBLTEN & - &QKE,EXCH_H - - INTEGER :: I,J,K,ITF,JTF,KTF - - JTF=MIN0(JTE,JDE-1) - KTF=MIN0(KTE,KDE-1) - ITF=MIN0(ITE,IDE-1) - - IF(.NOT.RESTART)THEN - DO K=KTS,KTF - DO I=ITS,ITF - RUBLTEN(i,k)=0. - RVBLTEN(i,k)=0. - RTHBLTEN(i,k)=0. - RQVBLTEN(i,k)=0. - if( p_qc >= param_first_scalar ) RQCBLTEN(i,k)=0. - if( p_qi >= param_first_scalar ) RQIBLTEN(i,k)=0. - !if( p_qnc >= param_first_scalar ) RQNCBLTEN(i,k)=0. - !if( p_qni >= param_first_scalar ) RQNIBLTEN(i,k)=0. - !QKE(i,k)=0. - EXCH_H(i,k)=0. -! if(icloud_bl > 0) qc_bl(i,k)=0. -! if(icloud_bl > 0) cldfra_bl(i,k)=0. - ENDDO - ENDDO - ENDIF - - mynn_level=level - - END SUBROUTINE mynn_bl_init_driver - ! ================================================================== !>\ingroup gsd_mynn_edmf !! This subroutine calculates hybrid diagnotic boundary-layer height (PBLH). @@ -5654,15 +5517,15 @@ SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea,kzi) # define kte HARDCODE_VERTICAL #endif - REAL(kind=kind_phys), INTENT(OUT) :: zi - REAL, INTENT(IN) :: landsea - REAL, DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D - REAL, DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D + real(kind_phys), INTENT(OUT) :: zi + real(kind_phys), INTENT(IN) :: landsea + real(kind_phys), DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D + real(kind_phys), DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D !LOCAL VARS - REAL :: PBLH_TKE,qtke,qtkem1,wt,maxqke,TKEeps,minthv - REAL :: delt_thv !delta theta-v; dependent on land/sea point - REAL, PARAMETER :: sbl_lim = 200. !upper limit of stable BL height (m). - REAL, PARAMETER :: sbl_damp = 400. !transition length for blending (m). + real(kind_phys):: PBLH_TKE,qtke,qtkem1,wt,maxqke,TKEeps,minthv + real(kind_phys):: delt_thv !delta theta-v; dependent on land/sea point + real(kind_phys), PARAMETER :: sbl_lim = 200. !upper limit of stable BL height (m). + real(kind_phys), PARAMETER :: sbl_damp = 400. !transition length for blending (m). INTEGER :: I,J,K,kthv,ktke,kzi !Initialize KPBL (kzi) @@ -5790,46 +5653,47 @@ END SUBROUTINE GET_PBLH !! !! This scheme remains under development, so consider it experimental code. !! - SUBROUTINE DMP_mf( & - & kts,kte,dt,zw,dz,p,rho, & - & momentum_opt, & - & tke_opt, & - & scalar_opt, & - & u,v,w,th,thl,thv,tk, & - & qt,qv,qc,qke, & - & qnc,qni,qnwfa,qnifa, & - & exner,vt,vq,sgm, & - & ust,flt,fltv,flq,flqv, & - & pblh,kpbl,DX,landsea,ts, & + SUBROUTINE DMP_mf( & + & kts,kte,dt,zw,dz,p,rho, & + & momentum_opt, & + & tke_opt, & + & scalar_opt, & + & u,v,w,th,thl,thv,tk, & + & qt,qv,qc,qke, & + & qnc,qni,qnwfa,qnifa,qnbca, & + & exner,vt,vq,sgm, & + & ust,flt,fltv,flq,flqv, & + & pblh,kpbl,dx,landsea,ts, & ! outputs - updraft properties - & edmf_a,edmf_w, & - & edmf_qt,edmf_thl, & - & edmf_ent,edmf_qc, & + & edmf_a,edmf_w, & + & edmf_qt,edmf_thl, & + & edmf_ent,edmf_qc, & ! outputs - variables needed for solver - & s_aw,s_awthl,s_awqt, & - & s_awqv,s_awqc, & - & s_awu,s_awv,s_awqke, & - & s_awqnc,s_awqni, & - & s_awqnwfa,s_awqnifa, & - & sub_thl,sub_sqv, & - & sub_u,sub_v, & - & det_thl,det_sqv,det_sqc, & - & det_u,det_v, & + & s_aw,s_awthl,s_awqt, & + & s_awqv,s_awqc, & + & s_awu,s_awv,s_awqke, & + & s_awqnc,s_awqni, & + & s_awqnwfa,s_awqnifa, & + & s_awqnbca, & + & sub_thl,sub_sqv, & + & sub_u,sub_v, & + & det_thl,det_sqv,det_sqc, & + & det_u,det_v, & ! chem/smoke - & nchem,chem1,s_awchem, & - & mix_chem, & + & nchem,chem1,s_awchem, & + & mix_chem, & ! in/outputs - subgrid scale clouds & qc_bl1d,cldfra_bl1d, & & qc_bl1D_old,cldfra_bl1D_old, & ! inputs - flags for moist arrays - & F_QC,F_QI, & - F_QNC,F_QNI, & - & F_QNWFA,F_QNIFA, & - & Psig_shcu, & + & F_QC,F_QI, & + & F_QNC,F_QNI, & + & F_QNWFA,F_QNIFA,F_QNBCA, & + & Psig_shcu, & ! output info - &nup2,ktop,maxmf,ztop, & - ! unputs for stochastic perturbations - &spp_pbl,rstoch_col) + & nup2,ktop,maxmf,ztop, & + ! inputs for stochastic perturbations + & spp_pbl,rstoch_col ) ! inputs: INTEGER, INTENT(IN) :: KTS,KTE,KPBL,momentum_opt,tke_opt,scalar_opt @@ -5840,140 +5704,134 @@ SUBROUTINE DMP_mf( & #endif ! Stochastic - INTEGER, INTENT(IN) :: spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,W,TH,THL,TK,QT,QV,QC,& - exner,dz,THV,P,rho,qke,qnc,qni,qnwfa,qnifa - REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW !height at full-sigma - REAL, INTENT(IN) :: FLT,FLTV,FLQ,FLQV,& - Psig_shcu,landsea,ts - REAL(kind=kind_phys), INTENT(IN) :: dx,dt,ust,pblh - LOGICAL, OPTIONAL :: F_QC,F_QI,F_QNC,F_QNI,F_QNWFA,F_QNIFA + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: & + &U,V,W,TH,THL,TK,QT,QV,QC, & + &exner,dz,THV,P,rho,qke,qnc,qni,qnwfa,qnifa,qnbca + real(kind_phys),DIMENSION(KTS:KTE+1), INTENT(IN) :: zw !height at full-sigma + real(kind_phys), INTENT(IN) :: flt,fltv,flq,flqv,Psig_shcu, & + &landsea,ts,dx,dt,ust,pblh + LOGICAL, OPTIONAL :: F_QC,F_QI,F_QNC,F_QNI,F_QNWFA,F_QNIFA,F_QNBCA ! outputs - updraft properties - REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a,edmf_w, & - & edmf_qt,edmf_thl, edmf_ent,edmf_qc + real(kind_phys),DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a,edmf_w, & + & edmf_qt,edmf_thl,edmf_ent,edmf_qc !add one local edmf variable: - REAL,DIMENSION(KTS:KTE) :: edmf_th + real(kind_phys),DIMENSION(KTS:KTE) :: edmf_th ! output INTEGER, INTENT(OUT) :: nup2,ktop - REAL(kind=kind_phys), INTENT(OUT) :: maxmf - REAL, INTENT(OUT) :: ztop + real(kind_phys), INTENT(OUT) :: maxmf + real(kind_phys), INTENT(OUT) :: ztop ! outputs - variables needed for solver - REAL,DIMENSION(KTS:KTE+1) :: s_aw, & !sum ai*rho*wis_awphi - s_awthl, & !sum ai*rho*wi*phii - s_awqt, & - s_awqv, & - s_awqc, & - s_awqnc, & - s_awqni, & - s_awqnwfa, & - s_awqnifa, & - s_awu, & - s_awv, & - s_awqke, s_aw2 - - REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: qc_bl1d,cldfra_bl1d, & - qc_bl1d_old,cldfra_bl1d_old + real(kind_phys),DIMENSION(KTS:KTE+1) :: s_aw, & !sum ai*rho*wis_awphi + &s_awthl,s_awqt,s_awqv,s_awqc,s_awqnc,s_awqni, & + &s_awqnwfa,s_awqnifa,s_awqnbca,s_awu,s_awv, & + &s_awqke,s_aw2 + + real(kind_phys),DIMENSION(KTS:KTE), INTENT(INOUT) :: & + &qc_bl1d,cldfra_bl1d,qc_bl1d_old,cldfra_bl1d_old INTEGER, PARAMETER :: nup=10, debug_mf=0 !------------- local variables ------------------- ! updraft properties defined on interfaces (k=1 is the top of the ! first model layer - REAL,DIMENSION(KTS:KTE+1,1:NUP) :: UPW,UPTHL,UPQT,UPQC,UPQV, & - UPA,UPU,UPV,UPTHV,UPQKE,UPQNC, & - UPQNI,UPQNWFA,UPQNIFA + real(kind_phys),DIMENSION(KTS:KTE+1,1:NUP) :: & + &UPW,UPTHL,UPQT,UPQC,UPQV, & + &UPA,UPU,UPV,UPTHV,UPQKE,UPQNC, & + &UPQNI,UPQNWFA,UPQNIFA,UPQNBCA ! entrainment variables - REAL,DIMENSION(KTS:KTE,1:NUP) :: ENT,ENTf - INTEGER,DIMENSION(KTS:KTE,1:NUP) :: ENTi + real(kind_phys),DIMENSION(KTS:KTE,1:NUP) :: ENT,ENTf + INTEGER,DIMENSION(KTS:KTE,1:NUP) :: ENTi ! internal variables INTEGER :: K,I,k50 - REAL :: fltv2,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & - pwmin,pwmax,wmin,wmax,wlv,Psig_w,maxw,maxqc,wpbl - REAL :: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,QNCn,QNIn,QNWFAn,QNIFAn, & - Wn2,Wn,EntEXP,EntEXM,EntW,BCOEFF,THVkm1,THVk,Pk,qtk,rho_int + real(kind_phys):: fltv2,wstar,qstar,thstar,sigmaW,sigmaQT, & + &sigmaTH,z0,pwmin,pwmax,wmin,wmax,wlv,Psig_w,maxw,maxqc,wpbl + real(kind_phys):: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,QNCn,QNIn, & + QNWFAn,QNIFAn,QNBCAn, & + Wn2,Wn,EntEXP,EntEXM,EntW,BCOEFF,THVkm1,THVk,Pk,rho_int ! w parameters - REAL,PARAMETER :: & - &Wa=2./3., & - &Wb=0.002, & + real(kind_phys), PARAMETER :: & + &Wa=2./3., & + &Wb=0.002, & &Wc=1.5 ! Lateral entrainment parameters ( L0=100 and ENT0=0.1) were taken from ! Suselj et al (2013, jas). Note that Suselj et al (2014,waf) use L0=200 and ENT0=0.2. - REAL,PARAMETER :: & + real(kind_phys),PARAMETER :: & & L0=100., & & ENT0=0.1 ! Implement ideas from Neggers (2016, JAMES): - REAL, PARAMETER :: Atot = 0.10 ! Maximum total fractional area of all updrafts - REAL, PARAMETER :: lmax = 1000.! diameter of largest plume - REAL, PARAMETER :: dl = 100. ! diff size of each plume - the differential multiplied by the integrand - REAL, PARAMETER :: dcut = 1.2 ! max diameter of plume to parameterize relative to dx (km) - REAL :: d != -2.3 to -1.7 ;=-1.9 in Neggers paper; power law exponent for number density (N=Cl^d). + real(kind_phys), PARAMETER :: Atot = 0.10 ! Maximum total fractional area of all updrafts + real(kind_phys), PARAMETER :: lmax = 1000.! diameter of largest plume + real(kind_phys), PARAMETER :: dl = 100. ! diff size of each plume - the differential multiplied by the integrand + real(kind_phys), PARAMETER :: dcut = 1.2 ! max diameter of plume to parameterize relative to dx (km) + real(kind_phys):: d != -2.3 to -1.7 ;=-1.9 in Neggers paper; power law exponent for number density (N=Cl^d). ! Note that changing d to -2.0 makes each size plume equally contribute to the total coverage of all plumes. ! Note that changing d to -1.7 doubles the area coverage of the largest plumes relative to the smallest plumes. - REAL :: cn,c,l,n,an2,hux,maxwidth,wspd_pbl,cloud_base,width_flx + real(kind_phys):: cn,c,l,n,an2,hux,maxwidth,wspd_pbl,cloud_base,width_flx ! chem/smoke INTEGER, INTENT(IN) :: nchem - REAL,DIMENSION(:, :) :: chem1 - REAL,DIMENSION(kts:kte+1, nchem) :: s_awchem - REAL,DIMENSION(nchem) :: chemn - REAL,DIMENSION(KTS:KTE+1,1:NUP, nchem) :: UPCHEM + real(kind_phys),DIMENSION(:, :) :: chem1 + real(kind_phys),DIMENSION(kts:kte+1, nchem) :: s_awchem + real(kind_phys),DIMENSION(nchem) :: chemn + real(kind_phys),DIMENSION(KTS:KTE+1,1:NUP, nchem) :: UPCHEM INTEGER :: ic - REAL,DIMENSION(KTS:KTE+1, nchem) :: edmf_chem + real(kind_phys),DIMENSION(KTS:KTE+1, nchem) :: edmf_chem LOGICAL, INTENT(IN) :: mix_chem !JOE: add declaration of ERF - REAL :: ERF + real(kind_phys):: ERF LOGICAL :: superadiabatic ! VARIABLES FOR CHABOUREAU-BECHTOLD CLOUD FRACTION - REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: vt, vq, sgm - REAL :: sigq,xl,rsl,cpm,a,qmq,mf_cf,Aup,Q1,diffqt,qsat_tk,& - Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid, & + real(kind_phys),DIMENSION(KTS:KTE), INTENT(INOUT) :: vt, vq, sgm + real(kind_phys):: sigq,xl,rsl,cpm,a,qmq,mf_cf,Aup,Q1,diffqt,qsat_tk,& + Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid, & Ac_mf,Ac_strat,qc_mf - REAL, PARAMETER :: cf_thresh = 0.5 ! only overwrite stratus CF less than this value + real(kind_phys), PARAMETER :: cf_thresh = 0.5 ! only overwrite stratus CF less than this value ! Variables for plume interpolation/saturation check - REAL,DIMENSION(KTS:KTE) :: exneri,dzi - REAL :: THp, QTp, QCp, QCs, esat, qsl - REAL :: csigma,acfac,ac_wsp,ac_cld + real(kind_phys),DIMENSION(KTS:KTE) :: exneri,dzi + real(kind_phys):: THp, QTp, QCp, QCs, esat, qsl + real(kind_phys):: csigma,acfac,ac_wsp,ac_cld !plume overshoot INTEGER :: overshoot - REAL :: bvf, Frz, dzp + real(kind_phys):: bvf, Frz, dzp !Flux limiter: not let mass-flux of heat between k=1&2 exceed (fluxportion)*(surface heat flux). !This limiter makes adjustments to the entire column. - REAL :: adjustment, flx1 - REAL, PARAMETER :: fluxportion=0.75 ! set liberally, so has minimal impact. 0.5 starts to have a noticeable impact + real(kind_phys):: adjustment, flx1 + real(kind_phys), PARAMETER :: fluxportion=0.75 ! set liberally, so has minimal impact. 0.5 starts to have a noticeable impact ! over land (decrease maxMF by 10-20%), but no impact over water. !Subsidence - REAL,DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v, & !tendencies due to subsidence - det_thl,det_sqv,det_sqc,det_u,det_v, & !tendencied due to detrainment - envm_a,envm_w,envm_thl,envm_sqv,envm_sqc, & + real(kind_phys),DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v, & !tendencies due to subsidence + det_thl,det_sqv,det_sqc,det_u,det_v, & !tendencied due to detrainment + envm_a,envm_w,envm_thl,envm_sqv,envm_sqc, & envm_u,envm_v !environmental variables defined at middle of layer - REAL,DIMENSION(KTS:KTE+1) :: envi_a,envi_w !environmental variables defined at model interface - REAL :: temp,sublim,qc_ent,qv_ent,qt_ent,thl_ent,detrate, & - detrateUV,oow,exc_fac,aratio,detturb,qc_grid,qc_sgs,& + real(kind_phys),DIMENSION(KTS:KTE+1) :: envi_a,envi_w !environmental variables defined at model interface + real(kind_phys):: temp,sublim,qc_ent,qv_ent,qt_ent,thl_ent,detrate, & + detrateUV,oow,exc_fac,aratio,detturb,qc_grid,qc_sgs, & qc_plume,exc_heat,exc_moist,tk_int - REAL, PARAMETER :: Cdet = 1./45. - REAL, PARAMETER :: dzpmax = 300. !limit dz used in detrainment - can be excessing in thick layers + real(kind_phys), PARAMETER :: Cdet = 1./45. + real(kind_phys), PARAMETER :: dzpmax = 300. !limit dz used in detrainment - can be excessing in thick layers !parameter "Csub" determines the propotion of upward vertical velocity that contributes to !environmenatal subsidence. Some portion is expected to be compensated by downdrafts instead of !gentle environmental subsidence. 1.0 assumes all upward vertical velocity in the mass-flux scheme !is compensated by "gentle" environmental subsidence. - REAL, PARAMETER :: Csub=0.25 + real(kind_phys), PARAMETER :: Csub=0.25 !Factor for the pressure gradient effects on momentum transport - REAL, PARAMETER :: pgfac = 0.00 ! Zhang and Wu showed 0.4 is more appropriate for lower troposphere - REAL :: Uk,Ukm1,Vk,Vkm1,dxsa + real(kind_phys), PARAMETER :: pgfac = 0.00 ! Zhang and Wu showed 0.4 is more appropriate for lower troposphere + real(kind_phys):: Uk,Ukm1,Vk,Vkm1,dxsa ! check the inputs ! print *,'dt',dt @@ -6002,6 +5860,7 @@ SUBROUTINE DMP_mf( & UPQNI=0. UPQNWFA=0. UPQNIFA=0. + UPQNBCA=0. IF ( mix_chem ) THEN UPCHEM(KTS:KTE+1,1:NUP,1:nchem)=0.0 ENDIF @@ -6031,6 +5890,7 @@ SUBROUTINE DMP_mf( & s_awqni=0. s_awqnwfa=0. s_awqnifa=0. + s_awqnbca=0. IF ( mix_chem ) THEN s_awchem(kts:kte+1,1:nchem) = 0.0 ENDIF @@ -6224,7 +6084,7 @@ SUBROUTINE DMP_mf( & wlv=wmin+(wmax-wmin)/NUP2*(i-1) !SURFACE UPDRAFT VERTICAL VELOCITY - UPW(1,I)=wmin + REAL(i)/REAL(NUP)*(wmax-wmin) + UPW(1,I)=wmin + real(i)/real(NUP)*(wmax-wmin) !IF (UPW(1,I) > 0.5*ZW(2)/dt) UPW(1,I) = 0.5*ZW(2)/dt UPU(1,I)=(U(KTS)*DZ(KTS+1)+U(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) @@ -6258,6 +6118,7 @@ SUBROUTINE DMP_mf( & UPQNI(1,I)=(QNI(KTS)*DZ(KTS+1)+QNI(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNWFA(1,I)=(QNWFA(KTS)*DZ(KTS+1)+QNWFA(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNIFA(1,I)=(QNIFA(KTS)*DZ(KTS+1)+QNIFA(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) + UPQNBCA(1,I)=(QNBCA(KTS)*DZ(KTS+1)+QNBCA(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) ENDDO IF ( mix_chem ) THEN @@ -6330,6 +6191,7 @@ SUBROUTINE DMP_mf( & QNIn=UPQNI(k-1,I)*(1.-EntExp) + QNI(k)*EntExp QNWFAn=UPQNWFA(k-1,I)*(1.-EntExp) + QNWFA(k)*EntExp QNIFAn=UPQNIFA(k-1,I)*(1.-EntExp) + QNIFA(k)*EntExp + QNBCAn=UPQNBCA(k-1,I)*(1.-EntExp) + QNBCA(k)*EntExp !capture the updated qc, qt & thl modified by entranment alone, !since they will be modified later if condensation occurs. @@ -6426,13 +6288,10 @@ SUBROUTINE DMP_mf( & dzp = dz(k) ENDIF - !Limit very tall plumes - Wn=Wn*EXP(-MAX(ZW(k+1)-MIN(pblh+2000.,3500.),0.0)/1000.) - - !JOE- minimize the plume penetratration in stratocu-topped PBL - ! IF (fltv2 < 0.06) THEN - ! IF(ZW(k+1) >= pblh-200. .AND. qc(k) > 1e-5 .AND. I > 4) Wn=0. - ! ENDIF + !minimize the plume penetratration in stratocu-topped PBL + !IF (fltv2 < 0.06) THEN + ! IF(ZW(k+1) >= pblh-200. .AND. qc(k) > 1e-5 .AND. I > 4) Wn=0. + !ENDIF !Modify environment variables (representative of the model layer - envm*) !following the updraft dynamical detrainment of Asai and Kasahara (1967, JAS). @@ -6470,6 +6329,7 @@ SUBROUTINE DMP_mf( & UPQNI(K,I)=QNIn UPQNWFA(K,I)=QNWFAn UPQNIFA(K,I)=QNIFAn + UPQNBCA(K,I)=QNBCAn UPA(K,I)=UPA(K-1,I) IF ( mix_chem ) THEN do ic = 1,nchem @@ -6527,11 +6387,11 @@ SUBROUTINE DMP_mf( & !to conform to grid mean properties, move qc to qv in grid mean !saturated layers, so total water fluxes are preserved but !negative qc fluxes in unsaturated layers is reduced. - IF (qc(k) > 1e-12 .OR. qc(k+1) > 1e-12) then +! if (qc(k) > 1e-12 .or. qc(k+1) > 1e-12) then qc_plume = UPQC(K,i) - ELSE - qc_plume = 0.0 - ENDIF +! else +! qc_plume = 0.0 +! endif s_awqc(k+1) = s_awqc(k+1) + rho_int*UPA(K,i)*UPW(K,i)*qc_plume*Psig_w IF (momentum_opt > 0) THEN s_awu(k+1) = s_awu(k+1) + rho_int*UPA(K,i)*UPW(K,i)*UPU(K,i)*Psig_w @@ -6567,6 +6427,7 @@ SUBROUTINE DMP_mf( & s_awqni(k+1)= s_awqni(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNI(K,i)*Psig_w s_awqnwfa(k+1)= s_awqnwfa(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNWFA(K,i)*Psig_w s_awqnifa(k+1)= s_awqnifa(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNIFA(K,i)*Psig_w + s_awqnbca(k+1)= s_awqnbca(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNBCA(K,i)*Psig_w ENDDO ENDDO ENDIF @@ -6596,6 +6457,7 @@ SUBROUTINE DMP_mf( & s_awqni= s_awqni*adjustment s_awqnwfa= s_awqnwfa*adjustment s_awqnifa= s_awqnifa*adjustment + s_awqnbca= s_awqnbca*adjustment IF (momentum_opt > 0) THEN s_awu = s_awu*adjustment s_awv = s_awv*adjustment @@ -6642,9 +6504,9 @@ SUBROUTINE DMP_mf( & !smoke/chem IF ( mix_chem ) THEN - DO k=KTS,KTE-1 + DO k=kts,kte-1 IF(k > KTOP) exit - rho_int = (rho(k)*DZ(k+1)+rho(k+1)*DZ(k))/(DZ(k+1)+DZ(k)) + rho_int = (rho(k)*dz(k+1)+rho(k+1)*dz(k))/(dz(k+1)+dz(k)) DO I=1,NUP !NUP2 IF(I > NUP2) exit do ic = 1,nchem @@ -6661,14 +6523,14 @@ SUBROUTINE DMP_mf( & ENDIF !Calculate the effects environmental subsidence. - !All envi_*variables are valid at the interfaces, like the edmf_* variables + !All envi_*variables are valid at the interfaces, like the edmf_* variables IF (env_subs) THEN - DO k=KTS+1,KTE-1 + DO k=kts+1,kte-1 !First, smooth the profiles of w & a, since sharp vertical gradients !in plume variables are not likely extended to env variables !Note1: w is treated as negative further below !Note2: both w & a will be transformed into env variables further below - envi_w(k) = onethird*(edmf_w(K-1)+edmf_w(K)+edmf_w(K+1)) + envi_w(k) = onethird*(edmf_w(k-1)+edmf_w(k)+edmf_w(k+1)) envi_a(k) = onethird*(edmf_a(k-1)+edmf_a(k)+edmf_a(k+1))*adjustment ENDDO !define env variables at k=1 (top of first model layer) @@ -6689,22 +6551,26 @@ SUBROUTINE DMP_mf( & sublim = 1.0 ENDIF !Transform w & a into env variables - DO k=KTS,KTE + DO k=kts,kte temp=envi_a(k) envi_a(k)=1.0-temp envi_w(k)=csub*sublim*envi_w(k)*temp/(1.-temp) ENDDO !calculate tendencies from subsidence and detrainment valid at the middle of - !each model layer - dzi(kts) = 0.5*(DZ(kts)+DZ(kts+1)) - sub_thl(kts)=0.5*envi_w(kts)*envi_a(kts)*(thl(kts+1)-thl(kts))/dzi(kts) - sub_sqv(kts)=0.5*envi_w(kts)*envi_a(kts)*(qv(kts+1)-qv(kts))/dzi(kts) - DO k=KTS+1,KTE-1 - dzi(k) = 0.5*(DZ(k)+DZ(k+1)) - sub_thl(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (thl(k+1)-thl(k))/dzi(k) - sub_sqv(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (qv(k+1)-qv(k))/dzi(k) + !each model layer. The lowest model layer uses an assumes w=0 at the surface. + dzi(kts) = 0.5*(dz(kts)+dz(kts+1)) + rho_int = (rho(kts)*dz(kts+1)+rho(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) + sub_thl(kts)= 0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*thl(kts+1)-rho(kts)*thl(kts))/dzi(kts)/rho_int + sub_sqv(kts)= 0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*qv(kts+1)-rho(kts)*qv(kts))/dzi(kts)/rho_int + DO k=kts+1,kte-1 + dzi(k) = 0.5*(dz(k)+dz(k+1)) + rho_int = (rho(k)*dz(k+1)+rho(k+1)*dz(k))/(dz(k+1)+dz(k)) + sub_thl(k)= 0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & + (rho(k+1)*thl(k+1)-rho(k)*thl(k))/dzi(k)/rho_int + sub_sqv(k)= 0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & + (rho(k+1)*qv(k+1)-rho(k)*qv(k))/dzi(k)/rho_int ENDDO DO k=KTS,KTE-1 @@ -6714,13 +6580,17 @@ SUBROUTINE DMP_mf( & ENDDO IF (momentum_opt > 0) THEN - sub_u(kts)=0.5*envi_w(kts)*envi_a(kts)*(u(kts+1)-u(kts))/dzi(kts) - sub_v(kts)=0.5*envi_w(kts)*envi_a(kts)*(v(kts+1)-v(kts))/dzi(kts) - DO k=KTS+1,KTE-1 + rho_int = (rho(kts)*dz(kts+1)+rho(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) + sub_u(kts)=0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*u(kts+1)-rho(kts)*u(kts))/dzi(kts)/rho_int + sub_v(kts)=0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*v(kts+1)-rho(kts)*v(kts))/dzi(kts)/rho_int + DO k=kts+1,kte-1 + rho_int = (rho(k)*dz(k+1)+rho(k+1)*dz(k))/(dz(k+1)+dz(k)) sub_u(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (u(k+1)-u(k))/dzi(k) + (rho(k+1)*u(k+1)-rho(k)*u(k))/dzi(k)/rho_int sub_v(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (v(k+1)-v(k))/dzi(k) + (rho(k+1)*v(k+1)-rho(k)*v(k))/dzi(k)/rho_int ENDDO DO k=KTS,KTE-1 @@ -6741,10 +6611,10 @@ SUBROUTINE DMP_mf( & !JOE: ADD CLDFRA_bl1d, qc_bl1d. Note that they have already been defined in ! mym_condensation. Here, a shallow-cu component is added, but no cumulus -! clouds can be added at k=1 (start loop at k=2). - DO K=KTS+1,KTE-2 +! clouds can be added at k=1 (start loop at k=2). + do k=kts+1,kte-2 IF(k > KTOP) exit - IF(0.5*(edmf_qc(k)+edmf_qc(k-1))>0.0)THEN + IF(0.5*(edmf_qc(k)+edmf_qc(k-1))>0.0 .and. (cldfra_bl1d(k) < cf_thresh))THEN !interpolate plume quantities to mass levels Aup = (edmf_a(k)*dzi(k-1)+edmf_a(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) THp = (edmf_th(k)*dzi(k-1)+edmf_th(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) @@ -6757,11 +6627,11 @@ SUBROUTINE DMP_mf( & qsl=ep_2*esat/max(1.e-7,(p(k)-ep_3*esat)) !condensed liquid in the plume on mass levels - IF (edmf_qc(k)>0.0 .AND. edmf_qc(k-1)>0.0)THEN + if (edmf_qc(k)>0.0 .and. edmf_qc(k-1)>0.0) then QCp = (edmf_qc(k)*dzi(k-1)+edmf_qc(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) - ELSE - QCp = MAX(edmf_qc(k),edmf_qc(k-1)) - ENDIF + else + QCp = max(edmf_qc(k),edmf_qc(k-1)) + endif !COMPUTE CLDFRA & QC_BL FROM MASS-FLUX SCHEME and recompute vt & vq xl = xl_blend(tk(k)) ! obtain blended heat capacity @@ -6794,10 +6664,11 @@ SUBROUTINE DMP_mf( & endif !CB form: - sigq = 3.5E-3 * Aup * 0.5*(edmf_w(k)+edmf_w(k-1)) * f ! convective component of sigma (CB2005) + !sigq = 3.5E-3 * Aup * 0.5*(edmf_w(k)+edmf_w(k-1)) * f ! convective component of sigma (CB2005) !sigq = SQRT(sigq**2 + sgm(k)**2) ! combined conv + stratus components !Per S.DeRoode 2009? - !sigq = 4. * Aup * (QTp - qt(k)) + !sigq = 5. * Aup * (QTp - qt(k)) + sigq = 10. * Aup * (QTp - qt(k)) !constrain sigq wrt saturation: sigq = max(sigq, qsat_tk*0.02 ) sigq = min(sigq, qsat_tk*0.25 ) @@ -6806,21 +6677,21 @@ SUBROUTINE DMP_mf( & Q1 = qmq/sigq ! the numerator of Q1 if ((landsea-1.5).GE.0) then ! WATER - mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.2)),0.01),0.6) + !modified form from LES + !mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.2)),0.01),0.6) + !Original CB + mf_cf = min(max(0.5 + 0.36 * atan(1.55*Q1),0.01),0.6) mf_cf = max(mf_cf, 1.2 * Aup) + mf_cf = min(mf_cf, 5.0 * Aup) else ! LAND - !mf_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.01),0.6) - mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.4)),0.01),0.6) ! New WA fit + !LES form + !mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.4)),0.01),0.6) + !Original CB + mf_cf = min(max(0.5 + 0.36 * atan(1.55*Q1),0.01),0.6) mf_cf = max(mf_cf, 1.75 * Aup) + mf_cf = min(mf_cf, 5.0 * Aup) endif - ! WA TEST 4/15/22 use fit to Aup rather than CB - !IF (Aup > 0.1) THEN - ! mf_cf = 2.5 * Aup - !ELSE - ! mf_cf = 1.8 * Aup - !ENDIF - !IF ( debug_code ) THEN ! print*,"In MYNN, StEM edmf" ! print*," CB: env qt=",qt(k)," qsat=",qsat_tk @@ -6832,21 +6703,17 @@ SUBROUTINE DMP_mf( & ! Update cloud fractions and specific humidities in grid cells ! where the mass-flux scheme is active. The specific humidities ! are converted to grid means (not in-cloud quantities). - if ((landsea-1.5).GE.0) then ! water - !don't overwrite stratus CF & qc_bl - degrades marine stratus - if (cldfra_bl1d(k) < cf_thresh) then - if (QCp * Aup > 5e-5) then - qc_bl1d(k) = 1.86 * (QCp * Aup) - 2.2e-5 - else - qc_bl1d(k) = 1.18 * (QCp * Aup) - endif - if (mf_cf .ge. Aup) then - qc_bl1d(k) = qc_bl1d(k) / mf_cf - endif - cldfra_bl1d(k) = mf_cf - Ac_mf = mf_cf + if (QCp * Aup > 5e-5) then + qc_bl1d(k) = 1.86 * (QCp * Aup) - 2.2e-5 + else + qc_bl1d(k) = 1.18 * (QCp * Aup) endif + if (mf_cf .ge. Aup) then + qc_bl1d(k) = qc_bl1d(k) / mf_cf + endif + cldfra_bl1d(k) = mf_cf + Ac_mf = mf_cf else ! land if (QCp * Aup > 5e-5) then qc_bl1d(k) = 1.86 * (QCp * Aup) - 2.2e-5 @@ -6865,42 +6732,40 @@ SUBROUTINE DMP_mf( & !Use Bechtold and Siebesma (1998) piecewise estimation of Fng with !limits ,since they really should be recalculated after all the other changes...: !Only overwrite vt & vq in non-stratus condition - if (cldfra_bl1d(k) < cf_thresh) then - !if ((landsea-1.5).GE.0) then ! WATER - Q1=max(Q1,-2.25) - !else - ! Q1=max(Q1,-2.0) - !endif - - if (Q1 .ge. 1.0) then - Fng = 1.0 - elseif (Q1 .ge. -1.7 .and. Q1 .lt. 1.0) then - Fng = EXP(-0.4*(Q1-1.0)) - elseif (Q1 .ge. -2.5 .and. Q1 .lt. -1.7) then - Fng = 3.0 + EXP(-3.8*(Q1+1.7)) - else - Fng = min(23.9 + EXP(-1.6*(Q1+2.5)), 60.) - endif - - !link the buoyancy flux function to active clouds only (c*Aup): - vt(k) = qww - (1.5*Aup)*beta*bb*Fng - 1. - vq(k) = alpha + (1.5*Aup)*beta*a*Fng - tv0 + !if ((landsea-1.5).GE.0) then ! WATER + Q1=max(Q1,-2.25) + !else + ! Q1=max(Q1,-2.0) + !endif + + if (Q1 .ge. 1.0) then + Fng = 1.0 + elseif (Q1 .ge. -1.7 .and. Q1 .lt. 1.0) then + Fng = EXP(-0.4*(Q1-1.0)) + elseif (Q1 .ge. -2.5 .and. Q1 .lt. -1.7) then + Fng = 3.0 + EXP(-3.8*(Q1+1.7)) + else + Fng = min(23.9 + EXP(-1.6*(Q1+2.5)), 60.) endif - endif + + !link the buoyancy flux function to active clouds only (c*Aup): + vt(k) = qww - (1.5*Aup)*beta*bb*Fng - 1. + vq(k) = alpha + (1.5*Aup)*beta*a*Fng - tv0 + endif !check for (qc in plume) .and. (cldfra_bl < threshold) enddo !k-loop ENDIF !end nup2 > 0 !modify output (negative: dry plume, positive: moist plume) - IF (ktop > 0) THEN + if (ktop > 0) then maxqc = maxval(edmf_qc(1:ktop)) - IF ( maxqc < 1.E-8) maxmf = -1.0*maxmf - ENDIF + if ( maxqc < 1.E-8) maxmf = -1.0*maxmf + endif ! -! debugging +! debugging ! -IF (edmf_w(1) > 4.0) THEN +if (edmf_w(1) > 4.0) then ! surface values print *,'flq:',flq,' fltv:',fltv2 print *,'pblh:',pblh,' wstar:',wstar @@ -6953,12 +6818,12 @@ subroutine condensation_edmf(QT,THL,P,zagl,THV,QC) ! ! zero or one condensation for edmf: calculates THV and QC ! -real,intent(in) :: QT,THL,P,zagl -real,intent(out) :: THV -real,intent(inout):: QC +real(kind_phys),intent(in) :: QT,THL,P,zagl +real(kind_phys),intent(out) :: THV +real(kind_phys),intent(inout):: QC integer :: niter,i -real :: diff,exn,t,th,qs,qcold +real(kind_phys):: diff,exn,t,th,qs,qcold ! constants used from module_model_constants.F ! p1000mb @@ -7000,7 +6865,7 @@ subroutine condensation_edmf(QT,THL,P,zagl,THV,QC) !THIS BASICALLY GIVE THE SAME RESULT AS THE PREVIOUS LINE !TH = THL + xlv/cp/EXN*QC - !THV= TH*(1. + 0.608*QT) + !THV= TH*(1. + p608*QT) !print *,'t,p,qt,qs,qc' !print *,t,p,qt,qs,qc @@ -7015,11 +6880,11 @@ subroutine condensation_edmf_r(QT,THL,P,zagl,THV,QC) ! zero or one condensation for edmf: calculates THL and QC ! similar to condensation_edmf but with different inputs ! -real,intent(in) :: QT,THV,P,zagl -real,intent(out) :: THL, QC +real(kind_phys),intent(in) :: QT,THV,P,zagl +real(kind_phys),intent(out) :: THL, QC integer :: niter,i -real :: diff,exn,t,th,qs,qcold +real(kind_phys):: diff,exn,t,th,qs,qcold ! number of iterations niter=50 @@ -7065,58 +6930,58 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & &rthraten ) INTEGER, INTENT(IN) :: KTS,KTE,KPBL - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,TH,THL,TK,QT,QV,QC,& + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: U,V,TH,THL,TK,QT,QV,QC,& THV,P,rho,exner,dz - REAL(kind=kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: rthraten + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: rthraten ! zw .. heights of the downdraft levels (edges of boxes) - REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW - REAL, INTENT(IN) :: WTHL,WQT - REAL(kind=kind_phys), INTENT(IN) :: dt,ust,pblh + real(kind_phys),DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW + real(kind_phys), INTENT(IN) :: WTHL,WQT + real(kind_phys), INTENT(IN) :: dt,ust,pblh ! outputs - downdraft properties - REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a_dd,edmf_w_dd, & + real(kind_phys),DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a_dd,edmf_w_dd, & & edmf_qt_dd,edmf_thl_dd, edmf_ent_dd,edmf_qc_dd ! outputs - variables needed for solver (sd_aw - sum ai*wi, sd_awphi - sum ai*wi*phii) - REAL,DIMENSION(KTS:KTE+1) :: sd_aw, sd_awthl, sd_awqt, sd_awu, & + real(kind_phys),DIMENSION(KTS:KTE+1) :: sd_aw, sd_awthl, sd_awqt, sd_awu, & sd_awv, sd_awqc, sd_awqv, sd_awqke, sd_aw2 - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: qc_bl1d, cldfra_bl1d + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: qc_bl1d, cldfra_bl1d INTEGER, PARAMETER :: NDOWN=5, debug_mf=0 !fixing number of plumes to 5 ! draw downdraft starting height randomly between cloud base and cloud top INTEGER, DIMENSION(1:NDOWN) :: DD_initK - REAL , DIMENSION(1:NDOWN) :: randNum + real(kind_phys) , DIMENSION(1:NDOWN) :: randNum ! downdraft properties - REAL,DIMENSION(KTS:KTE+1,1:NDOWN) :: DOWNW,DOWNTHL,DOWNQT,& + real(kind_phys),DIMENSION(KTS:KTE+1,1:NDOWN) :: DOWNW,DOWNTHL,DOWNQT,& DOWNQC,DOWNA,DOWNU,DOWNV,DOWNTHV ! entrainment variables - REAl,DIMENSION(KTS+1:KTE+1,1:NDOWN) :: ENT,ENTf + Real(Kind_phys),DIMENSION(KTS+1:KTE+1,1:NDOWN) :: ENT,ENTf INTEGER,DIMENSION(KTS+1:KTE+1,1:NDOWN) :: ENTi ! internal variables INTEGER :: K,I,ki, kminrad, qlTop, p700_ind, qlBase - REAL :: wthv,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & + real(kind_phys):: wthv,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & pwmin,pwmax,wmin,wmax,wlv,wtv,went,mindownw - REAL :: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,Wn2,Wn,THVk,Pk, & + real(kind_phys):: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,Wn2,Wn,THVk,Pk, & EntEXP,EntW, Beta_dm, EntExp_M, rho_int - REAL :: jump_thetav, jump_qt, jump_thetal, & + real(kind_phys):: jump_thetav, jump_qt, jump_thetal, & refTHL, refTHV, refQT ! DD specific internal variables - REAL :: minrad,zminrad, radflux, F0, wst_rad, wst_dd + real(kind_phys):: minrad,zminrad, radflux, F0, wst_rad, wst_dd logical :: cloudflg - REAL :: sigq,xl,rsl,cpm,a,mf_cf,diffqt,& + real(kind_phys):: sigq,xl,rsl,cpm,a,mf_cf,diffqt,& Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid ! w parameters - REAL,PARAMETER :: & + real(kind_phys),PARAMETER :: & &Wa=1., & &Wb=1.5,& &Z00=100.,& &BCOEFF=0.2 ! entrainment parameters - REAL,PARAMETER :: & + real(kind_phys),PARAMETER :: & & L0=80,& & ENT0=0.2 @@ -7178,7 +7043,7 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & do i=1,NDOWN ! downdraft starts somewhere between cloud base to cloud top ! the probability is equally distributed - DD_initK(i) = qlTop ! nint(randNum(i)*REAL(qlTop-qlBase)) + qlBase + DD_initK(i) = qlTop ! nint(randNum(i)*real(qlTop-qlBase)) + qlBase enddo ! LOOP RADFLUX @@ -7248,13 +7113,13 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & do I=1,NDOWN !downdraft now starts at different height ki = DD_initK(I) - wlv=wmin+(wmax-wmin)/REAL(NDOWN)*(i-1) - wtv=wmin+(wmax-wmin)/REAL(NDOWN)*i + wlv=wmin+(wmax-wmin)/real(NDOWN)*(i-1) + wtv=wmin+(wmax-wmin)/real(NDOWN)*i !DOWNW(ki,I)=0.5*(wlv+wtv) DOWNW(ki,I)=wlv !DOWNA(ki,I)=0.5*ERF(wtv/(sqrt(2.)*sigmaW))-0.5*ERF(wlv/(sqrt(2.)*sigmaW)) - DOWNA(ki,I)=.1/REAL(NDOWN) + DOWNA(ki,I)=.1/real(NDOWN) DOWNU(ki,I)=(u(ki-1)*DZ(ki) + u(ki)*DZ(ki-1)) /(DZ(ki)+DZ(ki-1)) DOWNV(ki,I)=(v(ki-1)*DZ(ki) + v(ki)*DZ(ki-1)) /(DZ(ki)+DZ(ki-1)) @@ -7424,9 +7289,9 @@ SUBROUTINE SCALE_AWARE(dx,PBL1,Psig_bl,Psig_shcu) ! Psig_bl tapers local mixing ! Psig_shcu tapers nonlocal mixing - REAL(kind=kind_phys), INTENT(IN) :: dx,pbl1 - REAL, INTENT(OUT) :: Psig_bl,Psig_shcu - REAL :: dxdh + real(kind_phys), INTENT(IN) :: dx,pbl1 + real(kind_phys), INTENT(OUT) :: Psig_bl,Psig_shcu + real(kind_phys) :: dxdh Psig_bl=1.0 Psig_shcu=1.0 @@ -7498,22 +7363,42 @@ FUNCTION esat_blend(t) IMPLICIT NONE - REAL, INTENT(IN):: t - REAL :: esat_blend,XC,ESL,ESI,chi - - XC=MAX(-80.,t - t0c) !note t0c = 273.15, tice is set in module mynn_common - -! For 253 < t < 273.16 K, the vapor pressures are "blended" as a function of temperature, -! using the approach of Chaboureau and Bechtold (2002), JAS, p. 2363. The resulting + real(kind_phys), INTENT(IN):: t + real(kind_phys):: esat_blend,XC,ESL,ESI,chi + !liquid + real(kind_phys), PARAMETER:: J0= .611583699E03 + real(kind_phys), PARAMETER:: J1= .444606896E02 + real(kind_phys), PARAMETER:: J2= .143177157E01 + real(kind_phys), PARAMETER:: J3= .264224321E-1 + real(kind_phys), PARAMETER:: J4= .299291081E-3 + real(kind_phys), PARAMETER:: J5= .203154182E-5 + real(kind_phys), PARAMETER:: J6= .702620698E-8 + real(kind_phys), PARAMETER:: J7= .379534310E-11 + real(kind_phys), PARAMETER:: J8=-.321582393E-13 + !ice + real(kind_phys), PARAMETER:: K0= .609868993E03 + real(kind_phys), PARAMETER:: K1= .499320233E02 + real(kind_phys), PARAMETER:: K2= .184672631E01 + real(kind_phys), PARAMETER:: K3= .402737184E-1 + real(kind_phys), PARAMETER:: K4= .565392987E-3 + real(kind_phys), PARAMETER:: K5= .521693933E-5 + real(kind_phys), PARAMETER:: K6= .307839583E-7 + real(kind_phys), PARAMETER:: K7= .105785160E-9 + real(kind_phys), PARAMETER:: K8= .161444444E-12 + + XC=MAX(-80.,t - t0c) !note t0c = 273.15, tice is set in module mynn_common to 240 + +! For 240 < t < 268.16 K, the vapor pressures are "blended" as a function of temperature, +! using the approach similar to Chaboureau and Bechtold (2002), JAS, p. 2363. The resulting ! values are returned from the function. - IF (t .GE. t0c) THEN + IF (t .GE. (t0c-6.)) THEN esat_blend = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) ELSE IF (t .LE. tice) THEN esat_blend = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) ELSE - ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) - ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) - chi = (t0c - t)/(t0c - tice) + ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) + chi = ((t0c-6.) - t)/((t0c-6.) - tice) esat_blend = (1.-chi)*ESL + chi*ESI END IF @@ -7523,39 +7408,54 @@ END FUNCTION esat_blend !>\ingroup gsd_mynn_edmf !! This function extends function "esat" and returns a "blended" -!! saturation mixing ratio. +!! saturation mixing ratio. Tice currently set to 240 K, t0c = 273.15 K. !!\author JAYMES - FUNCTION qsat_blend(t, P, waterice) + FUNCTION qsat_blend(t, P) IMPLICIT NONE - REAL, INTENT(IN):: t, P - CHARACTER(LEN=1), OPTIONAL, INTENT(IN) :: waterice - CHARACTER(LEN=1) :: wrt - REAL :: qsat_blend,XC,ESL,ESI,RSLF,RSIF,chi - - IF ( .NOT. PRESENT(waterice) ) THEN - wrt = 'b' - ELSE - wrt = waterice - ENDIF + real(kind_phys), INTENT(IN):: t, P + real(kind_phys):: qsat_blend,XC,ESL,ESI,RSLF,RSIF,chi + !liquid + real(kind_phys), PARAMETER:: J0= .611583699E03 + real(kind_phys), PARAMETER:: J1= .444606896E02 + real(kind_phys), PARAMETER:: J2= .143177157E01 + real(kind_phys), PARAMETER:: J3= .264224321E-1 + real(kind_phys), PARAMETER:: J4= .299291081E-3 + real(kind_phys), PARAMETER:: J5= .203154182E-5 + real(kind_phys), PARAMETER:: J6= .702620698E-8 + real(kind_phys), PARAMETER:: J7= .379534310E-11 + real(kind_phys), PARAMETER:: J8=-.321582393E-13 + !ice + real(kind_phys), PARAMETER:: K0= .609868993E03 + real(kind_phys), PARAMETER:: K1= .499320233E02 + real(kind_phys), PARAMETER:: K2= .184672631E01 + real(kind_phys), PARAMETER:: K3= .402737184E-1 + real(kind_phys), PARAMETER:: K4= .565392987E-3 + real(kind_phys), PARAMETER:: K5= .521693933E-5 + real(kind_phys), PARAMETER:: K6= .307839583E-7 + real(kind_phys), PARAMETER:: K7= .105785160E-9 + real(kind_phys), PARAMETER:: K8= .161444444E-12 XC=MAX(-80.,t - t0c) - IF ((t .GE. t0c) .OR. (wrt .EQ. 'w')) THEN - ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + IF (t .GE. (t0c-6.)) THEN + ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + ESL = min(ESL, P*0.15) ! Even with P=1050mb and T=55C, the sat. vap. pres only contributes to ~15% of total pres. qsat_blend = 0.622*ESL/max(P-ESL, 1e-5) -! ELSE IF (t .LE. 253.) THEN ELSE IF (t .LE. tice) THEN ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) + ESI = min(ESI, P*0.15) qsat_blend = 0.622*ESI/max(P-ESI, 1e-5) ELSE ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + ESL = min(ESL, P*0.15) ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) + ESI = min(ESI, P*0.15) RSLF = 0.622*ESL/max(P-ESL, 1e-5) RSIF = 0.622*ESI/max(P-ESI, 1e-5) -! chi = (273.16-t)/20.16 - chi = (t0c - t)/(t0c - tice) +! chi = (268.16-t)/(268.16-240.) + chi = ((t0c-6.) - t)/((t0c-6.) - tice) qsat_blend = (1.-chi)*RSLF + chi*RSIF END IF @@ -7572,8 +7472,8 @@ FUNCTION xl_blend(t) IMPLICIT NONE - REAL, INTENT(IN):: t - REAL :: xl_blend,xlvt,xlst,chi + real(kind_phys), INTENT(IN):: t + real(kind_phys):: xl_blend,xlvt,xlst,chi !note: t0c = 273.15, tice is set in mynn_common IF (t .GE. t0c) THEN @@ -7583,7 +7483,7 @@ FUNCTION xl_blend(t) ELSE xlvt = xlv + (cpv-cliq)*(t-t0c) !vaporization/condensation xlst = xls + (cpv-cice)*(t-t0c) !sublimation/deposition -! chi = (273.16-t)/20.16 +! chi = (273.16-t)/(273.16-240.) chi = (t0c - t)/(t0c - tice) xl_blend = (1.-chi)*xlvt + chi*xlst !blended END IF @@ -7601,12 +7501,12 @@ FUNCTION phim(zet) ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE - REAL, INTENT(IN):: zet - REAL :: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi - REAL, PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st - REAL, PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st - REAL, PARAMETER :: am_unst=10., ah_unst=34. - REAL :: phi_m,phim + real(kind_phys), INTENT(IN):: zet + real(kind_phys):: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi + real(kind_phys), PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st + real(kind_phys), PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st + real(kind_phys), PARAMETER :: am_unst=10., ah_unst=34. + real(kind_phys):: phi_m,phim if ( zet >= 0.0 ) then dummy_0=1+zet**bm_st @@ -7653,12 +7553,12 @@ FUNCTION phih(zet) ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE - REAL, INTENT(IN):: zet - REAL :: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi - REAL, PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st - REAL, PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st - REAL, PARAMETER :: am_unst=10., ah_unst=34. - REAL :: phh,phih + real(kind_phys), INTENT(IN):: zet + real(kind_phys):: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi + real(kind_phys), PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st + real(kind_phys), PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st + real(kind_phys), PARAMETER :: am_unst=10., ah_unst=34. + real(kind_phys):: phh,phih if ( zet >= 0.0 ) then dummy_0=1+zet**bh_st @@ -7698,23 +7598,23 @@ SUBROUTINE topdown_cloudrad(kts,kte,dz1,zw,xland,kpbl,PBLH, & &maxKHtopdown,KHtopdown,TKEprodTD ) !input - integer, intent(in) :: kte,kts - real, dimension(kts:kte), intent(in) :: dz1,sqc,sqi,sqw,& + integer, intent(in) :: kte,kts + real(kind_phys), dimension(kts:kte), intent(in) :: dz1,sqc,sqi,sqw,& thl,th1,ex1,p1,rho1,thetav,cldfra_bl1D - real(kind=kind_phys), dimension(kts:kte), intent(in) :: rthraten - real, dimension(kts:kte+1), intent(in) :: zw - real(kind=kind_phys), intent(in) :: pblh - real, intent(in) :: xland - integer,intent(in) :: kpbl + real(kind_phys), dimension(kts:kte), intent(in) :: rthraten + real(kind_phys), dimension(kts:kte+1), intent(in) :: zw + real(kind_phys), intent(in) :: pblh + real(kind_phys), intent(in) :: xland + integer , intent(in) :: kpbl !output - real, intent(out) :: maxKHtopdown - real, dimension(kts:kte), intent(out) :: KHtopdown,TKEprodTD + real(kind_phys), intent(out) :: maxKHtopdown + real(kind_phys), dimension(kts:kte), intent(out) :: KHtopdown,TKEprodTD !local - real, dimension(kts:kte) :: zfac,wscalek2,zfacent - real :: bfx0,sflux,wm2,wm3,h1,h2,bfxpbl,dthvx,tmp1 - real :: temps,templ,zl1,wstar3_2 - real :: ent_eff,radsum,radflux,we,rcldb,rvls,minrad,zminrad - real, parameter :: pfac =2.0, zfmin = 0.01, phifac=8.0 + real(kind_phys), dimension(kts:kte) :: zfac,wscalek2,zfacent + real(kind_phys) :: bfx0,sflux,wm2,wm3,h1,h2,bfxpbl,dthvx,tmp1 + real(kind_phys) :: temps,templ,zl1,wstar3_2 + real(kind_phys) :: ent_eff,radsum,radflux,we,rcldb,rvls,minrad,zminrad + real(kind_phys), parameter :: pfac =2.0, zfmin = 0.01, phifac=8.0 integer :: k,kk,kminrad logical :: cloudflg diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 8ac6378bd..74cf8fa30 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -2,7 +2,6 @@ !! This file contains all of the code related to running the MYNN !! eddy-diffusivity mass-flux scheme. -!>\ingroup gsd_mynn_edmf !> The following references best describe the code within !! Olson et al. (2019, NOAA Technical Memorandum) !! Nakanishi and Niino (2009) \cite NAKANISHI_2009 @@ -18,33 +17,32 @@ subroutine mynnedmf_wrapper_init ( & & con_cpv, con_cliq, con_cice, con_rcp, & & con_XLV, con_XLF, con_p608, con_ep2, & & con_karman, con_t0c, & - & do_mynnedmf, lheatstrg, & + & do_mynnedmf, & & errmsg, errflg ) use machine, only : kind_phys use bl_mynn_common implicit none - - logical, intent(in) :: do_mynnedmf - logical, intent(in) :: lheatstrg - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - real(kind=kind_phys),intent(in) :: con_xlv - real(kind=kind_phys),intent(in) :: con_xlf - real(kind=kind_phys),intent(in) :: con_rv - real(kind=kind_phys),intent(in) :: con_rd - real(kind=kind_phys),intent(in) :: con_ep2 - real(kind=kind_phys),intent(in) :: con_grav - real(kind=kind_phys),intent(in) :: con_cp - real(kind=kind_phys),intent(in) :: con_cpv - real(kind=kind_phys),intent(in) :: con_rcp - real(kind=kind_phys),intent(in) :: con_p608 - real(kind=kind_phys),intent(in) :: con_cliq - real(kind=kind_phys),intent(in) :: con_cice - real(kind=kind_phys),intent(in) :: con_karman - real(kind=kind_phys),intent(in) :: con_t0c + + logical, intent(in) :: do_mynnedmf + character(len=*),intent(out):: errmsg + integer, intent(out) :: errflg + + real(kind_phys),intent(in) :: con_xlv + real(kind_phys),intent(in) :: con_xlf + real(kind_phys),intent(in) :: con_rv + real(kind_phys),intent(in) :: con_rd + real(kind_phys),intent(in) :: con_ep2 + real(kind_phys),intent(in) :: con_grav + real(kind_phys),intent(in) :: con_cp + real(kind_phys),intent(in) :: con_cpv + real(kind_phys),intent(in) :: con_rcp + real(kind_phys),intent(in) :: con_p608 + real(kind_phys),intent(in) :: con_cliq + real(kind_phys),intent(in) :: con_cice + real(kind_phys),intent(in) :: con_karman + real(kind_phys),intent(in) :: con_t0c ! Initialize CCPP error handling variables errmsg = '' @@ -85,10 +83,8 @@ subroutine mynnedmf_wrapper_init ( & end subroutine mynnedmf_wrapper_init - subroutine mynnedmf_wrapper_finalize () - end subroutine mynnedmf_wrapper_finalize - -! \brief This scheme (1) performs pre-mynnedmf work, (2) runs the mynnedmf, and (3) performs post-mynnedmf work +!>\defgroup gp_mynnedmf MYNN-EDMF PBL and Shallow Convection Module +!> This scheme (1) performs pre-mynnedmf work, (2) runs the mynnedmf, and (3) performs post-mynnedmf work !> \section arg_table_mynnedmf_wrapper_run Argument Table !! \htmlinclude mynnedmf_wrapper_run.html !! @@ -101,14 +97,15 @@ SUBROUTINE mynnedmf_wrapper_run( & & phii,u,v,omega,t3d, & & qgrs_water_vapor, & & qgrs_liquid_cloud, & - & qgrs_ice_cloud, & + & qgrs_ice, & + & qgrs_snow, & & qgrs_cloud_droplet_num_conc, & & qgrs_cloud_ice_num_conc, & & qgrs_ozone, & & qgrs_water_aer_num_conc, & & qgrs_ice_aer_num_conc, & & qgrs_cccn, & - & prsl,exner, & + & prsl,prsi,exner, & & slmsk,tsurf,qsfc,ps, & & ust,ch,hflx,qflx,wspd,rb, & & dtsfc1,dqsfc1, & @@ -137,16 +134,18 @@ SUBROUTINE mynnedmf_wrapper_run( & & nupdraft,maxMF,ktop_plume, & & dudt, dvdt, dtdt, & & dqdt_water_vapor, dqdt_liquid_cloud, & ! <=== ntqv, ntcw - & dqdt_ice_cloud, dqdt_ozone, & ! <=== ntiw, ntoz + & dqdt_ice, dqdt_snow, & ! <=== ntiw, ntsw + & dqdt_ozone, & ! <=== ntoz & dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc, & ! <=== ntlnc, ntinc & dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc,& ! <=== ntwa, ntia & dqdt_cccn, & ! <=== ntccn & flag_for_pbl_generic_tend, & & dtend, dtidx, index_of_temperature, & & index_of_x_wind, index_of_y_wind, ntke, & - & ntqv, ntcw, ntiw, ntoz, ntlnc, ntinc, ntwa, ntia, & + & ntqv, ntcw, ntiw, ntsw, & + & ntoz, ntlnc, ntinc, ntwa, ntia, & & index_of_process_pbl, htrsw, htrlw, xmu, & - & bl_mynn_tkebudget, bl_mynn_tkeadvect, & + & tke_budget, bl_mynn_tkeadvect, & & bl_mynn_cloudpdf, bl_mynn_mixlength, & & bl_mynn_edmf, & & bl_mynn_edmf_mom, bl_mynn_edmf_tke, & @@ -155,10 +154,12 @@ SUBROUTINE mynnedmf_wrapper_run( & & icloud_bl, do_mynnsfclay, & & imp_physics, imp_physics_gfdl, & & imp_physics_thompson, imp_physics_wsm6, & - & rrfs_sd, chem3d, frp, mix_chem, enh_mix, & + & imp_physics_fa, & + & chem3d, frp, mix_chem, rrfs_sd, enh_mix, & & nchem, ndvel, vdep, smoke_dbg, & & imp_physics_nssl, nssl_ccn_on, & - & ltaerosol, spp_wts_pbl, spp_pbl, lprnt, huge, errmsg, errflg ) + & ltaerosol, mraerosol, spp_wts_pbl, spp_pbl, & + & lprnt, huge, errmsg, errflg ) ! should be moved to inside the mynn: use machine, only: kind_phys @@ -170,7 +171,7 @@ SUBROUTINE mynnedmf_wrapper_run( & implicit none !------------------------------------------------------------------- - real(kind=kind_phys) :: huge + real(kind_phys) :: huge character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -185,8 +186,8 @@ SUBROUTINE mynnedmf_wrapper_run( & ! NAMELIST OPTIONS (INPUT): logical, intent(in) :: & & bl_mynn_tkeadvect, & - & bl_mynn_tkebudget, & & ltaerosol, & + & mraerosol, & & lprnt, & & do_mynnsfclay, & & flag_for_pbl_generic_tend, & @@ -203,100 +204,100 @@ SUBROUTINE mynnedmf_wrapper_run( & & bl_mynn_output, & & imp_physics, imp_physics_wsm6, & & imp_physics_thompson, imp_physics_gfdl, & - & imp_physics_nssl, & - & spp_pbl - real(kind=kind_phys), intent(in) :: & + & imp_physics_nssl, imp_physics_fa, & + & spp_pbl, & + & tke_budget + real(kind_phys), intent(in) :: & & bl_mynn_closure !TENDENCY DIAGNOSTICS - real(kind=kind_phys), intent(inout), optional :: dtend(:,:,:) + real(kind_phys), intent(inout), optional :: dtend(:,:,:) integer, intent(in) :: dtidx(:,:) integer, intent(in) :: index_of_temperature, index_of_x_wind integer, intent(in) :: index_of_y_wind, index_of_process_pbl - integer, intent(in) :: ntoz, ntqv, ntcw, ntiw, ntlnc + integer, intent(in) :: ntoz, ntqv, ntcw, ntiw, ntsw, ntlnc integer, intent(in) :: ntinc, ntwa, ntia, ntke !MISC CONFIGURATION OPTIONS - INTEGER, PARAMETER :: & + INTEGER, PARAMETER :: & & bl_mynn_mixscalars=1 - LOGICAL :: & - & FLAG_QI, FLAG_QNI, FLAG_QC, FLAG_QNC, & - & FLAG_QNWFA, FLAG_QNIFA, FLAG_OZONE + LOGICAL :: & + & FLAG_QI, FLAG_QNI, FLAG_QC, FLAG_QS, FLAG_QNC, & + & FLAG_QNWFA, FLAG_QNIFA, FLAG_QNBCA, FLAG_OZONE ! Define locally until needed from CCPP LOGICAL, PARAMETER :: cycling = .false. - INTEGER, PARAMETER :: param_first_scalar = 1 - INTEGER :: & - & p_qc, p_qr, p_qi, p_qs, p_qg, p_qnc, p_qni !MYNN-1D - REAL(kind=kind_phys), intent(in) :: delt, dtf + REAL(kind_phys), intent(in) :: delt, dtf INTEGER, intent(in) :: im, levs LOGICAL, intent(in) :: flag_init, flag_restart INTEGER :: initflag, k, i - INTEGER :: IDS,IDE,JDS,JDE,KDS,KDE, & - & IMS,IME,JMS,JME,KMS,KME, & + INTEGER :: IDS,IDE,JDS,JDE,KDS,KDE, & + & IMS,IME,JMS,JME,KMS,KME, & & ITS,ITE,JTS,JTE,KTS,KTE - REAL(kind=kind_phys) :: tem + REAL(kind_phys) :: tem !MYNN-3D - real(kind=kind_phys), dimension(:,:), intent(in) :: phii - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(in) :: phii + real(kind_phys), dimension(:,:), intent(inout) :: & & dtdt, dudt, dvdt, & - & dqdt_water_vapor, dqdt_liquid_cloud, dqdt_ice_cloud, & + & dqdt_water_vapor, dqdt_liquid_cloud, dqdt_ice, & + & dqdt_snow, & & dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc, & & dqdt_ozone, dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc - real(kind=kind_phys), dimension(:,:), intent(inout) ::dqdt_cccn - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) ::dqdt_cccn + real(kind_phys), dimension(:,:), intent(inout) :: & & qke, qke_adv, EL_PBL, Sh3D, Sm3D, & & qc_bl, qi_bl, cldfra_bl !These 10 arrays are only allocated when bl_mynn_output > 0 - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & & edmf_a,edmf_w,edmf_qt, & & edmf_thl,edmf_ent,edmf_qc, & & sub_thl,sub_sqv,det_thl,det_sqv - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & & dqke,qWT,qSHEAR,qBUOY,qDISS - real(kind=kind_phys), dimension(:,:), intent(inout) :: & - & t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice_cloud - real(kind=kind_phys), dimension(:,:), intent(in) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & + & t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice, & + & qgrs_snow + real(kind_phys), dimension(:,:), intent(in) :: & & u,v,omega, & - & exner,prsl, & + & exner,prsl,prsi, & & qgrs_cloud_droplet_num_conc, & & qgrs_cloud_ice_num_conc, & & qgrs_ozone, & & qgrs_water_aer_num_conc, & & qgrs_ice_aer_num_conc - real(kind=kind_phys), dimension(:,:), intent(in) ::qgrs_cccn - real(kind=kind_phys), dimension(:,:), intent(out) :: & + real(kind_phys), dimension(:,:), intent(in) ::qgrs_cccn + real(kind_phys), dimension(:,:), intent(out) :: & & Tsq, Qsq, Cov, exch_h, exch_m - real(kind=kind_phys), dimension(:), intent(in) :: xmu - real(kind=kind_phys), dimension(:,:), intent(in) :: htrsw, htrlw + real(kind_phys), dimension(:), intent(in) :: xmu + real(kind_phys), dimension(:,:), intent(in) :: htrsw, htrlw ! spp_wts_pbl only allocated if spp_pbl == 1 - real(kind=kind_phys), dimension(:,:), intent(in) :: spp_wts_pbl + real(kind_phys), dimension(:,:), intent(in) :: spp_wts_pbl !LOCAL - real(kind=kind_phys), dimension(im,levs) :: & - & sqv,sqc,sqi,qnc,qni,ozone,qnwfa,qnifa, & + real(kind_phys), dimension(im,levs) :: & + & sqv,sqc,sqi,sqs,qnc,qni,ozone,qnwfa,qnifa,qnbca, & & dz, w, p, rho, th, qv, delp, & & RUBLTEN, RVBLTEN, RTHBLTEN, RQVBLTEN, & - & RQCBLTEN, RQNCBLTEN, RQIBLTEN, RQNIBLTEN, & - & RQNWFABLTEN, RQNIFABLTEN - real(kind=kind_phys), allocatable :: old_ozone(:,:) + & RQCBLTEN, RQNCBLTEN, RQIBLTEN, RQNIBLTEN, RQSBLTEN, & + & RQNWFABLTEN, RQNIFABLTEN, RQNBCABLTEN + real(kind_phys), allocatable :: old_ozone(:,:) !smoke/chem arrays - real(kind=kind_phys), dimension(:), intent(inout) :: frp + real(kind_phys), dimension(:), intent(inout) :: frp logical, intent(in) :: mix_chem, enh_mix, rrfs_sd - real(kind=kind_phys), dimension(:,:,:), intent(inout) :: chem3d - real(kind=kind_phys), dimension(:,: ), intent(inout) :: vdep - real(kind=kind_phys), dimension(im) :: emis_ant_no + real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d + real(kind_phys), dimension(:,: ), intent(inout) :: vdep + real(kind_phys), dimension(im) :: emis_ant_no !MYNN-2D - real(kind=kind_phys), dimension(:), intent(in) :: & + real(kind_phys), dimension(:), intent(in) :: & & dx,zorl,slmsk,tsurf,qsfc,ps, & & hflx,qflx,ust,wspd,rb,recmol - real(kind=kind_phys), dimension(:), intent(in) :: & + real(kind_phys), dimension(:), intent(in) :: & & dusfc_cice,dvsfc_cice,dtsfc_cice,dqsfc_cice, & & stress_wat,hflx_wat,qflx_wat, & & oceanfrac,fice @@ -304,26 +305,26 @@ SUBROUTINE mynnedmf_wrapper_run( & logical, dimension(:), intent(in) :: & & wet, dry, icy - real(kind=kind_phys), dimension(:), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & & pblh,dusfc_diag,dvsfc_diag,dtsfc_diag,dqsfc_diag - real(kind=kind_phys), dimension(:), intent(out) :: & + real(kind_phys), dimension(:), intent(out) :: & & ch,dtsfc1,dqsfc1,dusfc1,dvsfc1, & & dtsfci_diag,dqsfci_diag,dusfci_diag,dvsfci_diag, & & maxMF integer, dimension(:), intent(inout) :: & & kpbl,nupdraft,ktop_plume - real(kind=kind_phys), dimension(:), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & & dusfc_cpl,dvsfc_cpl,dtsfc_cpl,dqsfc_cpl - real(kind=kind_phys), dimension(:), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & & dusfci_cpl,dvsfci_cpl,dtsfci_cpl,dqsfci_cpl !LOCAL - real, dimension(im) :: & - & hfx,qfx,rmol,xland,uoce,voce,vdfg,znt,ts + real(kind_phys), dimension(im) :: & + & hfx,qfx,rmol,xland,uoce,voce,znt,ts integer :: idtend - real, dimension(im) :: dusfci1,dvsfci1,dtsfci1,dqsfci1 - real(kind=kind_phys), allocatable :: save_qke_adv(:,:) + real(kind_phys), dimension(im) :: dusfci1,dvsfci1,dtsfci1,dqsfci1 + real(kind_phys), allocatable :: save_qke_adv(:,:) ! Initialize CCPP error handling variables errmsg = '' @@ -356,62 +357,33 @@ SUBROUTINE mynnedmf_wrapper_run( & !initialize arrays for test EMIS_ANT_NO = 0. - - ! Check incoming moist species to ensure non-negative values - ! First, create height (dz) and pressure differences (delp) - ! across model layers - do k=1,levs - do i=1,im - dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv - enddo - enddo - - do i=1,im - delp(i,1) = ps(i) - (prsl(i,2)*dz(i,1) + prsl(i,1)*dz(i,2))/(dz(i,1)+dz(i,2)) - do k=2,levs-1 - delp(i,k) = (prsl(i,k)*dz(i,k-1) + prsl(i,k-1)*dz(i,k))/(dz(i,k)+dz(i,k-1)) - & - (prsl(i,k+1)*dz(i,k) + prsl(i,k)*dz(i,k+1))/(dz(i,k)+dz(i,k+1)) - enddo - delp(i,levs) = delp(i,levs-1) - enddo - - do i=1,im - call moisture_check2(levs, delt, & - delp(i,:), exner(i,:), & - qgrs_water_vapor(i,:), & - qgrs_liquid_cloud(i,:),& - qgrs_ice_cloud(i,:), & - t3d(i,:) ) - enddo + vdep = 0. FLAG_OZONE = ntoz>0 ! Assign variables for each microphysics scheme - if (imp_physics == imp_physics_wsm6) then - ! WSM6 + if (imp_physics == imp_physics_wsm6 .or. imp_physics == imp_physics_fa) then + ! WSM6 or Ferrier-Aligo FLAG_QI = .true. FLAG_QNI= .false. FLAG_QC = .true. FLAG_QNC= .false. + FLAG_QS = .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = 0. qni(i,k) = 0. qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo elseif (imp_physics == imp_physics_nssl ) then @@ -420,21 +392,16 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .true. FLAG_QC = .true. FLAG_QNC= .true. + FLAG_QS = .false. FLAG_QNWFA= nssl_ccn_on ! ERM: Perhaps could use this field for CCN field? FLAG_QNIFA= .false. - ! p_q vars not used? - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) @@ -443,6 +410,7 @@ SUBROUTINE mynnedmf_wrapper_run( & qnwfa(i,k) = qgrs_cccn(i,k) ENDIF qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo elseif (imp_physics == imp_physics_thompson) then @@ -451,52 +419,69 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QI = .true. FLAG_QNI= .true. FLAG_QC = .true. + FLAG_QS = .true. FLAG_QNC= .true. FLAG_QNWFA= .true. FLAG_QNIFA= .true. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) qnwfa(i,k) = qgrs_water_aer_num_conc(i,k) qnifa(i,k) = qgrs_ice_aer_num_conc(i,k) + qnbca(i,k) = 0. + enddo + enddo + else if(mraerosol) then + FLAG_QI = .true. + FLAG_QNI= .true. + FLAG_QC = .true. + FLAG_QS = .true. + FLAG_QNC= .true. + FLAG_QNWFA= .false. + FLAG_QNIFA= .false. + FLAG_QNBCA= .false. + do k=1,levs + do i=1,im + sqv(i,k) = qgrs_water_vapor(i,k) + sqc(i,k) = qgrs_liquid_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) + qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) + qni(i,k) = qgrs_cloud_ice_num_conc(i,k) + ozone(i,k) = qgrs_ozone(i,k) + qnwfa(i,k) = 0. + qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo else FLAG_QI = .true. FLAG_QNI= .true. FLAG_QC = .true. + FLAG_QS = .true. FLAG_QNC= .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) qnc(i,k) = 0. qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo endif @@ -506,24 +491,21 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .false. FLAG_QC = .true. FLAG_QNC= .false. + FLAG_QS = .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) qnc(i,k) = 0. qni(i,k) = 0. + sqs(i,k) = 0. qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) enddo enddo @@ -534,24 +516,21 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .false. FLAG_QC = .true. FLAG_QNC= .false. + FLAG_QS = .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 0 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) sqi(i,k) = 0. + sqs(i,k) = 0. qnc(i,k) = 0. qni(i,k) = 0. qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) enddo enddo @@ -560,17 +539,38 @@ SUBROUTINE mynnedmf_wrapper_run( & allocate(old_ozone(im,levs)) old_ozone = ozone endif - if (lprnt)write(0,*)"prepping MYNN-EDMF variables..." do k=1,levs do i=1,im - ! dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv th(i,k)=t3d(i,k)/exner(i,k) rho(i,k)=prsl(i,k)/(r_d*t3d(i,k)*(1.+p608*max(sqv(i,k),1e-8))) w(i,k) = -omega(i,k)/(rho(i,k)*grav) + enddo + enddo + + ! Check incoming moist species to ensure non-negative values + ! First, create height difference (dz) + do k=1,levs + do i=1,im + dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv enddo enddo + do i=1,im + do k=1,levs + delp(i,k) = prsi(i,k) - prsi(i,k+1) + enddo + enddo + + do i=1,im + call moisture_check2(levs, delt, & + delp(i,:), exner(i,:), & + sqv(i,:), sqc(i,:), & + sqi(i,:), sqs(i,:), & + t3d(i,:) ) + enddo + + !intialize more variables do i=1,im if (slmsk(i)==1. .or. slmsk(i)==2.) then !sea/land/ice mask (=0/1/2) in FV3 xland(i)=1.0 !but land/water = (1/2) in SFCLAY_mynn @@ -579,7 +579,6 @@ SUBROUTINE mynnedmf_wrapper_run( & endif uoce(i)=0.0 voce(i)=0.0 - vdfg(i)=0.0 !ust(i) = sqrt(stress(i)) ch(i)=0.0 hfx(i)=hflx(i)*rho(i,1)*cp @@ -663,7 +662,7 @@ SUBROUTINE mynnedmf_wrapper_run( & if (lprnt) then print* write(0,*)"===CALLING mynn_bl_driver; input:" - print*,"bl_mynn_tkebudget=",bl_mynn_tkebudget," bl_mynn_tkeadvect=",bl_mynn_tkeadvect + print*,"tke_budget=",tke_budget," bl_mynn_tkeadvect=",bl_mynn_tkeadvect print*,"bl_mynn_cloudpdf=",bl_mynn_cloudpdf," bl_mynn_mixlength=",bl_mynn_mixlength print*,"bl_mynn_edmf=",bl_mynn_edmf," bl_mynn_edmf_mom=",bl_mynn_edmf_mom print*,"bl_mynn_edmf_tke=",bl_mynn_edmf_tke @@ -689,7 +688,7 @@ SUBROUTINE mynnedmf_wrapper_run( & print*,"znt:",znt(1)," delt=",delt print*,"im=",im," levs=",levs print*,"PBLH=",pblh(1)," KPBL=",KPBL(1)," xland=",xland(1) - print*,"vdfg=",vdfg(1)," ch=",ch(1) + print*,"ch=",ch(1) !print*,"TKE:",TKE_PBL(1,1),TKE_PBL(1,2),TKE_PBL(1,levs) print*,"qke:",qke(1,1),qke(1,2),qke(1,levs) print*,"el_pbl:",el_pbl(1,1),el_pbl(1,2),el_pbl(1,levs) @@ -705,12 +704,12 @@ SUBROUTINE mynnedmf_wrapper_run( & & cycling=cycling, & & delt=delt,dz=dz,dx=dx,znt=znt, & & u=u,v=v,w=w,th=th,sqv3D=sqv,sqc3D=sqc, & - & sqi3D=sqi,qnc=qnc,qni=qni, & - & qnwfa=qnwfa,qnifa=qnifa,ozone=ozone, & + & sqi3D=sqi,sqs3D=sqs,qnc=qnc,qni=qni, & + & qnwfa=qnwfa,qnifa=qnifa,qnbca=qnbca,ozone=ozone, & & p=prsl,exner=exner,rho=rho,T3D=t3d, & & xland=xland,ts=ts,qsfc=qsfc,ps=ps, & & ust=ust,ch=ch,hfx=hfx,qfx=qfx,rmol=rmol, & - & wspd=wspd,uoce=uoce,voce=voce,vdfg=vdfg, & !input + & wspd=wspd,uoce=uoce,voce=voce, & !input & qke=QKE,qke_adv=qke_adv, & !output & sh3d=Sh3d,sm3d=Sm3d, & !chem/smoke @@ -724,15 +723,17 @@ SUBROUTINE mynnedmf_wrapper_run( & & RUBLTEN=RUBLTEN,RVBLTEN=RVBLTEN,RTHBLTEN=RTHBLTEN, & !output & RQVBLTEN=RQVBLTEN,RQCBLTEN=rqcblten, & & RQIBLTEN=rqiblten,RQNCBLTEN=rqncblten, & !output + & RQSBLTEN=rqsblten, & !output & RQNIBLTEN=rqniblten,RQNWFABLTEN=RQNWFABLTEN, & !output - & RQNIFABLTEN=RQNIFABLTEN,dozone=dqdt_ozone, & !output + & RQNIFABLTEN=RQNIFABLTEN,RQNBCABLTEN=RQNBCABLTEN, & !output + & dozone=dqdt_ozone, & !output & EXCH_H=exch_h,EXCH_M=exch_m, & !output & pblh=pblh,KPBL=KPBL, & !output & el_pbl=el_pbl, & !output & dqke=dqke, & !output & qWT=qWT,qSHEAR=qSHEAR,qBUOY=qBUOY,qDISS=qDISS, & !output & bl_mynn_tkeadvect=bl_mynn_tkeadvect, & - & bl_mynn_tkebudget=bl_mynn_tkebudget, & !input parameter + & tke_budget=tke_budget, & !input parameter & bl_mynn_cloudpdf=bl_mynn_cloudpdf, & !input parameter & bl_mynn_mixlength=bl_mynn_mixlength, & !input parameter & icloud_bl=icloud_bl, & !input parameter @@ -745,7 +746,7 @@ SUBROUTINE mynnedmf_wrapper_run( & & bl_mynn_cloudmix=bl_mynn_cloudmix, & !input parameter & bl_mynn_mixqt=bl_mynn_mixqt, & !input parameter & edmf_a=edmf_a,edmf_w=edmf_w,edmf_qt=edmf_qt, & !output - & edmf_thl=edmf_thl,edmf_ent=edmf_ent,edmf_qc=edmf_qc,&!output + & edmf_thl=edmf_thl,edmf_ent=edmf_ent,edmf_qc=edmf_qc,& !output & sub_thl3D=sub_thl,sub_sqv3D=sub_sqv, & & det_thl3D=det_thl,det_sqv3D=det_sqv, & & nupdraft=nupdraft,maxMF=maxMF, & !output @@ -753,12 +754,12 @@ SUBROUTINE mynnedmf_wrapper_run( & & spp_pbl=spp_pbl,pattern_spp_pbl=spp_wts_pbl, & !input & RTHRATEN=htrlw, & !input & FLAG_QI=flag_qi,FLAG_QNI=flag_qni, & !input - & FLAG_QC=flag_qc,FLAG_QNC=flag_qnc, & !input + & FLAG_QC=flag_qc,FLAG_QNC=flag_qnc,FLAG_QS=flag_qs, & !input & FLAG_QNWFA=FLAG_QNWFA,FLAG_QNIFA=FLAG_QNIFA, & !input - & FLAG_OZONE=FLAG_OZONE, & !input + & FLAG_QNBCA=FLAG_QNBCA,FLAG_OZONE=FLAG_OZONE, & !input & IDS=1,IDE=im,JDS=1,JDE=1,KDS=1,KDE=levs, & !input & IMS=1,IME=im,JMS=1,JME=1,KMS=1,KME=levs, & !input - & ITS=1,ITE=im,JTS=1,JTE=1,KTS=1,KTE=levs) !input + & ITS=1,ITE=im,JTS=1,JTE=1,KTS=1,KTE=levs ) !input ! POST MYNN (INTERSTITIAL) WORK: @@ -799,13 +800,14 @@ SUBROUTINE mynnedmf_wrapper_run( & !enddo !DO moist/scalar/tracer tendencies: - if (imp_physics == imp_physics_wsm6) then + if (imp_physics == imp_physics_wsm6 .or. imp_physics == imp_physics_fa) then ! WSM6 do k=1,levs do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 enddo enddo @@ -819,7 +821,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 ! enddo !enddo @@ -831,8 +833,9 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 dqdt_water_aer_num_conc(i,k) = RQNWFABLTEN(i,k) dqdt_ice_aer_num_conc(i,k) = RQNIFABLTEN(i,k) @@ -851,7 +854,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! qgrs_cloud_droplet_num_conc(i,k) = qgrs_cloud_droplet_num_conc(i,k) + RQNCBLTEN(i,k)*delt ! qgrs_cloud_ice_num_conc(i,k) = qgrs_cloud_ice_num_conc(i,k) + RQNIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 @@ -859,14 +862,33 @@ SUBROUTINE mynnedmf_wrapper_run( & ! !qgrs_ice_aer_num_conc(i,k) = qgrs_ice_aer_num_conc(i,k) + RQNIFABLTEN(i,k)*delt ! enddo !enddo + else if(mraerosol) then + do k=1,levs + do i=1,im + dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) + enddo + enddo + if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then + call dtend_helper(100+ntqv,RQVBLTEN) + call dtend_helper(100+ntcw,RQCBLTEN) + call dtend_helper(100+ntlnc,RQNCBLTEN) + call dtend_helper(100+ntiw,RQIBLTEN) + call dtend_helper(100+ntinc,RQNIBLTEN) + endif else !Thompson (2008) do k=1,levs do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 enddo enddo @@ -875,12 +897,13 @@ SUBROUTINE mynnedmf_wrapper_run( & call dtend_helper(100+ntcw,RQCBLTEN) call dtend_helper(100+ntiw,RQIBLTEN) call dtend_helper(100+ntinc,RQNIBLTEN) + call dtend_helper(100+ntsw,RQSBLTEN) endif !do k=1,levs ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! qgrs_cloud_ice_num_conc(i,k) = qgrs_cloud_ice_num_conc(i,k) + RQNIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 ! enddo @@ -893,8 +916,9 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) IF ( nssl_ccn_on ) THEN ! dqdt_cccn(i,k) = RQNWFABLTEN(i,k) ENDIF @@ -907,7 +931,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_rain(i,k) = 0.0 !dqdt_snow(i,k) = 0.0 !dqdt_graupel(i,k) = 0.0 @@ -923,7 +947,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 ! enddo !enddo @@ -933,7 +957,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = 0.0 + dqdt_ice(i,k) = 0.0 !dqdt_rain(i,k) = 0.0 !dqdt_snow(i,k) = 0.0 !dqdt_graupel(i,k) = 0.0 @@ -970,8 +994,7 @@ SUBROUTINE mynnedmf_wrapper_run( & print*,"znt:",znt(1)," delt=",delt print*,"im=",im," levs=",levs print*,"PBLH=",pblh(1)," KPBL=",KPBL(1)," xland=",xland(1) - print*,"vdfg=",vdfg(1)," ch=",ch(1) - !print*,"TKE:",TKE_PBL(1,1),TKE_PBL(1,2),TKE_PBL(1,levs) + print*,"ch=",ch(1) print*,"qke:",qke(1,1),qke(1,2),qke(1,levs) print*,"el_pbl:",el_pbl(1,1),el_pbl(1,2),el_pbl(1,levs) print*,"Sh3d:",Sh3d(1,1),sh3d(1,2),sh3d(1,levs) @@ -1001,8 +1024,8 @@ SUBROUTINE mynnedmf_wrapper_run( & CONTAINS SUBROUTINE dtend_helper(itracer,field,mult) - real(kind=kind_phys), intent(in) :: field(im,levs) - real(kind=kind_phys), intent(in), optional :: mult(im,levs) + real(kind_phys), intent(in) :: field(im,levs) + real(kind_phys), intent(in), optional :: mult(im,levs) integer, intent(in) :: itracer integer :: idtend @@ -1018,7 +1041,7 @@ END SUBROUTINE dtend_helper ! ================================================================== SUBROUTINE moisture_check2(kte, delt, dp, exner, & - qv, qc, qi, th ) + qv, qc, qi, qs, th ) ! ! If qc < qcmin, qi < qimin, or qv < qvmin happens in any layer, ! force them to be larger than minimum value by (1) condensating @@ -1032,11 +1055,11 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & implicit none integer, intent(in) :: kte - real(kind=kind_phys), intent(in) :: delt - real(kind=kind_phys), dimension(kte), intent(in) :: dp, exner - real(kind=kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, th + real(kind_phys), intent(in) :: delt + real(kind_phys), dimension(kte), intent(in) :: dp, exner + real(kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, qs, th integer k - real :: dqc2, dqi2, dqv2, sum, aa, dum + real :: dqc2, dqi2, dqs2, dqv2, sum, aa, dum real, parameter :: qvmin1= 1e-8, & !min at k=1 qvmin = 1e-20, & !min above k=1 qcmin = 0.0, & @@ -1045,17 +1068,19 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & do k = kte, 1, -1 ! From the top to the surface dqc2 = max(0.0, qcmin-qc(k)) !qc deficit (>=0) dqi2 = max(0.0, qimin-qi(k)) !qi deficit (>=0) + dqs2 = max(0.0, qimin-qs(k)) !qs deficit (>=0) !update species qc(k) = qc(k) + dqc2 qi(k) = qi(k) + dqi2 - qv(k) = qv(k) - dqc2 - dqi2 + qs(k) = qs(k) + dqs2 + qv(k) = qv(k) - dqc2 - dqi2 - dqs2 !for theta !th(k) = th(k) + xlvcp/exner(k)*dqc2 + & ! xlscp/exner(k)*dqi2 !for temperature th(k) = th(k) + xlvcp*dqc2 + & - xlscp*dqi2 + xlscp*(dqi2+dqs2) !then fix qv if lending qv made it negative if (k .eq. 1) then @@ -1071,6 +1096,7 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & endif qc(k) = max(qc(k),qcmin) qi(k) = max(qi(k),qimin) + qs(k) = max(qs(k),qimin) end do ! Extra moisture used to satisfy 'qv(1)>=qvmin' is proportionally diff --git a/physics/mynnedmf_wrapper.meta b/physics/mynnedmf_wrapper.meta index 044162dbb..ec4706aba 100644 --- a/physics/mynnedmf_wrapper.meta +++ b/physics/mynnedmf_wrapper.meta @@ -125,13 +125,6 @@ dimensions = () type = logical intent = in -[lheatstrg] - standard_name = flag_for_canopy_heat_storage_in_land_surface_scheme - long_name = flag for canopy heat storage parameterization - units = flag - dimensions = () - type = logical - intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -303,7 +296,7 @@ type = real kind = kind_phys intent = inout -[qgrs_ice_cloud] +[qgrs_ice] standard_name = cloud_ice_mixing_ratio long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) units = kg kg-1 @@ -311,6 +304,14 @@ type = real kind = kind_phys intent = inout +[qgrs_snow] + standard_name = snow_mixing_ratio + long_name = ratio of mass of snow water to mass of dry air plus vapor (without condensates) + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [qgrs_cloud_droplet_num_conc] standard_name = mass_number_concentration_of_cloud_liquid_water_particles_in_air long_name = number concentration of cloud droplets (liquid) @@ -367,6 +368,14 @@ type = real kind = kind_phys intent = in +[prsi] + standard_name = air_pressure_at_interface + long_name = air pressure at model layer interfaces + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [exner] standard_name = dimensionless_exner_function long_name = Exner function at layers @@ -1017,7 +1026,7 @@ type = real kind = kind_phys intent = inout -[dqdt_ice_cloud] +[dqdt_ice] standard_name = process_split_cumulative_tendency_of_cloud_ice_mixing_ratio long_name = cloud condensed water mixing ratio tendency due to model physics units = kg kg-1 s-1 @@ -1025,6 +1034,14 @@ type = real kind = kind_phys intent = inout +[dqdt_snow] + standard_name = process_split_cumulative_tendency_of_snow_mixing_ratio + long_name = ratio of mass of snow water tendency to mass of dry air plus vapor (without condensates) due to model physics + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [dqdt_ozone] standard_name = process_split_cumulative_tendency_of_ozone_mixing_ratio long_name = ozone mixing ratio tendency due to model physics @@ -1151,6 +1168,13 @@ dimensions = () type = integer intent = in +[ntsw] + 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 [ntlnc] standard_name = index_of_mass_number_concentration_of_cloud_droplets_in_tracer_concentration_array long_name = tracer index for liquid number concentration @@ -1210,12 +1234,12 @@ type = real kind = kind_phys intent = in -[bl_mynn_tkebudget] +[tke_budget] standard_name = control_for_tke_budget_output long_name = flag for activating TKE budget units = flag dimensions = () - type = logical + type = integer intent = in [bl_mynn_tkeadvect] standard_name = flag_for_tke_advection @@ -1329,6 +1353,13 @@ dimensions = () type = integer intent = in +[imp_physics_fa] + standard_name = identifier_for_fer_hires_microphysics_scheme + long_name = choice of Ferrier-Aligo microphysics scheme + units = flag + dimensions = () + type = integer + intent = in [imp_physics_nssl] standard_name = identifier_for_nssl_microphysics_scheme long_name = choice of NSSL 2-moment microphysics scheme @@ -1416,6 +1447,13 @@ dimensions = () type = logical intent = in +[mraerosol] + standard_name = do_merra2_aerosol_awareness + long_name = flag for merra2 aerosol-aware physics for example the thompson microphysics + units = flag + dimensions = () + type = logical + intent = in [spp_wts_pbl] standard_name = spp_weights_for_pbl_scheme long_name = spp weights for pbl scheme diff --git a/physics/sgscloud_radpre.F90 b/physics/sgscloud_radpre.F90 index ae0f39dde..05ca1af2a 100644 --- a/physics/sgscloud_radpre.F90 +++ b/physics/sgscloud_radpre.F90 @@ -35,7 +35,7 @@ module sgscloud_radpre !! !>\section sgscloud_radpre_mod SGS Cloud Scheme Pre General Algorithm subroutine sgscloud_radpre_run( & - im,dt,levs, & + im,dt,fhswr,levs, & flag_init,flag_restart, & con_g, con_pi, eps, epsm1, & r_v, cpv, rcp, & @@ -43,8 +43,9 @@ subroutine sgscloud_radpre_run( & do_mynnedmf, & qc, qi, qv, T3D, P3D, exner, & qr, qs, qg, & - qci_conv,ud_mf, & + qci_conv,qlc,qli,ud_mf, & imfdeepcnv, imfdeepcnv_gf, & + imfdeepcnv_sas, & qc_save, qi_save, qs_save, & qc_bl,qi_bl,cldfra_bl, & delp,clouds1,clouds2,clouds3, & @@ -53,6 +54,7 @@ subroutine sgscloud_radpre_run( & nlay, plyr, xlat, dz,de_lgth, & cldsa,mtopa,mbota, & imp_physics, imp_physics_gfdl,& + imp_physics_fa, & iovr, & errmsg, errflg ) @@ -67,17 +69,18 @@ subroutine sgscloud_radpre_run( & real(kind=kind_phys), intent(in) :: con_g, con_pi, eps, epsm1 real(kind=kind_phys), intent(in) :: r_v, cpv, rcp real(kind=kind_phys), intent(in) :: xlv, xlf, cp - real(kind=kind_phys), intent(in) :: dt + real(kind=kind_phys), intent(in) :: dt,fhswr real :: xls, xlvcp, xlscp !derived below real(kind=kind_phys) :: gfac integer, intent(in) :: im, levs, imfdeepcnv, imfdeepcnv_gf, & - & nlay, imp_physics, imp_physics_gfdl + & nlay, imfdeepcnv_sas, imp_physics, imp_physics_gfdl, imp_physics_fa logical, intent(in) :: flag_init, flag_restart, do_mynnedmf real(kind=kind_phys), dimension(:,:), intent(inout) :: qc, qi real(kind=kind_phys), dimension(:,:), intent(inout) :: qr, qs, qg - ! qci_conv only allocated if GF is used + ! note: qci_conv only allocated if GF is used real(kind=kind_phys), dimension(:,:), intent(inout) :: qci_conv + real(kind=kind_phys), dimension(:,:), intent(inout) :: qlc, qli !for SAS real(kind=kind_phys), dimension(:,:), intent(in) :: ud_mf real(kind=kind_phys), dimension(:,:), intent(in) :: T3D,delp real(kind=kind_phys), dimension(:,:), intent(in) :: qv,P3D,exner @@ -112,7 +115,8 @@ subroutine sgscloud_radpre_run( & real :: rhgrid,h2oliq,qsat,tem1,tem2,clwt,es,onemrh,value !Chaboureau and Bechtold (2002 and 2005) - real :: a, f, sigq, qmq, qt, xl, tlk, th, thl, rsl, cpm, cb_cf + real :: a, f, sigq, qmq, qt, xl, th, thl, rsl, cpm, cb_cf + real(kind=kind_phys) :: tlk !Option to convective cloud fraction integer, parameter :: conv_cf_opt = 0 !0: C-B, 1: X-R @@ -188,7 +192,7 @@ subroutine sgscloud_radpre_run( & !endif if (qc(i,k) < 1.e-6 .and. cldfra_bl(i,k)>0.001) then - qc(i,k) = qc_bl(i,k)*cldfra_bl(i,k) + qc(i,k) = qc_bl(i,k) !eff radius cloud water (microns) from Miles et al. (2007) if (nint(slmsk(i)) == 1) then !land @@ -206,8 +210,8 @@ subroutine sgscloud_radpre_run( & !~700 mb and decrease snow to zero by ~300 mb snow_frac = min(0.5, max((p3d(i,k)-30000.0),0.0)/140000.0) ice_frac = 1.0 - snow_frac - if (qi(i,k) < 1.e-8 .and. cldfra_bl(i,k)>0.001) then - qi(i,k) = ice_frac*qi_bl(i,k)*cldfra_bl(i,k) + if (qi(i,k) < 1.e-9 .and. cldfra_bl(i,k)>0.001) then + qi(i,k) = ice_frac*qi_bl(i,k) !eff radius cloud ice (microns), from Mishra et al. (2014, JGR Atmos, fig 6b) if(qi(i,k)>1.E-8)clouds5(i,k)=max(173.45 + 2.14*Tc, 20.) @@ -219,8 +223,8 @@ subroutine sgscloud_radpre_run( & clouds4(i,k) = max(0.0, qi(i,k) * gfac * delp(i,k)) endif - if (qs(i,k) < 1.e-8 .and. cldfra_bl(i,k)>0.001) then - qs(i,k) = snow_frac*qi_bl(i,k)*cldfra_bl(i,k) + if (qs(i,k) < 1.e-9 .and. cldfra_bl(i,k)>0.001) then + qs(i,k) = snow_frac*qi_bl(i,k) !eff radius cloud ice (microns), from Mishra et al. (2014, JGR Atmos, fig 6b) if(qs(i,k)>1.E-8)clouds9(i,k)=max(2.*(173.45 + 2.14*Tc), 50.) @@ -270,7 +274,6 @@ subroutine sgscloud_radpre_run( & if (imfdeepcnv == imfdeepcnv_gf) then do k = 1, levs do i = 1, im - !if ( qci_conv(i,k) > 0. .AND. (qi(i,k) < 1E-7 .AND. qc(i,k) < 1E-7 ) ) then if ( qci_conv(i,k) > 0. ) then Tk = T3D(i,k) Tc = Tk - 273.15 @@ -321,10 +324,15 @@ subroutine sgscloud_radpre_run( & sigq = SQRT(sigq**2 + 1e-10) ! combined conv + background components qmq = a * (qt - qsat) ! saturation deficit/excess; ! the numerator of Q1 - cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.01),0.99) + cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.0),0.99) + if (qci_conv(i,k) .lt. 1e-9) cb_cf = 0.0 if (do_mynnedmf .and. qmq .ge. 0.0) then ! leverage C-B stratus clouds from MYNN in saturated conditions - clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) + if (cb_cf .gt. 0.0) then + clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) + else + !default to MYNN clouds - already specified + endif else ! unsaturated clouds1(i,k) = cb_cf endif @@ -354,7 +362,101 @@ subroutine sgscloud_radpre_run( & endif ! qci_conv enddo enddo - endif ! imfdeepcnv_gf + + elseif (imfdeepcnv == imfdeepcnv_sas) then + + do k = 1, levs + do i = 1, im + h2oliq = qlc(i,k)+qli(i,k) + if ( h2oliq > 0. ) then + Tk = T3D(i,k) + Tc = Tk - 273.15 + + !Partition the convective clouds into water & frozen species + liqfrac = min(1., max(0., (Tk-244.)/29.)) + + qc(i,k) = qc(i,k)+qlc(i,k) + !split ice & snow 50-50% + qi(i,k) = qi(i,k)+0.5*qli(i,k) + qs(i,k) = qs(i,k)+0.5*qli(i,k) + + !eff radius cloud water (microns) + if (nint(slmsk(i)) == 1) then !land + if(qc(i,k)>1.E-8)clouds3(i,k)=5.4 + else + !from Miles et al. + if(qc(i,k)>1.E-8)clouds3(i,k)=9.6 + endif + !from Mishra et al. (2014, JGR Atmos), assume R_sno = 2*R_ice + if(qi(i,k)>1.e-8)clouds5(i,k)=max( 173.45 + 2.14*Tc , 20.) + if(qs(i,k)>1.e-8)clouds9(i,k)=max(2.0*(173.45 + 2.14*Tc), 50.) + + if ( conv_cf_opt .eq. 0 ) then + !print *,'Chab-Bechtold cloud fraction used' + !Alternatively, use Chaboureau-Bechtold (CB) convective component + !Based on both CB2002 and CB2005. + xl = xlv*liqfrac + xls*(1.-liqfrac) ! blended heat capacity + tlk = t3d(i,k) - xlvcp/exner(i,k)*qc(i,k) & + & - xlscp/exner(i,k)*qi(i,k)! liquid temp + ! get saturation water vapor mixing ratio at tl and p + es = min( p3d(i,k), fpvs( tlk ) ) ! fpvs and prsl in pa + qsat= max( QMIN, eps*es / (p3d(i,k) + epsm1*es) ) + rsl = xl*qsat / (r_v*tlk**2) ! slope of C-C curve at t = tl + ! CB02, Eqn. 4 + qt = qc(i,k) + qi(i,k) + qv(i,k) !total water + cpm = cp + qt*cpv ! CB02, sec. 2, para. 1 + a = 1./(1. + xl*rsl/cpm) ! CB02 variable "a" + !Now calculate convective component of the cloud fraction: + if (a > 0.0) then + f = min(1.0/a, 4.0) ! f is the vertical profile + else ! scaling function (CB2005) + f = 1.0 + endif + sigq = 1.5E-3 * ud_mf(i,k)/dt * f + !sigq = 3.E-3 * ud_mf(i,k)/dt * f + sigq = SQRT(sigq**2 + 1e-10) ! combined conv + background components + qmq = a * (qt - qsat) ! saturation deficit/excess; + ! the numerator of Q1 + cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.0),0.99) + if (h2oliq .lt. 1e-9) cb_cf = 0.0 + if (do_mynnedmf .and. qmq .ge. 0.0) then + ! leverage C-B stratus clouds from MYNN in saturated conditions + if (cb_cf .gt. 0.0) then + clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) + else + !default to MYNN clouds - already specified + endif + else ! unsaturated + clouds1(i,k) = cb_cf + endif + else + !print *,'SAS with Xu-Randall cloud fraction' + ! Xu-Randall (1996) cloud fraction + es = min( p3d(i,k), fpvs( t3d(i,k) ) ) ! fpvs and prsl in pa + qsat = max( QMIN, eps*es / (p3d(i,k) + epsm1*es) ) + rhgrid = max( 0., min( 1.00, qv(i,k)/qsat ) ) + h2oliq = qc(i,k) + qi(i,k) + qr(i,k) + qs(i,k) + qg(i,k) ! g/kg + clwt = 1.0e-6 * (p3d(i,k)*0.00001) + + if (h2oliq > clwt) then + onemrh= max( 1.e-10, 1.0-rhgrid ) + tem1 = min(max((onemrh*qsat)**0.49,0.0001),1.0) !jhan + tem1 = 100.0 / tem1 + value = max( min( tem1*(h2oliq-clwt), 50.0 ), 0.0 ) + tem2 = sqrt( sqrt(rhgrid) ) + + clouds1(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) + else + clouds1(i,k) = 0.0 + endif + !print*,"XuRandla- cf:",clouds1(i,k)," rh:",rhgrid," qt:",h2oliq + !print*,"XuRandlb- clwt:",clwt," qsat:",qsat," p:",p3d(i,k) + endif ! end convective cf choice + endif ! qlc/qli check + enddo + enddo + + endif ! convection scheme check endif ! timestep > 1 diff --git a/physics/sgscloud_radpre.meta b/physics/sgscloud_radpre.meta index 28c1b7da6..887ea0b45 100644 --- a/physics/sgscloud_radpre.meta +++ b/physics/sgscloud_radpre.meta @@ -29,6 +29,14 @@ dimensions = () type = integer intent = in +[fhswr] + standard_name = period_of_shortwave_radiation_calls + long_name = frequency for shortwave radiation + units = s + dimensions = () + type = real + kind = kind_phys + intent = in [flag_init] standard_name = flag_for_first_timestep long_name = flag signaling first time step for time integration loop @@ -218,6 +226,22 @@ type = real kind = kind_phys intent = inout +[qlc] + standard_name = cloud_condensed_water_mixing_ratio_convective_transport_tracer + long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) in the convectively transported tracer array + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[qli] + standard_name = ice_water_mixing_ratio_convective_transport_tracer + long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) in the convectively transported tracer array + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [imfdeepcnv] standard_name = control_for_deep_convection_scheme long_name = flag for mass-flux deep convection scheme @@ -232,6 +256,13 @@ dimensions = () type = integer intent = in +[imfdeepcnv_sas] + standard_name = identifier_for_simplified_arakawa_schubert_deep_convection + long_name = flag for SAS deep convection scheme + units = flag + dimensions = () + type = integer + intent = in [qc_save] standard_name = cloud_condensed_water_mixing_ratio_save long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) before entering a physics scheme @@ -427,6 +458,13 @@ dimensions = () type = integer intent = in +[imp_physics_fa] + standard_name = identifier_for_fer_hires_microphysics_scheme + long_name = choice of Ferrier-Aligo microphysics scheme + units = flag + dimensions = () + type = integer + intent = in [iovr] standard_name = flag_for_cloud_overlap_method_for_radiation long_name = max-random overlap clouds From 9c8839690eb024ab1f6c335fb0c5911aace3ca4f Mon Sep 17 00:00:00 2001 From: "samuel.trahan" Date: Tue, 14 Mar 2023 03:02:32 +0000 Subject: [PATCH 07/19] bug fixes from sam to get most regression tests to pass --- physics/mynnedmf_wrapper.F90 | 4 +++- physics/rrtmgp_aerosol_optics.F90 | 7 +++++-- physics/rrtmgp_aerosol_optics.meta | 8 ++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 74cf8fa30..be282a21a 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -357,7 +357,9 @@ SUBROUTINE mynnedmf_wrapper_run( & !initialize arrays for test EMIS_ANT_NO = 0. - vdep = 0. + if(rrfs_sd) then + vdep = 0. + endif FLAG_OZONE = ntoz>0 diff --git a/physics/rrtmgp_aerosol_optics.F90 b/physics/rrtmgp_aerosol_optics.F90 index ce0fa8ea9..9a92ea98a 100644 --- a/physics/rrtmgp_aerosol_optics.F90 +++ b/physics/rrtmgp_aerosol_optics.F90 @@ -27,7 +27,7 @@ module rrtmgp_aerosol_optics subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nDay, idxday, p_lev, & p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, iaermdl, iaerflg, & top_at_1, con_pi, con_rd, con_g, aerodp, aerlw_tau, aerlw_ssa, aerlw_g, aersw_tau, & - aersw_ssa, aersw_g, errmsg, errflg ) + aersw_ssa, aersw_g, ext550, errmsg, errflg ) ! Inputs logical, intent(in) :: & @@ -61,6 +61,8 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nDay, idxday, aerfld ! aerosol input concentrations real(kind_phys), dimension(:,:),intent(in) :: & p_lev ! Pressure @ layer-interfaces (Pa) + real (kind=kind_phys), dimension(:,:), intent(out) :: & + ext550 ! 3d optical extinction for total aerosol species ! Outputs real(kind_phys), dimension(:,:), intent(out) :: & @@ -92,7 +94,8 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nDay, idxday, ! Call module_radiation_aerosols::setaer(),to setup aerosols property profile 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., iaermdl, iaerflg, top_at_1, con_pi, con_rd, con_g, aerosolssw2, aerosolslw, aerodp, errflg, errmsg) + nLev+1, .true., .true., iaermdl, iaerflg, top_at_1, con_pi, con_rd, con_g, aerosolssw2, aerosolslw, & + aerodp, ext550, errflg, errmsg) ! Shortwave if (doSWrad .and. (nDay .gt. 0)) then diff --git a/physics/rrtmgp_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta index e2b81b192..d33e9f08f 100644 --- a/physics/rrtmgp_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -230,6 +230,14 @@ type = real kind = kind_phys intent = out +[ext550] + standard_name = atmosphere_optical_thickness_3d + long_name = 3d optical extinction for total aerosol species + units = none + 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 From 118f72c2500298f5344b50f849681c62d89e1342 Mon Sep 17 00:00:00 2001 From: "Haiqin.Li" Date: Tue, 14 Mar 2023 15:32:03 +0000 Subject: [PATCH 08/19] "include updates from Sam and Haiqin" --- physics/mynnedmf_wrapper.F90 | 1 - physics/rrtmgp_aerosol_optics.F90 | 7 +++++-- physics/rrtmgp_aerosol_optics.meta | 8 ++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 74cf8fa30..0f61a6e24 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -357,7 +357,6 @@ SUBROUTINE mynnedmf_wrapper_run( & !initialize arrays for test EMIS_ANT_NO = 0. - vdep = 0. FLAG_OZONE = ntoz>0 diff --git a/physics/rrtmgp_aerosol_optics.F90 b/physics/rrtmgp_aerosol_optics.F90 index ce0fa8ea9..9a92ea98a 100644 --- a/physics/rrtmgp_aerosol_optics.F90 +++ b/physics/rrtmgp_aerosol_optics.F90 @@ -27,7 +27,7 @@ module rrtmgp_aerosol_optics subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nDay, idxday, p_lev, & p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, iaermdl, iaerflg, & top_at_1, con_pi, con_rd, con_g, aerodp, aerlw_tau, aerlw_ssa, aerlw_g, aersw_tau, & - aersw_ssa, aersw_g, errmsg, errflg ) + aersw_ssa, aersw_g, ext550, errmsg, errflg ) ! Inputs logical, intent(in) :: & @@ -61,6 +61,8 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nDay, idxday, aerfld ! aerosol input concentrations real(kind_phys), dimension(:,:),intent(in) :: & p_lev ! Pressure @ layer-interfaces (Pa) + real (kind=kind_phys), dimension(:,:), intent(out) :: & + ext550 ! 3d optical extinction for total aerosol species ! Outputs real(kind_phys), dimension(:,:), intent(out) :: & @@ -92,7 +94,8 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nDay, idxday, ! Call module_radiation_aerosols::setaer(),to setup aerosols property profile 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., iaermdl, iaerflg, top_at_1, con_pi, con_rd, con_g, aerosolssw2, aerosolslw, aerodp, errflg, errmsg) + nLev+1, .true., .true., iaermdl, iaerflg, top_at_1, con_pi, con_rd, con_g, aerosolssw2, aerosolslw, & + aerodp, ext550, errflg, errmsg) ! Shortwave if (doSWrad .and. (nDay .gt. 0)) then diff --git a/physics/rrtmgp_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta index e2b81b192..d33e9f08f 100644 --- a/physics/rrtmgp_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -230,6 +230,14 @@ type = real kind = kind_phys intent = out +[ext550] + standard_name = atmosphere_optical_thickness_3d + long_name = 3d optical extinction for total aerosol species + units = none + 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 From 67b0511d8888587e677005e379d2064b3f2b51b5 Mon Sep 17 00:00:00 2001 From: "samuel.trahan" Date: Tue, 14 Mar 2023 19:05:59 +0000 Subject: [PATCH 09/19] do not initialize vdep --- physics/mynnedmf_wrapper.F90 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index be282a21a..27ffa162e 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -290,7 +290,7 @@ SUBROUTINE mynnedmf_wrapper_run( & logical, intent(in) :: mix_chem, enh_mix, rrfs_sd real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d real(kind_phys), dimension(:,: ), intent(inout) :: vdep - real(kind_phys), dimension(im) :: emis_ant_no + real(kind_phys), dimension(:) :: emis_ant_no !MYNN-2D real(kind_phys), dimension(:), intent(in) :: & @@ -357,9 +357,6 @@ SUBROUTINE mynnedmf_wrapper_run( & !initialize arrays for test EMIS_ANT_NO = 0. - if(rrfs_sd) then - vdep = 0. - endif FLAG_OZONE = ntoz>0 From 50c4f1bd5665c0aab3e6c3675e4d73735aae7135 Mon Sep 17 00:00:00 2001 From: "samuel.trahan" Date: Tue, 14 Mar 2023 19:13:07 +0000 Subject: [PATCH 10/19] revert accidental change --- physics/mynnedmf_wrapper.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 27ffa162e..0f61a6e24 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -290,7 +290,7 @@ SUBROUTINE mynnedmf_wrapper_run( & logical, intent(in) :: mix_chem, enh_mix, rrfs_sd real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d real(kind_phys), dimension(:,: ), intent(inout) :: vdep - real(kind_phys), dimension(:) :: emis_ant_no + real(kind_phys), dimension(im) :: emis_ant_no !MYNN-2D real(kind_phys), dimension(:), intent(in) :: & From 14557a5459e8735bdda8eaa69891bb96db078401 Mon Sep 17 00:00:00 2001 From: "samuel.trahan" Date: Tue, 14 Mar 2023 19:41:40 +0000 Subject: [PATCH 11/19] 1.2 GB of messages is a bit too much. --- physics/module_mp_nssl_2mom.F90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/physics/module_mp_nssl_2mom.F90 b/physics/module_mp_nssl_2mom.F90 index 6b184c35f..149da491d 100644 --- a/physics/module_mp_nssl_2mom.F90 +++ b/physics/module_mp_nssl_2mom.F90 @@ -8117,7 +8117,9 @@ subroutine radardd02(nx,ny,nz,nor,na,an,temk, & ! write(0,*) 'Hail,snow c: ',an(ix,jy,kz,lnh),an(ix,jy,kz,lns) ! write(0,*) 'dtmps,dtmph = ',dtmps,dtmph ! ENDIF - IF ( .not. dtmp(ix,kz) .lt. 1.e30 .or. dbz(ix,jy,kz) > 190.0 ) THEN + +! 1.2 GB of messages is a bit too much. + IF ( .false. ) then ! .not. dtmp(ix,kz) .lt. 1.e30 .or. dbz(ix,jy,kz) > 190.0 ! IF ( ix == 31 .and. kz == 20 .and. jy == 23 ) THEN ! write(0,*) 'my_rank = ',my_rank write(0,*) 'ix,jy,kz = ',ix,jy,kz From 0b369ef1fba957d3b231be26d3acb7208387a590 Mon Sep 17 00:00:00 2001 From: joeolson42 Date: Tue, 14 Mar 2023 22:24:08 +0000 Subject: [PATCH 12/19] More consistent logic for NSSL mp (mixing snow) --- physics/mynnedmf_wrapper.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index d2ca9f3cc..254592433 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -392,16 +392,16 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .true. FLAG_QC = .true. FLAG_QNC= .true. - FLAG_QS = .false. + FLAG_QS = .true. FLAG_QNWFA= nssl_ccn_on ! ERM: Perhaps could use this field for CCN field? FLAG_QNIFA= .false. FLAG_QNBCA= .false. do k=1,levs do i=1,im - sqv(i,k) = qgrs_water_vapor(i,k) - sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice(i,k) - sqs(i,k) = 0. + sqv(i,k) = qgrs_water_vapor(i,k) + sqc(i,k) = qgrs_liquid_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) From 4cc7227235e49b1711584712bd4ad362813f619c Mon Sep 17 00:00:00 2001 From: joeolson42 Date: Wed, 15 Mar 2023 14:32:54 +0000 Subject: [PATCH 13/19] removing snow mixing from nssl-mp --- physics/mynnedmf_wrapper.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 254592433..1e8eabe98 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -392,7 +392,7 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .true. FLAG_QC = .true. FLAG_QNC= .true. - FLAG_QS = .true. + FLAG_QS = .false. !.true. FLAG_QNWFA= nssl_ccn_on ! ERM: Perhaps could use this field for CCN field? FLAG_QNIFA= .false. FLAG_QNBCA= .false. @@ -401,7 +401,7 @@ SUBROUTINE mynnedmf_wrapper_run( & sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) sqi(i,k) = qgrs_ice(i,k) - sqs(i,k) = qgrs_snow(i,k) + sqs(i,k) = 0.0 !qgrs_snow(i,k) ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) @@ -918,7 +918,7 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) - dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) + !dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) IF ( nssl_ccn_on ) THEN ! dqdt_cccn(i,k) = RQNWFABLTEN(i,k) ENDIF From 6964aabe79905680e2a3a63efc572eb006f72397 Mon Sep 17 00:00:00 2001 From: "Haiqin.Li" Date: Wed, 15 Mar 2023 16:46:34 +0000 Subject: [PATCH 14/19] "update MYNN coupling to nssl-mp from PR #43" --- physics/mynnedmf_wrapper.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 0f61a6e24..83a73e6b3 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -391,16 +391,16 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .true. FLAG_QC = .true. FLAG_QNC= .true. - FLAG_QS = .false. + FLAG_QS = .false. !.true. FLAG_QNWFA= nssl_ccn_on ! ERM: Perhaps could use this field for CCN field? FLAG_QNIFA= .false. FLAG_QNBCA= .false. do k=1,levs do i=1,im - sqv(i,k) = qgrs_water_vapor(i,k) - sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice(i,k) - sqs(i,k) = 0. + sqv(i,k) = qgrs_water_vapor(i,k) + sqc(i,k) = qgrs_liquid_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = 0.0 !qgrs_snow(i,k) ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) @@ -917,7 +917,7 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) - dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) + !dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) IF ( nssl_ccn_on ) THEN ! dqdt_cccn(i,k) = RQNWFABLTEN(i,k) ENDIF From ffccfc8f8aca54c035268e025e29f50e4b2bdeb9 Mon Sep 17 00:00:00 2001 From: Grant Firl Date: Tue, 21 Mar 2023 14:30:18 -0400 Subject: [PATCH 15/19] remove test for MYNN SFC when using MYNN EDMF in noahmpdrv.F90; remove Dom and add Dustin in CMakeLists.txt authors --- CMakeLists.txt | 2 +- physics/noahmpdrv.F90 | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90f6556e3..950bd048e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(ccpp_physics #------------------------------------------------------------------------------ set(PACKAGE "ccpp-physics") -set(AUTHORS "Grant Firl" "Dom Heinzeller" "Man Zhang" "Mike Kavulich" "Chunxi Zhang") +set(AUTHORS "Grant Firl" "Dustin Swales" "Man Zhang" "Mike Kavulich" ) #------------------------------------------------------------------------------ # Set OpenMP flags for C/C++/Fortran diff --git a/physics/noahmpdrv.F90 b/physics/noahmpdrv.F90 index ac3867c1c..771cfa0f6 100644 --- a/physics/noahmpdrv.F90 +++ b/physics/noahmpdrv.F90 @@ -77,13 +77,6 @@ subroutine noahmpdrv_init(lsm, lsm_noahmp, me, isot, ivegsrc, & return end if - if (.not. do_mynnsfclay .and. do_mynnedmf) then - errmsg = 'Problem : do_mynnsfclay = .false.' // & - 'but mynnpbl is .true.. Exiting ...' - errflg = 1 - return - end if - if ( do_mynnsfclay .and. .not. do_mynnedmf) then errmsg = 'Problem : do_mynnsfclay = .true.' // & 'but mynnpbl is .false.. Exiting ...' From e0d3d45caf6f531656c56e860f7f61e432736b95 Mon Sep 17 00:00:00 2001 From: "Haiqin.Li" Date: Wed, 22 Mar 2023 15:34:01 +0000 Subject: [PATCH 16/19] "to address the comments and suggestions from the ccpp reviewer" --- physics/GFS_rrtmg_pre.meta | 2 +- physics/rrtmgp_aerosol_optics.meta | 2 +- physics/smoke_dust/module_smoke_plumerise.F90 | 18 +----------- physics/smoke_dust/rrfs_smoke_postpbl.F90 | 1 - physics/smoke_dust/rrfs_smoke_wrapper.F90 | 28 +++++++++++-------- 5 files changed, 20 insertions(+), 31 deletions(-) diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index 782868be6..a8b549bce 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -1286,7 +1286,7 @@ kind = kind_phys intent = out [ext550] - standard_name = atmosphere_optical_thickness_3d + standard_name = aerosol_optical_depth_at_550nm long_name = 3d optical extinction for total aerosol species units = none dimensions = (horizontal_loop_extent,vertical_layer_dimension) diff --git a/physics/rrtmgp_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta index d33e9f08f..cc9eb1cc2 100644 --- a/physics/rrtmgp_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -231,7 +231,7 @@ kind = kind_phys intent = out [ext550] - standard_name = atmosphere_optical_thickness_3d + standard_name = aerosol_optical_depth_at_550nm long_name = 3d optical extinction for total aerosol species units = none dimensions = (horizontal_loop_extent,vertical_layer_dimension) diff --git a/physics/smoke_dust/module_smoke_plumerise.F90 b/physics/smoke_dust/module_smoke_plumerise.F90 index 5a1a2319d..61be06181 100755 --- a/physics/smoke_dust/module_smoke_plumerise.F90 +++ b/physics/smoke_dust/module_smoke_plumerise.F90 @@ -448,20 +448,7 @@ subroutine get_fire_properties(coms,imm,iveg_ag,burnt_area,FRP,errmsg,errflg) !real(kind=kind_phys), parameter :: beta = 5.0 !ref.: Wooster et al., 2005 REAL(kind=kind_phys), parameter :: beta = 0.88 !ref.: Paugam et al., 2015 -!data heat_flux/ & RAR: not used -!--------------------------------------------------------------------- -! heat flux !IGBP Land Cover ! -! min ! max !Legend and ! reference -! kW/m^2 !description ! -!-------------------------------------------------------------------- -!30.0, 80.0, &! Tropical Forest ! igbp 2 & 4 -!30.0, 80.0, &! Boreal(kind=kind_phys) forest ! igbp 1 & 3 -!4.4, 23.0, &! cerrado/woody savanna | igbp 5 thru 9 -!3.3, 3.3 /! Grassland/cropland ! igbp 10 thru 17 -!-------------------------------------------------------------------- -!-- fire at surface -! -!coms%area = 20.e+4 ! area of burn, m^2 +! coms%area = burnt_area! area of burn, m^2 !IF ( PLUMERISE_flag == 1) THEN @@ -567,9 +554,6 @@ subroutine get_fire_properties(coms,imm,iveg_ag,burnt_area,FRP,errmsg,errflg) COMS%HEATING (3) = 2. * HINC COMS%HEATING (4) = 3. * HINC ELSE - ! RAR: I've commented out so we don't use the look-up table for heat flux - ! HINC = (COMS%HEATING (1) - heat_flux(imm-1,iveg_ag) * 1000. *0.55)/ 4. - ! COMS%HEATING (1) = heat_flux(imm-1,iveg_ag) * 1000. *0.55 + 0.1 COMS%HEATING (2) = COMS%HEATING (1)+ HINC COMS%HEATING (3) = COMS%HEATING (2)+ HINC COMS%HEATING (4) = COMS%HEATING (3)+ HINC diff --git a/physics/smoke_dust/rrfs_smoke_postpbl.F90 b/physics/smoke_dust/rrfs_smoke_postpbl.F90 index 8fbfa7a51..220284dbb 100755 --- a/physics/smoke_dust/rrfs_smoke_postpbl.F90 +++ b/physics/smoke_dust/rrfs_smoke_postpbl.F90 @@ -5,7 +5,6 @@ module rrfs_smoke_postpbl use machine , only : kind_phys - use rrfs_smoke_config implicit none diff --git a/physics/smoke_dust/rrfs_smoke_wrapper.F90 b/physics/smoke_dust/rrfs_smoke_wrapper.F90 index 530d875db..80c43360b 100755 --- a/physics/smoke_dust/rrfs_smoke_wrapper.F90 +++ b/physics/smoke_dust/rrfs_smoke_wrapper.F90 @@ -4,17 +4,23 @@ module rrfs_smoke_wrapper - use machine , only : kind_phys - use rrfs_smoke_config - use dust_data_mod - use seas_mod, only : gocart_seasalt_driver - use dust_fengsha_mod,only : gocart_dust_fengsha_driver - use plume_data_mod - use module_plumerise1 !plume_rise_mod - use module_add_emiss_burn - use coarsepm_settling_mod - use dep_dry_mod - use module_wetdep_ls + use machine , only : kind_phys + use rrfs_smoke_config, only : kemit, dust_opt, seas_opt, do_plumerise, & + addsmoke_flag, plumerisefire_frq, wetdep_ls_opt, & + drydep_opt, coarsepm_settling, aero_ind_fdb, & + dbg_opt, smoke_forecast, wetdep_ls_alpha, & + num_moist, num_chem, num_emis_seas, num_emis_dust, & + DUST_OPT_FENGSHA, p_qv, p_atm_shum, p_atm_cldq, & + p_smoke, p_dust_1, p_coarse_pm, epsilc + use dust_data_mod, only : dust_alpha, dust_gamma + use plume_data_mod, only : p_frp_std, p_frp_hr, num_frp_plume + use seas_mod, only : gocart_seasalt_driver + use dust_fengsha_mod, only : gocart_dust_fengsha_driver + use dep_dry_mod, only : dry_dep_driver + use module_wetdep_ls, only : wetdep_ls + use module_plumerise1, only : ebu_driver + use module_add_emiss_burn, only : add_emis_burn + use coarsepm_settling_mod, only : coarsepm_settling_driver implicit none From 486877983e1fdb5153b5b3ebdf4956043f29041d Mon Sep 17 00:00:00 2001 From: "samuel.trahan" Date: Thu, 23 Mar 2023 18:29:22 +0000 Subject: [PATCH 17/19] bug fixes and updates from develop --- CMakeLists.txt | 6 ++++-- physics/mp_nssl.F90 | 5 ++++- physics/mp_nssl.meta | 40 ++++++++++++++++++++++++++++++++-------- physics/noahmpdrv.F90 | 7 ------- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 482081614..950bd048e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(ccpp_physics #------------------------------------------------------------------------------ set(PACKAGE "ccpp-physics") -set(AUTHORS "Grant Firl" "Dom Heinzeller" "Man Zhang" "Mike Kavulich" "Chunxi Zhang") +set(AUTHORS "Grant Firl" "Dustin Swales" "Man Zhang" "Mike Kavulich" ) #------------------------------------------------------------------------------ # Set OpenMP flags for C/C++/Fortran @@ -183,7 +183,9 @@ set_target_properties(ccpp_physics PROPERTIES VERSION ${PROJECT_VERSION} target_include_directories(ccpp_physics PUBLIC $) -target_link_libraries(ccpp_physics PUBLIC w3emc::w3emc_d NetCDF::NetCDF_Fortran) +target_link_libraries(ccpp_physics PUBLIC w3emc::w3emc_d + sp::sp_d + NetCDF::NetCDF_Fortran) # Define where to install the library install(TARGETS ccpp_physics diff --git a/physics/mp_nssl.F90 b/physics/mp_nssl.F90 index d6de5a0a0..4e0e323ce 100644 --- a/physics/mp_nssl.F90 +++ b/physics/mp_nssl.F90 @@ -31,6 +31,7 @@ subroutine mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, & con_t0c, con_cliq, con_csol, con_eps, & imp_physics, imp_physics_nssl, & nssl_cccn, nssl_alphah, nssl_alphahl, & + nssl_alphar, nssl_ehw0_in, nssl_ehlw0_in, & nssl_ccn_on, nssl_hail_on, nssl_invertccn ) @@ -52,6 +53,7 @@ subroutine mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, & integer, intent(in) :: imp_physics integer, intent(in) :: imp_physics_nssl real(kind_phys), intent(in) :: nssl_cccn, nssl_alphah, nssl_alphahl + real(kind_phys), intent(in) :: nssl_alphar, nssl_ehw0_in, nssl_ehlw0_in logical, intent(in) :: nssl_ccn_on, nssl_hail_on, nssl_invertccn ! Local variables: dimensions used in nssl_init @@ -115,6 +117,7 @@ subroutine mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, & nssl_params(11) = 0 ! nssl_ipelec_tmp nssl_params(12) = 11 ! nssl_isaund nssl_params(13) = 0 ! 1= turn on cccna; 0 = turn off + nssl_params(14) = nssl_alphar nssl_qccn = nssl_cccn/1.225 ! if (mpirank==mpiroot) then @@ -129,7 +132,7 @@ subroutine mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, & ! write(0,*) 'call nssl_2mom_init' CALL nssl_2mom_init(ims,ime, jms,jme, kms,kme,nssl_params,ipctmp=5,mixphase=0, & - ihvol=ihailv,errmsg=errmsg,errflg=errflg,myrank=mpirank,mpiroot=mpiroot) + ihvol=ihailv,nssl_ehw0=nssl_ehw0_in,nssl_ehlw0=nssl_ehlw0_in,errmsg=errmsg,errflg=errflg,myrank=mpirank,mpiroot=mpiroot) ! For restart runs, the init is done here if (restart) then diff --git a/physics/mp_nssl.meta b/physics/mp_nssl.meta index 9b913da2b..c7e398f0a 100644 --- a/physics/mp_nssl.meta +++ b/physics/mp_nssl.meta @@ -151,7 +151,7 @@ intent = in [nssl_alphah] standard_name = nssl_alpha_graupel - long_name = graupel PSD shape parameter in NSSL micro + long_name = graupel particle size distribution(PSD) shape parameter in NSSL microphysics scheme units = none dimensions = () type = real @@ -159,7 +159,31 @@ intent = in [nssl_alphahl] standard_name = nssl_alpha_hail - long_name = hail PSD shape parameter in NSSL micro + long_name = hail particle size distribution(PSD) shape parameter in NSSL microphysics scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[nssl_alphar] + standard_name = nssl_alpha_rain + long_name = rain particle size distribution(PSD) shape parameter in NSSL microphysics scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[nssl_ehw0_in] + standard_name = nssl_graupel_collection_efficiency + long_name = graupel droplet collection efficiency in NSSL microphysics scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[nssl_ehlw0_in] + standard_name = nssl_hail_collection_efficiency + long_name = hail droplet collection efficiency in NSSL microphysics scheme units = none dimensions = () type = real @@ -167,21 +191,21 @@ intent = in [nssl_ccn_on] standard_name = nssl_ccn_on - long_name = CCN activation flag in NSSL micro + long_name = CCN activation flag in NSSL microphysics scheme units = flag dimensions = () type = logical intent = in [nssl_hail_on] standard_name = nssl_hail_on - long_name = hail activation flag in NSSL micro + long_name = hail activation flag in NSSL microphysics scheme units = flag dimensions = () type = logical intent = in [nssl_invertccn] standard_name = nssl_invertccn - long_name = flag to invert CCN in NSSL micro + long_name = flag to invert CCN in NSSL microphysics scheme units = flag dimensions = () type = logical @@ -571,21 +595,21 @@ intent = in [nssl_ccn_on] standard_name = nssl_ccn_on - long_name = CCN activation flag in NSSL micro + long_name = CCN activation flag in NSSL microphysics scheme units = flag dimensions = () type = logical intent = in [nssl_hail_on] standard_name = nssl_hail_on - long_name = hail activation flag in NSSL micro + long_name = hail activation flag in NSSL microphysics scheme units = flag dimensions = () type = logical intent = in [nssl_invertccn] standard_name = nssl_invertccn - long_name = flag to invert CCN in NSSL micro + long_name = flag to invert CCN in NSSL microphysics scheme units = flag dimensions = () type = logical diff --git a/physics/noahmpdrv.F90 b/physics/noahmpdrv.F90 index ac3867c1c..771cfa0f6 100644 --- a/physics/noahmpdrv.F90 +++ b/physics/noahmpdrv.F90 @@ -77,13 +77,6 @@ subroutine noahmpdrv_init(lsm, lsm_noahmp, me, isot, ivegsrc, & return end if - if (.not. do_mynnsfclay .and. do_mynnedmf) then - errmsg = 'Problem : do_mynnsfclay = .false.' // & - 'but mynnpbl is .true.. Exiting ...' - errflg = 1 - return - end if - if ( do_mynnsfclay .and. .not. do_mynnedmf) then errmsg = 'Problem : do_mynnsfclay = .true.' // & 'but mynnpbl is .false.. Exiting ...' From f54132caf2f96c4b44d28cfeea6e88c83d260521 Mon Sep 17 00:00:00 2001 From: "samuel.trahan" Date: Thu, 23 Mar 2023 19:36:09 +0000 Subject: [PATCH 18/19] restore a disabled debug check, and require debugging to be turned on to print it --- physics/module_mp_nssl_2mom.F90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/physics/module_mp_nssl_2mom.F90 b/physics/module_mp_nssl_2mom.F90 index 884bf657d..d190e94b4 100644 --- a/physics/module_mp_nssl_2mom.F90 +++ b/physics/module_mp_nssl_2mom.F90 @@ -8119,8 +8119,7 @@ subroutine radardd02(nx,ny,nz,nor,na,an,temk, & ! write(0,*) 'dtmps,dtmph = ',dtmps,dtmph ! ENDIF -! 1.2 GB of messages is a bit too much. - IF ( .false. ) then ! .not. dtmp(ix,kz) .lt. 1.e30 .or. dbz(ix,jy,kz) > 190.0 + IF ( ndebug>1 .and. .not. dtmp(ix,kz) .lt. 1.e30 .or. dbz(ix,jy,kz) > 190.0 ) THEN ! IF ( ix == 31 .and. kz == 20 .and. jy == 23 ) THEN ! write(0,*) 'my_rank = ',my_rank write(0,*) 'ix,jy,kz = ',ix,jy,kz From a1fe46d936f094f6201c1041716d183e91ff6226 Mon Sep 17 00:00:00 2001 From: "Haiqin.Li" Date: Fri, 24 Mar 2023 02:24:03 +0000 Subject: [PATCH 19/19] "to address the comments from the ccpp reviewer" --- physics/GFS_rrtmg_pre.F90 | 16 +++++++++------- physics/GFS_rrtmg_pre.meta | 12 ++++++++++-- physics/smoke_dust/rrfs_smoke_postpbl.meta | 4 ++-- physics/smoke_dust/rrfs_smoke_wrapper.F90 | 18 +++++++++--------- physics/smoke_dust/rrfs_smoke_wrapper.meta | 20 ++++++++++++++------ 5 files changed, 44 insertions(+), 26 deletions(-) diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index d43e182db..53e1d29b3 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -44,7 +44,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& gasvmr_ccl4, gasvmr_cfc113, aerodp,ext550, clouds6, clouds7, clouds8, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, & - aero_dir_fdb, spp_wts_rad, spp_rad, ico2, errmsg, errflg) + aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, errmsg, errflg) use machine, only: kind_phys @@ -155,6 +155,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& clouds2, clouds3, & clouds4, clouds5 real(kind=kind_phys), dimension(:,:), intent(in) :: qci_conv + real(kind=kind_phys), dimension(:), intent(in) :: fdb_coef real(kind=kind_phys), dimension(:), intent(out) :: lwp_ex,iwp_ex, & lwp_fc,iwp_fc @@ -640,12 +641,13 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& if (aero_dir_fdb) then do k=1,lmk do i=1,im - aer_nm(i,k,1 )=aer_nm(i,k,1 )+qgrs(i,k,ntdust)*0.33*1.e-9 ! dust bin1 - aer_nm(i,k,2 )=aer_nm(i,k,2 )+(qgrs(i,k,ntdust)*0.67+qgrs(i,k,ntcoarsepm)*0.02)*1.e-9 - aer_nm(i,k,3 )=aer_nm(i,k,3 )+qgrs(i,k,ntcoarsepm)*0.13*1.e-9 ! dust bin3 - aer_nm(i,k,4 )=aer_nm(i,k,4 )+qgrs(i,k,ntcoarsepm)*0.85*1.e-9 ! dust bin4 - aer_nm(i,k,12)=aer_nm(i,k,12)+qgrs(i,k,ntsmoke)*1.e-9*0.05 !Smoke BC - aer_nm(i,k,14)=aer_nm(i,k,14)+qgrs(i,k,ntsmoke)*1.e-9*0.95 !Smoke OA, we may need to revise later for OA vs. OC + aer_nm(i,k,1 )=aer_nm(i,k,1 )+ qgrs(i,k,ntdust)*fdb_coef(1)*1.e-9 ! dust bin1 + aer_nm(i,k,2 )=aer_nm(i,k,2 )+(qgrs(i,k,ntdust)*fdb_coef(2) & + +qgrs(i,k,ntcoarsepm)*fdb_coef(3))*1.e-9 ! dust bin2 + aer_nm(i,k,3 )=aer_nm(i,k,3 )+qgrs(i,k,ntcoarsepm)*fdb_coef(4)*1.e-9 ! dust bin3 + aer_nm(i,k,4 )=aer_nm(i,k,4 )+qgrs(i,k,ntcoarsepm)*fdb_coef(5)*1.e-9 ! dust bin4 + aer_nm(i,k,12)=aer_nm(i,k,12)+qgrs(i,k,ntsmoke)*fdb_coef(6)*1.e-9 ! Smoke BC + aer_nm(i,k,14)=aer_nm(i,k,14)+qgrs(i,k,ntsmoke)*fdb_coef(7)*1.e-9 ! Smoke OA enddo enddo endif diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index a8b549bce..82ffd07c2 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -234,8 +234,8 @@ type = integer intent = in [ntcoarsepm] - standard_name = index_for_coarse_pm_in_tracer_concentration_array - long_name = tracer index for coarse pm + standard_name = index_for_coarse_particulate_matter_in_tracer_concentration_array + long_name = tracer index for coarse particulate matter units = index dimensions = () type = integer @@ -1466,6 +1466,14 @@ dimensions = () type = logical intent = in +[fdb_coef] + standard_name = smoke_dust_direct_fdb_coef + long_name = smoke dust direct feedback coefficents + units = none + dimensions = (7) + type = real + kind = kind_phys + intent = in [spp_wts_rad] standard_name = spp_weights_for_radiation_scheme long_name = spp weights for radiation scheme diff --git a/physics/smoke_dust/rrfs_smoke_postpbl.meta b/physics/smoke_dust/rrfs_smoke_postpbl.meta index dab56cddc..50f7afae7 100755 --- a/physics/smoke_dust/rrfs_smoke_postpbl.meta +++ b/physics/smoke_dust/rrfs_smoke_postpbl.meta @@ -36,8 +36,8 @@ type = integer intent = in [ntcoarsepm] - standard_name = index_for_coarse_pm_in_tracer_concentration_array - long_name = tracer index for coarse pm + standard_name = index_for_coarse_particulate_matter_in_tracer_concentration_array + long_name = tracer index for coarse particulate matter units = index dimensions = () type = integer diff --git a/physics/smoke_dust/rrfs_smoke_wrapper.F90 b/physics/smoke_dust/rrfs_smoke_wrapper.F90 index 80c43360b..1f9ef6340 100755 --- a/physics/smoke_dust/rrfs_smoke_wrapper.F90 +++ b/physics/smoke_dust/rrfs_smoke_wrapper.F90 @@ -41,8 +41,8 @@ module rrfs_smoke_wrapper subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, & u10m, v10m, ustar, rlat, rlon, tskin, pb2d, t2m, dpt2m, & pr3d, ph3d,phl3d, prl3d, tk3d, us3d, vs3d, spechum, w, & - nsoil, smc, vegtype, soiltyp, sigmaf, dswsfc, zorl,snow, & - julian, idat, rain_cpl, rainc_cpl, exch, hf2d, g, pi, con_cp, con_rd, & + nsoil, smc, vegtype, soiltyp, sigmaf, dswsfc, zorl, snow, julian, & + idat, rain_cpl, rainc_cpl, exch, hf2d, g, pi, con_cp, con_rd, con_fv, & dust12m_in, emi_in, smoke_RRFS, ntrac, qgrs, gq0, chem3d, tile_num, & ntsmoke, ntdust, ntcoarsepm, imp_physics, imp_physics_thompson, & nwfa, nifa, emanoc, emdust, emseas, & @@ -60,7 +60,7 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, integer, intent(in) :: im,kte,kme,ktau,nsoil,tile_num,jdate(8),idat(8) integer, intent(in) :: ntrac, ntsmoke, ntdust, ntcoarsepm, ndvel - real(kind_phys),intent(in) :: dt, julian, g, pi, con_cp, con_rd + real(kind_phys),intent(in) :: dt, julian, g, pi, con_cp, con_rd, con_fv logical, intent(in) :: aero_ind_fdb_in,dbg_opt_in integer, intent(in) :: smoke_forecast_in @@ -228,7 +228,7 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !>- get ready for chemistry run call rrfs_smoke_prep( & - current_month, current_hour, gmt, & + current_month, current_hour, gmt, con_rd, con_fv, & u10m,v10m,ustar,land,garea,rlat,rlon,tskin, & pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,exch,w, & nsoil,smc,vegtype,soiltyp,sigmaf,dswsfc,zorl, & @@ -418,8 +418,8 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, do k=kts,kte do i=its,ite gq0(i,k,ntsmoke ) = min(5000.,max(epsilc,chem(i,k,1,p_smoke ))) - gq0(i,k,ntdust ) = min(100.,max(epsilc,chem(i,k,1,p_dust_1))) - gq0(i,k,ntcoarsepm)= min(1000.,max(epsilc,chem(i,k,1,p_coarse_pm))) + gq0(i,k,ntdust ) = min(200.,max(epsilc,chem(i,k,1,p_dust_1))) + gq0(i,k,ntcoarsepm)= min(5000.,max(epsilc,chem(i,k,1,p_coarse_pm))) enddo enddo @@ -482,7 +482,7 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, end subroutine rrfs_smoke_wrapper_run subroutine rrfs_smoke_prep( & - current_month,current_hour,gmt, & + current_month,current_hour,gmt,con_rd,con_fv, & u10m,v10m,ustar,land,garea,rlat,rlon,ts2d, & pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,exch,w, & nsoil,smc,vegtype,soiltyp,sigmaf,dswsfc,zorl, & @@ -510,7 +510,7 @@ subroutine rrfs_smoke_prep( & integer, intent(in) :: nsoil integer, dimension(ims:ime), intent(in) :: land, vegtype, soiltyp integer, intent(in) :: ntrac - real(kind=kind_phys), intent(in) :: g, pi, gmt + real(kind=kind_phys), intent(in) :: g, pi, gmt, con_rd, con_fv real(kind=kind_phys), dimension(ims:ime), intent(in) :: & u10m, v10m, ustar, garea, rlat, rlon, ts2d, sigmaf, dswsfc, & zorl, snow_cpl, pb2d, hf2d @@ -671,7 +671,7 @@ subroutine rrfs_smoke_prep( & p_phy(i,k,j)=prl3d(i,kkp) u_phy(i,k,j)=us3d(i,kkp) v_phy(i,k,j)=vs3d(i,kkp) - rho_phy(i,k,j)=p_phy(i,k,j)/(287.04*t_phy(i,k,j)*(1.+.608*spechum(i,kkp))) + rho_phy(i,k,j)=p_phy(i,k,j)/(con_rd*t_phy(i,k,j)*(1.+con_fv*spechum(i,kkp))) rri(i,k,j)=1./rho_phy(i,k,j) vvel(i,k,j)=-w(i,kkp)*rri(i,k,j)/g moist(i,k,j,:)=0. diff --git a/physics/smoke_dust/rrfs_smoke_wrapper.meta b/physics/smoke_dust/rrfs_smoke_wrapper.meta index 2b2be03b6..bf2fddd60 100755 --- a/physics/smoke_dust/rrfs_smoke_wrapper.meta +++ b/physics/smoke_dust/rrfs_smoke_wrapper.meta @@ -349,6 +349,14 @@ type = real kind = kind_phys intent = in +[con_fv] + standard_name = ratio_of_vapor_to_dry_air_gas_constants_minus_one + long_name = (rv/rd) - 1 (rv = ideal gas constant for water vapor) + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [dust12m_in] standard_name = fengsha_dust12m_input long_name = fengsha dust input @@ -426,8 +434,8 @@ type = integer intent = in [ntcoarsepm] - standard_name = index_for_coarse_pm_in_tracer_concentration_array - long_name = tracer index for coarse pm + standard_name = index_for_coarse_particulate_matter_in_tracer_concentration_array + long_name = tracer index for coarse particulate matter units = index dimensions = () type = integer @@ -463,8 +471,8 @@ kind = kind_phys intent = inout [emanoc] - standard_name = emission_of_anoc_for_thompson_mp - long_name = emission of anoc for thompson mp + standard_name = emission_of_anothropogenic_for_mp_indir_fdb + long_name = emission of anothropogenic for mp indirect feedabck units = ug m-2 s-1 dimensions = (horizontal_loop_extent) type = real @@ -479,8 +487,8 @@ kind = kind_phys intent = inout [emseas] - standard_name = emission_of_seas_for_smoke - long_name = emission of seas for smoke + standard_name = emission_of_sea_salt_for_mp_indir_fdb + long_name = emission of sea salt for mp indirect feedabck units = ug m-2 s-1 dimensions = (horizontal_loop_extent) type = real