1 !=================================================================================================================
2 !module_bl_ysu.F was modified to accomodate both the WRF and MPAS models / 2018-12-7
3 !=================================================================================================================
4 !WRF:model_layer:physics
16 !-------------------------------------------------------------------------------
18 subroutine ysu(u3d,v3d,th3d,t3d,qv3d,qc3d,qi3d,p3d,p3di,pi3d, &
19 rublten,rvblten,rthblten, &
20 rqvblten,rqcblten,rqiblten,flag_qi, &
21 cp,g,rovcp,rd,rovg,ep1,ep2,karman,xlv,rv, &
23 znt,ust,hpbl,psim,psih, &
24 xland,hfx,qfx,wspd,br, &
30 rthraten,ysu_topdown_pblmix, &
32 idiff,flag_bep,frc_urb2d, &
33 a_u_bep,a_v_bep,a_t_bep, &
35 a_e_bep,b_u_bep,b_v_bep, &
38 dl_u_bep,sf_bep,vl_bep, &
39 ids,ide, jds,jde, kds,kde, &
40 ims,ime, jms,jme, kms,kme, &
41 its,ite, jts,jte, kts,kte, &
45 !-------------------------------------------------------------------------------
47 !-------------------------------------------------------------------------------
48 !-- u3d 3d u-velocity interpolated to theta points (m/s)
49 !-- v3d 3d v-velocity interpolated to theta points (m/s)
50 !-- th3d 3d potential temperature (k)
51 !-- t3d temperature (k)
52 !-- qv3d 3d water vapor mixing ratio (kg/kg)
53 !-- qc3d 3d cloud mixing ratio (kg/kg)
54 !-- qi3d 3d ice mixing ratio (kg/kg)
55 ! (note: if P_QI<PARAM_FIRST_SCALAR this should be zero filled)
56 !-- p3d 3d pressure (pa)
57 !-- p3di 3d pressure (pa) at interface level
58 !-- pi3d 3d exner function (dimensionless)
59 !-- rr3d 3d dry air density (kg/m^3)
60 !-- rublten u tendency due to
61 ! pbl parameterization (m/s/s)
62 !-- rvblten v tendency due to
63 ! pbl parameterization (m/s/s)
64 !-- rthblten theta tendency due to
65 ! pbl parameterization (K/s)
66 !-- rqvblten qv tendency due to
67 ! pbl parameterization (kg/kg/s)
68 !-- rqcblten qc tendency due to
69 ! pbl parameterization (kg/kg/s)
70 !-- rqiblten qi tendency due to
71 ! pbl parameterization (kg/kg/s)
72 !-- cp heat capacity at constant pressure for dry air (j/kg/k)
73 !-- g acceleration due to gravity (m/s^2)
75 !-- rd gas constant for dry air (j/kg/k)
77 !-- dz8w dz between full levels (m)
78 !-- xlv latent heat of vaporization (j/kg)
79 !-- rv gas constant for water vapor (j/kg/k)
80 !-- psfc pressure at the surface (pa)
81 !-- znt roughness length (m)
82 !-- ust u* in similarity theory (m/s)
83 !-- hpbl pbl height (m)
84 !-- psim similarity stability function for momentum
85 !-- psih similarity stability function for heat
86 !-- xland land mask (1 for land, 2 for water)
87 !-- hfx upward heat flux at the surface (w/m^2)
88 !-- qfx upward moisture flux at the surface (kg/m^2/s)
89 !-- wspd wind speed at lowest model level (m/s)
90 !-- u10 u-wind speed at 10 m (m/s)
91 !-- v10 v-wind speed at 10 m (m/s)
92 !-- uoce sea surface zonal currents (m s-1)
93 !-- voce sea surface meridional currents (m s-1)
94 !-- br bulk richardson number in surface layer
96 !-- rvovrd r_v divided by r_d (dimensionless)
97 !-- ep1 constant for virtual temperature (r_v/r_d - 1)
98 !-- ep2 constant for specific humidity calculation
99 !-- karman von karman constant
100 !-- ids start index for i in domain
101 !-- ide end index for i in domain
102 !-- jds start index for j in domain
103 !-- jde end index for j in domain
104 !-- kds start index for k in domain
105 !-- kde end index for k in domain
106 !-- ims start index for i in memory
107 !-- ime end index for i in memory
108 !-- jms start index for j in memory
109 !-- jme end index for j in memory
110 !-- kms start index for k in memory
111 !-- kme end index for k in memory
112 !-- its start index for i in tile
113 !-- ite end index for i in tile
114 !-- jts start index for j in tile
115 !-- jte end index for j in tile
116 !-- kts start index for k in tile
117 !-- kte end index for k in tile
118 !-- idiff diff3d BEP/BEM+BEM diffusion flag
119 !-- flag_bep flag to use BEP/BEP+BEM
120 !-- frc_urb2d urban fraction
121 !-- a_u_bep BEP/BEP+BEM implicit component u-mom
122 !-- a_v_bep BEP/BEP+BEM implicit component v-mom
123 !-- a_t_bep BEP/BEP+BEM implicit component pot. temp.
124 !-- a_q_bep BEP/BEP+BEM implicit component vapor mixing ratio
125 !-- a_e_bep BEP/BEP+BEM implicit component TKE
126 !-- b_u_bep BEP/BEP+BEM explicit component u-mom
127 !-- b_v_bep BEP/BEP+BEM explicit component v-mom
128 !-- b_t_bep BEP/BEP+BEM explicit component pot.temp.
129 !-- b_q_bep BEP/BEP+BEM explicit component vapor mixing ratio
130 !-- b_e_bep BEP/BEP+BEM explicit component TKE
131 !-- dlg_bep Height above ground Martilli et al. (2002) Eq. 24
132 !-- dl_u_bep modified length scale Martilli et al. (2002) Eq. 22
133 !-- sf_bep fraction of vertical surface not occupied by buildings
134 !-- vl_bep volume fraction of grid cell not occupied by buildings
135 !-------------------------------------------------------------------------------
137 integer,parameter :: ndiff = 3
138 real,parameter :: rcl = 1.0
140 integer, intent(in ) :: ids,ide, jds,jde, kds,kde, &
141 ims,ime, jms,jme, kms,kme, &
142 its,ite, jts,jte, kts,kte
144 integer, intent(in) :: ysu_topdown_pblmix
146 real, intent(in ) :: dt,cp,g,rovcp,rovg,rd,xlv,rv
148 real, intent(in ) :: ep1,ep2,karman
150 real, dimension( ims:ime, kms:kme, jms:jme ) , &
151 intent(in ) :: qv3d, &
160 real, dimension( ims:ime, kms:kme, jms:jme ) , &
163 real, dimension( ims:ime, kms:kme, jms:jme ) , &
164 intent(inout) :: rublten, &
170 real, dimension( ims:ime, kms:kme, jms:jme ) , &
171 intent(inout) :: exch_h, &
173 real, dimension( ims:ime, jms:jme ) , &
174 intent(inout) :: wstar
175 real, dimension( ims:ime, jms:jme ) , &
176 intent(inout) :: delta
177 real, dimension( ims:ime, jms:jme ) , &
178 intent(inout) :: u10, &
180 real, dimension( ims:ime, jms:jme ) , &
181 intent(in ) :: uoce, &
184 real, dimension( ims:ime, jms:jme ) , &
185 intent(in ) :: xland, &
190 real, dimension( ims:ime, jms:jme ) , &
194 real, dimension( ims:ime, jms:jme ) , &
195 intent(inout) :: znt, &
200 real, dimension( ims:ime, kms:kme, jms:jme ) , &
201 intent(in ) :: u3d, &
204 integer, dimension( ims:ime, jms:jme ) , &
205 intent(out ) :: kpbl2d
206 logical, intent(in) :: flag_qi
207 integer, intent(in) :: idiff
208 logical, intent(in) :: flag_bep
209 real,dimension(ims:ime,kms:kme,jms:jme),intent(in) :: a_u_bep, &
217 real, dimension(ims:ime,jms:jme),intent(in) :: frc_urb2d
221 real, dimension( ims:ime, jms:jme ) , &
223 intent(inout) :: regime
225 real, dimension( ims:ime, kms:kme, jms:jme ) , &
227 intent(inout) :: rqiblten
229 real, dimension( ims:ime, jms:jme ) , &
231 intent(in ) :: ctopo, &
235 real, dimension( its:ite, kts:kte*ndiff ) :: rqvbl2dt, &
237 real, dimension( its:ite, kts:kte ) :: pdh
238 real, dimension( its:ite, kts:kte+1 ) :: pdhi
239 real, dimension( its:ite ) :: &
244 real,dimension(its:ite,kts:kte,jts:jte) :: a_u,a_v,a_t,a_e,b_u,b_v,b_t,b_e, &
245 a_q,b_q,dlg,dl_u,sfk,vlk
246 real,dimension(its:ite,jts:jte) :: frcurb
247 real :: bepswitch ! 0 if not using bep or bep+bem, 1 if using
249 qv2d(its:ite,:) = 0.0
271 if(k.le.kte)pdh(i,k) = p3d(i,k,j)
272 pdhi(i,k) = p3di(i,k,j)
278 qv2d(i,k) = qv3d(i,k,j)
279 qv2d(i,k+kte) = qc3d(i,k,j)
280 if(flag_qi) qv2d(i,k+kte+kte) = qi3d(i,k,j)
288 a_u(i,k,j)=a_u_bep(i,k,j)
289 a_v(i,k,j)=a_v_bep(i,k,j)
290 a_t(i,k,j)=a_t_bep(i,k,j)
291 a_q(i,k,j)=a_q_bep(i,k,j)
292 a_e(i,k,j)=a_e_bep(i,k,j)
293 b_u(i,k,j)=b_u_bep(i,k,j)
294 b_v(i,k,j)=b_v_bep(i,k,j)
295 b_t(i,k,j)=b_t_bep(i,k,j)
296 b_q(i,k,j)=b_q_bep(i,k,j)
297 b_e(i,k,j)=b_e_bep(i,k,j)
298 sfk(i,k,j)=sf_bep(i,k,j)
299 vlk(i,k,j)=vl_bep(i,k,j)
300 dl_u(i,k,j)=dl_u_bep(i,k,j)
301 dlg(i,k,j)=dlg_bep(i,k,j)
302 frcurb(i,j)=frc_urb2d(i,j)
307 call ysu2d(J=j,ux=u3d(ims,kms,j),vx=v3d(ims,kms,j) &
310 ,p2d=pdh(its,kts),p2di=pdhi(its,kts) &
311 ,pi2d=pi3d(ims,kms,j) &
312 ,utnp=rublten(ims,kms,j),vtnp=rvblten(ims,kms,j) &
313 ,ttnp=rthblten(ims,kms,j),qtnp=rqvbl2dt(its,kts),ndiff=ndiff &
314 ,cp=cp,g=g,rovcp=rovcp,rd=rd,rovg=rovg &
316 ,ep1=ep1,ep2=ep2,karman=karman &
317 ,dz8w2d=dz8w(ims,kms,j) &
318 ,psfcpa=psfc(ims,j),znt=znt(ims,j),ust=ust(ims,j) &
320 ,regime=regime(ims,j),psim=psim(ims,j) &
321 ,psih=psih(ims,j),xland=xland(ims,j) &
322 ,hfx=hfx(ims,j),qfx=qfx(ims,j) &
323 ,wspd=wspd(ims,j),br=br(ims,j) &
324 ,dusfc=dusfc,dvsfc=dvsfc,dtsfc=dtsfc,dqsfc=dqsfc &
325 ,dt=dt,rcl=1.0,kpbl1d=kpbl2d(ims,j) &
326 ,exch_hx=exch_h(ims,kms,j) &
327 ,exch_mx=exch_m(ims,kms,j) &
328 ,wstar=wstar(ims,j) &
329 ,delta=delta(ims,j) &
330 ,u10=u10(ims,j),v10=v10(ims,j) &
331 ,uox=uoce(ims,j),vox=voce(ims,j) &
332 ,rthraten=rthraten(ims,kms,j),p2diORG=p3di(ims,kms,j) &
333 ,ysu_topdown_pblmix=ysu_topdown_pblmix &
334 ,ctopo=ctopo(ims,j),ctopo2=ctopo2(ims,j) &
335 ,a_u2d=a_u(its,kts,j), a_v2d=a_v(its,kts,j) &
336 ,a_t2d=a_t(its,kts,j), a_q2d=a_q(its,kts,j) &
337 ,b_u2d=b_u(its,kts,j), b_v2d=b_v(its,kts,j) &
338 ,b_t2d=b_t(its,kts,j), b_q2d=b_q(its,kts,j) &
339 ,b_e2d=b_e(its,kts,j), a_e2d=a_e(its,kts,j) &
340 ,sfk2d=sfk(its,kts,j), vlk2d=vlk(its,kts,j) &
341 ,dlu2d=dl_u(its,kts,j), dlg2d=dlg(its,kts,j) &
342 ,frc_urb1d=frcurb(its,j), bepswitch=bepswitch &
343 ,ids=ids,ide=ide, jds=jds,jde=jde, kds=kds,kde=kde &
344 ,ims=ims,ime=ime, jms=jms,jme=jme, kms=kms,kme=kme &
345 ,its=its,ite=ite, jts=jts,jte=jte, kts=kts,kte=kte )
349 rthblten(i,k,j) = rthblten(i,k,j)/pi3d(i,k,j)
350 rqvblten(i,k,j) = rqvbl2dt(i,k)
351 rqcblten(i,k,j) = rqvbl2dt(i,k+kte)
352 if(flag_qi) rqiblten(i,k,j) = rqvbl2dt(i,k+kte+kte)
360 !-------------------------------------------------------------------------------
362 subroutine ysu2d(j,ux,vx,tx,qx,p2d,p2di,pi2d, &
363 utnp,vtnp,ttnp,qtnp,ndiff, &
364 cp,g,rovcp,rd,rovg,ep1,ep2,karman,xlv,rv, &
366 znt,ust,hpbl,psim,psih, &
367 xland,hfx,qfx,wspd,br, &
368 dusfc,dvsfc,dtsfc,dqsfc, &
375 ysu_topdown_pblmix, &
377 a_u2d, a_v2d, a_t2d, a_q2d, &
378 b_u2d, b_v2d, b_t2d, b_q2d, &
379 b_e2d, a_e2d, sfk2d, vlk2d, &
381 frc_urb1d, bepswitch, &
382 ids,ide, jds,jde, kds,kde, &
383 ims,ime, jms,jme, kms,kme, &
384 its,ite, jts,jte, kts,kte, &
388 !-------------------------------------------------------------------------------
390 !-------------------------------------------------------------------------------
392 ! this code is a revised vertical diffusion package ("ysupbl")
393 ! with a nonlocal turbulent mixing in the pbl after "mrfpbl".
394 ! the ysupbl (hong et al. 2006) is based on the study of noh
395 ! et al.(2003) and accumulated realism of the behavior of the
396 ! troen and mahrt (1986) concept implemented by hong and pan(1996).
397 ! the major ingredient of the ysupbl is the inclusion of an explicit
398 ! treatment of the entrainment processes at the entrainment layer.
399 ! this routine uses an implicit approach for vertical flux
400 ! divergence and does not require "miter" timesteps.
401 ! it includes vertical diffusion in the stable atmosphere
402 ! and moist vertical diffusion in clouds.
405 ! coded by song-you hong (ncep), implemented by jimy dudhia (ncar)
409 ! coded by song-you hong (yonsei university) and implemented by
410 ! song-you hong (yonsei university) and jimy dudhia (ncar)
413 ! further modifications :
414 ! an enhanced stable layer mixing, april 2008
415 ! ==> increase pbl height when sfc is stable (hong 2010)
416 ! pressure-level diffusion, april 2009
417 ! ==> negligible differences
418 ! implicit forcing for momentum with clean up, july 2009
419 ! ==> prevents model blowup when sfc layer is too low
420 ! incresea of lamda, maximum (30, 0.1 x del z) feb 2010
421 ! ==> prevents model blowup when delz is extremely large
422 ! revised prandtl number at surface, peggy lemone, feb 2010
423 ! ==> increase kh, decrease mixing due to counter-gradient term
424 ! revised thermal, shin et al. mon. wea. rev. , songyou hong, aug 2011
425 ! ==> reduce the thermal strength when z1 < 0.1 h
426 ! revised prandtl number for free convection, dudhia, mar 2012
427 ! ==> pr0 = 1 + bke (=0.272) when neutral, kh is reduced
428 ! minimum kzo = 0.01, lo = min (30m,delz), hong, mar 2012
429 ! ==> weaker mixing when stable, and les resolution in vertical
430 ! gz1oz0 is removed, and psim psih are ln(z1/z0)-psim,h, hong, mar 2012
431 ! ==> consider thermal z0 when differs from mechanical z0
432 ! a bug fix in wscale computation in stable bl, sukanta basu, jun 2012
433 ! ==> wscale becomes small with height, and less mixing in stable bl
434 ! revision in background diffusion (kzo), jan 2016
435 ! ==> kzo = 0.1 for momentum and = 0.01 for mass to account for
436 ! internal wave mixing of large et al. (1994), songyou hong, feb 2016
437 ! ==> alleviate superious excessive mixing when delz is large
438 ! add multilayer urban canopy models of BEP and BEP+BEM, jan 2021
442 ! hendricks, knievel, and wang (2020), j. appl. meteor. clim.
443 ! hong (2010) quart. j. roy. met. soc
444 ! hong, noh, and dudhia (2006), mon. wea. rev.
445 ! hong and pan (1996), mon. wea. rev.
446 ! noh, chun, hong, and raasch (2003), boundary layer met.
447 ! troen and mahrt (1986), boundary layer met.
449 !-------------------------------------------------------------------------------
451 real,parameter :: xkzminm = 0.1,xkzminh = 0.01
452 real,parameter :: xkzmin = 0.01,xkzmax = 1000.,rimin = -100.
453 real,parameter :: rlam = 30.,prmin = 0.25,prmax = 4.
454 real,parameter :: brcr_ub = 0.0,brcr_sb = 0.25,cori = 1.e-4
455 real,parameter :: afac = 6.8,bfac = 6.8,pfac = 2.0,pfac_q = 2.0
456 real,parameter :: phifac = 8.,sfcfrac = 0.1
457 real,parameter :: d1 = 0.02, d2 = 0.05, d3 = 0.001
458 real,parameter :: h1 = 0.33333333, h2 = 0.6666667
459 real,parameter :: zfmin = 1.e-8,aphi5 = 5.,aphi16 = 16.
460 real,parameter :: tmin=1.e-2
461 real,parameter :: gamcrt = 3.,gamcrq = 2.e-3
462 real,parameter :: xka = 2.4e-5
463 integer,parameter :: imvdif = 1
465 integer, intent(in ) :: ids,ide, jds,jde, kds,kde, &
466 ims,ime, jms,jme, kms,kme, &
467 its,ite, jts,jte, kts,kte, &
470 integer, intent(in) :: ysu_topdown_pblmix
472 real, intent(in ) :: dt,rcl,cp,g,rovcp,rovg,rd,xlv,rv
474 real, intent(in ) :: ep1,ep2,karman
476 real, dimension( ims:ime, kms:kme ), &
477 intent(in) :: dz8w2d, &
481 real, dimension( ims:ime, kms:kme ) , &
483 real, dimension( its:ite, kts:kte*ndiff ) , &
486 real, dimension( ims:ime, kms:kme ) , &
487 intent(inout) :: utnp, &
490 real, dimension( its:ite, kts:kte*ndiff ) , &
491 intent(inout) :: qtnp
493 real, dimension( its:ite, kts:kte+1 ) , &
496 real, dimension( its:ite, kts:kte ) , &
499 real, dimension( ims:ime ) , &
500 intent(inout) :: ust, &
503 real, dimension( ims:ime ) , &
504 intent(in ) :: xland, &
508 real, dimension( ims:ime ), intent(inout) :: wspd
509 real, dimension( ims:ime ), intent(in ) :: br
511 real, dimension( ims:ime ), intent(in ) :: psim, &
514 real, dimension( ims:ime ), intent(in ) :: psfcpa
515 integer, dimension( ims:ime ), intent(out ) :: kpbl1d
517 real, dimension( ims:ime, kms:kme ) , &
521 real, dimension( ims:ime ) , &
523 intent(in ) :: ctopo, &
525 real, dimension( ims:ime ) , &
527 intent(inout) :: regime
531 real, dimension( its:ite, kts:kte ), &
532 intent(in) :: a_u2d, &
547 real, dimension( its:ite ), &
548 intent(in) :: frc_urb1d
550 real, dimension( its:ite ) :: hol
551 real, dimension( its:ite, kts:kte+1 ) :: zq
553 real, dimension( its:ite, kts:kte ) :: &
562 real, dimension( its:ite ) :: &
575 real, dimension( its:ite, kts:kte ) :: xkzm,xkzh, &
589 real, dimension( ims:ime, kms:kme ) , &
590 intent(inout) :: exch_hx, &
593 real, dimension( ims:ime ) , &
594 intent(inout) :: u10, &
596 real, dimension( ims:ime ) , &
597 intent(in ) :: uox, &
599 real, dimension( its:ite ) :: &
605 real, dimension( its:ite, kts:kte, ndiff) :: r3,f3
606 integer, dimension( its:ite ) :: kpbl,kpblold
608 logical, dimension( its:ite ) :: pblflg, &
613 logical :: definebrup
615 integer :: n,i,k,l,ic,is,kk
616 integer :: klpbl, ktrace1, ktrace2, ktrace3
619 real :: dt2,rdt,spdk2,fm,fh,hol1,gamfac,vpert,prnum,prnum0
620 real :: ss,ri,qmean,tmean,alph,chi,zk,rl2,dk,sri
621 real :: brint,dtodsd,dtodsu,rdz,dsdzt,dsdzq,dsdz2,rlamdz
622 real :: utend,vtend,ttend,qtend
623 real :: dtstep,govrthv
624 real :: cont, conq, conw, conwrc
627 real, dimension( its:ite, kts:kte ) :: wscalek,wscalek2
628 real, dimension( ims:ime ) :: wstar
629 real, dimension( ims:ime ) :: delta
630 real, dimension( its:ite, kts:kte ) :: xkzml,xkzhl, &
632 real, dimension( its:ite ) :: ust3, &
641 real :: prnumfac,bfx0,hfx0,qfx0,delb,dux,dvx, &
642 dsdzu,dsdzv,wm3,dthx,dqx,wspd10,ross,tem1,dsig,tvcon,conpr, &
643 prfac,prfac2,phim8z,radsum,tmp1,templ,rvls,temps,ent_eff, &
644 rcldb,bruptmp,radflux,vconvlim,vconvnew,fluxc,vconvc,vconv
646 real, dimension( ims:ime, kms:kme ) :: fric, &
651 real, dimension( ims:ime ) :: pblh_ysu,&
654 !-------------------------------------------------------------------------------
661 conwrc = conw*sqrt(rcl)
662 conpr = bfac*karman*sfcfrac
664 ! k-start index for tracer diffusion
672 thx(i,k) = tx(i,k)/pi2d(i,k)
673 thlix(i,k) = (tx(i,k)-xlv*qx(i,ktrace2+k)/cp-2.834E6*qx(i,ktrace3+k)/cp)/pi2d(i,k)
679 tvcon = (1.+ep1*qx(i,k))
680 thvx(i,k) = thx(i,k)*tvcon
685 tvcon = (1.+ep1*qx(i,1))
686 rhox(i) = psfcpa(i)/(rd*tx(i,1)*tvcon)
687 govrth(i) = g/thx(i,1)
690 !-----compute the height of full- and half-sigma levels above ground
691 ! level, and the layer thicknesses.
699 zq(i,k+1) = dz8w2d(i,k)+zq(i,k)
700 tvcon = (1.+ep1*qx(i,k))
701 rhox2(i,k) = p2d(i,k)/(rd*tx(i,k)*tvcon)
707 za(i,k) = 0.5*(zq(i,k)+zq(i,k+1))
708 dzq(i,k) = zq(i,k+1)-zq(i,k)
709 del(i,k) = p2di(i,k)-p2di(i,k+1)
719 dza(i,k) = za(i,k)-za(i,k-1)
724 !-----initialize vertical tendencies and
732 wspd1(i) = sqrt( (ux(i,1)-uox(i))*(ux(i,1)-uox(i)) + (vx(i,1)-vox(i))*(vx(i,1)-vox(i)) )+1.e-9
735 !---- compute vertical diffusion
737 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
738 ! compute preliminary variables
789 thermal(i)= thvx(i,1)
790 thermalli(i) = thlix(i,1)
793 sflux(i) = hfx(i)/rhox(i)/cp + qfx(i)/rhox(i)*ep1*thx(i,1)
794 if(br(i).gt.0.0) sfcflg(i) = .false.
797 ! compute the first guess of pbl height
807 if(.not.stable(i))then
809 spdk2 = max(ux(i,k)**2+vx(i,k)**2,1.)
810 brup(i) = (thvx(i,k)-thermal(i))*(g*za(i,k)/thvx(i,1))/spdk2
812 stable(i) = brup(i).gt.brcr(i)
819 if(brdn(i).ge.brcr(i))then
821 elseif(brup(i).le.brcr(i))then
824 brint = (brcr(i)-brdn(i))/(brup(i)-brdn(i))
826 hpbl(i) = za(i,k-1)+brint*(za(i,k)-za(i,k-1))
827 if(hpbl(i).lt.zq(i,2)) kpbl(i) = 1
828 if(kpbl(i).le.1) pblflg(i) = .false.
834 zol1(i) = max(br(i)*fm*fm/fh,rimin)
836 zol1(i) = min(zol1(i),-zfmin)
838 zol1(i) = max(zol1(i),zfmin)
840 hol1 = zol1(i)*hpbl(i)/zl1(i)*sfcfrac
842 phim(i) = (1.-aphi16*hol1)**(-1./4.)
843 phih(i) = (1.-aphi16*hol1)**(-1./2.)
844 bfx0 = max(sflux(i),0.)
845 hfx0 = max(hfx(i)/rhox(i)/cp,0.)
846 qfx0 = max(ep1*thx(i,1)*qfx(i)/rhox(i),0.)
847 wstar3(i) = (govrth(i)*bfx0*hpbl(i))
848 wstar(i) = (wstar3(i))**h1
850 phim(i) = (1.+aphi5*hol1)
856 wscale(i) = (ust3(i)+phifac*karman*wstar3(i)*0.5)**h1
857 wscale(i) = min(wscale(i),ust(i)*aphi16)
858 wscale(i) = max(wscale(i),ust(i)/aphi5)
861 ! compute the surface variables for pbl height estimation
862 ! under unstable conditions
865 if(sfcflg(i).and.sflux(i).gt.0.0)then
866 gamfac = bfac/rhox(i)/wscale(i)
867 hgamt(i) = min(gamfac*hfx(i)/cp,gamcrt)
868 hgamq(i) = min(gamfac*qfx(i),gamcrq)
869 vpert = (hgamt(i)+ep1*thx(i,1)*hgamq(i))/bfac*afac
870 thermal(i) = thermal(i)+max(vpert,0.)*min(za(i,1)/(sfcfrac*hpbl(i)),1.0)
871 thermalli(i)= thermalli(i)+max(vpert,0.)*min(za(i,1)/(sfcfrac*hpbl(i)),1.0)
872 hgamt(i) = max(hgamt(i),0.0)
873 hgamq(i) = max(hgamq(i),0.0)
874 brint = -15.9*ust(i)*ust(i)/wspd(i)*wstar3(i)/(wscale(i)**4.)
875 hgamu(i) = brint*ux(i,1)
876 hgamv(i) = brint*vx(i,1)
882 ! enhance the pbl height by considering the thermal
901 if(.not.stable(i).and.pblflg(i))then
903 spdk2 = max(ux(i,k)**2+vx(i,k)**2,1.)
904 brup(i) = (thvx(i,k)-thermal(i))*(g*za(i,k)/thvx(i,1))/spdk2
906 stable(i) = brup(i).gt.brcr(i)
911 ! enhance pbl by theta-li
913 if (ysu_topdown_pblmix.eq.1)then
917 do k = kpblold(i), kte-1
918 spdk2 = max(ux(i,k)**2+vx(i,k)**2,1.)
919 bruptmp = (thlix(i,k)-thermalli(i))*(g*za(i,k)/thlix(i,1))/spdk2
920 stable(i) = bruptmp.ge.brcr(i)
926 if (.not.stable(i)) then !overwrite brup brdn values
938 if(brdn(i).ge.brcr(i))then
940 elseif(brup(i).le.brcr(i))then
943 brint = (brcr(i)-brdn(i))/(brup(i)-brdn(i))
945 hpbl(i) = za(i,k-1)+brint*(za(i,k)-za(i,k-1))
946 if(hpbl(i).lt.zq(i,2)) kpbl(i) = 1
947 if(kpbl(i).le.1) pblflg(i) = .false.
951 ! stable boundary layer
954 if((.not.sfcflg(i)).and.hpbl(i).lt.zq(i,2)) then
963 if((.not.stable(i)).and.((xland(i)-1.5).ge.0))then
964 wspd10 = u10(i)*u10(i) + v10(i)*v10(i)
965 wspd10 = sqrt(wspd10)
966 ross = wspd10 / (cori*znt(i))
967 brcr_sbro(i) = min(0.16*(1.e-7*ross)**(-0.18),.3)
972 if(.not.stable(i))then
973 if((xland(i)-1.5).ge.0)then
974 brcr(i) = brcr_sbro(i)
983 if(.not.stable(i))then
985 spdk2 = max(ux(i,k)**2+vx(i,k)**2,1.)
986 brup(i) = (thvx(i,k)-thermal(i))*(g*za(i,k)/thvx(i,1))/spdk2
988 stable(i) = brup(i).gt.brcr(i)
994 if((.not.sfcflg(i)).and.hpbl(i).lt.zq(i,2)) then
996 if(brdn(i).ge.brcr(i))then
998 elseif(brup(i).le.brcr(i))then
1001 brint = (brcr(i)-brdn(i))/(brup(i)-brdn(i))
1003 hpbl(i) = za(i,k-1)+brint*(za(i,k)-za(i,k-1))
1004 if(hpbl(i).lt.zq(i,2)) kpbl(i) = 1
1005 if(kpbl(i).le.1) pblflg(i) = .false.
1009 ! estimate the entrainment parameters
1015 wm3 = wstar3(i) + 5. * ust3(i)
1017 bfxpbl(i) = -0.15*thvx(i,1)/g*wm3/hpbl(i)
1018 dthvx(i) = max(thvx(i,k+1)-thvx(i,k),tmin)
1019 we(i) = max(bfxpbl(i)/dthvx(i),-sqrt(wm2(i)))
1020 if((qx(i,ktrace2+k)+qx(i,ktrace3+k)).gt.0.01e-3.and.ysu_topdown_pblmix.eq.1)then
1021 if ( kpbl(i) .ge. 2) then
1023 templ=thlix(i,k)*(p2di(i,k+1)/100000)**rovcp
1024 !rvls is ws at full level
1025 rvls=100.*6.112*EXP(17.67*(templ-273.16)/(templ-29.65))*(ep2/p2di(i,k+1))
1026 temps=templ + ((qx(i,k)+qx(i,ktrace2+k))-rvls)/(cp/xlv + &
1027 ep2*xlv*rvls/(rd*templ**2))
1028 rvls=100.*6.112*EXP(17.67*(temps-273.15)/(temps-29.65))*(ep2/p2di(i,k+1))
1029 rcldb=max((qx(i,k)+qx(i,ktrace2+k))-rvls,0.)
1030 !entrainment efficiency
1031 dthvx(i) = (thlix(i,k+2)+thx(i,k+2)*ep1*(qx(i,k+2)+qx(i,ktrace2+k+2))) &
1032 - (thlix(i,k) + thx(i,k) *ep1*(qx(i,k) +qx(i,ktrace2+k)))
1033 dthvx(i) = max(dthvx(i),0.1)
1034 tmp1 = xlv/cp * rcldb/(pi2d(i,k)*dthvx(i))
1035 ent_eff = 0.2 * 8. * tmp1 +0.2
1039 radflux=rthraten(i,kk)*pi2d(i,kk) !converts theta/s to temp/s
1040 radflux=radflux*cp/g*(p2diORG(i,kk)-p2diORG(i,kk+1)) ! converts temp/s to W/m^2
1041 if (radflux < 0.0 ) radsum=abs(radflux)+radsum
1043 radsum=max(radsum,0.0)
1045 !recompute entrainment from sfc thermals
1046 bfx0 = max(max(sflux(i),0.0)-radsum/rhox2(i,k)/cp,0.)
1047 bfx0 = max(sflux(i),0.0)
1048 wm3 = (govrth(i)*bfx0*hpbl(i))+5. * ust3(i)
1050 bfxpbl(i) = -0.15*thvx(i,1)/g*wm3/hpbl(i)
1051 dthvx(i) = max(thvx(i,k+1)-thvx(i,k),tmin)
1052 we(i) = max(bfxpbl(i)/dthvx(i),-sqrt(wm2(i)))
1054 !entrainment from PBL top thermals
1055 bfx0 = max(radsum/rhox2(i,k)/cp-max(sflux(i),0.0),0.)
1056 bfx0 = max(radsum/rhox2(i,k)/cp,0.)
1057 wm3 = (g/thvx(i,k)*bfx0*hpbl(i)) ! this is wstar3(i)
1058 wm2(i) = wm2(i)+wm3**h2
1059 bfxpbl(i) = - ent_eff * bfx0
1060 dthvx(i) = max(thvx(i,k+1)-thvx(i,k),0.1)
1061 we(i) = we(i) + max(bfxpbl(i)/dthvx(i),-sqrt(wm3**h2))
1064 bfx0 = max(radsum/rhox2(i,k)/cp,0.)
1065 wstar3_2(i) = (g/thvx(i,k)*bfx0*hpbl(i))
1067 wscale(i) = (ust3(i)+phifac*karman*(wstar3(i)+wstar3_2(i))*0.5)**h1
1068 wscale(i) = min(wscale(i),ust(i)*aphi16)
1069 wscale(i) = max(wscale(i),ust(i)/aphi5)
1070 gamfac = bfac/rhox(i)/wscale(i)
1071 hgamt(i) = min(gamfac*hfx(i)/cp,gamcrt)
1072 hgamq(i) = min(gamfac*qfx(i),gamcrq)
1073 gamfac = bfac/rhox2(i,k)/wscale(i)
1074 hgamt2(i,k) = min(gamfac*radsum/cp,gamcrt)
1075 hgamt(i) = max(hgamt(i),0.0) + max(hgamt2(i,k),0.0)
1076 brint = -15.9*ust(i)*ust(i)/wspd(i)*(wstar3(i)+wstar3_2(i))/(wscale(i)**4.)
1077 hgamu(i) = brint*ux(i,1)
1078 hgamv(i) = brint*vx(i,1)
1082 dthx = max(thx(i,k+1)-thx(i,k),tmin)
1083 dqx = min(qx(i,k+1)-qx(i,k),0.0)
1084 hfxpbl(i) = we(i)*dthx
1085 qfxpbl(i) = we(i)*dqx
1087 dux = ux(i,k+1)-ux(i,k)
1088 dvx = vx(i,k+1)-vx(i,k)
1089 if(dux.gt.tmin) then
1090 ufxpbl(i) = max(prpbl(i)*we(i)*dux,-ust(i)*ust(i))
1091 elseif(dux.lt.-tmin) then
1092 ufxpbl(i) = min(prpbl(i)*we(i)*dux,ust(i)*ust(i))
1096 if(dvx.gt.tmin) then
1097 vfxpbl(i) = max(prpbl(i)*we(i)*dvx,-ust(i)*ust(i))
1098 elseif(dvx.lt.-tmin) then
1099 vfxpbl(i) = min(prpbl(i)*we(i)*dvx,ust(i)*ust(i))
1103 delb = govrth(i)*d3*hpbl(i)
1104 delta(i) = min(d1*hpbl(i) + d2*wm2(i)/delb,100.)
1110 if(pblflg(i).and.k.ge.kpbl(i))then
1111 entfac(i,k) = ((zq(i,k+1)-hpbl(i))/delta(i))**2.
1118 ! compute diffusion coefficients below pbl
1122 if(k.lt.kpbl(i)) then
1123 zfac(i,k) = min(max((1.-(zq(i,k+1)-zl1(i))/(hpbl(i)-zl1(i))),zfmin),1.)
1124 zfacent(i,k) = (1.-zfac(i,k))**3.
1125 wscalek(i,k) = (ust3(i)+phifac*karman*wstar3(i)*(1.-zfac(i,k)))**h1
1126 wscalek2(i,k) = (phifac*karman*wstar3_2(i)*(zfac(i,k)))**h1
1129 prfac2 = 15.9*(wstar3(i)+wstar3_2(i))/ust3(i)/(1.+4.*karman*(wstar3(i)+wstar3_2(i))/ust3(i))
1130 prnumfac = -3.*(max(zq(i,k+1)-sfcfrac*hpbl(i),0.))**2./hpbl(i)**2.
1135 phim8z = 1.+aphi5*zol1(i)*zq(i,k+1)/zl1(i)
1136 wscalek(i,k) = ust(i)/phim8z
1137 wscalek(i,k) = max(wscalek(i,k),0.001)
1139 prnum0 = (phih(i)/phim(i)+prfac)
1140 prnum0 = max(min(prnum0,prmax),prmin)
1141 xkzm(i,k) = wscalek(i,k) *karman* zq(i,k+1) * zfac(i,k)**pfac+ &
1142 wscalek2(i,k)*karman*(hpbl(i)-zq(i,k+1))*(1-zfac(i,k))**pfac
1143 !Do not include xkzm at kpbl-1 since it changes entrainment
1144 if (k.eq.kpbl(i)-1.and.cloudflg(i).and.we(i).lt.0.0) then
1147 prnum = 1. + (prnum0-1.)*exp(prnumfac)
1148 xkzq(i,k) = xkzm(i,k)/prnum*zfac(i,k)**(pfac_q-pfac)
1149 prnum0 = prnum0/(1.+prfac2*karman*sfcfrac)
1150 prnum = 1. + (prnum0-1.)*exp(prnumfac)
1151 xkzh(i,k) = xkzm(i,k)/prnum
1152 xkzm(i,k) = xkzm(i,k)+xkzom(i,k)
1153 xkzh(i,k) = xkzh(i,k)+xkzoh(i,k)
1154 xkzq(i,k) = xkzq(i,k)+xkzoh(i,k)
1155 xkzm(i,k) = min(xkzm(i,k),xkzmax)
1156 xkzh(i,k) = min(xkzh(i,k),xkzmax)
1157 xkzq(i,k) = min(xkzq(i,k),xkzmax)
1162 ! compute diffusion coefficients over pbl (free atmosphere)
1166 if(k.ge.kpbl(i)) then
1167 ss = ((ux(i,k+1)-ux(i,k))*(ux(i,k+1)-ux(i,k)) &
1168 +(vx(i,k+1)-vx(i,k))*(vx(i,k+1)-vx(i,k))) &
1169 /(dza(i,k+1)*dza(i,k+1))+1.e-9
1170 govrthv = g/(0.5*(thvx(i,k+1)+thvx(i,k)))
1171 ri = govrthv*(thvx(i,k+1)-thvx(i,k))/(ss*dza(i,k+1))
1172 if(imvdif.eq.1.and.ndiff.ge.3)then
1173 if((qx(i,ktrace2+k)+qx(i,ktrace3+k)).gt.0.01e-3.and.(qx(i &
1174 ,ktrace2+k+1)+qx(i,ktrace3+k+1)).gt.0.01e-3)then
1176 qmean = 0.5*(qx(i,k)+qx(i,k+1))
1177 tmean = 0.5*(tx(i,k)+tx(i,k+1))
1178 alph = xlv*qmean/rd/tmean
1179 chi = xlv*xlv*qmean/cp/rv/tmean/tmean
1180 ri = (1.+alph)*(ri-g*g/ss/tmean/cp*((chi-alph)/(1.+chi)))
1183 zk = karman*zq(i,k+1)
1184 rlamdz = min(max(0.1*dza(i,k+1),rlam),300.)
1185 rlamdz = min(dza(i,k+1),rlamdz)
1186 rl2 = (zk*rlamdz/(rlamdz+zk))**2
1192 xkzm(i,k) = dk*(1+8.*(-ri)/(1+1.746*sri))
1193 xkzh(i,k) = dk*(1+8.*(-ri)/(1+1.286*sri))
1196 xkzh(i,k) = dk/(1+5.*ri)**2
1198 prnum = min(prnum,prmax)
1199 xkzm(i,k) = xkzh(i,k)*prnum
1202 xkzm(i,k) = xkzm(i,k)+xkzom(i,k)
1203 xkzh(i,k) = xkzh(i,k)+xkzoh(i,k)
1204 xkzm(i,k) = min(xkzm(i,k),xkzmax)
1205 xkzh(i,k) = min(xkzh(i,k),xkzmax)
1206 xkzml(i,k) = xkzm(i,k)
1207 xkzhl(i,k) = xkzh(i,k)
1212 ! compute tridiagonal matrix elements for heat
1225 f1(i,1) = thx(i,1)-300.+(1.0-bepswitch)*hfx(i)/cont/del(i,1)*dt2
1230 dtodsd = sfk2d(i,k)*dt2/del(i,k)
1231 dtodsu = sfk2d(i,k)*dt2/del(i,k+1)
1232 dsig = p2d(i,k)-p2d(i,k+1)
1234 tem1 = dsig*xkzh(i,k)*rdz
1235 if(pblflg(i).and.k.lt.kpbl(i)) then
1236 dsdzt = tem1*(-hgamt(i)/hpbl(i)-hfxpbl(i)*zfacent(i,k)/xkzh(i,k))
1237 f1(i,k) = f1(i,k)+dtodsd*dsdzt
1238 f1(i,k+1) = thx(i,k+1)-300.-dtodsu*dsdzt
1239 elseif(pblflg(i).and.k.ge.kpbl(i).and.entfac(i,k).lt.4.6) then
1240 xkzh(i,k) = -we(i)*dza(i,kpbl(i))*exp(-entfac(i,k))
1241 xkzh(i,k) = sqrt(xkzh(i,k)*xkzhl(i,k))
1242 xkzh(i,k) = max(xkzh(i,k),xkzoh(i,k))
1243 xkzh(i,k) = min(xkzh(i,k),xkzmax)
1244 f1(i,k+1) = thx(i,k+1)-300.
1246 f1(i,k+1) = thx(i,k+1)-300.
1248 tem1 = dsig*xkzh(i,k)*rdz
1250 au(i,k) = -dtodsd*dsdz2/vlk2d(i,k)
1251 al(i,k) = -dtodsu*dsdz2/vlk2d(i,k)
1252 ad(i,k) = ad(i,k)-au(i,k)
1253 ad(i,k+1) = 1.-al(i,k)
1254 exch_hx(i,k+1) = xkzh(i,k)
1258 ! add bep/bep+bem forcing for heat if flag_bep=.true.
1262 ad(i,k) = ad(i,k) - a_t2d(i,k)*dt2
1263 f1(i,k) = f1(i,k) + b_t2d(i,k)*dt2
1267 ! copies here to avoid duplicate input args for tridin
1276 call tridin_ysu(al,ad,cu,r1,au,f1,its,ite,kts,kte,1)
1278 ! recover tendencies of heat
1282 ttend = (f1(i,k)-thx(i,k)+300.)*rdt*pi2d(i,k)
1283 ttnp(i,k) = ttnp(i,k)+ttend
1284 dtsfc(i) = dtsfc(i)+ttend*cont*del(i,k)/pi2d(i,k)
1288 ! compute tridiagonal matrix elements for moisture, clouds, and gases
1308 f3(i,1,1) = qx(i,1)+(1.0-bepswitch)*qfx(i)*g/del(i,1)*dt2
1315 f3(i,1,ic) = qx(i,1+is)
1322 if(k.ge.kpbl(i)) then
1323 xkzq(i,k) = xkzh(i,k)
1330 dtodsd = sfk2d(i,k)*dt2/del(i,k)
1331 dtodsu = sfk2d(i,k)*dt2/del(i,k+1)
1332 dsig = p2d(i,k)-p2d(i,k+1)
1334 tem1 = dsig*xkzq(i,k)*rdz
1335 if(pblflg(i).and.k.lt.kpbl(i)) then
1336 dsdzq = tem1*(-qfxpbl(i)*zfacent(i,k)/xkzq(i,k))
1337 f3(i,k,1) = f3(i,k,1)+dtodsd*dsdzq
1338 f3(i,k+1,1) = qx(i,k+1)-dtodsu*dsdzq
1339 elseif(pblflg(i).and.k.ge.kpbl(i).and.entfac(i,k).lt.4.6) then
1340 xkzq(i,k) = -we(i)*dza(i,kpbl(i))*exp(-entfac(i,k))
1341 xkzq(i,k) = sqrt(xkzq(i,k)*xkzhl(i,k))
1342 xkzq(i,k) = max(xkzq(i,k),xkzoh(i,k))
1343 xkzq(i,k) = min(xkzq(i,k),xkzmax)
1344 f3(i,k+1,1) = qx(i,k+1)
1346 f3(i,k+1,1) = qx(i,k+1)
1348 tem1 = dsig*xkzq(i,k)*rdz
1350 au(i,k) = -dtodsd*dsdz2/vlk2d(i,k)
1351 al(i,k) = -dtodsu*dsdz2/vlk2d(i,k)
1352 ad(i,k) = ad(i,k)-au(i,k)
1353 ad(i,k+1) = 1.-al(i,k)
1354 ! exch_hx(i,k+1) = xkzh(i,k)
1363 f3(i,k+1,ic) = qx(i,k+1+is)
1369 ! add bep/bep+bem forcing for water vapor if flag_bep=.true.
1373 ad(i,k) = ad(i,k) - a_q2d(i,k)*dt2
1374 f3(i,k,1) = f3(i,k,1) + b_q2d(i,k)*dt2
1378 ! copies here to avoid duplicate input args for tridin
1389 r3(i,k,ic) = f3(i,k,ic)
1394 ! solve tridiagonal problem for moisture, clouds, and gases
1396 call tridin_ysu(al,ad,cu,r3,au,f3,its,ite,kts,kte,ndiff)
1398 ! recover tendencies of heat and moisture
1402 qtend = (f3(i,k,1)-qx(i,k))*rdt
1403 qtnp(i,k) = qtnp(i,k)+qtend
1404 dqsfc(i) = dqsfc(i)+qtend*conq*del(i,k)
1413 qtend = (f3(i,k,ic)-qx(i,k+is))*rdt
1414 qtnp(i,k+is) = qtnp(i,k+is)+qtend
1420 ! compute tridiagonal matrix elements for momentum
1432 ! paj: ctopo=1 if topo_wind=0 (default)
1433 !raquel---paj tke code (could be replaced with shin-hong tke in future
1436 shear_ysu(i,k)=xkzm(i,k)*((-hgamu(i)/hpbl(i)+(ux(i,k+1)-ux(i,k))/dza(i,k+1))*(ux(i,k+1)-ux(i,k))/dza(i,k+1) &
1437 + (-hgamv(i)/hpbl(i)+(vx(i,k+1)-vx(i,k))/dza(i,k+1))*(vx(i,k+1)-vx(i,k))/dza(i,k+1))
1438 buoy_ysu(i,k)=xkzh(i,k)*g*(1.0/thx(i,k))*(-hgamt(i)/hpbl(i)+(thx(i,k+1)-thx(i,k))/dza(i,k+1))
1440 zk = karman*zq(i,k+1)
1442 if (k.ge.kpbl(i)) then
1443 rlamdz = min(max(0.1*dza(i,k+1),rlam),300.)
1444 rlamdz = min(dza(i,k+1),rlamdz)
1449 el_ysu(i,k) = zk*rlamdz/(rlamdz+zk)
1450 tke_ysu(i,k)=16.6*el_ysu(i,k)*(shear_ysu(i,k)-buoy_ysu(i,k)+b_e2d(i,k))
1451 !q2 when q3 positive
1452 if(tke_ysu(i,k).le.0) then
1455 tke_ysu(i,k)=(tke_ysu(i,k))**0.66
1458 !Hybrid pblh of MYNN
1460 CALL GET_PBLH(KTS,KTE,pblh_ysu(i),thvx(i,kts:kte),&
1461 & tke_ysu(i,kts:kte),zq(i,kts:kte+1),dzq(i,kts:kte),xland(i))
1464 ! Use Beljaars over land
1465 if (xland(i).lt.1.5) then
1466 fluxc = max(sflux(i),0.0)
1468 VCONV = vconvc*(g/thvx(i,1)*pblh_ysu(i)*fluxc)**.33
1470 ! for water there is no topo effect so vconv not needed
1475 !ctopo stability correction
1476 fric(i,1)=ust(i)**2/wspd1(i)*rhox(i)*g/del(i,1)*dt2 &
1477 *(wspd1(i)/wspd(i))**2
1478 if(present(ctopo)) then
1479 vconvnew=0.9*vconvfx(i)+1.5*(max((pblh_ysu(i)-500)/1000.0,0.0))
1480 vconvlim = min(vconvnew,1.0)
1481 ad(i,1) = 1.+(1.0-bepswitch*frc_urb1d(i))* &
1482 (fric(i,1)*vconvlim+ctopo(i)*fric(i,1)*(1-vconvlim)) - &
1483 fric(i,1)*bepswitch*(1-frc_urb1d(i))
1485 ad(i,1) = 1.+(1.0-bepswitch)*fric(i,1)
1487 f1(i,1) = ux(i,1)+uox(i)*ust(i)**2*rhox(i)*g/del(i,1)*dt2/wspd1(i)*(wspd1(i)/wspd(i))**2
1488 f2(i,1) = vx(i,1)+vox(i)*ust(i)**2*rhox(i)*g/del(i,1)*dt2/wspd1(i)*(wspd1(i)/wspd(i))**2
1493 dtodsd = sfk2d(i,k)*dt2/del(i,k)
1494 dtodsu = sfk2d(i,k)*dt2/del(i,k+1)
1495 dsig = p2d(i,k)-p2d(i,k+1)
1497 tem1 = dsig*xkzm(i,k)*rdz
1498 if(pblflg(i).and.k.lt.kpbl(i))then
1499 dsdzu = tem1*(-hgamu(i)/hpbl(i)-ufxpbl(i)*zfacent(i,k)/xkzm(i,k))
1500 dsdzv = tem1*(-hgamv(i)/hpbl(i)-vfxpbl(i)*zfacent(i,k)/xkzm(i,k))
1501 f1(i,k) = f1(i,k)+dtodsd*dsdzu
1502 f1(i,k+1) = ux(i,k+1)-dtodsu*dsdzu
1503 f2(i,k) = f2(i,k)+dtodsd*dsdzv
1504 f2(i,k+1) = vx(i,k+1)-dtodsu*dsdzv
1505 elseif(pblflg(i).and.k.ge.kpbl(i).and.entfac(i,k).lt.4.6) then
1506 xkzm(i,k) = prpbl(i)*xkzh(i,k)
1507 xkzm(i,k) = sqrt(xkzm(i,k)*xkzml(i,k))
1508 xkzm(i,k) = max(xkzm(i,k),xkzom(i,k))
1509 xkzm(i,k) = min(xkzm(i,k),xkzmax)
1510 f1(i,k+1) = ux(i,k+1)
1511 f2(i,k+1) = vx(i,k+1)
1513 f1(i,k+1) = ux(i,k+1)
1514 f2(i,k+1) = vx(i,k+1)
1516 tem1 = dsig*xkzm(i,k)*rdz
1518 au(i,k) = -dtodsd*dsdz2/vlk2d(i,k)
1519 al(i,k) = -dtodsu*dsdz2/vlk2d(i,k)
1520 ad(i,k) = ad(i,k)-au(i,k)
1521 ad(i,k+1) = 1.-al(i,k)
1522 exch_mx(i,k+1) = xkzm(i,k)
1526 ! add bep/bep+bem forcing for momentum if flag_bep=.true.
1535 ad(i,k) = ad(i,k) - a_u2d(i,k)*dt2
1536 ad1(i,k) = ad1(i,k) - a_v2d(i,k)*dt2
1537 f1(i,k) = f1(i,k) + b_u2d(i,k)*dt2
1538 f2(i,k) = f2(i,k) + b_v2d(i,k)*dt2
1542 ! copies here to avoid duplicate input args for tridin
1552 ! solve tridiagonal problem for momentum
1554 call tridi2n(al,ad,ad1,cu,r1,r2,au,f1,f2,its,ite,kts,kte,1)
1556 ! recover tendencies of momentum
1560 utend = (f1(i,k)-ux(i,k))*rdt
1561 vtend = (f2(i,k)-vx(i,k))*rdt
1562 utnp(i,k) = utnp(i,k)+utend
1563 vtnp(i,k) = vtnp(i,k)+vtend
1564 dusfc(i) = dusfc(i) + utend*conwrc*del(i,k)
1565 dvsfc(i) = dvsfc(i) + vtend*conwrc*del(i,k)
1569 ! paj: ctopo2=1 if topo_wind=0 (default)
1572 if(present(ctopo).and.present(ctopo2)) then ! mchen for NMM
1573 u10(i) = ctopo2(i)*u10(i)+(1-ctopo2(i))*ux(i,1)
1574 v10(i) = ctopo2(i)*v10(i)+(1-ctopo2(i))*vx(i,1)
1578 !---- end of vertical diffusion
1584 end subroutine ysu2d
1585 !-------------------------------------------------------------------------------
1587 !-------------------------------------------------------------------------------
1588 subroutine tridi2n(cl,cm,cm1,cu,r1,r2,au,f1,f2,its,ite,kts,kte,nt)
1589 !-------------------------------------------------------------------------------
1591 !-------------------------------------------------------------------------------
1593 integer, intent(in ) :: its,ite, kts,kte, nt
1595 real, dimension( its:ite, kts+1:kte+1 ) , &
1598 real, dimension( its:ite, kts:kte ) , &
1599 intent(in ) :: cm, &
1602 real, dimension( its:ite, kts:kte,nt ) , &
1605 real, dimension( its:ite, kts:kte ) , &
1606 intent(inout) :: au, &
1609 real, dimension( its:ite, kts:kte,nt ) , &
1613 integer :: i,k,l,n,it
1615 !-------------------------------------------------------------------------------
1622 au(i,1) = fk*cu(i,1)
1623 f1(i,1) = fk*r1(i,1)
1629 f2(i,1,it) = fk*r2(i,1,it)
1635 fk = 1./(cm(i,k)-cl(i,k)*au(i,k-1))
1636 au(i,k) = fk*cu(i,k)
1637 f1(i,k) = fk*(r1(i,k)-cl(i,k)*f1(i,k-1))
1644 fk = 1./(cm1(i,k)-cl(i,k)*au(i,k-1))
1645 f2(i,k,it) = fk*(r2(i,k,it)-cl(i,k)*f2(i,k-1,it))
1651 fk = 1./(cm(i,n)-cl(i,n)*au(i,n-1))
1652 f1(i,n) = fk*(r1(i,n)-cl(i,n)*f1(i,n-1))
1657 fk = 1./(cm1(i,n)-cl(i,n)*au(i,n-1))
1658 f2(i,n,it) = fk*(r2(i,n,it)-cl(i,n)*f2(i,n-1,it))
1664 f1(i,k) = f1(i,k)-au(i,k)*f1(i,k+1)
1671 f2(i,k,it) = f2(i,k,it)-au(i,k)*f2(i,k+1,it)
1676 end subroutine tridi2n
1677 !-------------------------------------------------------------------------------
1679 !-------------------------------------------------------------------------------
1680 subroutine tridin_ysu(cl,cm,cu,r2,au,f2,its,ite,kts,kte,nt)
1681 !-------------------------------------------------------------------------------
1683 !-------------------------------------------------------------------------------
1685 integer, intent(in ) :: its,ite, kts,kte, nt
1687 real, dimension( its:ite, kts+1:kte+1 ) , &
1690 real, dimension( its:ite, kts:kte ) , &
1692 real, dimension( its:ite, kts:kte,nt ) , &
1695 real, dimension( its:ite, kts:kte ) , &
1696 intent(inout) :: au, &
1698 real, dimension( its:ite, kts:kte,nt ) , &
1702 integer :: i,k,l,n,it
1704 !-------------------------------------------------------------------------------
1712 au(i,1) = fk*cu(i,1)
1713 f2(i,1,it) = fk*r2(i,1,it)
1720 fk = 1./(cm(i,k)-cl(i,k)*au(i,k-1))
1721 au(i,k) = fk*cu(i,k)
1722 f2(i,k,it) = fk*(r2(i,k,it)-cl(i,k)*f2(i,k-1,it))
1729 fk = 1./(cm(i,n)-cl(i,n)*au(i,n-1))
1730 f2(i,n,it) = fk*(r2(i,n,it)-cl(i,n)*f2(i,n-1,it))
1737 f2(i,k,it) = f2(i,k,it)-au(i,k)*f2(i,k+1,it)
1742 end subroutine tridin_ysu
1743 !-------------------------------------------------------------------------------
1745 !-------------------------------------------------------------------------------
1746 subroutine ysuinit(rublten,rvblten,rthblten,rqvblten, &
1747 rqcblten,rqiblten,p_qi,p_first_scalar, &
1748 restart, allowed_to_read, &
1749 ids, ide, jds, jde, kds, kde, &
1750 ims, ime, jms, jme, kms, kme, &
1751 its, ite, jts, jte, kts, kte )
1752 !-------------------------------------------------------------------------------
1754 !-------------------------------------------------------------------------------
1756 logical , intent(in) :: restart, allowed_to_read
1757 integer , intent(in) :: ids, ide, jds, jde, kds, kde, &
1758 ims, ime, jms, jme, kms, kme, &
1759 its, ite, jts, jte, kts, kte
1760 integer , intent(in) :: p_qi,p_first_scalar
1761 real , dimension( ims:ime , kms:kme , jms:jme ), intent(out) :: &
1768 integer :: i, j, k, itf, jtf, ktf
1770 jtf = min0(jte,jde-1)
1771 ktf = min0(kte,kde-1)
1772 itf = min0(ite,ide-1)
1774 if(.not.restart)then
1780 rthblten(i,k,j) = 0.
1781 rqvblten(i,k,j) = 0.
1782 rqcblten(i,k,j) = 0.
1788 if (p_qi .ge. p_first_scalar .and. .not.restart) then
1792 rqiblten(i,k,j) = 0.
1798 end subroutine ysuinit
1799 !-------------------------------------------------------------------------------
1800 ! ==================================================================
1802 SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea)
1803 ! Copied from MYNN PBL
1805 !---------------------------------------------------------------
1806 ! NOTES ON THE PBLH FORMULATION
1808 !The 1.5-theta-increase method defines PBL heights as the level at
1809 !which the potential temperature first exceeds the minimum potential
1810 !temperature within the boundary layer by 1.5 K. When applied to
1811 !observed temperatures, this method has been shown to produce PBL-
1812 !height estimates that are unbiased relative to profiler-based
1813 !estimates (Nielsen-Gammon et al. 2008). However, their study did not
1814 !include LLJs. Banta and Pichugina (2008) show that a TKE-based
1815 !threshold is a good estimate of the PBL height in LLJs. Therefore,
1816 !a hybrid definition is implemented that uses both methods, weighting
1817 !the TKE-method more during stable conditions (PBLH < 400 m).
1818 !A variable tke threshold (TKEeps) is used since no hard-wired
1819 !value could be found to work best in all conditions.
1820 !---------------------------------------------------------------
1822 INTEGER,INTENT(IN) :: KTS,KTE
1823 REAL, INTENT(OUT) :: zi
1824 REAL, INTENT(IN) :: landsea
1825 REAL, DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D
1826 REAL, DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D
1828 REAL :: PBLH_TKE,qtke,qtkem1,wt,maxqke,TKEeps,minthv
1829 REAL :: delt_thv !delta theta-v; dependent on land/sea point
1830 REAL, PARAMETER :: sbl_lim = 200. !Theta-v PBL lower limit of trust (m).
1831 REAL, PARAMETER :: sbl_damp = 400. !Damping range for averaging with TKE-based PBLH (m).
1832 INTEGER :: I,J,K,kthv,ktke
1834 !FIND MAX TKE AND MIN THETAV IN THE LOWEST 500 M
1841 DO WHILE (zw1D(k) .LE. 500.)
1842 qtke =MAX(Qke1D(k),0.) ! maximum QKE
1843 IF (maxqke < qtke) then
1847 IF (minthv > thetav1D(k)) then
1848 minthv = thetav1D(k)
1853 !TKEeps = maxtke/20. = maxqke/40.
1855 TKEeps = MAX(TKEeps,0.025)
1856 TKEeps = MIN(TKEeps,0.25)
1858 !FIND THETAV-BASED PBLH (BEST FOR DAYTIME).
1861 IF((landsea-1.5).GE.0)THEN
1871 DO WHILE (zi .EQ. 0.)
1872 IF (thetav1D(k) .GE. (minthv + delt_thv))THEN
1873 zi = zw1D(k) - dz1D(k-1)* &
1874 & MIN((thetav1D(k)-(minthv + delt_thv))/MAX(thetav1D(k)-thetav1D(k-1),1E-6),1.0)
1877 IF (k .EQ. kte-1) zi = zw1D(kts+1) !EXIT SAFEGUARD
1880 !print*,"IN GET_PBLH:",thsfc,zi
1881 !FOR STABLE BOUNDARY LAYERS, USE TKE METHOD TO COMPLEMENT THE
1882 !THETAV-BASED DEFINITION (WHEN THE THETA-V BASED PBLH IS BELOW ~0.5 KM).
1883 !THE TANH WEIGHTING FUNCTION WILL MAKE THE TKE-BASED DEFINITION NEGLIGIBLE
1884 !WHEN THE THETA-V-BASED DEFINITION IS ABOVE ~1 KM.
1885 !FIND TKE-BASED PBLH (BEST FOR NOCTURNAL/STABLE CONDITIONS).
1889 DO WHILE (PBLH_TKE .EQ. 0.)
1890 !QKE CAN BE NEGATIVE (IF CKmod == 0)... MAKE TKE NON-NEGATIVE.
1891 qtke =MAX(Qke1D(k)/2.,0.) ! maximum TKE
1892 qtkem1=MAX(Qke1D(k-1)/2.,0.)
1893 IF (qtke .LE. TKEeps) THEN
1894 PBLH_TKE = zw1D(k) - dz1D(k-1)* &
1895 & MIN((TKEeps-qtke)/MAX(qtkem1-qtke, 1E-6), 1.0)
1896 !IN CASE OF NEAR ZERO TKE, SET PBLH = LOWEST LEVEL.
1897 PBLH_TKE = MAX(PBLH_TKE,zw1D(kts+1))
1898 !print *,"PBLH_TKE:",i,j,PBLH_TKE, Qke1D(k)/2., zw1D(kts+1)
1901 IF (k .EQ. kte-1) PBLH_TKE = zw1D(kts+1) !EXIT SAFEGUARD
1904 !BLEND THE TWO PBLH TYPES HERE:
1906 wt=.5*TANH((zi - sbl_lim)/sbl_damp) + .5
1907 zi=PBLH_TKE*(1.-wt) + zi*wt
1909 END SUBROUTINE GET_PBLH
1910 ! ==================================================================
1912 end module module_bl_ysu
1913 !-------------------------------------------------------------------------------