diff --git a/physics/CONV/SAMF/samfdeepcnv.f b/physics/CONV/SAMF/samfdeepcnv.f index 7c2d9acf8..3ad067657 100644 --- a/physics/CONV/SAMF/samfdeepcnv.f +++ b/physics/CONV/SAMF/samfdeepcnv.f @@ -215,7 +215,8 @@ subroutine samfdeepcnv_run (im,km,first_time_step,restart, & ! ! parameters for prognostic sigma closure real(kind=kind_phys) omega_u(im,km),zdqca(im,km),tmfq(im,km), - & omegac(im),zeta(im,km),dbyo1(im,km),sigmab(im),qadv(im,km) + & omegac(im),zeta(im,km),dbyo1(im,km),sigmab(im),qadv(im,km), + & sigmaoutx(im) real(kind=kind_phys) gravinv,invdelt,sigmind,sigminm,sigmins parameter(sigmind=0.01,sigmins=0.03,sigminm=0.01) logical flag_shallow, flag_mid @@ -3423,17 +3424,28 @@ subroutine samfdeepcnv_run (im,km,first_time_step,restart, & endif enddo c -c convective cloud water +! + if(progsigma)then + do i = 1, im + sigmaoutx(i)=max(sigmaout(i,1),0.0) + sigmaoutx(i)=min(sigmaoutx(i),1.0) + enddo + endif c !> - Calculate convective cloud water. do k = 1, km - do i = 1, im - if (cnvflg(i) .and. rn(i) > 0.) then - if (k >= kbcon(i) .and. k < ktcon(i)) then - cnvw(i,k) = cnvwt(i,k) * xmb(i) * dt2 + do i = 1, im + if (cnvflg(i) .and. rn(i) > 0.) then + if (k >= kbcon(i) .and. k < ktcon(i)) then + cnvw(i,k) = cnvwt(i,k) * xmb(i) * dt2 + if(progsigma)then + cnvw(i,k) = cnvw(i,k) * sigmaoutx(i) + else + cnvw(i,k) = cnvw(i,k) * sigmagfm(i) + endif + endif endif - endif - enddo + enddo enddo c c convective cloud cover diff --git a/physics/CONV/SAMF/samfshalcnv.f b/physics/CONV/SAMF/samfshalcnv.f index f720c4701..ce783ea15 100644 --- a/physics/CONV/SAMF/samfshalcnv.f +++ b/physics/CONV/SAMF/samfshalcnv.f @@ -162,7 +162,7 @@ subroutine samfshalcnv_run(im,km,itc,ntc,cliq,cp,cvap, & ! parameters for prognostic sigma closure real(kind=kind_phys) omega_u(im,km),zdqca(im,km),tmfq(im,km), & omegac(im),zeta(im,km),dbyo1(im,km), - & sigmab(im),qadv(im,km) + & sigmab(im),qadv(im,km),sigmaoutx(im) real(kind=kind_phys) gravinv,dxcrtas,invdelt,sigmind,sigmins, & sigminm logical flag_shallow,flag_mid @@ -2397,20 +2397,29 @@ subroutine samfshalcnv_run(im,km,itc,ntc,cliq,cp,cvap, & endif enddo c -c convective cloud water -c -!> - Calculate shallow convective cloud water. + if(progsigma)then + do i = 1, im + sigmaoutx(i)=max(sigmaout(i,1),0.0) + sigmaoutx(i)=min(sigmaoutx(i),1.0) + enddo + endif + +c convective cloud water do k = 1, km - do i = 1, im - if (cnvflg(i)) then - if (k >= kbcon(i) .and. k < ktcon(i)) then - cnvw(i,k) = cnvwt(i,k) * xmb(i) * dt2 + do i = 1, im + if (cnvflg(i)) then + if (k >= kbcon(i) .and. k < ktcon(i)) then + cnvw(i,k) = cnvwt(i,k) * xmb(i) * dt2 + if (progsigma) then + cnvw(i,k) = cnvw(i,k) * sigmaoutx(i) + else + cnvw(i,k) = cnvw(i,k) * sigmagfm(i) + endif + endif endif - endif - enddo + enddo enddo - -c +c c convective cloud cover c !> - Calculate convective cloud cover, which is used when pdf-based cloud fraction is used (i.e., pdfcld=.true.). diff --git a/physics/GWD/drag_suite.F90 b/physics/GWD/drag_suite.F90 index fcad796a8..5c2bf6c2c 100644 --- a/physics/GWD/drag_suite.F90 +++ b/physics/GWD/drag_suite.F90 @@ -219,8 +219,8 @@ subroutine drag_suite_run( & & dusfc_ms,dvsfc_ms,dusfc_bl,dvsfc_bl, & & dusfc_ss,dvsfc_ss,dusfc_fd,dvsfc_fd, & & slmsk,br1,hpbl, & - & g, cp, rd, rv, fv, pi, imx, cdmbgwd, me, master, & - & lprnt, ipr, rdxzb, dx, gwd_opt, & + & g, cp, rd, rv, fv, pi, imx, cdmbgwd, alpha_fd, & + & me, master, lprnt, ipr, rdxzb, dx, gwd_opt, & & do_gsl_drag_ls_bl, do_gsl_drag_ss, do_gsl_drag_tofd, & & dtend, dtidx, index_of_process_orographic_gwd, & & index_of_temperature, index_of_x_wind, & @@ -327,18 +327,18 @@ subroutine drag_suite_run( & integer, intent(in) :: gwd_opt logical, intent(in) :: lprnt integer, intent(in) :: KPBL(:) - real(kind=kind_phys), intent(in) :: deltim, G, CP, RD, RV, cdmbgwd(:) + real(kind=kind_phys), intent(in) :: deltim, G, CP, RD, RV, & + & cdmbgwd(:), alpha_fd real(kind=kind_phys), intent(inout), optional :: dtend(:,:,:) logical, intent(in) :: ldiag3d - integer, intent(in) :: dtidx(:,:) - integer, intent(in) :: index_of_temperature, & + integer, intent(in) :: dtidx(:,:), index_of_temperature, & & index_of_process_orographic_gwd, index_of_x_wind, index_of_y_wind integer :: kpblmax integer, parameter :: ims=1, kms=1, its=1, kts=1 real(kind=kind_phys), intent(in) :: fv, pi real(kind=kind_phys) :: rcl, cdmb - real(kind=kind_phys) :: g_inv + real(kind=kind_phys) :: g_inv, rd_inv real(kind=kind_phys), intent(inout) :: & & dudt(:,:),dvdt(:,:), & @@ -444,6 +444,7 @@ subroutine drag_suite_run( & real(kind=kind_phys), dimension(im,km) :: utendform,vtendform real(kind=kind_phys) :: a1,a2,wsp real(kind=kind_phys) :: H_efold + real(kind=kind_phys), parameter :: coeff_fd = 6.325e-3 ! critical richardson number for wave breaking : ! larger drag with larger value real(kind=kind_phys), parameter :: ric = 0.25 @@ -512,7 +513,6 @@ subroutine drag_suite_run( & real(kind=kind_phys),parameter :: olmin = 1.0e-5 real(kind=kind_phys),parameter :: odmin = 0.1 real(kind=kind_phys),parameter :: odmax = 10. - real(kind=kind_phys),parameter :: erad = 6371.315e+3 integer :: komax(im) integer :: kblk real(kind=kind_phys) :: cd @@ -708,11 +708,12 @@ subroutine drag_suite_run( & taufb(1:im,1:km+1) = 0.0 komax(1:im) = 0 ! + rd_inv = 1./rd do k = kts,km do i = its,im vtj(i,k) = t1(i,k) * (1.+fv*q1(i,k)) vtk(i,k) = vtj(i,k) / prslk(i,k) - ro(i,k) = 1./rd * prsl(i,k) / vtj(i,k) ! density kg/m**3 + ro(i,k) = rd_inv * prsl(i,k) / vtj(i,k) ! density kg/m**3 enddo enddo ! @@ -1363,8 +1364,10 @@ subroutine drag_suite_run( & H_efold = 1500. DO k=kts,km wsp=SQRT(uwnd1(i,k)**2 + vwnd1(i,k)**2) - ! alpha*beta*Cmd*Ccorr*2.109 = 12.*1.*0.005*0.6*2.109 = 0.0759 - var_temp = 0.0759*EXP(-(zl(i,k)/H_efold)**1.5)*a2* & + ! Note: In Beljaars et al. (2004): + ! alpha_fd*beta*Cmd*Ccorr*2.109 = 12.*1.*0.005*0.6*2.109 = 0.0759 + ! lump beta*Cmd*Ccorr*2.109 into 1.*0.005*0.6*2.109 = coeff_fd ~ 6.325e-3_kind_phys + var_temp = alpha_fd*coeff_fd*EXP(-(zl(i,k)/H_efold)**1.5)*a2* & zl(i,k)**(-1.2)*ss_taper(i) ! this is greater than zero ! Note: This is a semi-implicit treatment of the time differencing ! per Beljaars et al. (2004, QJRMS) @@ -1414,6 +1417,1228 @@ subroutine drag_suite_run( & return end subroutine drag_suite_run !------------------------------------------------------------------- + + subroutine drag_suite_psl( & + & IM,KM,dvdt,dudt,dtdt,U1,V1,T1,Q1,KPBL, & + & PRSI,DEL,PRSL,PRSLK,PHII,PHIL,DELTIM,KDT, & + & var,oc1,oa4,ol4, & + & varss,oc1ss,oa4ss,ol4ss, & + & THETA,SIGMA,GAMMA,ELVMAX, & + & dtaux2d_ls,dtauy2d_ls,dtaux2d_bl,dtauy2d_bl, & + & dtaux2d_ss,dtauy2d_ss,dtaux2d_fd,dtauy2d_fd, & + & dusfc,dvsfc, & + & dusfc_ls,dvsfc_ls,dusfc_bl,dvsfc_bl, & + & dusfc_ss,dvsfc_ss,dusfc_fd,dvsfc_fd, & + & slmsk,br1,hpbl,vtype, & + & g, cp, rd, rv, fv, pi, imx, cdmbgwd, alpha_fd, & + & me, master, lprnt, ipr, rdxzb, dx, gwd_opt, & + & do_gsl_drag_ls_bl, do_gsl_drag_ss, do_gsl_drag_tofd, & + & psl_gwd_dx_factor, & + & dtend, dtidx, index_of_process_orographic_gwd, & + & index_of_temperature, index_of_x_wind, & + & index_of_y_wind, ldiag3d, ldiag_ugwp, ugwp_seq_update, & + & spp_wts_gwd, spp_gwd, errmsg, errflg) + +! ******************************************************************** +! -----> I M P L E M E N T A T I O N V E R S I O N <---------- +! +! ----- This code ----- +!begin WRF code + +! this code handles the time tendencies of u v due to the effect of mountain +! induced gravity wave drag from sub-grid scale orography. this routine +! not only treats the traditional upper-level wave breaking due to mountain +! variance (alpert 1988), but also the enhanced lower-tropospheric wave +! breaking due to mountain convexity and asymmetry (kim and arakawa 1995). +! thus, in addition to the terrain height data in a model grid box, +! additional 10-2d topographic statistics files are needed, including +! orographic standard deviation (var), convexity (oc1), asymmetry (oa4) +! and ol (ol4). these data sets are prepared based on the 30 sec usgs orography +! hong (1999). the current scheme was implmented as in hong et al.(2008) +! +! Originally coded by song-you hong and young-joon kim and implemented by song-you hong +! +! program history log: +! 2014-10-01 Hyun-Joo Choi (from KIAPS) flow-blocking drag of kim and doyle +! with blocked height by dividing streamline theory +! 2017-04-06 Joseph Olson (from Gert-Jan Steeneveld) added small-scale +! orographic grabity wave drag: +! 2017-09-15 Joseph Olson, with some bug fixes from Michael Toy: added the +! topographic form drag of Beljaars et al. (2004, QJRMS) +! Activation of each component is done by specifying the integer-parameters +! (defined below) to 0: inactive or 1: active +! gwd_opt_ls = 0 or 1: large-scale +! gwd_opt_bl = 0 or 1: blocking drag +! gwd_opt_ss = 0 or 1: small-scale gravity wave drag +! gwd_opt_fd = 0 or 1: topographic form drag +! 2017-09-25 Michael Toy (from NCEP GFS model) added dissipation heating +! gsd_diss_ht_opt = 0: dissipation heating off +! gsd_diss_ht_opt = 1: dissipation heating on +! 2020-08-25 Michael Toy changed logic control for drag component selection +! for CCPP. +! Namelist options: +! do_gsl_drag_ls_bl - logical flag for large-scale GWD + blocking +! do_gsl_drag_ss - logical flag for small-scale GWD +! do_gsl_drag_tofd - logical flag for turbulent form drag +! Compile-time options (same as before): +! gwd_opt_ls = 0 or 1: large-scale GWD +! gwd_opt_bl = 0 or 1: blocking drag +! +! References: +! Choi and Hong (2015) J. Geophys. Res. +! Hong et al. (2008), wea. and forecasting +! Kim and Doyle (2005), Q. J. R. Meteor. Soc. +! Kim and Arakawa (1995), j. atmos. sci. +! Alpert et al. (1988), NWP conference. +! Hong (1999), NCEP office note 424. +! Steeneveld et al (2008), JAMC +! Tsiringakis et al. (2017), Q. J. R. Meteor. Soc. +! Beljaars et al. (2004), Q. J. R. Meteor. Soc. +! +! notice : comparible or lower resolution orography files than model resolution +! are desirable in preprocess (wps) to prevent weakening of the drag +!------------------------------------------------------------------------------- +! +! input +! dudt (im,km) non-lin tendency for u wind component +! dvdt (im,km) non-lin tendency for v wind component +! u1(im,km) zonal wind / sqrt(rcl) m/sec at t0-dt +! v1(im,km) meridional wind / sqrt(rcl) m/sec at t0-dt +! t1(im,km) temperature deg k at t0-dt +! q1(im,km) specific humidity at t0-dt +! deltim time step secs +! del(km) positive increment of pressure across layer (pa) +! KPBL(IM) is the index of the top layer of the PBL +! ipr & lprnt for diagnostics +! +! output +! dudt, dvdt wind tendency due to gwdo +! dTdt +! +!------------------------------------------------------------------------------- + +!end wrf code +!----------------------------------------------------------------------C +! USE +! ROUTINE IS CALLED FROM CCPP (AFTER CALLING PBL SCHEMES) +! +! PURPOSE +! USING THE GWD PARAMETERIZATIONS OF PS-GLAS AND PH- +! GFDL TECHNIQUE. THE TIME TENDENCIES OF U V +! ARE ALTERED TO INCLUDE THE EFFECT OF MOUNTAIN INDUCED +! GRAVITY WAVE DRAG FROM SUB-GRID SCALE OROGRAPHY INCLUDING +! CONVECTIVE BREAKING, SHEAR BREAKING AND THE PRESENCE OF +! CRITICAL LEVELS +! +! +! ******************************************************************** + USE MACHINE , ONLY : kind_phys + implicit none + + ! Interface variables + integer, intent(in) :: im, km, imx, kdt, ipr, me, master + integer, intent(in) :: gwd_opt + logical, intent(in) :: lprnt + integer, intent(in) :: KPBL(:) + real(kind=kind_phys), intent(in) :: deltim, G, CP, RD, RV, & + & cdmbgwd(:), alpha_fd + real(kind=kind_phys), intent(inout), optional :: dtend(:,:,:) + logical, intent(in) :: ldiag3d + integer, intent(in) :: dtidx(:,:), index_of_temperature, & + & index_of_process_orographic_gwd, index_of_x_wind, index_of_y_wind + + integer :: kpblmax + integer, parameter :: ims=1, kms=1, its=1, kts=1 + real(kind=kind_phys), intent(in) :: fv, pi + real(kind=kind_phys) :: rcl, cdmb + real(kind=kind_phys) :: g_inv, g_cp, rd_inv + + real(kind=kind_phys), intent(inout) :: & + & dudt(:,:),dvdt(:,:), & + & dtdt(:,:) + real(kind=kind_phys), intent(out) :: rdxzb(:) + real(kind=kind_phys), intent(in) :: & + & u1(:,:),v1(:,:), & + & t1(:,:),q1(:,:), & + & PHII(:,:),prsl(:,:), & + & prslk(:,:),PHIL(:,:) + real(kind=kind_phys), intent(in) :: prsi(:,:), & + & del(:,:) + real(kind=kind_phys), intent(in) :: var(:),oc1(:), & + & oa4(:,:),ol4(:,:), & + & dx(:) + real(kind=kind_phys), intent(in), optional :: varss(:),oc1ss(:), & + & oa4ss(:,:),ol4ss(:,:) + real(kind=kind_phys), intent(in) :: THETA(:),SIGMA(:), & + & GAMMA(:),ELVMAX(:) + +! added for small-scale orographic wave drag + real(kind=kind_phys), dimension(im,km) :: utendwave,vtendwave,thx,thvx + integer, intent(in) :: vtype(:) + real(kind=kind_phys), intent(in) :: br1(:), & + & hpbl(:), & + & slmsk(:) + real(kind=kind_phys), dimension(im) :: govrth,xland + !real(kind=kind_phys), dimension(im,km) :: dz2 + real(kind=kind_phys) :: tauwavex0,tauwavey0, & + & XNBV,density,tvcon,hpbl2 + integer :: kpbl2,kvar + !real(kind=kind_phys), dimension(im,km+1) :: zq ! = PHII/g + real(kind=kind_phys), dimension(im,km) :: zl ! = PHIL/g + +!SPP + real(kind=kind_phys), dimension(im) :: var_stoch, varss_stoch, & + varmax_ss_stoch, varmax_fd_stoch + real(kind=kind_phys), intent(in), optional :: spp_wts_gwd(:,:) + integer, intent(in) :: spp_gwd + + real(kind=kind_phys), dimension(im) :: rstoch + +!Output: + real(kind=kind_phys), intent(out) :: & + & dusfc(:), dvsfc(:) +!Output (optional): + real(kind=kind_phys), intent(out), optional :: & + & dusfc_ls(:),dvsfc_ls(:), & + & dusfc_bl(:),dvsfc_bl(:), & + & dusfc_ss(:),dvsfc_ss(:), & + & dusfc_fd(:),dvsfc_fd(:) + real(kind=kind_phys), intent(out), optional :: & + & dtaux2d_ls(:,:),dtauy2d_ls(:,:), & + & dtaux2d_bl(:,:),dtauy2d_bl(:,:), & + & dtaux2d_ss(:,:),dtauy2d_ss(:,:), & + & dtaux2d_fd(:,:),dtauy2d_fd(:,:) + +!Misc arrays + real(kind=kind_phys), dimension(im,km) :: dtaux2d, dtauy2d + +!------------------------------------------------------------------------- +! Flags to regulate the activation of specific components of drag suite: +! Each component is tapered off automatically as a function of dx, so best to +! keep them activated (.true.). + logical, intent(in) :: & + do_gsl_drag_ls_bl, & ! large-scale gravity wave drag and blocking + do_gsl_drag_ss, & ! small-scale gravity wave drag (Steeneveld et al. 2008) + do_gsl_drag_tofd ! form drag (Beljaars et al. 2004, QJRMS) +! Flag for diagnostic outputs + logical, intent(in) :: ldiag_ugwp + +! Flag for sequential update of u and v between +! LSGWD + BLOCKING and SSGWD + TOFD calculations + logical, intent(in) :: ugwp_seq_update +! +! Additional flags + integer, parameter :: & + gwd_opt_ls = 1, & ! large-scale gravity wave drag + gwd_opt_bl = 1, & ! blocking drag + gsd_diss_ht_opt = 0 + +! Parameters for bounding the scale-adaptive variability: +! Small-scale GWD + turbulent form drag + real(kind=kind_phys), parameter :: dxmin_ss = 1000., & + & dxmax_ss = 12000. ! min,max range of tapering (m) +! Large-scale GWD + blocking + real(kind=kind_phys), parameter :: dxmin_ls = 3000., & + & dxmax_ls = 13000. ! min,max range of tapering (m) + real(kind=kind_phys), dimension(im) :: ss_taper, ls_taper ! small- and large-scale tapering factors (-) +! +! Variables for limiting topographic standard deviation (var) + real(kind=kind_phys), parameter :: varmax_ss = 50., & + varmax_fd = 150., & + beta_ss = 0.1, & + beta_fd = 0.2 + real(kind=kind_phys) :: var_temp, var_temp2 + +! added Beljaars orographic form drag + real(kind=kind_phys), dimension(im,km) :: utendform,vtendform + real(kind=kind_phys) :: a1,a2,wsp + real(kind=kind_phys) :: H_efold + real(kind=kind_phys), parameter :: coeff_fd = 6.325e-3 + +! multification factor of standard deviation : ! larger drag with larger value +!!! real(kind=kind_phys), parameter :: psl_gwd_dx_factor = 6.0 + real(kind=kind_phys), intent(in) :: psl_gwd_dx_factor + +! critical richardson number for wave breaking : ! larger drag with larger value + real(kind=kind_phys), parameter :: ric = 0.25 + real(kind=kind_phys), parameter :: dw2min = 1. + real(kind=kind_phys), parameter :: rimin = -100. + real(kind=kind_phys), parameter :: bnv2min = 1.0e-5 + real(kind=kind_phys), parameter :: efmin = 0.0 + real(kind=kind_phys), parameter :: efmax = 10.0 + real(kind=kind_phys), parameter :: xl = 4.0e4 + real(kind=kind_phys), parameter :: critac = 1.0e-5 + real(kind=kind_phys), parameter :: gmax = 1. + real(kind=kind_phys), parameter :: veleps = 1.0 + real(kind=kind_phys), parameter :: factop = 0.5 + real(kind=kind_phys), parameter :: frc = 1.0 + real(kind=kind_phys), parameter :: ce = 0.8 + real(kind=kind_phys), parameter :: cg = 1.0 +! real(kind=kind_phys), parameter :: var_min = 100.0 + real(kind=kind_phys), parameter :: var_min = 10.0 + real(kind=kind_phys), parameter :: hmt_min = 50. + real(kind=kind_phys), parameter :: oc_min = 1.0 + real(kind=kind_phys), parameter :: oc_max = 10.0 +! 7.5 mb -- 33 km ... 0.01 kgm-3 reduce gwd drag above cutoff level + real(kind=kind_phys), parameter :: pcutoff = 7.5e2 +! 0.76 mb -- 50 km ...0.001 kgm-3 --- 0.1 mb 65 km 0.0001 kgm-3 + real(kind=kind_phys), parameter :: pcutoff_den = 0.01 ! + + integer,parameter :: kpblmin = 2 + +! +! local variables +! + integer :: i,j,k,lcap,lcapp1,nwd,idir, & + klcap,kp1 +! + real(kind=kind_phys) :: rcs,csg,fdir,cs, & + rcsks,wdir,ti,rdz,tem2,dw2,shr2, & + bvf2,rdelks,wtkbj,tem,gfobnv,hd,fro, & + rim,temc,tem1,efact,temv,dtaux,dtauy, & + dtauxb,dtauyb,eng0,eng1 + real(kind=kind_phys) :: denfac +! + logical :: ldrag(im),icrilv(im), & + flag(im) +! + real(kind=kind_phys) :: invgrcs +! + real(kind=kind_phys) :: taub(im),taup(im,km+1), & + xn(im),yn(im), & + ubar(im),vbar(im), & + fr(im),ulow(im), & + rulow(im),bnv(im), & + oa(im),ol(im),oc(im), & + oass(im),olss(im), & + roll(im),dtfac(im,km), & + brvf(im),xlinv(im), & + delks(im),delks1(im), & + bnv2(im,km),usqj(im,km), & + taud_ls(im,km),taud_bl(im,km), & + ro(im,km), & + vtk(im,km),vtj(im,km), & + zlowtop(im),velco(im,km-1), & + coefm(im),coefm_ss(im) + real(kind=kind_phys) :: cleff(im),cleff_ss(im) +! + integer :: kbl(im),klowtop(im) + integer,parameter :: mdir=8 + !integer :: nwdir(mdir) + !data nwdir/6,7,5,8,2,3,1,4/ + integer, parameter :: nwdir(8) = (/6,7,5,8,2,3,1,4/) +! +! variables for flow-blocking drag +! + real(kind=kind_phys),parameter :: frmax = 10. + real(kind=kind_phys),parameter :: olmin = 1.e-5 + real(kind=kind_phys),parameter :: odmin = 0.1 + real(kind=kind_phys),parameter :: odmax = 10. + real(kind=kind_phys),parameter :: cdmin = 0.0 + integer :: komax(im),kbmax(im),kblk(im) + real(kind=kind_phys) :: hmax(im) + real(kind=kind_phys) :: cd + real(kind=kind_phys) :: zblk,tautem + real(kind=kind_phys) :: pe,ke + real(kind=kind_phys) :: delx,dely + real(kind=kind_phys) :: dxy4(im,4),dxy4p(im,4) + real(kind=kind_phys) :: dxy(im),dxyp(im) + real(kind=kind_phys) :: ol4p(4),olp(im),od(im) + real(kind=kind_phys) :: taufb(im,km+1) + + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + + integer :: udtend, vdtend, Tdtend + + ! Calculate inverse of gravitational acceleration + g_inv = 1./G + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! Initialize local variables + var_temp2 = 0. + udtend = -1 + vdtend = -1 + Tdtend = -1 + + if(ldiag3d) then + udtend = dtidx(index_of_x_wind,index_of_process_orographic_gwd) + vdtend = dtidx(index_of_y_wind,index_of_process_orographic_gwd) + Tdtend = dtidx(index_of_temperature,index_of_process_orographic_gwd) + endif +! +!---- constants +! + rcl = 1. + rcs = sqrt(rcl) + cs = 1. / sqrt(rcl) + csg = cs * g + lcap = km + lcapp1 = lcap + 1 + fdir = mdir / (2.0*pi) + invgrcs = 1._kind_phys/g*rcs + kpblmax = km / 2 ! maximum pbl height : # of vertical levels / 2 + denfac = 1.0 + + 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 this module + else + xland(i)=2.0 + endif + RDXZB(i) = 0.0 + enddo + +!--- calculate scale-aware tapering factors + do i=1,im + if ( dx(i) .ge. dxmax_ls ) then + ls_taper(i) = 1. + else + if ( dx(i) .le. dxmin_ls) then + ls_taper(i) = 0. + else + ls_taper(i) = 0.5 * ( SIN(pi*(dx(i)-0.5*(dxmax_ls+dxmin_ls))/ & + (dxmax_ls-dxmin_ls)) + 1. ) + endif + endif + enddo + + ! Remove ss_tapering + ss_taper(:) = 1. + + ! SPP, if spp_gwd is 0, no perturbations are applied. + if ( spp_gwd==1 ) then + do i = its,im + var_stoch(i) = var(i) + var(i)*0.75*spp_wts_gwd(i,1) + varss_stoch(i) = varss(i) + varss(i)*0.75*spp_wts_gwd(i,1) + varmax_ss_stoch(i) = varmax_ss + varmax_ss*0.75*spp_wts_gwd(i,1) + varmax_fd_stoch(i) = varmax_fd + varmax_fd*0.75*spp_wts_gwd(i,1) + enddo + else + do i = its,im + var_stoch(i) = var(i) + varss_stoch(i) = varss(i) + varmax_ss_stoch(i) = varmax_ss + varmax_fd_stoch(i) = varmax_fd + enddo + endif + + !--- calculate length of grid for flow-blocking drag + ! + do i=1,im + delx = dx(i) + dely = dx(i) + dxy4(i,1) = delx + dxy4(i,2) = dely + dxy4(i,3) = sqrt(delx*delx + dely*dely) + dxy4(i,4) = dxy4(i,3) + dxy4p(i,1) = dxy4(i,2) + dxy4p(i,2) = dxy4(i,1) + dxy4p(i,3) = dxy4(i,4) + dxy4p(i,4) = dxy4(i,3) + cleff(i) = psl_gwd_dx_factor*(delx+dely)*0.5 + cleff_ss(i) = 0.1 * max(dxmax_ss,dxy4(i,3)) + ! cleff_ss(i) = cleff(i) ! consider ..... + enddo +! +!-----initialize arrays +! + dtaux = 0.0 + dtauy = 0.0 + do i = its,im + klowtop(i) = 0 + kbl(i) = 0 + enddo +! + do i = its,im + xn(i) = 0.0 + yn(i) = 0.0 + ubar (i) = 0.0 + vbar (i) = 0.0 + roll (i) = 0.0 + taub (i) = 0.0 + oa(i) = 0.0 + ol(i) = 0.0 + oc(i) = 0.0 + oass(i) = 0.0 + olss(i) = 0.0 + ulow (i) = 0.0 + rstoch(i) = 0.0 + ldrag(i) = .false. + icrilv(i) = .false. + enddo + + do k = kts,km + do i = its,im + usqj(i,k) = 0.0 + bnv2(i,k) = 0.0 + vtj(i,k) = 0.0 + vtk(i,k) = 0.0 + taup(i,k) = 0.0 + taud_ls(i,k) = 0.0 + taud_bl(i,k) = 0.0 + dtaux2d(i,k) = 0.0 + dtauy2d(i,k) = 0.0 + dtfac(i,k) = 1.0 + enddo + enddo +! + if ( ldiag_ugwp ) then + do i = its,im + dusfc_ls(i) = 0.0 + dvsfc_ls(i) = 0.0 + dusfc_bl(i) = 0.0 + dvsfc_bl(i) = 0.0 + dusfc_ss(i) = 0.0 + dvsfc_ss(i) = 0.0 + dusfc_fd(i) = 0.0 + dvsfc_fd(i) = 0.0 + enddo + do k = kts,km + do i = its,im + dtaux2d_ls(i,k)= 0.0 + dtauy2d_ls(i,k)= 0.0 + dtaux2d_bl(i,k)= 0.0 + dtauy2d_bl(i,k)= 0.0 + dtaux2d_ss(i,k)= 0.0 + dtauy2d_ss(i,k)= 0.0 + dtaux2d_fd(i,k)= 0.0 + dtauy2d_fd(i,k)= 0.0 + enddo + enddo + endif + + do i = its,im + taup(i,km+1) = 0.0 + xlinv(i) = 1.0/xl + dusfc(i) = 0.0 + dvsfc(i) = 0.0 + enddo +! +! initialize array for flow-blocking drag +! + taufb(1:im,1:km+1) = 0.0 + hmax(1:im) = 0.0 + komax(1:im) = 0 + kbmax(1:im) = 0 + kblk(1:im) = 0 +! + rd_inv = 1./rd + do k = kts,km + do i = its,im + vtj(i,k) = t1(i,k) * (1.+fv*q1(i,k)) + vtk(i,k) = vtj(i,k) / prslk(i,k) + ro(i,k) = rd_inv * prsl(i,k) / vtj(i,k) ! density kg/m**3 + enddo + enddo +! +! calculate mid-layer height (zl), interface height (zq), and layer depth (dz2). +! + !zq=0. + do k = kts,km + do i = its,im + !zq(i,k+1) = PHII(i,k+1)*g_inv + !dz2(i,k) = (PHII(i,k+1)-PHII(i,k))*g_inv + zl(i,k) = PHIL(i,k)*g_inv + enddo + enddo +! +! determine reference level: maximum of 2*var and pbl heights +! + do i = its,im + if(vtype(i)==15) then + zlowtop(i) = 1.0 * var_stoch(i) !!! reduce drag over land ice + else + zlowtop(i) = 2.0 * var_stoch(i) + endif + enddo +! + do i = its,im + flag(i) = .true. + enddo +! + do k = kts+1,km + do i = its,im + if(flag(i).and.zl(i,k).ge.zlowtop(i)) then + klowtop(i) = k+1 + flag(i) = .false. + endif + enddo + enddo +! +! determine the maximum height level +! note taht elvmax and zl are the heights from the model surface whereas +! oro (mean orography) is the height from the sea level +! + do i = its,im + flag(i) = .true. + enddo +! + do k = kts+1,km + do i = its,im + if(flag(i).and.zl(i,k).ge.elvmax(i)) then + komax(i) = k+1 + flag(i) = .false. + endif + enddo + enddo +! +! determine the launching level in determining blocking layer +! + do i = its,im + flag(i) = .true. + enddo +! + do k = kts+1,km + do i = its,im + if(flag(i).and.zl(i,k).ge.elvmax(i)+zlowtop(i)) then + kbmax(i) = k+1 + flag(i) = .false. + endif + enddo + enddo +! +! determing the reference level for gwd and blockding... +! + do i = its,im + hmax(i) = max(elvmax(i),zlowtop(i)) + enddo +! + do i = its,im +!!! kbl(i) = max(kpbl(i), klowtop(i)) ! do not use pbl height for the time being... + kbl(i) = max(komax(i), klowtop(i)) + kbl(i) = max(min(kbl(i),kpblmax),kpblmin) + enddo +! +! compute low level averages below reference level +! + do i = its,im + delks(i) = 1.0 / (prsi(i,1) - prsi(i,kbl(i))) + delks1(i) = 1.0 / (prsl(i,1) - prsl(i,kbl(i))) + enddo + do k = kts,kpblmax + do i = its,im + if (k.lt.kbl(i)) then + rcsks = rcs * del(i,k) * delks(i) + rdelks = del(i,k) * delks(i) + ubar(i) = ubar(i) + rcsks * u1(i,k) ! pbl u mean + vbar(i) = vbar(i) + rcsks * v1(i,k) ! pbl v mean + roll(i) = roll(i) + rdelks * ro(i,k) ! ro mean + endif + enddo + enddo +! +! figure out low-level horizontal wind direction +! +! nwd 1 2 3 4 5 6 7 8 +! wd w s sw nw e n ne se +! + do i = its,im + wdir = atan2(ubar(i),vbar(i)) + pi + idir = mod(nint(fdir*wdir),mdir) + 1 + nwd = nwdir(idir) + oa(i) = (1-2*int( (nwd-1)/4 )) * oa4(i,mod(nwd-1,4)+1) + ol(i) = max(ol4(i,mod(nwd-1,4)+1),olmin) + oc(i) = min(max(oc1(i),oc_min),oc_max) +! if (var(i).le.var_min) then +! oc(i) = max(oc(i)*var(i)/var_min,oc_min) +! endif + ! Repeat for small-scale gwd + oass(i) = (1-2*int( (nwd-1)/4 )) * oa4ss(i,mod(nwd-1,4)+1) + olss(i) = ol4ss(i,mod(nwd-1,4)+1) + +! +!----- compute orographic width along (ol) and perpendicular (olp) +!----- the direction of wind +! + ol4p(1) = ol4(i,2) + ol4p(2) = ol4(i,1) + ol4p(3) = ol4(i,4) + ol4p(4) = ol4(i,3) + olp(i) = max(ol4p(mod(nwd-1,4)+1),olmin) +! +!----- compute orographic direction (horizontal orographic aspect ratio) +! + od(i) = olp(i)/ol(i) + od(i) = min(od(i),odmax) + od(i) = max(od(i),odmin) +! +!----- compute length of grid in the along(dxy) and cross(dxyp) wind directions +! + dxy(i) = dxy4(i,MOD(nwd-1,4)+1) + dxyp(i) = dxy4p(i,MOD(nwd-1,4)+1) + enddo +! +! END INITIALIZATION; BEGIN GWD CALCULATIONS: +! +IF ( (do_gsl_drag_ls_bl).and. & + ((gwd_opt_ls .EQ. 1).or.(gwd_opt_bl .EQ. 1)) ) then + + g_cp = g/cp + do i=its,im + + if ( ls_taper(i).GT.1.E-02 ) then + +! +!--- saving richardson number in usqj for migwdi +! + do k = kts,km-1 + ti = 2.0 / (t1(i,k)+t1(i,k+1)) + rdz = 1./(zl(i,k+1) - zl(i,k)) + tem1 = u1(i,k) - u1(i,k+1) + tem2 = v1(i,k) - v1(i,k+1) + dw2 = rcl*(tem1*tem1 + tem2*tem2) + shr2 = max(dw2,dw2min) * rdz * rdz + bvf2 = g*(g_cp+rdz*(vtj(i,k+1)-vtj(i,k))) * ti + usqj(i,k) = max(bvf2/shr2,rimin) + bnv2(i,k) = 2.0*g*rdz*(vtk(i,k+1)-vtk(i,k))/(vtk(i,k+1)+vtk(i,k)) + bnv2(i,k) = max( bnv2(i,k), bnv2min ) + enddo +! +!----compute the "low level" or 1/3 wind magnitude (m/s) +! + ulow(i) = max(sqrt(ubar(i)*ubar(i) + vbar(i)*vbar(i)), 1.0) + rulow(i) = 1./ulow(i) +! + do k = kts,km-1 + velco(i,k) = (0.5*rcs) * ((u1(i,k)+u1(i,k+1)) * ubar(i) & + + (v1(i,k)+v1(i,k+1)) * vbar(i)) + velco(i,k) = velco(i,k) * rulow(i) + if ((velco(i,k).lt.veleps) .and. (velco(i,k).gt.0.)) then + velco(i,k) = veleps + endif + enddo +! +! no drag when sub-oro is too small.. +! + ldrag(i) = hmax(i).le.hmt_min +! +! no drag when critical level in the base layer +! + ldrag(i) = ldrag(i).or. velco(i,1).le.0. +! +! no drag when velco.lt.0 +! + do k = kpblmin,kpblmax + if (k .lt. kbl(i)) ldrag(i) = ldrag(i).or. velco(i,k).le.0. + enddo +! +! no drag when bnv2.lt.0 +! + do k = kts,kpblmax + if (k .lt. kbl(i)) ldrag(i) = ldrag(i).or. bnv2(i,k).lt.0. + enddo +! +!-----the low level weighted average ri is stored in usqj(1,1; im) +!-----the low level weighted average n**2 is stored in bnv2(1,1; im) +!---- this is called bnvl2 in phys_gwd_alpert_sub not bnv2 +!---- rdelks (del(k)/delks) vert ave factor so we can * instead of / +! + wtkbj = (prsl(i,1)-prsl(i,2)) * delks1(i) + bnv2(i,1) = wtkbj * bnv2(i,1) + usqj(i,1) = wtkbj * usqj(i,1) +! + do k = kpblmin,kpblmax + if (k .lt. kbl(i)) then + rdelks = (prsl(i,k)-prsl(i,k+1)) * delks1(i) + bnv2(i,1) = bnv2(i,1) + bnv2(i,k) * rdelks + usqj(i,1) = usqj(i,1) + usqj(i,k) * rdelks + endif + enddo +! + ldrag(i) = ldrag(i) .or. bnv2(i,1).le.0.0 + ldrag(i) = ldrag(i) .or. ulow(i).eq.1.0 + ldrag(i) = ldrag(i) .or. var_stoch(i) .le. 0.0 + ldrag(i) = ldrag(i) .or. xland(i) .gt. 1.5 +! +! set all ri low level values to the low level value +! + do k = kpblmin,kpblmax + if (k .lt. kbl(i)) usqj(i,k) = usqj(i,1) + enddo +! + if (.not.ldrag(i)) then + bnv(i) = sqrt( bnv2(i,1) ) + fr(i) = bnv(i) * rulow(i) * 2. * var_stoch(i) * od(i) + fr(i) = min(fr(i),frmax) + xn(i) = ubar(i) * rulow(i) + yn(i) = vbar(i) * rulow(i) + endif +! +! compute the base level stress and store it in taub +! calculate enhancement factor, number of mountains & aspect +! ratio const. use simplified relationship between standard +! deviation & critical hgt + + if (.not. ldrag(i)) then + efact = (oa(i) + 2.) ** (ce*fr(i)/frc) + efact = min( max(efact,efmin), efmax ) + coefm(i) = (1. + ol(i)) ** (oa(i)+1.) + xlinv(i) = coefm(i) / cleff(i) + tem = fr(i) * fr(i) * oc(i) + gfobnv = gmax * tem / ((tem + cg)*bnv(i)) + if ( gwd_opt_ls .NE. 0 ) then + taub(i) = xlinv(i) * roll(i) * ulow(i) * ulow(i) & + * ulow(i) * gfobnv * efact + else ! We've gotten what we need for the blocking scheme + taub(i) = 0.0 + end if + else + taub(i) = 0.0 + xn(i) = 0.0 + yn(i) = 0.0 + endif + + endif ! (ls_taper(i).GT.1.E-02) + + enddo ! do i=its,im + +ENDIF ! (do_gsl_drag_ls_bl).and.((gwd_opt_ls .EQ. 1).or.(gwd_opt_bl .EQ. 1)) + +!========================================================= +! add small-scale wavedrag for stable boundary layer +!========================================================= + XNBV=0. + tauwavex0=0. + tauwavey0=0. + density=1.2 + utendwave=0. + vtendwave=0. +! +IF ( do_gsl_drag_ss ) THEN + + do i=its,im + + if ( ss_taper(i).GT.1.E-02 ) then + ! + ! calculating potential temperature + ! + do k = kts,km + thx(i,k) = t1(i,k)/prslk(i,k) + enddo + ! + do k = kts,km + tvcon = (1.+fv*q1(i,k)) + thvx(i,k) = thx(i,k)*tvcon + enddo + + hpbl2 = hpbl(i)+10. + kpbl2 = kpbl(i) + !kvar = MIN(kpbl, k-level of var) + kvar = 1 + do k=kts+1,MAX(kpbl(i),kts+1) +! IF (zl(i,k)>2.*var(i) .or. zl(i,k)>2*varmax) then + IF (zl(i,k)>300.) then + kpbl2 = k + IF (k == kpbl(i)) then + hpbl2 = hpbl(i)+10. + ELSE + hpbl2 = zl(i,k)+10. + ENDIF + exit + ENDIF + enddo + if((xland(i)-1.5).le.0. .and. 2.*varss_stoch(i).le.hpbl(i))then + if(br1(i).gt.0. .and. thvx(i,kpbl2)-thvx(i,kts) > 0.)then + coefm_ss(i) = (1. + olss(i)) ** (oass(i)+1.) + xlinv(i) = coefm_ss(i) / cleff_ss(i) + !govrth(i)=g/(0.5*(thvx(i,kpbl(i))+thvx(i,kts))) + govrth(i)=g/(0.5*(thvx(i,kpbl2)+thvx(i,kts))) + !XNBV=sqrt(govrth(i)*(thvx(i,kpbl(i))-thvx(i,kts))/hpbl(i)) + XNBV=sqrt(govrth(i)*(thvx(i,kpbl2)-thvx(i,kts))/hpbl2) +! + !if(abs(XNBV/u1(i,kpbl(i))).gt.xlinv(i))then + if(abs(XNBV/u1(i,kpbl2)).gt.xlinv(i))then + !tauwavex0=0.5*XNBV*xlinv(i)*(2*MIN(varss(i),75.))**2*ro(i,kts)*u1(i,kpbl(i)) + !tauwavex0=0.5*XNBV*xlinv(i)*(2.*MIN(varss(i),40.))**2*ro(i,kts)*u1(i,kpbl2) + !tauwavex0=0.5*XNBV*xlinv(i)*(2.*MIN(varss(i),40.))**2*ro(i,kts)*u1(i,3) + ! Remove limit on varss_stoch + var_temp = varss_stoch(i) + ! Note: This is a semi-implicit treatment of the time differencing + var_temp2 = 0.5*XNBV*xlinv(i)*(2.*var_temp)**2*ro(i,kvar) ! this is greater than zero + tauwavex0=var_temp2*u1(i,kvar)/(1.+var_temp2*deltim) + tauwavex0=tauwavex0*ss_taper(i) + else + tauwavex0=0. + endif +! + !if(abs(XNBV/v1(i,kpbl(i))).gt.xlinv(i))then + if(abs(XNBV/v1(i,kpbl2)).gt.xlinv(i))then + !tauwavey0=0.5*XNBV*xlinv(i)*(2*MIN(varss(i),75.))**2*ro(i,kts)*v1(i,kpbl(i)) + !tauwavey0=0.5*XNBV*xlinv(i)*(2.*MIN(varss(i),40.))**2*ro(i,kts)*v1(i,kpbl2) + !tauwavey0=0.5*XNBV*xlinv(i)*(2.*MIN(varss(i),40.))**2*ro(i,kts)*v1(i,3) + ! Remove limit on varss_stoch + var_temp = varss_stoch(i) + ! Note: This is a semi-implicit treatment of the time differencing + var_temp2 = 0.5*XNBV*xlinv(i)*(2.*var_temp)**2*ro(i,kvar) ! this is greater than zero + tauwavey0=var_temp2*v1(i,kvar)/(1.+var_temp2*deltim) + tauwavey0=tauwavey0*ss_taper(i) + else + tauwavey0=0. + endif + + do k=kts,kpbl(i) !MIN(kpbl2+1,km-1) +!original + !utendwave(i,k)=-1.*tauwavex0*2.*max((1.-zl(i,k)/hpbl(i)),0.)/hpbl(i) + !vtendwave(i,k)=-1.*tauwavey0*2.*max((1.-zl(i,k)/hpbl(i)),0.)/hpbl(i) +!new + utendwave(i,k)=-1.*tauwavex0*2.*max((1.-zl(i,k)/hpbl2),0.)/hpbl2 + vtendwave(i,k)=-1.*tauwavey0*2.*max((1.-zl(i,k)/hpbl2),0.)/hpbl2 +!mod-to be used in HRRRv3/RAPv4 + !utendwave(i,k)=-1.*tauwavex0 * max((1.-zl(i,k)/hpbl2),0.)**2 + !vtendwave(i,k)=-1.*tauwavey0 * max((1.-zl(i,k)/hpbl2),0.)**2 + enddo + endif + endif + + do k = kts,km + dudt(i,k) = dudt(i,k) + utendwave(i,k) + dvdt(i,k) = dvdt(i,k) + vtendwave(i,k) + dusfc(i) = dusfc(i) + utendwave(i,k) * del(i,k) + dvsfc(i) = dvsfc(i) + vtendwave(i,k) * del(i,k) + enddo + if(udtend>0) then + dtend(i,kts:km,udtend) = dtend(i,kts:km,udtend) + utendwave(i,kts:km)*deltim + endif + if(vdtend>0) then + dtend(i,kts:km,vdtend) = dtend(i,kts:km,vdtend) + vtendwave(i,kts:km)*deltim + endif + if ( ldiag_ugwp ) then + do k = kts,km + dusfc_ss(i) = dusfc_ss(i) + utendwave(i,k) * del(i,k) + dvsfc_ss(i) = dvsfc_ss(i) + vtendwave(i,k) * del(i,k) + dtaux2d_ss(i,k) = utendwave(i,k) + dtauy2d_ss(i,k) = vtendwave(i,k) + enddo + endif + + endif ! if (ss_taper(i).GT.1.E-02) + + enddo ! i=its,im + +ENDIF ! if (do_gsl_drag_ss) + +!================================================================ +! Topographic Form Drag from Beljaars et al. (2004, QJRMS, equ. 16): +!================================================================ +IF ( do_gsl_drag_tofd ) THEN + + do i=its,im + + if ( ss_taper(i).GT.1.E-02 ) then + + utendform=0. + vtendform=0. + + IF ((xland(i)-1.5) .le. 0.) then + !(IH*kflt**n1)**-1 = (0.00102*0.00035**-1.9)**-1 = 0.00026615161 + ! Remove limit on varss_stoch + var_temp = varss_stoch(i) + !var_temp = MIN(var_temp, 250.) + a1=0.00026615161*var_temp**2 +! a1=0.00026615161*MIN(varss(i),varmax)**2 +! a1=0.00026615161*(0.5*varss(i))**2 + ! k1**(n1-n2) = 0.003**(-1.9 - -2.8) = 0.003**0.9 = 0.005363 + a2=a1*0.005363 + ! Beljaars H_efold + H_efold = 1500. + DO k=kts,km + wsp=SQRT(u1(i,k)**2 + v1(i,k)**2) + ! Note: In Beljaars et al. (2004): + ! alpha_fd*beta*Cmd*Ccorr*2.109 = 12.*1.*0.005*0.6*2.109 = 0.0759 + ! lump beta*Cmd*Ccorr*2.109 into 1.*0.005*0.6*2.109 = coeff_fd ~ 6.325e-3_kind_phys + var_temp = alpha_fd*coeff_fd*EXP(-(zl(i,k)/H_efold)**1.5)*a2* & + zl(i,k)**(-1.2)*ss_taper(i) ! this is greater than zero + ! Note: This is a semi-implicit treatment of the time differencing + ! per Beljaars et al. (2004, QJRMS) + utendform(i,k) = - var_temp*wsp*u1(i,k)/(1. + var_temp*deltim*wsp) + vtendform(i,k) = - var_temp*wsp*v1(i,k)/(1. + var_temp*deltim*wsp) + !IF(zl(i,k) > 4000.) exit + ENDDO + ENDIF + + do k = kts,km + dudt(i,k) = dudt(i,k) + utendform(i,k) + dvdt(i,k) = dvdt(i,k) + vtendform(i,k) + dusfc(i) = dusfc(i) + utendform(i,k) * del(i,k) + dvsfc(i) = dvsfc(i) + vtendform(i,k) * del(i,k) + enddo + if(udtend>0) then + dtend(i,kts:km,udtend) = dtend(i,kts:km,udtend) + utendform(i,kts:km)*deltim + endif + if(vdtend>0) then + dtend(i,kts:km,vdtend) = dtend(i,kts:km,vdtend) + vtendform(i,kts:km)*deltim + endif + if ( ldiag_ugwp ) then + do k = kts,km + dtaux2d_fd(i,k) = utendform(i,k) + dtauy2d_fd(i,k) = vtendform(i,k) + dusfc_fd(i) = dusfc_fd(i) + utendform(i,k) * del(i,k) + dvsfc_fd(i) = dvsfc_fd(i) + vtendform(i,k) * del(i,k) + enddo + endif + + endif ! if (ss_taper(i).GT.1.E-02) + + enddo ! i=its,im + +ENDIF ! if (do_gsl_drag_tofd) +!======================================================= +! More for the large-scale gwd component +IF ( (do_gsl_drag_ls_bl).and.(gwd_opt_ls .EQ. 1) ) THEN + + do i=its,im + + if ( ls_taper(i).GT.1.E-02 ) then + +! +! now compute vertical structure of the stress. + do k = kts,kpblmax + if (k .le. kbl(i)) taup(i,k) = taub(i) + enddo +! + do k = kpblmin, km-1 ! vertical level k loop! + kp1 = k + 1 +! +! unstablelayer if ri < ric +! unstable layer if upper air vel comp along surf vel <=0 (crit lay) +! at (u-c)=0. crit layer exists and bit vector should be set (.le.) +! + if (k .ge. kbl(i)) then + icrilv(i) = icrilv(i) .or. ( usqj(i,k) .lt. ric) & + .or. (velco(i,k) .le. 0.0) + brvf(i) = max(bnv2(i,k),bnv2min) ! brunt-vaisala frequency squared + brvf(i) = sqrt(brvf(i)) ! brunt-vaisala frequency + endif +! + if (k .ge. kbl(i) .and. (.not. ldrag(i))) then + if (.not.icrilv(i) .and. taup(i,k) .gt. 0.0 ) then + temv = 1.0 / velco(i,k) + tem1 = coefm(i)/dxy(i)*(ro(i,kp1)+ro(i,k))*brvf(i)* & + velco(i,k)*0.5 + hd = sqrt(taup(i,k) / tem1) + fro = brvf(i) * hd * temv +! +! rim is the minimum-richardson number by shutts (1985) + tem2 = sqrt(usqj(i,k)) + tem = 1. + tem2 * fro + rim = usqj(i,k) * (1.-fro) / (tem * tem) +! +! check stability to employ the 'saturation hypothesis' +! of lindzen (1981) except at tropospheric downstream regions +! + if (rim .le. ric) then ! saturation hypothesis! + temc = 2.0 + 1.0 / tem2 + hd = velco(i,k) * (2.*sqrt(temc)-temc) / brvf(i) + taup(i,kp1) = tem1 * hd * hd + else ! no wavebreaking! + taup(i,kp1) = taup(i,k) + endif + endif + endif + enddo +! + if(lcap.lt.km) then + do klcap = lcapp1,km + taup(i,klcap) = prsi(i,klcap) / prsi(i,lcap) * taup(i,lcap) + enddo + endif + + endif ! if ( ls_taper(i).GT.1.E-02 ) + + enddo ! do i=its,im + +ENDIF ! (do_gsl_drag_ls_bl).and.(gwd_opt_ls .EQ. 1) +!=============================================================== +!COMPUTE BLOCKING COMPONENT +!=============================================================== +IF ( (do_gsl_drag_ls_bl) .and. (gwd_opt_bl .EQ. 1) ) THEN + do i = its,im + flag(i) = .true. + enddo + + do i=its,im + + if ( ls_taper(i).GT.1.E-02 ) then + + if (.not.ldrag(i)) then +! +!------- determine the height of flow-blocking layer +! + pe = 0.0 + ke = 0.0 + do k = km, kpblmin, -1 + if(flag(i).and. k.le.kbmax(i)) then + pe = pe + bnv2(i,k)*(zl(i,kbmax(i))-zl(i,k))* & + del(i,k)*g_inv/ro(i,k) + ke = 0.5*((rcs*u1(i,k))**2.+(rcs*v1(i,k))**2.) +! +!---------- apply flow-blocking drag when pe >= ke +! + if(pe.ge.ke.and.zl(i,k).le.hmax(i)) then + kblk(i)= k + zblk = zl(i,k) + RDXZB(i) = real(k,kind=kind_phys) + flag(i) = .false. + endif + endif + enddo + if(.not.flag(i)) then +! +!--------- compute flow-blocking stress +! + cd = max(2.0-1.0/od(i),cdmin) + taufb(i,kts) = 0.5 * roll(i) * coefm(i) / & + max(dxmax_ls,dxy(i))**2 * cd * dxyp(i) * & + olp(i) * zblk * ulow(i)**2 + tautem = taufb(i,kts)/float(kblk(i)-kts) + do k = kts+1, kpblmax + if (k .le. kblk(i)) taufb(i,k) = taufb(i,k-1) - tautem + enddo +! +! reset gwd stress below blocking layer +! + do k = kts,kpblmax + if (k .le. kblk(i)) taup(i,k) = taup(i,kblk(i)) + enddo +! if(kblk(i).gt.5) print *,' gwd kbl komax kbmax kblk ',kbl(i),komax(i),kbmax(i),kblk(i) +! if(kblk(i).gt.5) print *,' gwd elvmax zlowtop zblk ',elvmax(i),zlowtop(i),zl(i,kblk(i)) + endif + + endif ! if (.not.ldrag(i)) + + endif ! if ( ls_taper(i).GT.1.E-02 ) + + enddo ! do i=its,im + +ENDIF ! IF ( (do_gsl_drag_ls_bl) .and. (gwd_opt_bl .EQ. 1) ) +!=========================================================== +IF ( (do_gsl_drag_ls_bl) .and. & + (gwd_opt_ls .EQ. 1 .OR. gwd_opt_bl .EQ. 1) ) THEN + + do i=its,im + + if ( ls_taper(i) .GT. 1.E-02 ) then + +! +! calculate - (g)*d(tau)/d(pressure) and deceleration terms dtaux, dtauy +! + do k = kts,km + taud_ls(i,k) = 1. * (taup(i,k+1) - taup(i,k)) * csg / del(i,k) + taud_bl(i,k) = 1. * (taufb(i,k+1) - taufb(i,k)) * csg / del(i,k) + enddo +! +! limit de-acceleration (momentum deposition ) at top to 1/2 value +! the idea is some stuff must go out the 'top' + do klcap = lcap,km + taud_ls(i,klcap) = taud_ls(i,klcap) * factop + taud_bl(i,klcap) = taud_bl(i,klcap) * factop + enddo +! +! if the gravity wave drag would force a critical line +! in the lower ksmm1 layers during the next deltim timestep, +! then only apply drag until that critical line is reached. +! + do k = kts,kpblmax-1 + if ((taud_ls(i,k)+taud_bl(i,k)).ne.0.) then + dtfac(i,k) = min(dtfac(i,k),abs(velco(i,k) & + /(deltim*rcs*(taud_ls(i,k)+taud_bl(i,k))))) + endif + enddo +! apply limiter to mesosphere drag, reduce the drag by density factor 10-3 +! prevent wind reversal... +! + do k = kpblmax,km-1 + if ((taud_ls(i,k)+taud_bl(i,k)).ne.0..and.prsl(i,k).le.pcutoff) then + denfac = min(ro(i,k)/pcutoff_den,1.) + dtfac(i,k) = min(dtfac(i,k),denfac*abs(velco(i,k) & + /(deltim*rcs*(taud_ls(i,k)+taud_bl(i,k))))) + endif + enddo +! + do k = kts,km + taud_ls(i,k) = taud_ls(i,k)*dtfac(i,k)* ls_taper(i) *(1.-rstoch(i)) + taud_bl(i,k) = taud_bl(i,k)*dtfac(i,k)* ls_taper(i) *(1.-rstoch(i)) + dtaux = taud_ls(i,k) * xn(i) + dtauy = taud_ls(i,k) * yn(i) + dtauxb = taud_bl(i,k) * xn(i) + dtauyb = taud_bl(i,k) * yn(i) + + !add blocking and large-scale contributions to tendencies + dudt(i,k) = dtaux + dtauxb + dudt(i,k) + dvdt(i,k) = dtauy + dtauyb + dvdt(i,k) + + if ( gsd_diss_ht_opt .EQ. 1 ) then + ! Calculate dissipation heating + ! Initial kinetic energy (at t0-dt) + eng0 = 0.5*( (rcs*u1(i,k))**2. + (rcs*v1(i,k))**2. ) + ! Kinetic energy after wave-breaking/flow-blocking + eng1 = 0.5*( (rcs*(u1(i,k)+(dtaux+dtauxb)*deltim))**2 + & + (rcs*(v1(i,k)+(dtauy+dtauyb)*deltim))**2 ) + ! Modify theta tendency + dtdt(i,k) = dtdt(i,k) + max((eng0-eng1),0.0)/cp/deltim + if ( Tdtend>0 ) then + dtend(i,k,Tdtend) = dtend(i,k,Tdtend) + max((eng0-eng1),0.0)/cp + endif + endif + + dusfc(i) = dusfc(i) + taud_ls(i,k)*xn(i)*del(i,k) + & + taud_bl(i,k)*xn(i)*del(i,k) + dvsfc(i) = dvsfc(i) + taud_ls(i,k)*yn(i)*del(i,k) + & + taud_bl(i,k)*yn(i)*del(i,k) + if(udtend>0) then + dtend(i,k,udtend) = dtend(i,k,udtend) + (taud_ls(i,k) * & + xn(i) + taud_bl(i,k) * xn(i)) * deltim + endif + if(vdtend>0) then + dtend(i,k,vdtend) = dtend(i,k,vdtend) + (taud_ls(i,k) * & + yn(i) + taud_bl(i,k) * yn(i)) * deltim + endif + + enddo + + ! Finalize dusfc and dvsfc diagnostics + dusfc(i) = -(invgrcs) * dusfc(i) + dvsfc(i) = -(invgrcs) * dvsfc(i) + + if ( ldiag_ugwp ) then + do k = kts,km + dtaux2d_ls(i,k) = taud_ls(i,k) * xn(i) + dtauy2d_ls(i,k) = taud_ls(i,k) * yn(i) + dtaux2d_bl(i,k) = taud_bl(i,k) * xn(i) + dtauy2d_bl(i,k) = taud_bl(i,k) * yn(i) + dusfc_ls(i) = dusfc_ls(i) + dtaux2d_ls(i,k) * del(i,k) + dvsfc_ls(i) = dvsfc_ls(i) + dtauy2d_ls(i,k) * del(i,k) + dusfc_bl(i) = dusfc_bl(i) + dtaux2d_bl(i,k) * del(i,k) + dvsfc_bl(i) = dvsfc_bl(i) + dtauy2d_bl(i,k) * del(i,k) + enddo + endif + + endif ! if ( ls_taper(i) .GT. 1.E-02 ) + + enddo ! do i=its,im + +ENDIF ! (do_gsl_drag_ls_bl).and.(gwd_opt_ls.EQ.1 .OR. gwd_opt_bl.EQ.1) + +if ( ldiag_ugwp ) then + ! Finalize dusfc and dvsfc diagnostics + do i = its,im + dusfc_ls(i) = -(invgrcs) * dusfc_ls(i) + dvsfc_ls(i) = -(invgrcs) * dvsfc_ls(i) + dusfc_bl(i) = -(invgrcs) * dusfc_bl(i) + dvsfc_bl(i) = -(invgrcs) * dvsfc_bl(i) + dusfc_ss(i) = -(invgrcs) * dusfc_ss(i) + dvsfc_ss(i) = -(invgrcs) * dvsfc_ss(i) + dusfc_fd(i) = -(invgrcs) * dusfc_fd(i) + dvsfc_fd(i) = -(invgrcs) * dvsfc_fd(i) + enddo +endif +! + return + end subroutine drag_suite_psl ! !> @} diff --git a/physics/GWD/drag_suite.meta b/physics/GWD/drag_suite.meta index fd3d605c1..5413a5482 100644 --- a/physics/GWD/drag_suite.meta +++ b/physics/GWD/drag_suite.meta @@ -521,6 +521,14 @@ type = real kind = kind_phys intent = in +[alpha_fd] + standard_name = alpha_coefficient_for_turbulent_orographic_form_drag + long_name = alpha coefficient for Beljaars et al turbulent orographic form drag + units = 1 + dimensions = () + type = real + kind = kind_phys + intent = in [me] standard_name = mpi_rank long_name = rank of the current MPI task diff --git a/physics/GWD/ugwpv1_gsldrag.F90 b/physics/GWD/ugwpv1_gsldrag.F90 index 290cedd1b..fc90955bd 100644 --- a/physics/GWD/ugwpv1_gsldrag.F90 +++ b/physics/GWD/ugwpv1_gsldrag.F90 @@ -44,7 +44,7 @@ module ugwpv1_gsldrag use cires_ugwpv1_solv2, only: cires_ugwpv1_ngw_solv2 use cires_ugwpv1_oro, only: orogw_v1 - use drag_suite, only: drag_suite_run + use drag_suite, only: drag_suite_run, drag_suite_psl implicit none @@ -305,11 +305,13 @@ end subroutine ugwpv1_gsldrag_finalize !! @{ subroutine ugwpv1_gsldrag_run(me, master, im, levs, ak, bk, ntrac, lonr, dtp, & fhzero, kdt, ldiag3d, lssav, flag_for_gwd_generic_tend, do_gsl_drag_ls_bl, & - do_gsl_drag_ss, do_gsl_drag_tofd, do_ugwp_v1, do_ugwp_v1_orog_only, & + do_gsl_drag_ss, do_gsl_drag_tofd, & + do_gwd_opt_psl, psl_gwd_dx_factor, & + do_ugwp_v1, do_ugwp_v1_orog_only, & do_ugwp_v1_w_gsldrag, gwd_opt, do_tofd, ldiag_ugwp, ugwp_seq_update, & - cdmbgwd, jdat, nmtvr, hprime, oc, theta, sigma, gamma, & + cdmbgwd, alpha_fd, jdat, nmtvr, hprime, oc, theta, sigma, gamma, & elvmax, clx, oa4, varss,oc1ss,oa4ss,ol4ss, dx, xlat, xlat_d, sinlat, coslat, & - area, rain, br1, hpbl, kpbl, slmsk, & + area, rain, br1, hpbl,vtype, kpbl, slmsk, & ugrs, vgrs, tgrs, q1, prsi, prsl, prslk, phii, phil, del, tau_amf, & dudt_ogw, dvdt_ogw, du_ogwcol, dv_ogwcol, & dudt_obl, dvdt_obl, du_oblcol, dv_oblcol, & @@ -367,11 +369,13 @@ subroutine ugwpv1_gsldrag_run(me, master, im, levs, ak, bk, ntrac, lonr, dtp, real(kind=kind_phys), intent(in) :: dtp, fhzero real(kind=kind_phys), intent(in) :: ak(:), bk(:) integer, intent(in) :: kdt, jdat(:) - +! option for psl gwd + logical, intent(in) :: do_gwd_opt_psl ! option for psl gravity wave drag + real(kind=kind_phys), intent(in) :: psl_gwd_dx_factor ! ! SSO parameters and variables integer, intent(in) :: gwd_opt !gwd_opt and nmtvr are "redundant" controls integer, intent(in) :: nmtvr - real(kind=kind_phys), intent(in) :: cdmbgwd(:) ! for gsl_drag + real(kind=kind_phys), intent(in) :: cdmbgwd(:), alpha_fd ! for gsl_drag real(kind=kind_phys), intent(in), dimension(:) :: hprime, oc, theta, sigma, gamma @@ -397,10 +401,10 @@ subroutine ugwpv1_gsldrag_run(me, master, im, levs, ak, bk, ntrac, lonr, dtp, real(kind=kind_phys), intent(in), dimension(:,:) :: prsi, phii real(kind=kind_phys), intent(in), dimension(:,:) :: q1 integer, intent(in), dimension(:) :: kpbl + integer, intent(in), dimension(:) :: vtype real(kind=kind_phys), intent(in), dimension(:) :: rain - real(kind=kind_phys), intent(in), dimension(:) :: br1, slmsk - real(kind=kind_phys), intent(in), dimension(:) :: hpbl + real(kind=kind_phys), intent(in), dimension(:) :: br1, hpbl, slmsk ! ! moved to GFS_phys_time_vary ! real(kind=kind_phys), intent(in), dimension(:) :: ddy_j1tau, ddy_j2tau @@ -545,6 +549,28 @@ subroutine ugwpv1_gsldrag_run(me, master, im, levs, ak, bk, ntrac, lonr, dtp, ! dusfcg, dvsfcg ! ! + if (do_gwd_opt_psl) then + call drag_suite_psl(im, levs, Pdvdt, Pdudt, Pdtdt, & + ugrs,vgrs,tgrs,q1, & + kpbl,prsi,del,prsl,prslk,phii,phil,dtp, & + kdt,hprime,oc,oa4,clx,varss,oc1ss,oa4ss, & + ol4ss,theta,sigma,gamma,elvmax, & + dudt_ogw, dvdt_ogw, dudt_obl, dvdt_obl, & + dudt_oss, dvdt_oss, dudt_ofd, dvdt_ofd, & + dusfcg, dvsfcg, & + du_ogwcol, dv_ogwcol, du_oblcol, dv_oblcol, & + du_osscol, dv_osscol, du_ofdcol, dv_ofdcol, & + slmsk,br1,hpbl,vtype,con_g,con_cp,con_rd,con_rv, & + con_fv, con_pi, lonr, & + cdmbgwd(1:2),alpha_fd,me,master, & + lprnt,ipr,rdxzb,dx,gwd_opt, & + do_gsl_drag_ls_bl,do_gsl_drag_ss,do_gsl_drag_tofd, & + psl_gwd_dx_factor, & + dtend, dtidx, index_of_process_orographic_gwd, & + index_of_temperature, index_of_x_wind, & + index_of_y_wind, ldiag3d, ldiag_ugwp, & + ugwp_seq_update, spp_wts_gwd, spp_gwd, errmsg, errflg) + else call drag_suite_run(im, levs, Pdvdt, Pdudt, Pdtdt, & ugrs,vgrs,tgrs,q1, & kpbl,prsi,del,prsl,prslk,phii,phil,dtp, & @@ -555,14 +581,16 @@ subroutine ugwpv1_gsldrag_run(me, master, im, levs, ak, bk, ntrac, lonr, dtp, dusfcg, dvsfcg, & du_ogwcol, dv_ogwcol, du_oblcol, dv_oblcol, & du_osscol, dv_osscol, du_ofdcol, dv_ofdcol, & - slmsk,br1,hpbl, con_g,con_cp,con_rd,con_rv, & + slmsk,br1,hpbl,con_g,con_cp,con_rd,con_rv, & con_fv, con_pi, lonr, & - cdmbgwd(1:2),me,master,lprnt,ipr,rdxzb,dx,gwd_opt, & + cdmbgwd(1:2),alpha_fd,me,master, & + lprnt,ipr,rdxzb,dx,gwd_opt, & do_gsl_drag_ls_bl,do_gsl_drag_ss,do_gsl_drag_tofd, & dtend, dtidx, index_of_process_orographic_gwd, & index_of_temperature, index_of_x_wind, & index_of_y_wind, ldiag3d, ldiag_ugwp, & ugwp_seq_update, spp_wts_gwd, spp_gwd, errmsg, errflg) + endif ! ! dusfcg = du_ogwcol + du_oblcol + du_osscol + du_ofdcol ! diff --git a/physics/GWD/ugwpv1_gsldrag.meta b/physics/GWD/ugwpv1_gsldrag.meta index 4004ade59..6d9f5426b 100644 --- a/physics/GWD/ugwpv1_gsldrag.meta +++ b/physics/GWD/ugwpv1_gsldrag.meta @@ -402,6 +402,21 @@ dimensions = () type = logical intent = in +[do_gwd_opt_psl] + standard_name = do_gsl_drag_suite_with_psl_gwd_option + long_name = flag to activate PSL drag suite - mesoscale GWD and blocking + units = flag + dimensions = () + type = logical + intent = in +[psl_gwd_dx_factor] + standard_name = effective_grid_spacing_of_psl_gwd_suite + long_name = multiplication of grid spacing + units = 1 + dimensions = () + type = real + kind = kind_phys + intent = in [do_ugwp_v1] standard_name = flag_for_ugwp_version_1 long_name = flag to activate ver 1 CIRES UGWP @@ -459,6 +474,14 @@ type = real kind = kind_phys intent = in +[alpha_fd] + standard_name = alpha_coefficient_for_turbulent_orographic_form_drag + long_name = alpha coefficient for Beljaars et al turbulent orographic form drag + units = 1 + dimensions = () + type = real + kind = kind_phys + intent = in [jdat] standard_name = date_and_time_of_forecast_in_united_states_order long_name = current forecast date and time @@ -645,6 +668,13 @@ type = real kind = kind_phys intent = in +[vtype] + standard_name = vegetation_type_classification + long_name = vegetation type for lsm + units = index + dimensions = (horizontal_loop_extent) + type = integer + intent = in [kpbl] standard_name = vertical_index_at_top_of_atmosphere_boundary_layer long_name = vertical index at top atmospheric boundary layer diff --git a/physics/GWD/unified_ugwp.F90 b/physics/GWD/unified_ugwp.F90 index a169fd101..adedeeb15 100644 --- a/physics/GWD/unified_ugwp.F90 +++ b/physics/GWD/unified_ugwp.F90 @@ -40,7 +40,7 @@ module unified_ugwp use gwdps, only: gwdps_run use cires_ugwp_triggers use ugwp_driver_v0 - use drag_suite, only: drag_suite_run + use drag_suite, only: drag_suite_run, drag_suite_psl implicit none @@ -249,8 +249,8 @@ subroutine unified_ugwp_run(me, master, im, levs, ak,bk, ntrac, dtp, fhzero, kdt varss,oc1ss,oa4ss,ol4ss,dx,dusfc_ms,dvsfc_ms,dusfc_bl,dvsfc_bl,dusfc_ss, & dvsfc_ss,dusfc_fd,dvsfc_fd,dtaux2d_ms,dtauy2d_ms,dtaux2d_bl,dtauy2d_bl, & dtaux2d_ss,dtauy2d_ss,dtaux2d_fd,dtauy2d_fd,dudt_ngw,dvdt_ngw,dtdt_ngw, & - br1,hpbl,slmsk, do_tofd, ldiag_ugwp, ugwp_seq_update, & - cdmbgwd, jdat, xlat, xlat_d, sinlat, coslat, area, & + br1,hpbl,vtype,slmsk, do_tofd, ldiag_ugwp, ugwp_seq_update, & + cdmbgwd, alpha_fd, jdat, xlat, xlat_d, sinlat, coslat, area, & ugrs, vgrs, tgrs, q1, prsi, prsl, prslk, phii, phil, & del, kpbl, dusfcg, dvsfcg, gw_dudt, gw_dvdt, gw_dtdt, gw_kdis, & tau_tofd, tau_mtb, tau_ogw, tau_ngw, & @@ -262,6 +262,7 @@ subroutine unified_ugwp_run(me, master, im, levs, ak,bk, ntrac, dtp, fhzero, kdt index_of_process_nonorographic_gwd, & lssav, flag_for_gwd_generic_tend, do_ugwp_v0, do_ugwp_v0_orog_only, & do_ugwp_v0_nst_only, do_gsl_drag_ls_bl, do_gsl_drag_ss, do_gsl_drag_tofd, & + do_gwd_opt_psl, psl_gwd_dx_factor, & gwd_opt, spp_wts_gwd, spp_gwd, errmsg, errflg) implicit none @@ -270,6 +271,7 @@ subroutine unified_ugwp_run(me, master, im, levs, ak,bk, ntrac, dtp, fhzero, kdt integer, intent(in) :: me, master, im, levs, ntrac, kdt, lonr, nmtvr integer, intent(in) :: gwd_opt integer, intent(in), dimension(:) :: kpbl + integer, intent(in), dimension(:) :: vtype real(kind=kind_phys), intent(in), dimension(:) :: ak, bk real(kind=kind_phys), intent(in), dimension(:) :: oro, oro_uf, hprime, oc, theta, sigma, gamma real(kind=kind_phys), intent(in), dimension(:), optional :: varss,oc1ss @@ -288,7 +290,7 @@ subroutine unified_ugwp_run(me, master, im, levs, ak,bk, ntrac, dtp, fhzero, kdt real(kind=kind_phys), intent(in), dimension(:,:) :: del, ugrs, vgrs, tgrs, prsl, prslk, phil real(kind=kind_phys), intent(in), dimension(:,:) :: prsi, phii real(kind=kind_phys), intent(in), dimension(:,:) :: q1 - real(kind=kind_phys), intent(in) :: dtp, fhzero, cdmbgwd(:) + real(kind=kind_phys), intent(in) :: dtp, fhzero, cdmbgwd(:), alpha_fd integer, intent(in) :: jdat(:) logical, intent(in) :: do_tofd, ldiag_ugwp, ugwp_seq_update @@ -346,6 +348,10 @@ subroutine unified_ugwp_run(me, master, im, levs, ak,bk, ntrac, dtp, fhzero, kdt real(kind=kind_phys), intent(in), optional :: spp_wts_gwd(:,:) integer, intent(in) :: spp_gwd + ! option for psl gwd + logical, intent(in) :: do_gwd_opt_psl ! option for psl gravity wave drag + real(kind=kind_phys), intent(in) :: psl_gwd_dx_factor ! + character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -379,6 +385,18 @@ subroutine unified_ugwp_run(me, master, im, levs, ak,bk, ntrac, dtp, fhzero, kdt errflg = 0 + ! Initialize intent(out) variables in case they are not set below + dusfcg(:) = 0.0 + dvsfcg(:) = 0.0 + rdxzb(:) = 0.0 + tau_ngw(:) = 0.0 + gw_dudt(:,:) = 0.0 + gw_dvdt(:,:) = 0.0 + gw_dtdt(:,:) = 0.0 + gw_kdis(:,:) = 0.0 + dudt_mtb(:,:) = 0.0 + dudt_tms(:,:) = 0.0 + ! 1) ORO stationary GWs ! ------------------ @@ -488,7 +506,27 @@ subroutine unified_ugwp_run(me, master, im, levs, ak,bk, ntrac, dtp, fhzero, kdt ! Note: In case of GSL drag_suite, this includes ss and tofd if ( do_gsl_drag_ls_bl.or.do_gsl_drag_ss.or.do_gsl_drag_tofd ) then - +! + if (do_gwd_opt_psl) then + call drag_suite_psl(im,levs,dvdt,dudt,dtdt,uwnd1,vwnd1, & + tgrs,q1,kpbl,prsi,del,prsl,prslk,phii,phil,dtp, & + kdt,hprime,oc,oa4,clx,varss,oc1ss,oa4ss, & + ol4ss,theta,sigma,gamma,elvmax,dtaux2d_ms, & + dtauy2d_ms,dtaux2d_bl,dtauy2d_bl,dtaux2d_ss, & + dtauy2d_ss,dtaux2d_fd,dtauy2d_fd,dusfcg, & + dvsfcg,dusfc_ms,dvsfc_ms,dusfc_bl,dvsfc_bl, & + dusfc_ss,dvsfc_ss,dusfc_fd,dvsfc_fd, & + slmsk,br1,hpbl,vtype,con_g,con_cp,con_rd,con_rv, & + con_fvirt,con_pi,lonr, & + cdmbgwd,alpha_fd,me,master, & + lprnt,ipr,rdxzb,dx,gwd_opt, & + do_gsl_drag_ls_bl,do_gsl_drag_ss,do_gsl_drag_tofd, & + psl_gwd_dx_factor, & + dtend, dtidx, index_of_process_orographic_gwd, & + index_of_temperature, index_of_x_wind, & + index_of_y_wind, ldiag3d, ldiag_ugwp, & + ugwp_seq_update, spp_wts_gwd, spp_gwd, errmsg, errflg) + else call drag_suite_run(im,levs,dvdt,dudt,dtdt,uwnd1,vwnd1, & tgrs,q1,kpbl,prsi,del,prsl,prslk,phii,phil,dtp, & kdt,hprime,oc,oa4,clx,varss,oc1ss,oa4ss, & @@ -499,12 +537,14 @@ subroutine unified_ugwp_run(me, master, im, levs, ak,bk, ntrac, dtp, fhzero, kdt dusfc_ss,dvsfc_ss,dusfc_fd,dvsfc_fd, & slmsk,br1,hpbl,con_g,con_cp,con_rd,con_rv, & con_fvirt,con_pi,lonr, & - cdmbgwd,me,master,lprnt,ipr,rdxzb,dx,gwd_opt, & + cdmbgwd,alpha_fd,me,master, & + lprnt,ipr,rdxzb,dx,gwd_opt, & do_gsl_drag_ls_bl,do_gsl_drag_ss,do_gsl_drag_tofd, & dtend, dtidx, index_of_process_orographic_gwd, & index_of_temperature, index_of_x_wind, & index_of_y_wind, ldiag3d, ldiag_ugwp, & ugwp_seq_update, spp_wts_gwd, spp_gwd, errmsg, errflg) + endif ! ! put zeros due to xy GSL-drag style: dtaux2d_bl,dtauy2d_bl,dtaux2d_ss.......dusfc_ms,dvsfc_ms ! diff --git a/physics/GWD/unified_ugwp.meta b/physics/GWD/unified_ugwp.meta index de1ce672b..91f63f03e 100644 --- a/physics/GWD/unified_ugwp.meta +++ b/physics/GWD/unified_ugwp.meta @@ -671,6 +671,13 @@ type = real kind = kind_phys intent = in +[vtype] + standard_name = vegetation_type_classification + long_name = vegetation type for lsm + units = index + dimensions = (horizontal_loop_extent) + type = integer + intent = in [slmsk] standard_name = area_type long_name = landmask: sea/land/ice=0/1/2 @@ -708,6 +715,14 @@ type = real kind = kind_phys intent = in +[alpha_fd] + standard_name = alpha_coefficient_for_turbulent_orographic_form_drag + long_name = alpha coefficient for Beljaars et al turbulent orographic form drag + units = 1 + dimensions = () + type = real + kind = kind_phys + intent = in [jdat] standard_name = date_and_time_of_forecast_in_united_states_order long_name = current forecast date and time @@ -1221,6 +1236,21 @@ dimensions = () type = logical intent = in +[do_gwd_opt_psl] + standard_name = do_gsl_drag_suite_with_psl_gwd_option + long_name = flag to activate PSL drag suite - mesoscale GWD and blocking + units = flag + dimensions = () + type = logical + intent = in +[psl_gwd_dx_factor] + standard_name = effective_grid_spacing_of_psl_gwd_suite + long_name = multiplication of grid spacing + units = 1 + dimensions = () + type = real + kind = kind_phys + intent = in [gwd_opt] standard_name = control_for_drag_suite_gravity_wave_drag long_name = flag to choose gwd scheme diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_debug.F90 b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_debug.F90 index 8313368fc..cdd3d8e2b 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_debug.F90 +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_debug.F90 @@ -303,6 +303,16 @@ module GFS_diagtoscreen use print_var_chksum, only: print_var + use machine, only: kind_phys + + use GFS_typedefs, only: GFS_control_type, GFS_statein_type, & + GFS_stateout_type, GFS_sfcprop_type, & + GFS_coupling_type, GFS_grid_type, & + GFS_tbd_type, GFS_cldprop_type, & + GFS_radtend_type, GFS_diag_type + + use CCPP_typedefs, only: GFS_interstitial_type + implicit none private @@ -314,66 +324,70 @@ module GFS_diagtoscreen !> \section arg_table_GFS_diagtoscreen_init Argument Table !! \htmlinclude GFS_diagtoscreen_init.html !! - subroutine GFS_diagtoscreen_init (Model, Data, Interstitial, errmsg, errflg) - - use GFS_typedefs, only: GFS_control_type, GFS_data_type - use CCPP_typedefs, only: GFS_interstitial_type + subroutine GFS_diagtoscreen_init (Model, Statein, Stateout, Sfcprop, Coupling, & + Grid, Tbd, Cldprop, Radtend, Diag, Interstitial, & + errmsg, errflg) implicit none !--- interface variables type(GFS_control_type), intent(in) :: Model - type(GFS_data_type), intent(in) :: Data(:) + type(GFS_statein_type), intent(in) :: Statein + type(GFS_stateout_type), intent(in) :: Stateout + type(GFS_sfcprop_type), intent(in) :: Sfcprop + type(GFS_coupling_type), intent(in) :: Coupling + type(GFS_grid_type), intent(in) :: Grid + type(GFS_tbd_type), intent(in) :: Tbd + type(GFS_cldprop_type), intent(in) :: Cldprop + type(GFS_radtend_type), intent(in) :: Radtend + type(GFS_diag_type), intent(in) :: Diag type(GFS_interstitial_type), intent(in) :: Interstitial(:) character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg - !--- local variables - integer :: i - ! Initialize CCPP error handling variables errmsg = '' errflg = 0 - do i=1,size(Data) - call GFS_diagtoscreen_run (Model, Data(i)%Statein, Data(i)%Stateout, Data(i)%Sfcprop, & - Data(i)%Coupling, Data(i)%Grid, Data(i)%Tbd, Data(i)%Cldprop, & - Data(i)%Radtend, Data(i)%Intdiag, Interstitial(1), & - size(Interstitial), i, errmsg, errflg) - end do + call GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, & + Coupling, Grid, Tbd, Cldprop, & + Radtend, Diag, Interstitial(1), & + size(Interstitial), -999, errmsg, errflg) end subroutine GFS_diagtoscreen_init !> \section arg_table_GFS_diagtoscreen_timestep_init Argument Table !! \htmlinclude GFS_diagtoscreen_timestep_init.html !! - subroutine GFS_diagtoscreen_timestep_init (Model, Data, Interstitial, errmsg, errflg) - - use GFS_typedefs, only: GFS_control_type, GFS_data_type - use CCPP_typedefs, only: GFS_interstitial_type + subroutine GFS_diagtoscreen_timestep_init (Model, Statein, Stateout, Sfcprop, Coupling, & + Grid, Tbd, Cldprop, Radtend, Diag, Interstitial, & + errmsg, errflg) implicit none !--- interface variables type(GFS_control_type), intent(in) :: Model - type(GFS_data_type), intent(in) :: Data(:) + type(GFS_statein_type), intent(in) :: Statein + type(GFS_stateout_type), intent(in) :: Stateout + type(GFS_sfcprop_type), intent(in) :: Sfcprop + type(GFS_coupling_type), intent(in) :: Coupling + type(GFS_grid_type), intent(in) :: Grid + type(GFS_tbd_type), intent(in) :: Tbd + type(GFS_cldprop_type), intent(in) :: Cldprop + type(GFS_radtend_type), intent(in) :: Radtend + type(GFS_diag_type), intent(in) :: Diag type(GFS_interstitial_type), intent(in) :: Interstitial(:) character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg - !--- local variables - integer :: i - ! Initialize CCPP error handling variables errmsg = '' errflg = 0 - do i=1,size(Data) - call GFS_diagtoscreen_run (Model, Data(i)%Statein, Data(i)%Stateout, Data(i)%Sfcprop, & - Data(i)%Coupling, Data(i)%Grid, Data(i)%Tbd, Data(i)%Cldprop, & - Data(i)%Radtend, Data(i)%Intdiag, Interstitial(1), & - size(Interstitial), i, errmsg, errflg) - end do + call GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, & + Coupling, Grid, Tbd, Cldprop, & + Radtend, Diag, Interstitial(1), & + size(Interstitial), -999, errmsg, errflg) end subroutine GFS_diagtoscreen_timestep_init @@ -390,12 +404,6 @@ subroutine GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, #ifdef _OPENMP use omp_lib #endif - use GFS_typedefs, only: GFS_control_type, GFS_statein_type, & - GFS_stateout_type, GFS_sfcprop_type, & - GFS_coupling_type, GFS_grid_type, & - GFS_tbd_type, GFS_cldprop_type, & - GFS_radtend_type, GFS_diag_type - use CCPP_typedefs, only: GFS_interstitial_type implicit none @@ -418,7 +426,7 @@ subroutine GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, !--- local variables integer :: impi, iomp, ierr, n, idtend, iprocess, itracer - integer :: mpirank, mpisize, mpicomm + integer :: mpirank, mpisize integer :: omprank, ompsize ! Initialize CCPP error handling variables @@ -426,13 +434,11 @@ subroutine GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, errflg = 0 #ifdef MPI - mpicomm = Model%communicator mpirank = Model%me mpisize = Model%ntasks #else mpirank = 0 mpisize = 1 - mpicomm = 0 #endif #ifdef _OPENMP omprank = OMP_GET_THREAD_NUM() @@ -446,7 +452,7 @@ subroutine GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, !$OMP BARRIER #endif #ifdef MPI -! call MPI_BARRIER(mpicomm,ierr) +! call MPI_BARRIER(Model%communicator,ierr) #endif do impi=0,mpisize-1 @@ -619,7 +625,7 @@ subroutine GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Tbd%in_nm' , Tbd%in_nm) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Tbd%ccn_nm' , Tbd%ccn_nm) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Tbd%aer_nm' , Tbd%aer_nm) - if (Model%imfdeepcnv == Model%imfdeepcnv_gf .or. Model%imfdeepcnv == Model%imfdeepcnv_unified) then + if (Model%imfdeepcnv == Model%imfdeepcnv_gf) then call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Tbd%cactiv' , Tbd%cactiv) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Tbd%cactiv_m' , Tbd%cactiv_m) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Tbd%aod_gf' , Tbd%aod_gf) @@ -877,13 +883,6 @@ subroutine GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Coupling%v10mi_cpl ', Coupling%v10mi_cpl ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Coupling%tsfci_cpl ', Coupling%tsfci_cpl ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Coupling%psurfi_cpl ', Coupling%psurfi_cpl ) - if (Model%use_med_flux) then - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Coupling%dusfcino_cpl ', Coupling%dusfcino_cpl ) - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Coupling%dvsfcino_cpl ', Coupling%dvsfcino_cpl ) - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Coupling%dtsfcino_cpl ', Coupling%dtsfcino_cpl ) - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Coupling%dqsfcino_cpl ', Coupling%dqsfcino_cpl ) - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Coupling%ulwsfcino_cpl', Coupling%ulwsfcino_cpl ) - end if end if if (Model%cplchm) then call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Coupling%rainc_cpl', Coupling%rainc_cpl) @@ -951,7 +950,7 @@ subroutine GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, #endif end do #ifdef MPI -! call MPI_BARRIER(mpicomm,ierr) +! call MPI_BARRIER(Model%communicator,ierr) #endif end do @@ -959,7 +958,7 @@ subroutine GFS_diagtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, !$OMP BARRIER #endif #ifdef MPI -! call MPI_BARRIER(mpicomm,ierr) +! call MPI_BARRIER(Model%communicator,ierr) #endif end subroutine GFS_diagtoscreen_run @@ -971,6 +970,17 @@ module GFS_interstitialtoscreen use print_var_chksum, only: print_var + use machine, only: kind_phys + + use GFS_typedefs, only: GFS_control_type, GFS_statein_type, & + GFS_stateout_type, GFS_sfcprop_type, & + GFS_coupling_type, GFS_grid_type, & + GFS_tbd_type, GFS_cldprop_type, & + GFS_radtend_type, GFS_diag_type + + use CCPP_typedefs, only: GFS_interstitial_type + + implicit none private @@ -982,16 +992,23 @@ module GFS_interstitialtoscreen !> \section arg_table_GFS_interstitialtoscreen_init Argument Table !! \htmlinclude GFS_interstitialtoscreen_init.html !! - subroutine GFS_interstitialtoscreen_init (Model, Data, Interstitial, errmsg, errflg) - - use GFS_typedefs, only: GFS_control_type, GFS_data_type - use CCPP_typedefs, only: GFS_interstitial_type + subroutine GFS_interstitialtoscreen_init (Model, Statein, Stateout, Sfcprop, Coupling, & + Grid, Tbd, Cldprop, Radtend, Diag, Interstitial, & + errmsg, errflg) implicit none !--- interface variables type(GFS_control_type), intent(in) :: Model - type(GFS_data_type), intent(in) :: Data(:) + type(GFS_statein_type), intent(in) :: Statein + type(GFS_stateout_type), intent(in) :: Stateout + type(GFS_sfcprop_type), intent(in) :: Sfcprop + type(GFS_coupling_type), intent(in) :: Coupling + type(GFS_grid_type), intent(in) :: Grid + type(GFS_tbd_type), intent(in) :: Tbd + type(GFS_cldprop_type), intent(in) :: Cldprop + type(GFS_radtend_type), intent(in) :: Radtend + type(GFS_diag_type), intent(in) :: Diag type(GFS_interstitial_type), intent(in) :: Interstitial(:) character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -1003,11 +1020,9 @@ subroutine GFS_interstitialtoscreen_init (Model, Data, Interstitial, errmsg, err errmsg = '' errflg = 0 - do i=1,size(Interstitial) - call GFS_interstitialtoscreen_run (Model, Data(1)%Statein, Data(1)%Stateout, Data(1)%Sfcprop, & - Data(1)%Coupling, Data(1)%Grid, Data(1)%Tbd, Data(1)%Cldprop, & - Data(1)%Radtend, Data(1)%Intdiag, Interstitial(i), & + call GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, & + Grid, Tbd, Cldprop, Radtend, Diag, Interstitial(i), & size(Interstitial), -999, errmsg, errflg) end do @@ -1016,16 +1031,23 @@ end subroutine GFS_interstitialtoscreen_init !> \section arg_table_GFS_interstitialtoscreen_timestep_init Argument Table !! \htmlinclude GFS_interstitialtoscreen_timestep_init.html !! - subroutine GFS_interstitialtoscreen_timestep_init (Model, Data, Interstitial, errmsg, errflg) - - use GFS_typedefs, only: GFS_control_type, GFS_data_type - use CCPP_typedefs, only: GFS_interstitial_type + subroutine GFS_interstitialtoscreen_timestep_init (Model, Statein, Stateout, Sfcprop, Coupling, & + Grid, Tbd, Cldprop, Radtend, Diag, Interstitial, & + errmsg, errflg) implicit none !--- interface variables type(GFS_control_type), intent(in) :: Model - type(GFS_data_type), intent(in) :: Data(:) + type(GFS_statein_type), intent(in) :: Statein + type(GFS_stateout_type), intent(in) :: Stateout + type(GFS_sfcprop_type), intent(in) :: Sfcprop + type(GFS_coupling_type), intent(in) :: Coupling + type(GFS_grid_type), intent(in) :: Grid + type(GFS_tbd_type), intent(in) :: Tbd + type(GFS_cldprop_type), intent(in) :: Cldprop + type(GFS_radtend_type), intent(in) :: Radtend + type(GFS_diag_type), intent(in) :: Diag type(GFS_interstitial_type), intent(in) :: Interstitial(:) character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -1039,9 +1061,8 @@ subroutine GFS_interstitialtoscreen_timestep_init (Model, Data, Interstitial, er do i=1,size(Interstitial) - call GFS_interstitialtoscreen_run (Model, Data(1)%Statein, Data(1)%Stateout, Data(1)%Sfcprop, & - Data(1)%Coupling, Data(1)%Grid, Data(1)%Tbd, Data(1)%Cldprop, & - Data(1)%Radtend, Data(1)%Intdiag, Interstitial(i), & + call GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coupling, & + Grid, Tbd, Cldprop, Radtend, Diag, Interstitial(i), & size(Interstitial), -999, errmsg, errflg) end do @@ -1060,14 +1081,6 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup #ifdef _OPENMP use omp_lib #endif - use machine, only: kind_phys - use GFS_typedefs, only: GFS_control_type, GFS_statein_type, & - GFS_stateout_type, GFS_sfcprop_type, & - GFS_coupling_type, GFS_grid_type, & - GFS_tbd_type, GFS_cldprop_type, & - GFS_radtend_type, GFS_diag_type - use CCPP_typedefs, only: GFS_interstitial_type - implicit none !--- interface variables @@ -1089,7 +1102,7 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup !--- local variables integer :: impi, iomp, ierr - integer :: mpirank, mpisize, mpicomm + integer :: mpirank, mpisize integer :: omprank, ompsize integer :: istart, iend, kstart, kend @@ -1098,13 +1111,11 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup errflg = 0 #ifdef MPI - mpicomm = Model%communicator mpirank = Model%me - call MPI_COMM_SIZE(mpicomm, mpisize, ierr) + call MPI_COMM_SIZE(Model%communicator, mpisize, ierr) #else mpirank = 0 mpisize = 1 - mpicomm = 0 #endif #ifdef _OPENMP omprank = OMP_GET_THREAD_NUM() @@ -1118,7 +1129,7 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup !$OMP BARRIER #endif #ifdef MPI -! call MPI_BARRIER(mpicomm,ierr) +! call MPI_BARRIER(Model%communicator,ierr) #endif do impi=0,mpisize-1 @@ -1293,7 +1304,6 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%qss_ice ', Interstitial%qss_ice ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%qss_land ', Interstitial%qss_land ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%qss_water ', Interstitial%qss_water ) - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%radar_reset ', Interstitial%radar_reset ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%raddt ', Interstitial%raddt ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%raincd ', Interstitial%raincd ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%raincs ', Interstitial%raincs ) @@ -1322,8 +1332,6 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%sigmafrac ', Interstitial%sigmafrac ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%sigmatot ', Interstitial%sigmatot ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%snowc ', Interstitial%snowc ) - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%snowd_ice ', Interstitial%snowd_ice ) - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%snowd_land ', Interstitial%snowd_land ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%snohf ', Interstitial%snohf ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%snowmt ', Interstitial%snowmt ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%stress ', Interstitial%stress ) @@ -1470,7 +1478,7 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup #endif end do #ifdef MPI -! call MPI_BARRIER(mpicomm,ierr) +! call MPI_BARRIER(Model%communicator,ierr) #endif end do @@ -1478,7 +1486,7 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup !$OMP BARRIER #endif #ifdef MPI -! call MPI_BARRIER(mpicomm,ierr) +! call MPI_BARRIER(Model%communicator,ierr) #endif end subroutine GFS_interstitialtoscreen_run @@ -1535,7 +1543,7 @@ module GFS_checkland !! \htmlinclude GFS_checkland_run.html !! subroutine GFS_checkland_run (me, master, blkno, im, kdt, iter, flag_iter, flag_guess, & - flag_init, flag_restart, frac_grid, isot, ivegsrc, stype,scolor, vtype, slope, & + flag_init, flag_restart, frac_grid, isot, ivegsrc, stype,scolor, vtype, slope, & dry, icy, wet, lake, ocean, oceanfrac, landfrac, lakefrac, slmsk, islmsk, & zorl, zorlw, zorll, zorli, fice, errmsg, errflg ) diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_debug.meta b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_debug.meta index 10eb43671..0d12b2bbb 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_debug.meta +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_debug.meta @@ -9,17 +9,73 @@ type = scheme [Model] standard_name = GFS_control_type_instance - long_name = instance of derived type GFS_control_type in FV3 + long_name = instance of derived type GFS_control_type units = DDT dimensions = () type = GFS_control_type intent = in -[Data] - standard_name = GFS_data_type_instance_all_blocks - long_name = instance of derived type GFS_data_type +[Statein] + standard_name = GFS_statein_type_instance + long_name = prognostic state data in from dycore + units = DDT + dimensions = () + type = GFS_statein_type + intent = in +[Stateout] + standard_name = GFS_stateout_type_instance + long_name = prognostic state or tendencies return to dycore + units = DDT + dimensions = () + type = GFS_stateout_type + intent = in +[Sfcprop] + standard_name = GFS_sfcprop_type_instance + long_name = instance of derived type GFS_sfcprop_type + units = DDT + dimensions = () + type = GFS_sfcprop_type + intent = in +[Coupling] + standard_name = GFS_coupling_type_instance + long_name = instance of derived type GFS_coupling_type + units = DDT + dimensions = () + type = GFS_coupling_type + intent = in +[Grid] + standard_name = GFS_grid_type_instance + long_name = instance of derived type GFS_grid_type + units = DDT + dimensions = () + type = GFS_grid_type + intent = in +[Tbd] + standard_name = GFS_tbd_type_instance + long_name = instance of derived type GFS_tbd_type + units = DDT + dimensions = () + type = GFS_tbd_type + intent = in +[Cldprop] + standard_name = GFS_cldprop_type_instance + long_name = instance of derived type GFS_cldprop_type + units = DDT + dimensions = () + type = GFS_cldprop_type + intent = in +[Radtend] + standard_name = GFS_radtend_type_instance + long_name = instance of derived type GFS_radtend_type units = DDT - dimensions = (ccpp_block_count) - type = GFS_data_type + dimensions = () + type = GFS_radtend_type + intent = in +[Diag] + standard_name = GFS_diag_type_instance + long_name = instance of derived type GFS_diag_type + units = DDT + dimensions = () + type = GFS_diag_type intent = in [Interstitial] standard_name = GFS_interstitial_type_instance_all_threads @@ -55,12 +111,68 @@ dimensions = () type = GFS_control_type intent = in -[Data] - standard_name = GFS_data_type_instance_all_blocks - long_name = instance of derived type GFS_data_type +[Statein] + standard_name = GFS_statein_type_instance + long_name = prognostic state data in from dycore + units = DDT + dimensions = () + type = GFS_statein_type + intent = in +[Stateout] + standard_name = GFS_stateout_type_instance + long_name = prognostic state or tendencies return to dycore + units = DDT + dimensions = () + type = GFS_stateout_type + intent = in +[Sfcprop] + standard_name = GFS_sfcprop_type_instance + long_name = instance of derived type GFS_sfcprop_type + units = DDT + dimensions = () + type = GFS_sfcprop_type + intent = in +[Coupling] + standard_name = GFS_coupling_type_instance + long_name = instance of derived type GFS_coupling_type + units = DDT + dimensions = () + type = GFS_coupling_type + intent = in +[Grid] + standard_name = GFS_grid_type_instance + long_name = instance of derived type GFS_grid_type units = DDT - dimensions = (ccpp_block_count) - type = GFS_data_type + dimensions = () + type = GFS_grid_type + intent = in +[Tbd] + standard_name = GFS_tbd_type_instance + long_name = instance of derived type GFS_tbd_type + units = DDT + dimensions = () + type = GFS_tbd_type + intent = in +[Cldprop] + standard_name = GFS_cldprop_type_instance + long_name = instance of derived type GFS_cldprop_type + units = DDT + dimensions = () + type = GFS_cldprop_type + intent = in +[Radtend] + standard_name = GFS_radtend_type_instance + long_name = instance of derived type GFS_radtend_type + units = DDT + dimensions = () + type = GFS_radtend_type + intent = in +[Diag] + standard_name = GFS_diag_type_instance + long_name = instance of derived type GFS_diag_type + units = DDT + dimensions = () + type = GFS_diag_type intent = in [Interstitial] standard_name = GFS_interstitial_type_instance_all_threads @@ -213,12 +325,68 @@ dimensions = () type = GFS_control_type intent = in -[Data] - standard_name = GFS_data_type_instance_all_blocks - long_name = instance of derived type GFS_data_type +[Statein] + standard_name = GFS_statein_type_instance + long_name = prognostic state data in from dycore + units = DDT + dimensions = () + type = GFS_statein_type + intent = in +[Stateout] + standard_name = GFS_stateout_type_instance + long_name = prognostic state or tendencies return to dycore + units = DDT + dimensions = () + type = GFS_stateout_type + intent = in +[Sfcprop] + standard_name = GFS_sfcprop_type_instance + long_name = instance of derived type GFS_sfcprop_type + units = DDT + dimensions = () + type = GFS_sfcprop_type + intent = in +[Coupling] + standard_name = GFS_coupling_type_instance + long_name = instance of derived type GFS_coupling_type + units = DDT + dimensions = () + type = GFS_coupling_type + intent = in +[Grid] + standard_name = GFS_grid_type_instance + long_name = instance of derived type GFS_grid_type + units = DDT + dimensions = () + type = GFS_grid_type + intent = in +[Tbd] + standard_name = GFS_tbd_type_instance + long_name = instance of derived type GFS_tbd_type + units = DDT + dimensions = () + type = GFS_tbd_type + intent = in +[Cldprop] + standard_name = GFS_cldprop_type_instance + long_name = instance of derived type GFS_cldprop_type + units = DDT + dimensions = () + type = GFS_cldprop_type + intent = in +[Radtend] + standard_name = GFS_radtend_type_instance + long_name = instance of derived type GFS_radtend_type units = DDT - dimensions = (ccpp_block_count) - type = GFS_data_type + dimensions = () + type = GFS_radtend_type + intent = in +[Diag] + standard_name = GFS_diag_type_instance + long_name = instance of derived type GFS_diag_type + units = DDT + dimensions = () + type = GFS_diag_type intent = in [Interstitial] standard_name = GFS_interstitial_type_instance_all_threads @@ -254,12 +422,68 @@ dimensions = () type = GFS_control_type intent = in -[Data] - standard_name = GFS_data_type_instance_all_blocks - long_name = instance of derived type GFS_data_type +[Statein] + standard_name = GFS_statein_type_instance + long_name = prognostic state data in from dycore + units = DDT + dimensions = () + type = GFS_statein_type + intent = in +[Stateout] + standard_name = GFS_stateout_type_instance + long_name = prognostic state or tendencies return to dycore + units = DDT + dimensions = () + type = GFS_stateout_type + intent = in +[Sfcprop] + standard_name = GFS_sfcprop_type_instance + long_name = instance of derived type GFS_sfcprop_type units = DDT - dimensions = (ccpp_block_count) - type = GFS_data_type + dimensions = () + type = GFS_sfcprop_type + intent = in +[Coupling] + standard_name = GFS_coupling_type_instance + long_name = instance of derived type GFS_coupling_type + units = DDT + dimensions = () + type = GFS_coupling_type + intent = in +[Grid] + standard_name = GFS_grid_type_instance + long_name = instance of derived type GFS_grid_type + units = DDT + dimensions = () + type = GFS_grid_type + intent = in +[Tbd] + standard_name = GFS_tbd_type_instance + long_name = instance of derived type GFS_tbd_type + units = DDT + dimensions = () + type = GFS_tbd_type + intent = in +[Cldprop] + standard_name = GFS_cldprop_type_instance + long_name = instance of derived type GFS_cldprop_type + units = DDT + dimensions = () + type = GFS_cldprop_type + intent = in +[Radtend] + standard_name = GFS_radtend_type_instance + long_name = instance of derived type GFS_radtend_type + units = DDT + dimensions = () + type = GFS_radtend_type + intent = in +[Diag] + standard_name = GFS_diag_type_instance + long_name = instance of derived type GFS_diag_type + units = DDT + dimensions = () + type = GFS_diag_type intent = in [Interstitial] standard_name = GFS_interstitial_type_instance_all_threads diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_phys_time_vary.fv3.F90 b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_phys_time_vary.fv3.F90 index ea9beaf90..08d1d0b49 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_phys_time_vary.fv3.F90 +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_phys_time_vary.fv3.F90 @@ -593,8 +593,10 @@ subroutine GFS_phys_time_vary_init ( isnow = nint(snowxy(ix))+1 ! snowxy <=0.0, dzsno >= 0.0 +! using stc and tgxy to linearly interpolate the snow temp for each layer + do is = isnow,0 - tsnoxy(ix,is) = tgxy(ix) + tsnoxy(ix,is) = tgxy(ix) + (( sum(dzsno(isnow:is)) -0.5*dzsno(is) )/snd)*(stc(ix,1)-tgxy(ix)) snliqxy(ix,is) = zero snicexy(ix,is) = one * dzsno(is) * weasd(ix)/snd enddo diff --git a/physics/MP/Thompson/module_mp_thompson.F90 b/physics/MP/Thompson/module_mp_thompson.F90 index aa1361c3b..3fc27ca4a 100644 --- a/physics/MP/Thompson/module_mp_thompson.F90 +++ b/physics/MP/Thompson/module_mp_thompson.F90 @@ -1048,7 +1048,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & INTEGER, INTENT(IN) :: rand_perturb_on, kme_stoch, n_var_spp REAL, DIMENSION(:,:), INTENT(IN), OPTIONAL :: rand_pert REAL, DIMENSION(:), INTENT(IN), OPTIONAL :: spp_prt_list - REAL, DIMENSION(:), INTENT(IN) :: spp_stddev_cutoff + REAL, DIMENSION(:), INTENT(IN), OPTIONAL :: spp_stddev_cutoff CHARACTER(len=10), DIMENSION(:), INTENT(IN), OPTIONAL :: spp_var_list INTEGER, INTENT(IN):: has_reqc, has_reqi, has_reqs #if ( WRF_CHEM == 1 ) diff --git a/physics/MP/Thompson/mp_thompson.F90 b/physics/MP/Thompson/mp_thompson.F90 index 5ec9553cf..16144bfd0 100644 --- a/physics/MP/Thompson/mp_thompson.F90 +++ b/physics/MP/Thompson/mp_thompson.F90 @@ -412,7 +412,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & real(kind_phys), intent(in), optional :: spp_wts_mp(:,:) real(kind_phys), intent(in), optional :: spp_prt_list(:) character(len=10), intent(in), optional :: spp_var_list(:) - real(kind_phys), intent(in) :: spp_stddev_cutoff(:) + real(kind_phys), intent(in), optional :: spp_stddev_cutoff(:) logical, intent (in) :: cplchm ! ice and liquid water 3d precipitation fluxes - only allocated if cplchm is .true. diff --git a/physics/PBL/SATMEDMF/satmedmfvdifq.F b/physics/PBL/SATMEDMF/satmedmfvdifq.F index 95a1e35e5..c0e43e809 100644 --- a/physics/PBL/SATMEDMF/satmedmfvdifq.F +++ b/physics/PBL/SATMEDMF/satmedmfvdifq.F @@ -275,7 +275,7 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, & parameter(elmfac=1.0,elefac=1.0,cql=100.) parameter(dw2min=1.e-4,dkmax=1000.,xkgdx=1000.) parameter(qlcr=3.5e-5,zstblmax=2500.) - parameter(xkinv1=0.4,xkinv2=0.3) + parameter(xkinv1=0.15,xkinv2=0.3) parameter(h1=0.33333333,hcrinv=250.) parameter(vegflo=0.1,vegfup=1.0,z0lo=0.1,z0up=1.0) parameter(vc0=1.0,zc0=1.0) diff --git a/physics/SFC_Layer/UFS/sfc_diag_post.F90 b/physics/SFC_Layer/UFS/sfc_diag_post.F90 index c1e69ae48..2a7bd0f77 100644 --- a/physics/SFC_Layer/UFS/sfc_diag_post.F90 +++ b/physics/SFC_Layer/UFS/sfc_diag_post.F90 @@ -14,7 +14,7 @@ module sfc_diag_post !! #endif subroutine sfc_diag_post_run (im, lsm, lsm_noahmp, opt_diag, dry, lssav, dtf, con_eps, con_epsm1, pgr,& - vegtype,t2mmp,q2mp, t2m, q2m, u10m, v10m, tmpmin, tmpmax, spfhmin, spfhmax, & + t2mmp,q2mp, t2m, q2m, u10m, v10m, tmpmin, tmpmax, spfhmin, spfhmax, & wind10mmax, u10mmax, v10mmax, dpt2m, errmsg, errflg) use machine, only: kind_phys, kind_dbl_prec @@ -22,7 +22,6 @@ subroutine sfc_diag_post_run (im, lsm, lsm_noahmp, opt_diag, dry, lssav, dtf, co implicit none integer, intent(in) :: im, lsm, lsm_noahmp,opt_diag - integer, dimension(:), intent(in) :: vegtype ! vegetation type (integer index) logical, intent(in) :: lssav real(kind=kind_phys), intent(in) :: dtf, con_eps, con_epsm1 logical , dimension(:), intent(in) :: dry @@ -42,17 +41,6 @@ subroutine sfc_diag_post_run (im, lsm, lsm_noahmp, opt_diag, dry, lssav, dtf, co errflg = 0 if (lsm == lsm_noahmp) then -! over shrublands use opt_diag=2 - do i=1, im - if(dry(i)) then - if (vegtype(i) == 6 .or. vegtype(i) == 7 & - .or. vegtype(i) == 16) then - t2m(i) = t2mmp(i) - q2m(i) = q2mp(i) - endif - endif - enddo - if (opt_diag == 2 .or. opt_diag == 3) then do i=1,im if(dry(i)) then diff --git a/physics/SFC_Layer/UFS/sfc_diag_post.meta b/physics/SFC_Layer/UFS/sfc_diag_post.meta index 7cdfee16a..7469b89b7 100644 --- a/physics/SFC_Layer/UFS/sfc_diag_post.meta +++ b/physics/SFC_Layer/UFS/sfc_diag_post.meta @@ -82,13 +82,6 @@ type = real kind = kind_phys intent = in -[vegtype] - standard_name = vegetation_type_classification - long_name = vegetation type at each grid cell - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent= in [t2mmp] standard_name = temperature_at_2m_from_noahmp long_name = 2 meter temperature from noahmp diff --git a/physics/SFC_Models/Lake/CLM/clm_lake.f90 b/physics/SFC_Models/Lake/CLM/clm_lake.f90 index 8686221fa..565430a08 100644 --- a/physics/SFC_Models/Lake/CLM/clm_lake.f90 +++ b/physics/SFC_Models/Lake/CLM/clm_lake.f90 @@ -316,7 +316,7 @@ SUBROUTINE clm_lake_run( & REAL(KIND_PHYS), INTENT(IN) :: min_lakeice, lakedepth_default, dtp LOGICAL, INTENT(IN) :: use_lakedepth INTEGER, DIMENSION(:), INTENT(IN) :: use_lake_model - REAL(KIND_PHYS), INTENT(INOUT), OPTIONAL :: clm_lake_initialized(:) + REAL(KIND_PHYS), INTENT(INOUT) :: clm_lake_initialized(:) LOGICAL, INTENT(IN) :: frac_grid, frac_ice ! @@ -326,7 +326,7 @@ SUBROUTINE clm_lake_run( & tg3, pgr, zlvl, qvcurr, xlat_d, xlon_d, ch, cm, & dlwsfci, dswsfci, oro_lakedepth, wind, & t1, qv1, prsl1 - REAL(KIND_PHYS), DIMENSION(:), INTENT(IN), OPTIONAL :: & + REAL(KIND_PHYS), DIMENSION(:), INTENT(IN) :: & rainncprv, raincprv REAL(KIND_PHYS), DIMENSION(:,:), INTENT(in) :: gu0, gv0, prsi, gt0, phii LOGICAL, DIMENSION(:), INTENT(IN) :: flag_iter @@ -343,34 +343,34 @@ SUBROUTINE clm_lake_run( & weasdi, snodi, hice, qss_water, qss_ice, & cmm_water, cmm_ice, chh_water, chh_ice, & uustar_water, uustar_ice, zorlw, zorli, weasd, snowd, fice - REAL(KIND_PHYS), DIMENSION(:), INTENT(INOUT) , OPTIONAL :: & + REAL(KIND_PHYS), DIMENSION(:), INTENT(INOUT) :: & lake_t_snow, albedo, lake_t2m, lake_q2m LOGICAL, INTENT(INOUT) :: icy(:) ! ! Lake model internal state stored by caller: ! - INTEGER, DIMENSION( : ), INTENT(INOUT), OPTIONAL :: salty - INTEGER, DIMENSION( : ), INTENT(INOUT), OPTIONAL :: cannot_freeze + INTEGER, DIMENSION( : ), INTENT(INOUT) :: salty + INTEGER, DIMENSION( : ), INTENT(INOUT) :: cannot_freeze - real(kind_phys), dimension(: ), OPTIONAL ,intent(inout) :: savedtke12d, & + real(kind_phys), dimension(: ) ,intent(inout) :: savedtke12d, & snowdp2d, & h2osno2d, & snl2d, & t_grnd2d - real(kind_phys), dimension( :,: ), OPTIONAL, INTENT(inout) :: t_lake3d, & + real(kind_phys), dimension( :,: ), INTENT(inout) :: t_lake3d, & lake_icefrac3d - real(kind_phys), dimension( :,-nlevsnow+1: ) ,INTENT(inout), OPTIONAL :: t_soisno3d, & + real(kind_phys), dimension( :,-nlevsnow+1: ) ,INTENT(inout) :: t_soisno3d, & h2osoi_ice3d, & h2osoi_liq3d, & h2osoi_vol3d, & z3d, & dz3d - real(kind_phys), dimension( :,-nlevsnow+0: ) ,INTENT(inout), OPTIONAL :: zi3d + real(kind_phys), dimension( :,-nlevsnow+0: ) ,INTENT(inout) :: zi3d - REAL(KIND_PHYS), DIMENSION( : ) ,INTENT(INOUT), OPTIONAL :: clm_lakedepth - REAL(KIND_PHYS), DIMENSION( : ) ,INTENT(INOUT), OPTIONAL :: input_lakedepth + REAL(KIND_PHYS), DIMENSION( : ) ,INTENT(INOUT) :: clm_lakedepth + REAL(KIND_PHYS), DIMENSION( : ) ,INTENT(INOUT) :: input_lakedepth ! ! Error reporting: @@ -5377,42 +5377,39 @@ SUBROUTINE lakeini(kdt, ISLTYP, gt0, snowd, INTEGER , INTENT (IN) :: im, me, master, km, kdt REAL(KIND_PHYS), INTENT(IN) :: min_lakeice, fhour - REAL(KIND_PHYS), DIMENSION(IM), INTENT(INOUT):: FICE, hice - REAL(KIND_PHYS), DIMENSION(IM), INTENT(IN):: TG3, xlat_d, xlon_d - REAL(KIND_PHYS), DIMENSION(IM), INTENT(IN):: tsfc - REAL(KIND_PHYS), DIMENSION(IM) ,INTENT(INOUT) :: clm_lake_initialized - integer, dimension(IM), intent(in) :: use_lake_model - !INTEGER , INTENT (IN) :: lakeflag - !INTEGER , INTENT (INOUT) :: lake_depth_flag + REAL(KIND_PHYS), DIMENSION(:), INTENT(INOUT):: FICE, hice + REAL(KIND_PHYS), DIMENSION(:), INTENT(IN):: TG3, xlat_d, xlon_d + REAL(KIND_PHYS), DIMENSION(:), INTENT(IN):: tsfc + REAL(KIND_PHYS), DIMENSION(:) ,INTENT(INOUT) :: clm_lake_initialized + integer, dimension(:), intent(in) :: use_lake_model LOGICAL, INTENT (IN) :: use_lakedepth - INTEGER, DIMENSION(IM), INTENT(IN) :: ISLTYP - REAL(KIND_PHYS), DIMENSION(IM), INTENT(INOUT) :: snowd,weasd - REAL(kind_phys), DIMENSION(IM,KM), INTENT(IN) :: gt0, prsi + INTEGER, DIMENSION(:), INTENT(IN) :: ISLTYP + REAL(KIND_PHYS), DIMENSION(:), INTENT(INOUT) :: snowd,weasd + REAL(kind_phys), DIMENSION(:,:), INTENT(IN) :: gt0 + REAL(kind_phys), DIMENSION(:,:), INTENT(IN) :: prsi real(kind_phys), intent(in) :: lakedepth_default - real(kind_phys), dimension(IM),intent(inout) :: clm_lakedepth - real(kind_phys), dimension(IM),intent(inout) :: input_lakedepth - real(kind_phys), dimension(IM),intent(in) :: oro_lakedepth - real(kind_phys), dimension(IM),intent(out) :: savedtke12d - real(kind_phys), dimension(IM),intent(out) :: snowdp2d, & + real(kind_phys), dimension(:),intent(inout) :: clm_lakedepth + real(kind_phys), dimension(:),intent(inout) :: input_lakedepth + real(kind_phys), dimension(:),intent(in) :: oro_lakedepth + real(kind_phys), dimension(:),intent(out) :: savedtke12d + real(kind_phys), dimension(:),intent(out) :: snowdp2d, & h2osno2d, & snl2d, & t_grnd2d - real(kind_phys), dimension(IM,nlevlake),INTENT(out) :: t_lake3d, & + real(kind_phys), dimension(:,:),INTENT(out) :: t_lake3d, & lake_icefrac3d - real(kind_phys), dimension(IM,-nlevsnow+1:nlevsoil ),INTENT(out) :: t_soisno3d, & + real(kind_phys), dimension(:,-nlevsnow+1:),INTENT(out) :: t_soisno3d, & h2osoi_ice3d, & h2osoi_liq3d, & h2osoi_vol3d, & z3d, & dz3d - real(kind_phys), dimension( IM,-nlevsnow+0:nlevsoil ),INTENT(out) :: zi3d + real(kind_phys), dimension(:,-nlevsnow+0:),INTENT(out) :: zi3d - !LOGICAL, DIMENSION( : ),intent(out) :: lake - !REAL(KIND_PHYS), OPTIONAL, DIMENSION( : ), INTENT(IN) :: lake_depth ! no separate variable for this in CCPP integer :: n,i,j,k,ib,lev,bottom ! indices real(kind_lake),dimension(1:im ) :: bd2d ! bulk density of dry soil material [kg/m^3] diff --git a/physics/SFC_Models/Land/Noahmp/module_sf_noahmplsm.F90 b/physics/SFC_Models/Land/Noahmp/module_sf_noahmplsm.F90 index 2472f11ba..a76a354e6 100644 --- a/physics/SFC_Models/Land/Noahmp/module_sf_noahmplsm.F90 +++ b/physics/SFC_Models/Land/Noahmp/module_sf_noahmplsm.F90 @@ -1989,7 +1989,7 @@ subroutine energy (parameters,ice ,vegtyp ,ist ,nsnow ,nsoil , & !in real (kind=kind_phys), parameter :: mpe = 1.e-6 real (kind=kind_phys), parameter :: psiwlt = -150. !metric potential for wilting point (m) - real (kind=kind_phys), parameter :: z0 = 0.002 ! bare-soil roughness length (m) (i.e., under the canopy) + real (kind=kind_phys), parameter :: z0 = 0.015 ! bare-soil roughness length (m) (i.e., under the canopy) ! --------------------------------------------------------------------------------------------------- ! initialize fluxes from veg. fraction @@ -2629,10 +2629,10 @@ subroutine csnow (parameters,isnow ,nsnow ,nsoil ,snice ,snliq ,dzsnso ! thermal conductivity of snow do iz = isnow+1, 0 -! tksno(iz) = 3.2217e-6*bdsnoi(iz)**2. ! stieglitz(yen,1965) +! tksno(iz) = 3.2217e-6*bdsnoi(iz)**2. ! stieglitz(yen,1965) ! tksno(iz) = 2e-2+2.5e-6*bdsnoi(iz)*bdsnoi(iz) ! anderson, 1976 -! tksno(iz) = 0.35 ! constant - tksno(iz) = 2.576e-6*bdsnoi(iz)**2. + 0.074 ! verseghy (1991) + tksno(iz) = 0.35 ! constant +! tksno(iz) = 2.576e-6*bdsnoi(iz)**2. + 0.074 ! verseghy (1991) ! tksno(iz) = 2.22*(bdsnoi(iz)/1000.)**1.88 ! douvill(yen, 1981) enddo @@ -4056,11 +4056,6 @@ subroutine vege_flux(parameters,nsnow ,nsoil ,isnow ,vegtyp ,veg , & end if -! prepare for longwave rad. - - air = -emv*(1.+(1.-emv)*(1.-emg))*lwdn - emv*emg*sb*tg**4 - cir = (2.-emv*(1.-emg))*emv*sb -! if(opt_sfc == 4) then gdx = sqrt(garea1) @@ -4207,6 +4202,11 @@ subroutine vege_flux(parameters,nsnow ,nsoil ,isnow ,vegtyp ,veg , & end if end if +! prepare for longwave rad. + + air = -emv*(1.+(1.-emv)*(1.-emg))*lwdn - emv*emg*sb*tg**4 + cir = (2.-emv*(1.-emg))*emv*sb + ! prepare for sensible heat flux above veg. cah = 1./rahc @@ -4269,7 +4269,7 @@ subroutine vege_flux(parameters,nsnow ,nsoil ,isnow ,vegtyp ,veg , & ! update vegetation surface temperature tv = tv + dtv -! tah = ata + bta*tv ! canopy air t; update here for consistency + tah = ata + bta*tv ! canopy air t; update here for consistency ! for computing m-o length in the next iteration h = rhoair*cpair*(tah - sfctmp) /rahc @@ -4282,15 +4282,7 @@ subroutine vege_flux(parameters,nsnow ,nsoil ,isnow ,vegtyp ,veg , & qfx = (qsfc-qair)*rhoair*caw endif - - if (liter == 1) then - exit loop1 - endif - if (iter >= 5 .and. abs(dtv) <= 0.01 .and. liter == 0) then - liter = 1 - endif - - end do loop1 ! end stability iteration +! after canopy balance, do the under-canopy ground balance ! under-canopy fluxes and tg @@ -4300,8 +4292,6 @@ subroutine vege_flux(parameters,nsnow ,nsoil ,isnow ,vegtyp ,veg , & cev = rhoair*cpair / (gammag*(rawg+rsurf)) ! barlage: change to ground v3.6 cgh = 2.*df(isnow+1)/dzsnso(isnow+1) - loop2: do iter = 1, niterg - t = tdc(tg) call esat(t, esatw, esati, dsatw, dsati) if (t .gt. 0.) then @@ -4327,7 +4317,14 @@ subroutine vege_flux(parameters,nsnow ,nsoil ,isnow ,vegtyp ,veg , & gh = gh + cgh*dtg tg = tg + dtg - end do loop2 + if (liter == 1) then + exit loop1 + endif + if (iter >= 5 .and. abs(dtv) <= 0.01 .and. abs(dtg) <= 0.01 .and. liter == 0) then + liter = 1 ! if conditions are met, then do one final loop + endif + + end do loop1 ! tah = (cah*sfctmp + cvh*tv + cgh*tg)/(cah + cvh + cgh) @@ -5824,7 +5821,8 @@ subroutine thermalz0(parameters, fveg, z0m, z0mg, zlvl, if (opt_trs == z0heqz0m) then - z0m_out = exp(fveg * log(z0m) + (1.0 - fveg) * log(z0mg)) +! z0m_out = exp(fveg * log(z0m) + (1.0 - fveg) * log(z0mg)) + z0m_out = fveg * z0m + (1.0 - fveg) * z0mg z0h_out = z0m_out elseif (opt_trs == chen09) then @@ -5841,7 +5839,7 @@ subroutine thermalz0(parameters, fveg, z0m, z0mg, zlvl, endif z0h_out = exp( fveg * log(z0m * exp(-czil*0.4*258.2*sqrt(ustarx*z0m))) + & - (1.0 - fveg) * log(max(z0m/exp(kb_sigma_f0),1.0e-6)) ) + (1.0 - fveg) * log(max(z0mg/exp(kb_sigma_f0),1.0e-6)) ) elseif (opt_trs == tessel) then @@ -5880,7 +5878,7 @@ subroutine thermalz0(parameters, fveg, z0m, z0mg, zlvl, z0h_out = z0m_out - elseif (opt_trs == chen09 .or. opt_trs == tessel) then + elseif (opt_trs == tessel) then if (vegtyp <= 5) then z0h_out = z0m_out @@ -5888,7 +5886,7 @@ subroutine thermalz0(parameters, fveg, z0m, z0mg, zlvl, z0h_out = z0m_out * 0.01 endif - elseif (opt_trs == blumel99) then + elseif (opt_trs == chen09 .or. opt_trs == blumel99) then reyn = ustarx*z0m_out/viscosity ! Blumel99 eqn 36c if (reyn > 2.0) then diff --git a/physics/SFC_Models/Land/Noahmp/noahmpdrv.F90 b/physics/SFC_Models/Land/Noahmp/noahmpdrv.F90 index 6234f46d9..1313e9ff3 100644 --- a/physics/SFC_Models/Land/Noahmp/noahmpdrv.F90 +++ b/physics/SFC_Models/Land/Noahmp/noahmpdrv.F90 @@ -663,6 +663,7 @@ subroutine noahmpdrv_run & real (kind=kind_phys) :: precip_freeze_frac_in ! used for penman calculation real (kind=kind_phys) :: virtfac1 ! virtual factor + real (kind=kind_phys) :: tflux ! surface flux temp real (kind=kind_phys) :: tvs1 ! surface virtual temp real (kind=kind_phys) :: vptemp ! virtual potential temp @@ -944,7 +945,8 @@ subroutine noahmpdrv_run & t2mmp(i) = temperature_bare_2m q2mp(i) = spec_humidity_bare_2m - tskin(i) = temperature_ground + tskin(i) = temperature_radiative + tflux = temperature_ground surface_temperature = temperature_ground vegetation_fraction = vegetation_frac ch_vegetated = 0.0 @@ -1038,7 +1040,8 @@ subroutine noahmpdrv_run & q2mp(i) = spec_humidity_veg_2m * vegetation_fraction + & spec_humidity_bare_2m * (1-vegetation_fraction) - tskin(i) = surface_temperature + tskin(i) = temperature_radiative + tflux = surface_temperature endif ! glacial split ends @@ -1194,9 +1197,9 @@ subroutine noahmpdrv_run & endif if(thsfc_loc) then ! Use local potential temperature - tvs1 = tskin(i) * virtfac1 + tvs1 = tflux * virtfac1 else ! Use potential temperature referenced to 1000 hPa - tvs1 = tskin(i)/prsik1(i) * virtfac1 + tvs1 = tflux/prsik1(i) * virtfac1 endif z0_total = max(min(z0_total,forcing_height),1.0e-6) diff --git a/physics/SFC_Models/Land/Noahmp/noahmptable.tbl b/physics/SFC_Models/Land/Noahmp/noahmptable.tbl index 3ffd5b532..44531919e 100644 --- a/physics/SFC_Models/Land/Noahmp/noahmptable.tbl +++ b/physics/SFC_Models/Land/Noahmp/noahmptable.tbl @@ -217,7 +217,7 @@ !--------------------------------------------------------------------------------------------------------------------------------------------------------------------- ch2op = 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, dleaf = 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, - z0mvt = 1.09, 1.10, 0.85, 0.80, 0.80, 0.20, 0.06, 0.60, 0.50, 0.12, 0.30, 0.15, 1.00, 0.14, 0.00, 0.00, 0.00, 0.30, 0.20, 0.03, + z0mvt = 1.00, 1.50, 0.75, 0.90, 0.85, 0.20, 0.10, 0.90, 0.60, 0.20, 0.30, 0.25, 1.00, 0.25, 0.00, 0.015, 0.00, 0.30, 0.10, 0.05, hvt = 20.0, 20.0, 18.0, 16.0, 16.0, 1.10, 1.10, 13.0, 10.0, 1.00, 5.00, 2.00, 15.0, 1.50, 0.00, 0.00, 0.00, 4.00, 2.00, 0.50, hvb = 8.50, 8.00, 7.00, 11.5, 10.0, 0.10, 0.10, 0.10, 0.10, 0.05, 0.10, 0.10, 1.00, 0.10, 0.00, 0.00, 0.00, 0.30, 0.20, 0.10, z0mhvt= 0.0545, 0.055, 0.047, 0.050, 0.050, 0.182, 0.0545, 0.046, 0.050, 0.120, 0.060, 0.075, 0.067, 0.093, 0.000, 0.000, 0.000, 0.075, 0.100, 0.060, @@ -226,32 +226,34 @@ !mfsno = 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, 2.50, ! c. he 12/17/2020: optimized mfsno values dependent on land type based on evaluation with snotel swe and modis scf, surface albedo mfsno = 1.00, 1.00, 1.00, 1.00, 1.00, 2.00, 2.00, 2.00, 2.00, 2.00, 3.00, 3.00, 4.00, 4.00, 2.50, 3.00, 3.00, 3.50, 3.50, 3.50, +!mfsno = 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, ! c. he 12/17/2020: optimized snow cover factor (m) in scf formulation to replace original constant 2.5*z0,z0=0.002m, based on evaluation with snotel swe and modis scf, surface albedo ! scffac = 0.008, 0.008, 0.008, 0.008, 0.008, 0.016, 0.016, 0.020, 0.020, 0.020, 0.020, 0.014, 0.042, 0.026, 0.030, 0.016, 0.030, 0.030, 0.030, 0.030, - scffac = 0.005, 0.005, 0.005, 0.005, 0.005, 0.008, 0.008, 0.010, 0.010, 0.010, 0.010, 0.007, 0.021, 0.013, 0.015, 0.008, 0.015, 0.015, 0.015, 0.015, + scffac = 0.005, 0.005, 0.005, 0.005, 0.005, 0.008, 0.008, 0.010, 0.010, 0.010, 0.010, 0.007, 0.021, 0.013, 0.015, 0.008, 0.015, 0.015, 0.015, 0.015, +! scffac = 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, 0.059, cbiom = 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, ! row 1: vis ! row 2: near ir rhol_vis=0.07, 0.10, 0.07, 0.10, 0.10, 0.07, 0.07, 0.07, 0.10, 0.11, 0.105, 0.11, 0.00, 0.11, 0.00, 0.00, 0.00, 0.10, 0.10, 0.10, - rhol_nir=0.35, 0.45, 0.35, 0.45, 0.45, 0.35, 0.35, 0.35, 0.45, 0.58, 0.515, 0.58, 0.00, 0.58, 0.00, 0.00, 0.00, 0.45, 0.45, 0.45, + rhol_nir=0.35, 0.45, 0.35, 0.45, 0.45, 0.35, 0.35, 0.35, 0.45, 0.35, 0.515, 0.35, 0.00, 0.35, 0.00, 0.00, 0.00, 0.45, 0.45, 0.45, ! row 1: vis ! row 2: near ir - rhos_vis=0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.36, 0.26, 0.36, 0.00, 0.36, 0.00, 0.00, 0.00, 0.16, 0.16, 0.16, - rhos_nir=0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.58, 0.485, 0.58, 0.00, 0.58, 0.00, 0.00, 0.00, 0.39, 0.39, 0.39, + rhos_vis=0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.31, 0.26, 0.31, 0.00, 0.31, 0.00, 0.00, 0.00, 0.16, 0.16, 0.16, + rhos_nir=0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.53, 0.485, 0.53, 0.00, 0.53, 0.00, 0.00, 0.00, 0.39, 0.39, 0.39, ! row 1: vis ! row 2: near ir - taul_vis=0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.07, 0.06, 0.07, 0.00, 0.07, 0.00, 0.00, 0.00, 0.05, 0.05, 0.05, - taul_nir=0.10, 0.25, 0.10, 0.25, 0.25, 0.10, 0.10, 0.10, 0.25, 0.25, 0.25, 0.25, 0.00, 0.25, 0.00, 0.00, 0.00, 0.25, 0.25, 0.25, + taul_vis=0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.06, 0.05, 0.00, 0.05, 0.00, 0.00, 0.00, 0.05, 0.05, 0.05, + taul_nir=0.10, 0.25, 0.10, 0.25, 0.25, 0.10, 0.10, 0.10, 0.25, 0.34, 0.25, 0.34, 0.00, 0.34, 0.00, 0.00, 0.00, 0.25, 0.25, 0.25, ! row 1: vis ! row 2: near ir - taus_vis=0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.220, 0.1105, 0.220, 0.000, 0.220, 0.000, 0.000, 0.000, 0.001, 0.001, 0.001, - taus_nir=0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.380, 0.1905, 0.380, 0.000, 0.380, 0.000, 0.000, 0.000, 0.001, 0.001, 0.001, + taus_vis=0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.120, 0.1105, 0.120, 0.000, 0.120, 0.000, 0.000, 0.000, 0.001, 0.001, 0.001, + taus_nir=0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.250, 0.1905, 0.250, 0.000, 0.250, 0.000, 0.000, 0.000, 0.001, 0.001, 0.001, - xl = 0.010, 0.010, 0.010, 0.250, 0.250, 0.010, 0.010, 0.010, 0.010, -0.30, -0.025, -0.30, 0.000, -0.30, 0.000, 0.000, 0.000, 0.250, 0.250, 0.250, + xl = 0.010, 0.10, 0.010, 0.250, 0.250, 0.010, 0.010, 0.010, 0.010, -0.30, -0.025, -0.30, 0.000, -0.30, 0.000, 0.000, 0.000, 0.250, 0.250, 0.250, ! make cwpvt vegetation dependent according to j. goudriaan, crop micrometeorology: a simulation study (simulation monographs), 1977). c. he, 12/17/2020 ! cwpvt = 0.18, 0.67, 0.18, 0.67, 0.29, 1.0, 2.0, 1.3, 1.0, 5.0, 1.17, 1.67, 1.67, 1.67, 0.18, 0.18, 0.18, 0.67, 1.0, 0.18, cwpvt = 0.09, 0.335, 0.09, 0.335, 0.145, 0.5, 1.0, 0.65, 0.5, 2.5, 0.585, 0.835, 0.835, 0.835, 0.09, 0.09, 0.09, 0.335, 0.5, 0.09, @@ -335,10 +337,10 @@ !-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 soil color index for soil albedo !-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - albsat_vis = 0.25, 0.23, 0.21, 0.20, 0.19, 0.18, 0.17, 0.16, 0.15, 0.14, 0.13, 0.12, 0.11, 0.10, 0.09, 0.08, 0.07, 0.06, 0.05, 0.04 ! saturated soil albedos - albsat_nir = 0.50, 0.46, 0.42, 0.40, 0.38, 0.36, 0.34, 0.32, 0.30, 0.28, 0.26, 0.24, 0.22, 0.20, 0.18, 0.16, 0.14, 0.12, 0.10, 0.08 ! saturated soil albedos - albdry_vis = 0.36, 0.34, 0.32, 0.31, 0.30, 0.29, 0.28, 0.27, 0.26, 0.25, 0.24, 0.23, 0.22, 0.20, 0.18, 0.16, 0.14, 0.12, 0.10, 0.08 ! dry soil albedos - albdry_nir = 0.61, 0.57, 0.53, 0.51, 0.49, 0.48, 0.45, 0.43, 0.41, 0.39, 0.37, 0.35, 0.33, 0.31, 0.29, 0.27, 0.25, 0.23, 0.21, 0.16 ! dry soil albedos + albsat_vis = 0.21, 0.20, 0.18, 0.17, 0.16, 0.15, 0.14, 0.13, 0.13, 0.12, 0.11, 0.10, 0.10, 0.09, 0.08, 0.08, 0.08, 0.07, 0.07, 0.06 ! saturated soil albedos + albsat_nir = 0.42, 0.40, 0.36, 0.34, 0.32, 0.30, 0.28, 0.26, 0.26, 0.24, 0.22, 0.20, 0.20, 0.18, 0.16, 0.16, 0.16, 0.14, 0.14, 0.13 ! saturated soil albedos + albdry_vis = 0.31, 0.30, 0.28, 0.27, 0.26, 0.24, 0.23, 0.22, 0.22, 0.22, 0.20, 0.19, 0.20, 0.18, 0.16, 0.16, 0.16, 0.14, 0.14, 0.13 ! dry soil albedos + albdry_nir = 0.52, 0.50, 0.46, 0.44, 0.42, 0.40, 0.38, 0.37, 0.36, 0.34, 0.32, 0.30, 0.30, 0.28, 0.27, 0.27, 0.27, 0.26, 0.25, 0.25 ! dry soil albedos albice = 0.80, 0.55 ! albedo land ice: 1=vis, 2=nir alblak = 0.60, 0.40 ! albedo frozen lakes: 1=vis, 2=nir omegas = 0.8 , 0.4 ! two-stream parameter omega for snow @@ -397,7 +399,7 @@ class_sno_age = 3600.0 ! snow aging e-folding time (s) in class albedo scheme class_alb_new = 0.84 ! fresh snow albedo in class scheme psiwlt = -150.0 !metric potential for wilting point (m) - z0soil = 0.002 ! bare-soil roughness length (m) (i.e., under the canopy) + z0soil = 0.015 ! bare-soil roughness length (m) (i.e., under the canopy) z0lake = 0.01 ! lake surface roughness length (m) /