1 !WRF:model_layer:physics
14 !-------------------------------------------------------------------
16 subroutine ysu(u3d,v3d,th3d,t3d,qv3d,qc3d,qi3d,p3d,p3di,pi3d, &
17 rublten,rvblten,rthblten, &
18 rqvblten,rqcblten,rqiblten,flag_qi, &
19 cp,g,rovcp,rd,rovg,ep1,ep2,karman,xlv,rv, &
22 znt,ust,hpbl,psim,psih, &
23 xland,hfx,qfx,gz1oz0,wspd,br, &
28 ids,ide, jds,jde, kds,kde, &
29 ims,ime, jms,jme, kms,kme, &
30 its,ite, jts,jte, kts,kte, &
33 !-------------------------------------------------------------------
35 !-------------------------------------------------------------------
36 !-- u3d 3d u-velocity interpolated to theta points (m/s)
37 !-- v3d 3d v-velocity interpolated to theta points (m/s)
38 !-- th3d 3d potential temperature (k)
39 !-- t3d temperature (k)
40 !-- qv3d 3d water vapor mixing ratio (kg/kg)
41 !-- qc3d 3d cloud mixing ratio (kg/kg)
42 !-- qi3d 3d ice mixing ratio (kg/kg)
43 ! (note: if P_QI<PARAM_FIRST_SCALAR this should be zero filled)
44 !-- p3d 3d pressure (pa)
45 !-- p3di 3d pressure (pa) at interface level
46 !-- pi3d 3d exner function (dimensionless)
47 !-- rr3d 3d dry air density (kg/m^3)
48 !-- rublten u tendency due to
49 ! pbl parameterization (m/s/s)
50 !-- rvblten v tendency due to
51 ! pbl parameterization (m/s/s)
52 !-- rthblten theta tendency due to
53 ! pbl parameterization (K/s)
54 !-- rqvblten qv tendency due to
55 ! pbl parameterization (kg/kg/s)
56 !-- rqcblten qc tendency due to
57 ! pbl parameterization (kg/kg/s)
58 !-- rqiblten qi tendency due to
59 ! pbl parameterization (kg/kg/s)
60 !-- cp heat capacity at constant pressure for dry air (j/kg/k)
61 !-- g acceleration due to gravity (m/s^2)
63 !-- rd gas constant for dry air (j/kg/k)
65 !-- dz8w dz between full levels (m)
66 !-- xlv latent heat of vaporization (j/kg)
67 !-- rv gas constant for water vapor (j/kg/k)
68 !-- psfc pressure at the surface (pa)
69 !-- znt roughness length (m)
70 !-- ust u* in similarity theory (m/s)
71 !-- hpbl pbl height (m)
72 !-- psim similarity stability function for momentum
73 !-- psih similarity stability function for heat
74 !-- xland land mask (1 for land, 2 for water)
75 !-- hfx upward heat flux at the surface (w/m^2)
76 !-- qfx upward moisture flux at the surface (kg/m^2/s)
77 !-- gz1oz0 log(z/z0) where z0 is roughness length
78 !-- wspd wind speed at lowest model level (m/s)
79 !-- u10 u-wind speed at 10 m (m/s)
80 !-- v10 v-wind speed at 10 m (m/s)
81 !-- br bulk richardson number in surface layer
83 !-- rvovrd r_v divided by r_d (dimensionless)
84 !-- ep1 constant for virtual temperature (r_v/r_d - 1) (dimensionless)
85 !-- ep2 constant for specific humidity calculation
86 !-- karman von karman constant
87 !-- ids start index for i in domain
88 !-- ide end index for i in domain
89 !-- jds start index for j in domain
90 !-- jde end index for j in domain
91 !-- kds start index for k in domain
92 !-- kde end index for k in domain
93 !-- ims start index for i in memory
94 !-- ime end index for i in memory
95 !-- jms start index for j in memory
96 !-- jme end index for j in memory
97 !-- kms start index for k in memory
98 !-- kme end index for k in memory
99 !-- its start index for i in tile
100 !-- ite end index for i in tile
101 !-- jts start index for j in tile
102 !-- jte end index for j in tile
103 !-- kts start index for k in tile
104 !-- kte end index for k in tile
105 !-------------------------------------------------------------------
107 integer,parameter :: ndiff = 3
108 real,parameter :: rcl = 1.0
110 integer, intent(in ) :: ids,ide, jds,jde, kds,kde, &
111 ims,ime, jms,jme, kms,kme, &
112 its,ite, jts,jte, kts,kte
114 real, intent(in ) :: dt,cp,g,rovcp,rovg,rd,xlv,rv
116 real, intent(in ) :: ep1,ep2,karman
118 real, dimension( ims:ime, kms:kme, jms:jme ) , &
119 intent(in ) :: qv3d, &
127 real, dimension( ims:ime, kms:kme, jms:jme ) , &
130 real, dimension( ims:ime, kms:kme, jms:jme ) , &
131 intent(inout) :: rublten, &
137 real, dimension( ims:ime, kms:kme, jms:jme ) , &
138 intent(inout) :: exch_h
139 real, dimension( ims:ime, jms:jme ) , &
140 intent(inout) :: u10, &
143 real, dimension( ims:ime, jms:jme ) , &
144 intent(in ) :: xland, &
149 real, dimension( ims:ime, jms:jme ) , &
154 real, dimension( ims:ime, jms:jme ) , &
155 intent(inout) :: znt, &
160 real, dimension( ims:ime, kms:kme, jms:jme ) , &
161 intent(in ) :: u3d, &
164 integer, dimension( ims:ime, jms:jme ) , &
165 intent(out ) :: kpbl2d
166 logical, intent(in) :: flag_qi
168 real, dimension( ims:ime, jms:jme ) , &
170 intent(inout) :: regime
172 real, dimension( ims:ime, kms:kme, jms:jme ) , &
174 intent(inout) :: rqiblten
176 real, dimension( kms:kme ) , &
178 intent(in ) :: znu, &
181 real, dimension( ims:ime, jms:jme ) , &
185 real, optional, intent(in ) :: p_top
187 real, dimension( ims:ime, jms:jme ) , &
189 intent(in ) :: ctopo, &
193 real, dimension( its:ite, kts:kte*ndiff ) :: rqvbl2dt, &
195 real, dimension( its:ite, kts:kte ) :: pdh
196 real, dimension( its:ite, kts:kte+1 ) :: pdhi
197 real, dimension( its:ite ) :: &
206 ! For ARW we will replace p and p8w with dry hydrostatic pressure
209 if(k.le.kte)pdh(i,k) = mut(i,j)*znu(k) + p_top
210 pdhi(i,k) = mut(i,j)*znw(k) + p_top
216 if(k.le.kte)pdh(i,k) = p3d(i,k,j)
217 pdhi(i,k) = p3di(i,k,j)
223 qv2d(i,k) = qv3d(i,k,j)
224 qv2d(i,k+kte) = qc3d(i,k,j)
225 if(present(rqiblten)) qv2d(i,k+kte+kte) = qi3d(i,k,j)
229 call ysu2d(J=j,ux=u3d(ims,kms,j),vx=v3d(ims,kms,j) &
232 ,p2d=pdh(its,kts),p2di=pdhi(its,kts) &
233 ,pi2d=pi3d(ims,kms,j) &
234 ,utnp=rublten(ims,kms,j),vtnp=rvblten(ims,kms,j) &
235 ,ttnp=rthblten(ims,kms,j),qtnp=rqvbl2dt(its,kts),ndiff=ndiff &
236 ,cp=cp,g=g,rovcp=rovcp,rd=rd,rovg=rovg &
238 ,ep1=ep1,ep2=ep2,karman=karman &
239 ,dz8w2d=dz8w(ims,kms,j) &
240 ,psfcpa=psfc(ims,j),znt=znt(ims,j),ust=ust(ims,j) &
242 ,regime=regime(ims,j),psim=psim(ims,j) &
243 ,psih=psih(ims,j),xland=xland(ims,j) &
244 ,hfx=hfx(ims,j),qfx=qfx(ims,j) &
245 ,wspd=wspd(ims,j),br=br(ims,j) &
246 ,dusfc=dusfc,dvsfc=dvsfc,dtsfc=dtsfc,dqsfc=dqsfc &
247 ,dt=dt,rcl=1.0,kpbl1d=kpbl2d(ims,j) &
248 ,exch_hx=exch_h(ims,kms,j) &
249 ,u10=u10(ims,j),v10=v10(ims,j) &
250 #if ( NMM_CORE != 1 )
251 ,ctopo=ctopo(ims,j),ctopo2=ctopo2(ims,j) &
253 ,gz1oz0=gz1oz0(ims,j) &
254 ,ids=ids,ide=ide, jds=jds,jde=jde, kds=kds,kde=kde &
255 ,ims=ims,ime=ime, jms=jms,jme=jme, kms=kms,kme=kme &
256 ,its=its,ite=ite, jts=jts,jte=jte, kts=kts,kte=kte )
260 rthblten(i,k,j) = rthblten(i,k,j)/pi3d(i,k,j)
261 rqvblten(i,k,j) = rqvbl2dt(i,k)
262 rqcblten(i,k,j) = rqvbl2dt(i,k+kte)
263 if(present(rqiblten)) rqiblten(i,k,j) = rqvbl2dt(i,k+kte+kte)
270 !-------------------------------------------------------------------
272 subroutine ysu2d(j,ux,vx,tx,qx,p2d,p2di,pi2d, &
273 utnp,vtnp,ttnp,qtnp,ndiff, &
274 cp,g,rovcp,rd,rovg,ep1,ep2,karman,xlv,rv, &
276 znt,ust,hpbl,psim,psih, &
277 xland,hfx,qfx,wspd,br, &
278 dusfc,dvsfc,dtsfc,dqsfc, &
284 ids,ide, jds,jde, kds,kde, &
285 ims,ime, jms,jme, kms,kme, &
286 its,ite, jts,jte, kts,kte, &
289 !-------------------------------------------------------------------
291 !-------------------------------------------------------------------
293 ! this code is a revised vertical diffusion package ("ysupbl")
294 ! with a nonlocal turbulent mixing in the pbl after "mrfpbl".
295 ! the ysupbl (hong et al. 2006) is based on the study of noh
296 ! et al.(2003) and accumulated realism of the behavior of the
297 ! troen and mahrt (1986) concept implemented by hong and pan(1996).
298 ! the major ingredient of the ysupbl is the inclusion of an explicit
299 ! treatment of the entrainment processes at the entrainment layer.
300 ! this routine uses an implicit approach for vertical flux
301 ! divergence and does not require "miter" timesteps.
302 ! it includes vertical diffusion in the stable atmosphere
303 ! and moist vertical diffusion in clouds.
306 ! coded by song-you hong (ncep), implemented by jimy dudhia (ncar)
310 ! coded by song-you hong (yonsei university) and implemented by
311 ! song-you hong (yonsei university) and jimy dudhia (ncar)
314 ! further modifications :
315 ! an enhanced stable layer mixing, april 2008
316 ! ==> increase pbl height when sfc is stable (hong 2010)
317 ! pressure-level diffusion, april 2009
318 ! ==> negligible differences
319 ! implicit forcing for momentum with clean up, july 2009
320 ! ==> prevents model blowup when sfc layer is too low
321 ! increase of lamda, maximum (30, 0.1 x del z) feb 2010
322 ! ==> prevents model blowup when delz is extremely large
323 ! revised prandtl number at surface, peggy lemone, feb 2010
324 ! ==> increase kh, decrease mixing due to counter-gradient term
325 ! revised thermal, shin et al. mon. wea. rev. , songyou hong, aug 2011
326 ! ==> reduce the thermal strength when z1 < 0.1 h
327 ! revised prandtl number for free convection, dudhia, mar 2012
328 ! ==> pr0 = 1 + bke (=0.272) when newtral, kh is reduced
329 ! minimum kzo = 0.01, lo = min (30m,delz), hong, mar 2012
330 ! ==> weaker mixing when stable, and les resolution in vertical
334 ! hong (2010) quart. j. roy. met. soc
335 ! hong, noh, and dudhia (2006), mon. wea. rev.
336 ! hong and pan (1996), mon. wea. rev.
337 ! noh, chun, hong, and raasch (2003), boundary layer met.
338 ! troen and mahrt (1986), boundary layer met.
340 !-------------------------------------------------------------------
342 real,parameter :: xkzmin = 0.01,xkzmax = 1000.,rimin = -100.
343 real,parameter :: rlam = 30.,prmin = 0.25,prmax = 4.
344 real,parameter :: brcr_ub = 0.0,brcr_sb = 0.25,cori = 1.e-4
345 real,parameter :: afac = 6.8,bfac = 6.8,pfac = 2.0,pfac_q = 2.0
346 real,parameter :: phifac = 8.,sfcfrac = 0.1
347 real,parameter :: d1 = 0.02, d2 = 0.05, d3 = 0.001
348 real,parameter :: h1 = 0.33333335, h2 = 0.6666667
349 real,parameter :: ckz = 0.001,zfmin = 1.e-8,aphi5 = 5.,aphi16 = 16.
350 real,parameter :: tmin=1.e-2
351 real,parameter :: gamcrt = 3.,gamcrq = 2.e-3
352 real,parameter :: xka = 2.4e-5
353 integer,parameter :: imvdif = 1
355 integer, intent(in ) :: ids,ide, jds,jde, kds,kde, &
356 ims,ime, jms,jme, kms,kme, &
357 its,ite, jts,jte, kts,kte, &
360 real, intent(in ) :: dt,rcl,cp,g,rovcp,rovg,rd,xlv,rv
362 real, intent(in ) :: ep1,ep2,karman
364 real, dimension( ims:ime, kms:kme ), &
365 intent(in) :: dz8w2d, &
368 real, dimension( ims:ime, kms:kme ) , &
370 real, dimension( its:ite, kts:kte*ndiff ) , &
373 real, dimension( ims:ime, kms:kme ) , &
374 intent(inout) :: utnp, &
377 real, dimension( its:ite, kts:kte*ndiff ) , &
378 intent(inout) :: qtnp
380 real, dimension( its:ite, kts:kte+1 ) , &
383 real, dimension( its:ite, kts:kte ) , &
387 real, dimension( ims:ime ) , &
388 intent(inout) :: ust, &
391 real, dimension( ims:ime ) , &
392 intent(in ) :: xland, &
396 real, dimension( ims:ime ), intent(inout) :: wspd
397 real, dimension( ims:ime ), intent(in ) :: br
399 real, dimension( ims:ime ), intent(in ) :: psim, &
401 real, dimension( ims:ime ), intent(in ) :: gz1oz0
403 real, dimension( ims:ime ), intent(in ) :: psfcpa
404 integer, dimension( ims:ime ), intent(out ) :: kpbl1d
406 real, dimension( ims:ime, kms:kme ) , &
409 real, dimension( ims:ime ) , &
411 intent(in ) :: ctopo, &
413 real, dimension( ims:ime ) , &
415 intent(inout) :: regime
419 real, dimension( its:ite ) :: hol
420 real, dimension( its:ite, kts:kte+1 ) :: zq
422 real, dimension( its:ite, kts:kte ) :: &
430 real, dimension( its:ite ) :: &
443 real, dimension( its:ite, kts:kte ) :: xkzm,xkzh, &
453 real, dimension( ims:ime, kms:kme ) , &
454 intent(inout) :: exch_hx
456 real, dimension( ims:ime ) , &
457 intent(inout) :: u10, &
459 real, dimension( its:ite ) :: &
464 real, dimension( its:ite, kts:kte, ndiff) :: r3,f3
465 integer, dimension( its:ite ) :: kpbl
467 logical, dimension( its:ite ) :: pblflg, &
471 integer :: n,i,k,l,ic,is
472 integer :: klpbl, ktrace1, ktrace2, ktrace3
475 real :: dt2,rdt,spdk2,fm,fh,hol1,gamfac,vpert,prnum,prnum0
476 real :: ss,ri,qmean,tmean,alph,chi,zk,rl2,dk,sri
477 real :: brint,dtodsd,dtodsu,rdz,dsdzt,dsdzq,dsdz2,rlamdz
478 real :: utend,vtend,ttend,qtend
479 real :: dtstep,govrthv
480 real :: cont, conq, conw, conwrc
482 real, dimension( its:ite, kts:kte ) :: wscalek
483 real, dimension( its:ite ) :: delta
484 real, dimension( its:ite, kts:kte ) :: xkzml,xkzhl, &
486 real, dimension( its:ite ) :: ust3, &
494 real :: prnumfac,bfx0,hfx0,qfx0,delb,dux,dvx, &
495 dsdzu,dsdzv,wm3,dthx,dqx,wspd10,ross,tem1,dsig,tvcon,conpr, &
498 !----------------------------------------------------------------------
505 conwrc = conw*sqrt(rcl)
506 conpr = bfac*karman*sfcfrac
508 ! k-start index for tracer diffusion
516 thx(i,k) = tx(i,k)/pi2d(i,k)
522 tvcon = (1.+ep1*qx(i,k))
523 thvx(i,k) = thx(i,k)*tvcon
528 tvcon = (1.+ep1*qx(i,1))
529 rhox(i) = psfcpa(i)/(rd*tx(i,1)*tvcon)
530 govrth(i) = g/thx(i,1)
533 !-----compute the height of full- and half-sigma levels above ground
534 ! level, and the layer thicknesses.
542 zq(i,k+1) = dz8w2d(i,k)+zq(i,k)
548 za(i,k) = 0.5*(zq(i,k)+zq(i,k+1))
549 dzq(i,k) = zq(i,k+1)-zq(i,k)
550 del(i,k) = p2di(i,k)-p2di(i,k+1)
560 dza(i,k) = za(i,k)-za(i,k-1)
565 !-----initialize vertical tendencies and
573 wspd1(i) = sqrt(ux(i,1)*ux(i,1)+vx(i,1)*vx(i,1))+1.e-9
576 !---- compute vertical diffusion
578 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
579 ! compute preliminary variables
609 xkzo(i,k) = ckz*dza(i,k+1)
627 thermal(i)= thvx(i,1)
630 sflux(i) = hfx(i)/rhox(i)/cp + qfx(i)/rhox(i)*ep1*thx(i,1)
631 if(br(i).gt.0.0) sfcflg(i) = .false.
634 ! compute the first guess of pbl height
644 if(.not.stable(i))then
646 spdk2 = max(ux(i,k)**2+vx(i,k)**2,1.)
647 brup(i) = (thvx(i,k)-thermal(i))*(g*za(i,k)/thvx(i,1))/spdk2
649 stable(i) = brup(i).gt.brcr(i)
656 if(brdn(i).ge.brcr(i))then
658 elseif(brup(i).le.brcr(i))then
661 brint = (brcr(i)-brdn(i))/(brup(i)-brdn(i))
663 hpbl(i) = za(i,k-1)+brint*(za(i,k)-za(i,k-1))
664 if(hpbl(i).lt.zq(i,2)) kpbl(i) = 1
665 if(kpbl(i).le.1) pblflg(i) = .false.
669 fm = gz1oz0(i)-psim(i)
670 fh = gz1oz0(i)-psih(i)
671 hol(i) = max(br(i)*fm*fm/fh,rimin)
673 hol(i) = min(hol(i),-zfmin)
675 hol(i) = max(hol(i),zfmin)
677 hol1 = hol(i)*hpbl(i)/zl1(i)*sfcfrac
678 hol(i) = -hol(i)*hpbl(i)/zl1(i)
680 phim(i) = (1.-aphi16*hol1)**(-1./4.)
681 phih(i) = (1.-aphi16*hol1)**(-1./2.)
682 bfx0 = max(sflux(i),0.)
683 hfx0 = max(hfx(i)/rhox(i)/cp,0.)
684 qfx0 = max(ep1*thx(i,1)*qfx(i)/rhox(i),0.)
685 wstar3(i) = (govrth(i)*bfx0*hpbl(i))
686 wstar(i) = (wstar3(i))**h1
688 phim(i) = (1.+aphi5*hol1)
694 wscale(i) = (ust3(i)+phifac*karman*wstar3(i)*0.5)**h1
695 wscale(i) = min(wscale(i),ust(i)*aphi16)
696 wscale(i) = max(wscale(i),ust(i)/aphi5)
699 ! compute the surface variables for pbl height estimation
700 ! under unstable conditions
703 if(sfcflg(i).and.sflux(i).gt.0.0)then
704 gamfac = bfac/rhox(i)/wscale(i)
705 hgamt(i) = min(gamfac*hfx(i)/cp,gamcrt)
706 hgamq(i) = min(gamfac*qfx(i),gamcrq)
707 vpert = (hgamt(i)+ep1*thx(i,1)*hgamq(i))/bfac*afac
708 thermal(i) = thermal(i)+max(vpert,0.)*min(za(i,1)/(sfcfrac*hpbl(i)),1.0)
709 hgamt(i) = max(hgamt(i),0.0)
710 hgamq(i) = max(hgamq(i),0.0)
711 brint = -15.9*ust(i)*ust(i)/wspd(i)*wstar3(i)/(wscale(i)**4.)
712 hgamu(i) = brint*ux(i,1)
713 hgamv(i) = brint*vx(i,1)
719 ! enhance the pbl height by considering the thermal
738 if(.not.stable(i).and.pblflg(i))then
740 spdk2 = max(ux(i,k)**2+vx(i,k)**2,1.)
741 brup(i) = (thvx(i,k)-thermal(i))*(g*za(i,k)/thvx(i,1))/spdk2
743 stable(i) = brup(i).gt.brcr(i)
751 if(brdn(i).ge.brcr(i))then
753 elseif(brup(i).le.brcr(i))then
756 brint = (brcr(i)-brdn(i))/(brup(i)-brdn(i))
758 hpbl(i) = za(i,k-1)+brint*(za(i,k)-za(i,k-1))
759 if(hpbl(i).lt.zq(i,2)) kpbl(i) = 1
760 if(kpbl(i).le.1) pblflg(i) = .false.
764 ! stable boundary layer
767 if((.not.sfcflg(i)).and.hpbl(i).lt.zq(i,2)) then
776 if((.not.stable(i)).and.((xland(i)-1.5).ge.0))then
777 wspd10 = u10(i)*u10(i) + v10(i)*v10(i)
778 wspd10 = sqrt(wspd10)
779 ross = wspd10 / (cori*znt(i))
780 brcr_sbro(i) = min(0.16*(1.e-7*ross)**(-0.18),.3)
785 if(.not.stable(i))then
786 if((xland(i)-1.5).ge.0)then
787 brcr(i) = brcr_sbro(i)
795 if(.not.stable(i))then
797 spdk2 = max(ux(i,k)**2+vx(i,k)**2,1.)
798 brup(i) = (thvx(i,k)-thermal(i))*(g*za(i,k)/thvx(i,1))/spdk2
800 stable(i) = brup(i).gt.brcr(i)
806 if((.not.sfcflg(i)).and.hpbl(i).lt.zq(i,2)) then
808 if(brdn(i).ge.brcr(i))then
810 elseif(brup(i).le.brcr(i))then
813 brint = (brcr(i)-brdn(i))/(brup(i)-brdn(i))
815 hpbl(i) = za(i,k-1)+brint*(za(i,k)-za(i,k-1))
816 if(hpbl(i).lt.zq(i,2)) kpbl(i) = 1
817 if(kpbl(i).le.1) pblflg(i) = .false.
821 ! estimate the entrainment parameters
827 wm3 = wstar3(i) + 5. * ust3(i)
829 bfxpbl(i) = -0.15*thvx(i,1)/g*wm3/hpbl(i)
830 dthvx(i) = max(thvx(i,k+1)-thvx(i,k),tmin)
831 dthx = max(thx(i,k+1)-thx(i,k),tmin)
832 dqx = min(qx(i,k+1)-qx(i,k),0.0)
833 we(i) = max(bfxpbl(i)/dthvx(i),-sqrt(wm2(i)))
834 hfxpbl(i) = we(i)*dthx
835 qfxpbl(i) = we(i)*dqx
837 dux = ux(i,k+1)-ux(i,k)
838 dvx = vx(i,k+1)-vx(i,k)
840 ufxpbl(i) = max(prpbl(i)*we(i)*dux,-ust(i)*ust(i))
841 elseif(dux.lt.-tmin) then
842 ufxpbl(i) = min(prpbl(i)*we(i)*dux,ust(i)*ust(i))
847 vfxpbl(i) = max(prpbl(i)*we(i)*dvx,-ust(i)*ust(i))
848 elseif(dvx.lt.-tmin) then
849 vfxpbl(i) = min(prpbl(i)*we(i)*dvx,ust(i)*ust(i))
853 delb = govrth(i)*d3*hpbl(i)
854 delta(i) = min(d1*hpbl(i) + d2*wm2(i)/delb,100.)
860 if(pblflg(i).and.k.ge.kpbl(i))then
861 entfac(i,k) = ((zq(i,k+1)-hpbl(i))/delta(i))**2.
868 ! compute diffusion coefficients below pbl
872 if(k.lt.kpbl(i)) then
873 zfac(i,k) = min(max((1.-(zq(i,k+1)-zl1(i))/(hpbl(i)-zl1(i))),zfmin),1.)
874 zfacent(i,k) = (1.-zfac(i,k))**3.
875 wscalek(i,k) = (ust3(i)+phifac*karman*wstar3(i)*(1.-zfac(i,k)))**h1
878 prfac2 = 15.9*wstar3(i)/ust3(i)/(1.+4.*karman*wstar3(i)/ust3(i))
879 prnumfac = -3.*(max(zq(i,k+1)-sfcfrac*hpbl(i),0.))**2./hpbl(i)**2.
884 phim8z = 1.+(phim(i)-1.)*zq(i,k+1)/sfcfrac/hpbl(i)
885 wscalek(i,k) = ust(i)/phim8z
886 wscalek(i,k) = max(wscalek(i,k),ust(i)/aphi5)
888 prnum0 = (phih(i)/phim(i)+prfac)
889 prnum0 = min(prnum0,prmax)
890 prnum0 = max(prnum0,prmin)
891 xkzm(i,k) = wscalek(i,k)*karman*zq(i,k+1)*zfac(i,k)**pfac
892 prnum = 1. + (prnum0-1.)*exp(prnumfac)
893 xkzq(i,k) = xkzm(i,k)/prnum*zfac(i,k)**(pfac_q-pfac)
894 prnum0 = prnum0/(1.+prfac2*karman*sfcfrac)
895 prnum = 1. + (prnum0-1.)*exp(prnumfac)
896 xkzh(i,k) = xkzm(i,k)/prnum
897 xkzm(i,k) = min(xkzm(i,k),xkzmax)
898 xkzm(i,k) = max(xkzm(i,k),xkzo(i,k))
899 xkzh(i,k) = min(xkzh(i,k),xkzmax)
900 xkzh(i,k) = max(xkzh(i,k),xkzo(i,k))
901 xkzq(i,k) = min(xkzq(i,k),xkzmax)
902 xkzq(i,k) = max(xkzq(i,k),xkzo(i,k))
907 ! compute diffusion coefficients over pbl (free atmosphere)
911 if(k.ge.kpbl(i)) then
912 ss = ((ux(i,k+1)-ux(i,k))*(ux(i,k+1)-ux(i,k)) &
913 +(vx(i,k+1)-vx(i,k))*(vx(i,k+1)-vx(i,k))) &
914 /(dza(i,k+1)*dza(i,k+1))+1.e-9
915 govrthv = g/(0.5*(thvx(i,k+1)+thvx(i,k)))
916 ri = govrthv*(thvx(i,k+1)-thvx(i,k))/(ss*dza(i,k+1))
917 if(imvdif.eq.1.and.ndiff.ge.3)then
918 if((qx(i,ktrace2+k)+qx(i,ktrace3+k)).gt.0.01e-3.and.(qx(i &
919 ,ktrace2+k+1)+qx(i,ktrace3+k+1)).gt.0.01e-3)then
921 qmean = 0.5*(qx(i,k)+qx(i,k+1))
922 tmean = 0.5*(tx(i,k)+tx(i,k+1))
923 alph = xlv*qmean/rd/tmean
924 chi = xlv*xlv*qmean/cp/rv/tmean/tmean
925 ri = (1.+alph)*(ri-g*g/ss/tmean/cp*((chi-alph)/(1.+chi)))
928 zk = karman*zq(i,k+1)
929 rlamdz = min(max(0.1*dza(i,k+1),rlam),300.)
930 rlamdz = min(dza(i,k+1),rlamdz)
931 rl2 = (zk*rlamdz/(rlamdz+zk))**2
936 xkzm(i,k) = dk*(1+8.*(-ri)/(1+1.746*sri))
937 xkzh(i,k) = dk*(1+8.*(-ri)/(1+1.286*sri))
940 xkzh(i,k) = dk/(1+5.*ri)**2
942 prnum = min(prnum,prmax)
943 xkzm(i,k) = xkzh(i,k)*prnum
946 xkzm(i,k) = min(xkzm(i,k),xkzmax)
947 xkzm(i,k) = max(xkzm(i,k),xkzo(i,k))
948 xkzh(i,k) = min(xkzh(i,k),xkzmax)
949 xkzh(i,k) = max(xkzh(i,k),xkzo(i,k))
950 xkzml(i,k) = xkzm(i,k)
951 xkzhl(i,k) = xkzh(i,k)
956 ! compute tridiagonal matrix elements for heat
969 f1(i,1) = thx(i,1)-300.+hfx(i)/cont/del(i,1)*dt2
974 dtodsd = dt2/del(i,k)
975 dtodsu = dt2/del(i,k+1)
976 dsig = p2d(i,k)-p2d(i,k+1)
978 tem1 = dsig*xkzh(i,k)*rdz
979 if(pblflg(i).and.k.lt.kpbl(i)) then
980 dsdzt = tem1*(-hgamt(i)/hpbl(i)-hfxpbl(i)*zfacent(i,k)/xkzh(i,k))
981 f1(i,k) = f1(i,k)+dtodsd*dsdzt
982 f1(i,k+1) = thx(i,k+1)-300.-dtodsu*dsdzt
983 elseif(pblflg(i).and.k.ge.kpbl(i).and.entfac(i,k).lt.4.6) then
984 xkzh(i,k) = -we(i)*dza(i,kpbl(i))*exp(-entfac(i,k))
985 xkzh(i,k) = sqrt(xkzh(i,k)*xkzhl(i,k))
986 xkzh(i,k) = min(xkzh(i,k),xkzmax)
987 xkzh(i,k) = max(xkzh(i,k),xkzo(i,k))
988 f1(i,k+1) = thx(i,k+1)-300.
990 f1(i,k+1) = thx(i,k+1)-300.
992 tem1 = dsig*xkzh(i,k)*rdz
994 au(i,k) = -dtodsd*dsdz2
995 al(i,k) = -dtodsu*dsdz2
996 ad(i,k) = ad(i,k)-au(i,k)
997 ad(i,k+1) = 1.-al(i,k)
998 exch_hx(i,k+1) = xkzh(i,k)
1002 ! copies here to avoid duplicate input args for tridin
1011 call tridin_ysu(al,ad,cu,r1,au,f1,its,ite,kts,kte,1)
1013 ! recover tendencies of heat
1017 ttend = (f1(i,k)-thx(i,k)+300.)*rdt*pi2d(i,k)
1018 ttnp(i,k) = ttnp(i,k)+ttend
1019 dtsfc(i) = dtsfc(i)+ttend*cont*del(i,k)/pi2d(i,k)
1023 ! compute tridiagonal matrix elements for moisture, clouds, and tracers
1043 f3(i,1,1) = qx(i,1)+qfx(i)*g/del(i,1)*dt2
1050 f3(i,1,ic) = qx(i,1+is)
1057 if(k.ge.kpbl(i)) then
1058 xkzq(i,k) = xkzh(i,k)
1065 dtodsd = dt2/del(i,k)
1066 dtodsu = dt2/del(i,k+1)
1067 dsig = p2d(i,k)-p2d(i,k+1)
1069 tem1 = dsig*xkzq(i,k)*rdz
1070 if(pblflg(i).and.k.lt.kpbl(i)) then
1071 dsdzq = tem1*(-qfxpbl(i)*zfacent(i,k)/xkzq(i,k))
1072 f3(i,k,1) = f3(i,k,1)+dtodsd*dsdzq
1073 f3(i,k+1,1) = qx(i,k+1)-dtodsu*dsdzq
1074 elseif(pblflg(i).and.k.ge.kpbl(i).and.entfac(i,k).lt.4.6) then
1075 xkzq(i,k) = -we(i)*dza(i,kpbl(i))*exp(-entfac(i,k))
1076 xkzq(i,k) = sqrt(xkzq(i,k)*xkzhl(i,k))
1077 xkzq(i,k) = min(xkzq(i,k),xkzmax)
1078 xkzq(i,k) = max(xkzq(i,k),xkzo(i,k))
1079 f3(i,k+1,1) = qx(i,k+1)
1081 f3(i,k+1,1) = qx(i,k+1)
1083 tem1 = dsig*xkzq(i,k)*rdz
1085 au(i,k) = -dtodsd*dsdz2
1086 al(i,k) = -dtodsu*dsdz2
1087 ad(i,k) = ad(i,k)-au(i,k)
1088 ad(i,k+1) = 1.-al(i,k)
1089 ! exch_hx(i,k+1) = xkzh(i,k)
1098 f3(i,k+1,ic) = qx(i,k+1+is)
1104 ! copies here to avoid duplicate input args for tridin
1115 r3(i,k,ic) = f3(i,k,ic)
1120 ! solve tridiagonal problem for moisture, clouds, and tracers
1122 call tridin_ysu(al,ad,cu,r3,au,f3,its,ite,kts,kte,ndiff)
1124 ! recover tendencies of heat and moisture
1128 qtend = (f3(i,k,1)-qx(i,k))*rdt
1129 qtnp(i,k) = qtnp(i,k)+qtend
1130 dqsfc(i) = dqsfc(i)+qtend*conq*del(i,k)
1139 qtend = (f3(i,k,ic)-qx(i,k+is))*rdt
1140 qtnp(i,k+is) = qtnp(i,k+is)+qtend
1146 ! compute tridiagonal matrix elements for momentum
1159 ! paj: ctopo=1 if topo_wind=0 (default)
1160 ! mchen add this line to make sure NMM can still work with YSU PBL
1161 if(present(ctopo)) then
1162 ad(i,1) = 1.+ctopo(i)*ust(i)**2/wspd1(i)*rhox(i)*g/del(i,1)*dt2 &
1163 *(wspd1(i)/wspd(i))**2
1165 ad(i,1) = 1.+ust(i)**2/wspd1(i)*rhox(i)*g/del(i,1)*dt2 &
1166 *(wspd1(i)/wspd(i))**2
1174 dtodsd = dt2/del(i,k)
1175 dtodsu = dt2/del(i,k+1)
1176 dsig = p2d(i,k)-p2d(i,k+1)
1178 tem1 = dsig*xkzm(i,k)*rdz
1179 if(pblflg(i).and.k.lt.kpbl(i))then
1180 dsdzu = tem1*(-hgamu(i)/hpbl(i)-ufxpbl(i)*zfacent(i,k)/xkzm(i,k))
1181 dsdzv = tem1*(-hgamv(i)/hpbl(i)-vfxpbl(i)*zfacent(i,k)/xkzm(i,k))
1182 f1(i,k) = f1(i,k)+dtodsd*dsdzu
1183 f1(i,k+1) = ux(i,k+1)-dtodsu*dsdzu
1184 f2(i,k) = f2(i,k)+dtodsd*dsdzv
1185 f2(i,k+1) = vx(i,k+1)-dtodsu*dsdzv
1186 elseif(pblflg(i).and.k.ge.kpbl(i).and.entfac(i,k).lt.4.6) then
1187 xkzm(i,k) = prpbl(i)*xkzh(i,k)
1188 xkzm(i,k) = sqrt(xkzm(i,k)*xkzml(i,k))
1189 xkzm(i,k) = min(xkzm(i,k),xkzmax)
1190 xkzm(i,k) = max(xkzm(i,k),xkzo(i,k))
1191 f1(i,k+1) = ux(i,k+1)
1192 f2(i,k+1) = vx(i,k+1)
1194 f1(i,k+1) = ux(i,k+1)
1195 f2(i,k+1) = vx(i,k+1)
1197 tem1 = dsig*xkzm(i,k)*rdz
1199 au(i,k) = -dtodsd*dsdz2
1200 al(i,k) = -dtodsu*dsdz2
1201 ad(i,k) = ad(i,k)-au(i,k)
1202 ad(i,k+1) = 1.-al(i,k)
1206 ! copies here to avoid duplicate input args for tridin
1216 ! solve tridiagonal problem for momentum
1218 call tridi1n(al,ad,cu,r1,r2,au,f1,f2,its,ite,kts,kte,1)
1220 ! recover tendencies of momentum
1224 utend = (f1(i,k)-ux(i,k))*rdt
1225 vtend = (f2(i,k)-vx(i,k))*rdt
1226 utnp(i,k) = utnp(i,k)+utend
1227 vtnp(i,k) = vtnp(i,k)+vtend
1228 dusfc(i) = dusfc(i) + utend*conwrc*del(i,k)
1229 dvsfc(i) = dvsfc(i) + vtend*conwrc*del(i,k)
1233 ! paj: ctopo2=1 if topo_wind=0 (default)
1236 if(present(ctopo).and.present(ctopo2)) then ! mchen for NMM
1237 u10(i) = ctopo2(i)*u10(i)+(1-ctopo2(i))*ux(i,1)
1238 v10(i) = ctopo2(i)*v10(i)+(1-ctopo2(i))*vx(i,1)
1242 !---- end of vertical diffusion
1248 end subroutine ysu2d
1250 subroutine tridi1n(cl,cm,cu,r1,r2,au,f1,f2,its,ite,kts,kte,nt)
1251 !----------------------------------------------------------------
1253 !----------------------------------------------------------------
1255 integer, intent(in ) :: its,ite, kts,kte, nt
1257 real, dimension( its:ite, kts+1:kte+1 ) , &
1260 real, dimension( its:ite, kts:kte ) , &
1261 intent(in ) :: cm, &
1263 real, dimension( its:ite, kts:kte,nt ) , &
1266 real, dimension( its:ite, kts:kte ) , &
1267 intent(inout) :: au, &
1270 real, dimension( its:ite, kts:kte,nt ) , &
1274 integer :: i,k,l,n,it
1276 !----------------------------------------------------------------
1283 au(i,1) = fk*cu(i,1)
1284 f1(i,1) = fk*r1(i,1)
1289 f2(i,1,it) = fk*r2(i,1,it)
1294 fk = 1./(cm(i,k)-cl(i,k)*au(i,k-1))
1295 au(i,k) = fk*cu(i,k)
1296 f1(i,k) = fk*(r1(i,k)-cl(i,k)*f1(i,k-1))
1302 fk = 1./(cm(i,k)-cl(i,k)*au(i,k-1))
1303 f2(i,k,it) = fk*(r2(i,k,it)-cl(i,k)*f2(i,k-1,it))
1308 fk = 1./(cm(i,n)-cl(i,n)*au(i,n-1))
1309 f1(i,n) = fk*(r1(i,n)-cl(i,n)*f1(i,n-1))
1313 fk = 1./(cm(i,n)-cl(i,n)*au(i,n-1))
1314 f2(i,n,it) = fk*(r2(i,n,it)-cl(i,n)*f2(i,n-1,it))
1319 f1(i,k) = f1(i,k)-au(i,k)*f1(i,k+1)
1325 f2(i,k,it) = f2(i,k,it)-au(i,k)*f2(i,k+1,it)
1330 end subroutine tridi1n
1332 subroutine tridin_ysu(cl,cm,cu,r2,au,f2,its,ite,kts,kte,nt)
1333 !----------------------------------------------------------------
1335 !----------------------------------------------------------------
1337 integer, intent(in ) :: its,ite, kts,kte, nt
1339 real, dimension( its:ite, kts+1:kte+1 ) , &
1342 real, dimension( its:ite, kts:kte ) , &
1344 real, dimension( its:ite, kts:kte,nt ) , &
1347 real, dimension( its:ite, kts:kte ) , &
1348 intent(inout) :: au, &
1350 real, dimension( its:ite, kts:kte,nt ) , &
1354 integer :: i,k,l,n,it
1356 !----------------------------------------------------------------
1364 au(i,1) = fk*cu(i,1)
1365 f2(i,1,it) = fk*r2(i,1,it)
1371 fk = 1./(cm(i,k)-cl(i,k)*au(i,k-1))
1372 au(i,k) = fk*cu(i,k)
1373 f2(i,k,it) = fk*(r2(i,k,it)-cl(i,k)*f2(i,k-1,it))
1379 fk = 1./(cm(i,n)-cl(i,n)*au(i,n-1))
1380 f2(i,n,it) = fk*(r2(i,n,it)-cl(i,n)*f2(i,n-1,it))
1386 f2(i,k,it) = f2(i,k,it)-au(i,k)*f2(i,k+1,it)
1391 end subroutine tridin_ysu
1393 subroutine ysuinit(rublten,rvblten,rthblten,rqvblten, &
1394 rqcblten,rqiblten,p_qi,p_first_scalar, &
1395 restart, allowed_to_read, &
1396 ids, ide, jds, jde, kds, kde, &
1397 ims, ime, jms, jme, kms, kme, &
1398 its, ite, jts, jte, kts, kte )
1399 !-------------------------------------------------------------------
1401 !-------------------------------------------------------------------
1403 logical , intent(in) :: restart, allowed_to_read
1404 integer , intent(in) :: ids, ide, jds, jde, kds, kde, &
1405 ims, ime, jms, jme, kms, kme, &
1406 its, ite, jts, jte, kts, kte
1407 integer , intent(in) :: p_qi,p_first_scalar
1408 real , dimension( ims:ime , kms:kme , jms:jme ), intent(out) :: &
1415 integer :: i, j, k, itf, jtf, ktf
1417 jtf = min0(jte,jde-1)
1418 ktf = min0(kte,kde-1)
1419 itf = min0(ite,ide-1)
1421 if(.not.restart)then
1427 rthblten(i,k,j) = 0.
1428 rqvblten(i,k,j) = 0.
1429 rqcblten(i,k,j) = 0.
1435 if (p_qi .ge. p_first_scalar .and. .not.restart) then
1439 rqiblten(i,k,j) = 0.
1445 end subroutine ysuinit
1446 !-------------------------------------------------------------------
1447 end module module_bl_ysu