1 ! translated from NN f77 to F90 and put into WRF by Mariusz Pagowski
2 ! NOAA/GSD & CIRA/CSU, Feb 2008
3 ! changes to original code:
5 ! 2. no advection of TKE, covariances and variances
6 ! 3. Cranck-Nicholson replaced with the implicit scheme
7 ! 4. removed terrain dependent grid since input in WRF in actual
9 ! 5. cosmetic changes to adhere to WRF standard (remove common blocks,
11 !-------------------------------------------------------------------
12 !Modifications implemented by Joseph Olson NOAA/GSD/AMB - CU/CIRES
13 !(approved by Mikio Nakanishi):
14 ! 1. Addition of BouLac mixing length in the free atmosphere.
15 ! 2. Changed the turbulent mixing length to be integrated from the
16 ! surface to the top of the BL + a transition layer depth.
17 ! 3. Option to use Kitamura/Canuto modification which removes the
18 ! critical Richardson number and negative TKE (default).
19 ! 4. Hybrid PBL height diagnostic, which blends a theta-v-based
20 ! definition in neutral/convective BL and a TKE-based definition
21 ! in stable conditions.
22 ! For changes 1 and 3, see "JOE's mods" below:
23 !-------------------------------------------------------------------
27 USE module_model_constants, only: &
28 &karman, g, p1000mb, &
30 &svp1, svp2, svp3, svpt0, ep_1, ep_2
32 !-------------------------------------------------------------------
34 !-------------------------------------------------------------------
36 ! The parameters below depend on stability functions of module_sf_mynn.
37 REAL, PARAMETER :: cphm_st=5.0, cphm_unst=16.0, &
38 cphh_st=5.0, cphh_unst=16.0
40 REAL, PARAMETER :: xlvcp=xlv/cp, ev=xlv, rd=r_d, rk=cp/rd, &
41 &svp11=svp1*1.e3, p608=ep_1, ep_3=1.-ep_2
43 REAL, PARAMETER :: tref=300.0 ! reference temperature (K)
44 REAL, PARAMETER :: tv0=p608*tref, tv1=(1.+p608)*tref, gtr=g/tref
52 &b2 = 15.0, & ! CKmod NN2009
53 &c2 = 0.729, & ! 0.729, & !0.75, &
54 &c3 = 0.340, & ! 0.340, & !0.352, &
57 &a1 = b1*( 1.0-3.0*g1 )/6.0, &
58 ! &c1 = g1 -1.0/( 3.0*a1*b1**(1.0/3.0) ), &
59 &c1 = g1 -1.0/( 3.0*a1*2.88449914061481660), &
60 &a2 = a1*( g1-c1 )/( g1*pr ), &
61 &g2 = b2/b1*( 1.0-c3 ) +2.0*a1/b1*( 3.0-2.0*c2 )
66 &e1c = 3.0*a2*b2*cc3, &
67 &e2c = 9.0*a1*a2*cc2, &
68 &e3c = 9.0*a2*a2*cc2*( 1.0-c5 ), &
69 &e4c = 12.0*a1*a2*cc2, &
72 ! Constants for length scale
73 REAL, PARAMETER :: qmin=0.0, zmax=1.0, cns=2.7, &
74 !NN2009: &alp1=0.23, alp2=1.0, alp3=5.0, alp4=100.0, Sqfac=3.0
75 &alp1=0.23, alp2=0.53, alp3=5.0, alp4=100.0, Sqfac=2.0
77 ! Constants for gravitational settling
78 ! REAL, PARAMETER :: gno=1.e6/(1.e8)**(2./3.), gpw=5./3., qcgmin=1.e-8
79 REAL, PARAMETER :: gno=4.64158883361278196
80 REAL, PARAMETER :: gpw=5./3., qcgmin=1.e-8,qkemin=1.e-12
81 ! REAL, PARAMETER :: pblh_ref=1500.
83 REAL, PARAMETER :: rr2=0.7071068, rrp=0.3989423
86 !Use Canuto/Kitamura mod (remove Ric and negative TKE) (1:yes, 0:no)
87 !For more info, see Canuto et al. (2008 JAS) and Kitamura (Journal of the
88 !Meteorological Society of Japan, Vol. 88, No. 5, pp. 857-864, 2010).
89 !Note that this change required further modification of other parameters
90 !above (c2, c3, alp2, and Sqfac). If you want to remove this option, set these
91 !parameters back to NN2009 values (see commented out lines next to the
92 !parameters above). This only removes the negative TKE problem
93 !but does not necessarily improve performance - neutral impact.
94 REAL, PARAMETER :: CKmod=1.
96 !Use BouLac mixing length in free atmosphere (1:yes, 0:no)
97 !This helps remove excessively large mixing in unstable layers aloft.
98 REAL, PARAMETER :: BLmod=1.
101 INTEGER :: mynn_level
105 ! **********************************************************************
106 ! * An improved Mellor-Yamada turbulence closure model *
108 ! * Aug/2005 M. Nakanishi (N.D.A) *
109 ! * Modified: Dec/2005 M. Nakanishi (N.D.A) *
113 ! * 1. mym_initialize (to be called once initially) *
114 ! * gives the closure constants and initializes the turbulent *
116 ! * (2) mym_level2 (called in the other subroutines) *
117 ! * calculates the stability functions at Level 2. *
118 ! * (3) mym_length (called in the other subroutines) *
119 ! * calculates the master length scale. *
120 ! * 4. mym_turbulence *
121 ! * calculates the vertical diffusivity coefficients and the *
122 ! * production terms for the turbulent quantities. *
124 ! * predicts the turbulent quantities at the next step. *
125 ! * 6. mym_condensation *
126 ! * determines the liquid water content and the cloud fraction *
127 ! * diagnostically. *
129 ! * call mym_initialize *
131 ! * |<----------------+ *
133 ! * call mym_condensation | *
134 ! * call mym_turbulence | *
135 ! * call mym_predict | *
137 ! * |-----------------+ *
141 ! * Variables worthy of special mention: *
142 ! * tref : Reference temperature *
143 ! * thl : Liquid water potential temperature *
144 ! * qw : Total water (water vapor+liquid water) content *
145 ! * ql : Liquid water content *
146 ! * vt, vq : Functions for computing the buoyancy flux *
148 ! * If the water contents are unnecessary, e.g., in the case of *
149 ! * ocean models, thl is the potential temperature and qw, ql, vt *
150 ! * and vq are all zero. *
152 ! * Grid arrangement: *
153 ! * k+1 +---------+ *
155 ! * (k) | * | j = 1 - ny *
160 ! * All the predicted variables are defined at the center (*) of *
161 ! * the grid boxes. The diffusivity coefficients are, however, *
162 ! * defined on the walls of the grid boxes. *
163 ! * # Upper boundary values are given at k=nz. *
166 ! * 1. Nakanishi, M., 2001: *
167 ! * Boundary-Layer Meteor., 99, 349-378. *
168 ! * 2. Nakanishi, M. and H. Niino, 2004: *
169 ! * Boundary-Layer Meteor., 112, 1-31. *
170 ! * 3. Nakanishi, M. and H. Niino, 2006: *
171 ! * Boundary-Layer Meteor., (in press). *
172 ! * 4. Nakanishi, M. and H. Niino, 2009: *
173 ! * Jour. Meteor. Soc. Japan, 87, 895-912. *
174 ! **********************************************************************
176 ! SUBROUTINE mym_initialize:
179 ! iniflag : <>0; turbulent quantities will be initialized
180 ! = 0; turbulent quantities have been already
181 ! given, i.e., they will not be initialized
182 ! mx, my : Maximum numbers of grid boxes
183 ! in the x and y directions, respectively
184 ! nx, ny, nz : Numbers of the actual grid boxes
185 ! in the x, y and z directions, respectively
186 ! tref : Reference temperature (K)
187 ! dz(nz) : Vertical grid spacings (m)
189 ! zw(nz+1) : Heights of the walls of the grid boxes (m)
190 ! # zw(1)=0.0 and zw(k)=zw(k-1)+dz(k-1)
191 ! h(mx,ny) : G^(1/2) in the terrain-following coordinate
192 ! # h=1-zg/zt, where zg is the height of the
193 ! terrain and zt the top of the model domain
194 ! pi0(mx,my,nz) : Exner function at zw*h+zg (J/kg K)
195 ! defined by c_p*( p_basic/1000hPa )^kappa
196 ! This is usually computed by integrating
197 ! d(pi0)/dz = -h*g/tref.
198 ! rmo(mx,ny) : Inverse of the Obukhov length (m^(-1))
199 ! flt, flq(mx,ny) : Turbulent fluxes of sensible and latent heat,
200 ! respectively, e.g., flt=-u_*Theta_* (K m/s)
201 !! flt - liquid water potential temperature surface flux
202 !! flq - total water flux surface flux
203 ! ust(mx,ny) : Friction velocity (m/s)
204 ! pmz(mx,ny) : phi_m-zeta at z1*h+z0, where z1 (=0.5*dz(1))
205 ! is the first grid point above the surafce, z0
206 ! the roughness length and zeta=(z1*h+z0)*rmo
207 ! phh(mx,ny) : phi_h at z1*h+z0
208 ! u, v(mx,my,nz): Components of the horizontal wind (m/s)
209 ! thl(mx,my,nz) : Liquid water potential temperature
211 ! qw(mx,my,nz) : Total water content Q_w (kg/kg)
214 ! ql(mx,my,nz) : Liquid water content (kg/kg)
215 ! v?(mx,my,nz) : Functions for computing the buoyancy flux
216 ! qke(mx,my,nz) : Twice the turbulent kinetic energy q^2
218 ! tsq(mx,my,nz) : Variance of Theta_l (K^2)
219 ! qsq(mx,my,nz) : Variance of Q_w
220 ! cov(mx,my,nz) : Covariance of Theta_l and Q_w (K)
221 ! el(mx,my,nz) : Master length scale L (m)
222 ! defined on the walls of the grid boxes
223 ! bsh : no longer used
224 ! via common : Closure constants
226 ! Work arrays: see subroutine mym_level2
227 ! pd?(mx,my,nz) : Half of the production terms at Level 2
228 ! defined on the walls of the grid boxes
229 ! qkw(mx,my,nz) : q on the walls of the grid boxes (m/s)
231 ! # As to dtl, ...gh, see subroutine mym_turbulence.
233 !-------------------------------------------------------------------
234 SUBROUTINE mym_initialize ( kts,kte,&
237 ! & ust, rmo, pmz, phh, flt, flq,&
242 & Qke, Tsq, Qsq, Cov)
244 !-------------------------------------------------------------------
246 INTEGER, INTENT(IN) :: kts,kte
247 ! REAL, INTENT(IN) :: ust, rmo, pmz, phh, flt, flq
248 REAL, INTENT(IN) :: ust, rmo
249 REAL, DIMENSION(kts:kte), INTENT(in) :: dz
250 REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw
251 REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw
253 REAL, DIMENSION(kts:kte), INTENT(out) :: qke,tsq,qsq,cov
256 REAL, DIMENSION(kts:kte) :: &
257 &ql,el,pdk,pdt,pdq,pdc,dtl,dqw,dtv,&
258 &gm,gh,sm,sh,qkw,vt,vq
260 REAL :: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1.,flt=0.,flq=0.,tmpq
261 !JOE-BouLac and PBLH mod
263 REAL, DIMENSION(kts:kte) :: theta
267 ! ** At first ql, vt and vq are set to zero. **
274 CALL mym_level2 ( kts,kte,&
278 & dtl, dqw, dtv, gm, gh, sm, sh )
280 ! ** Preliminary setting **
283 qke(kts) = ust**2 * ( b1*pmz )**(2.0/3.0)
285 phm = phh*b2 / ( b1*pmz )**(1.0/3.0)
286 tsq(kts) = phm*( flt/ust )**2
287 qsq(kts) = phm*( flq/ust )**2
288 cov(kts) = phm*( flt/ust )*( flq/ust )
292 el (k) = vkz/( 1.0 + vkz/100.0 )
300 ! ** Initialization with an iterative manner **
301 ! ** lmax is the iteration count. This is arbitrary. **
306 CALL mym_length ( kts,kte,&
313 !JOE-added for BouLac/PBHL Test
320 pdk(k) = elq*( sm(k)*gm (k)+&
322 pdt(k) = elq* sh(k)*dtl(k)**2
323 pdq(k) = elq* sh(k)*dqw(k)**2
324 pdc(k) = elq* sh(k)*dtl(k)*dqw(k)
327 ! ** Strictly, vkz*h(i,j) -> vk*( 0.5*dz(1)*h(i,j)+z0 ) **
330 elv = 0.5*( el(kts+1)+el(kts) ) / vkz
331 qke(kts) = ust**2 * ( b1*pmz*elv )**(2.0/3.0)
333 phm = phh*b2 / ( b1*pmz/elv**2 )**(1.0/3.0)
334 tsq(kts) = phm*( flt/ust )**2
335 qsq(kts) = phm*( flq/ust )**2
336 cov(kts) = phm*( flt/ust )*( flq/ust )
339 b1l = b1*0.25*( el(k+1)+el(k) )
340 tmpq=MAX(b1l*( pdk(k+1)+pdk(k) ),qkemin)
341 ! PRINT *,'tmpqqqqq',tmpq,pdk(k+1),pdk(k)
342 qke(k) = tmpq**(2.0/3.0)
345 IF ( qke(k) .LE. 0.0 ) THEN
348 b2l = b2*( b1l/b1 ) / SQRT( qke(k) )
351 tsq(k) = b2l*( pdt(k+1)+pdt(k) )
352 qsq(k) = b2l*( pdq(k+1)+pdq(k) )
353 cov(k) = b2l*( pdc(k+1)+pdc(k) )
359 !! qke(kts)=qke(kts+1)
360 !! tsq(kts)=tsq(kts+1)
361 !! qsq(kts)=qsq(kts+1)
362 !! cov(kts)=cov(kts+1)
372 END SUBROUTINE mym_initialize
375 ! ==================================================================
376 ! SUBROUTINE mym_level2:
378 ! Input variables: see subroutine mym_initialize
381 ! dtl(mx,my,nz) : Vertical gradient of Theta_l (K/m)
382 ! dqw(mx,my,nz) : Vertical gradient of Q_w
383 ! dtv(mx,my,nz) : Vertical gradient of Theta_V (K/m)
384 ! gm (mx,my,nz) : G_M divided by L^2/q^2 (s^(-2))
385 ! gh (mx,my,nz) : G_H divided by L^2/q^2 (s^(-2))
386 ! sm (mx,my,nz) : Stability function for momentum, at Level 2
387 ! sh (mx,my,nz) : Stability function for heat, at Level 2
389 ! These are defined on the walls of the grid boxes.
391 SUBROUTINE mym_level2 (kts,kte,&
395 & dtl, dqw, dtv, gm, gh, sm, sh )
397 !-------------------------------------------------------------------
399 INTEGER, INTENT(IN) :: kts,kte
400 REAL, DIMENSION(kts:kte), INTENT(in) :: dz
401 REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,ql,vt,vq
403 REAL, DIMENSION(kts:kte), INTENT(out) :: &
404 &dtl,dqw,dtv,gm,gh,sm,sh
408 REAL :: rfc,f1,f2,rf1,rf2,smc,shc,&
409 &ri1,ri2,ri3,ri4,duz,dtz,dqz,vtt,vqq,dtq,dzk,afk,abk,ri,rf
411 !JOE-Canuto/Kitamura mod
421 f1 = b1*( g1-c1 ) +3.0*a2*( 1.0 -c2 )*( 1.0-c5 ) &
422 & +2.0*a1*( 3.0-2.0*c2 )
423 f2 = b1*( g1+g2 ) -3.0*a1*( 1.0 -c2 )
424 rf1 = b1*( g1-c1 )/f1
427 shc = 3.0*a2*( g1+g2 )
431 ri3 = 4.0*rf2*smc -2.0*ri2
435 dzk = 0.5 *( dz(k)+dz(k-1) )
436 afk = dz(k)/( dz(k)+dz(k-1) )
438 duz = ( u(k)-u(k-1) )**2 +( v(k)-v(k-1) )**2
440 dtz = ( thl(k)-thl(k-1) )/( dzk )
441 dqz = ( qw(k)-qw(k-1) )/( dzk )
443 vtt = 1.0 +vt(k)*abk +vt(k-1)*afk
444 vqq = tv0 +vq(k)*abk +vq(k-1)*afk
445 dtq = vtt*dtz +vqq*dqz
450 !? dtv(i,j,k) = dtz +tv0*dqz
451 !? : +( ev/pi0(i,j,k)-tv1 )
452 !? : *( ql(i,j,k)-ql(i,j,k-1) )/( dzk*h(i,j) )
457 ! ** Gradient Richardson number **
458 ri = -gh(k)/MAX( duz, 1.0e-10 )
460 !JOE-Canuto/Kitamura mod
461 IF (CKmod .eq. 1) THEN
462 a2den = 1. + MAX(ri,0.0)
468 f1 = b1*( g1-c1 ) +3.0*(a2/a2den)*( 1.0 -c2 )*( 1.0-c5 ) &
469 & +2.0*a1*( 3.0-2.0*c2 )
470 f2 = b1*( g1+g2 ) -3.0*a1*( 1.0 -c2 )
471 rf1 = b1*( g1-c1 )/f1
473 smc = a1 /(a2/a2den)* f1/f2
474 shc = 3.0*(a2/a2den)*( g1+g2 )
478 ri3 = 4.0*rf2*smc -2.0*ri2
482 ! ** Flux Richardson number **
483 rf = MIN( ri1*( ri+ri2-SQRT(ri**2-ri3*ri+ri4) ), rfc )
485 sh (k) = shc*( rfc-rf )/( 1.0-rf )
486 sm (k) = smc*( rf1-rf )/( rf2-rf ) * sh(k)
491 END SUBROUTINE mym_level2
493 ! ==================================================================
494 ! SUBROUTINE mym_length:
496 ! Input variables: see subroutine mym_initialize
498 ! Output variables: see subroutine mym_initialize
501 ! elt(mx,ny) : Length scale depending on the PBL depth (m)
502 ! vsc(mx,ny) : Velocity scale q_c (m/s)
503 ! at first, used for computing elt
505 SUBROUTINE mym_length ( kts,kte,&
512 !JOE-added for BouLac ML (PBLH)
517 !-------------------------------------------------------------------
519 INTEGER, INTENT(IN) :: kts,kte
520 REAL, DIMENSION(kts:kte), INTENT(in) :: dz
521 REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw
522 REAL, INTENT(in) :: rmo,flt,flq
523 REAL, DIMENSION(kts:kte), INTENT(IN) :: qke,vt,vq
525 REAL, DIMENSION(kts:kte), INTENT(out) :: qkw, el
526 REAL, DIMENSION(kts:kte), INTENT(in) :: dtv
529 !JOE-added for BouLac ML
530 REAL, DIMENSION(kts:kte), INTENT(IN) :: theta
531 REAL, DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg
532 REAL :: wt,zi,zi2,elt0,h1,h2,alp1mod
534 !THE FOLLOWING LIMITS DO NOT DIRECTLY AFFECT THE ACTUAL PBLH.
535 !THEY ONLY IMPOSE LIMITS ON THE CALCULATION OF THE MIXING LENGTH
536 !SCALES SO THAT THE BOULAC MIXING LENGTH (IN FREE ATMOS) DOES
537 !NOT ENCROACH UPON THE BOUNDARY LAYER MIXING LENGTH (els, elb & elt).
538 REAL, PARAMETER :: minzi = 300. !min mixed-layer height
539 REAL, PARAMETER :: maxdz = 750. !max (half) transition layer depth
540 !=0.3*2500 m PBLH, so the transition
541 !layer stops growing for PBLHs > 2.5 km.
542 REAL, PARAMETER :: mindz = 300. !min (half) transition layer depth
546 REAL :: afk,abk,zwk,dzk,qdz,vflx,bv,elb,els,elf
551 !JOE-added to impose limits on the height integration for lt as well
552 ! as the transition layer depth - limit artificial gradients.
554 h1=MAX(0.3*zi2,mindz)
555 h1=MIN(h1,maxdz) !limit (1/2) transition layer depth
556 h2=h1/2.0 !~1/4 of the transition layer depth
558 !JOE-added for BouLac ML
559 qtke(kts)=MAX(qke(kts)/2.,0.01)
563 afk = dz(k)/( dz(k)+dz(k-1) )
565 qkw(k) = SQRT(MAX(qke(k)*abk+qke(k-1)*&
569 qtke(k) = MAX(qke(k)/2.,0.001)
577 ! ** Strictly, zwk*h(i,j) -> ( zwk*h(i,j)+z0 ) **
578 !JOE-Lt mod: only integrate to top of PBL (+ transition/entrainment
579 ! layer), since TKE aloft is not relevant. Make WHILE loop, so it
580 ! exits after looping through the boundary layer.
584 DO WHILE (zwk .LE. (zi2+h1))
585 dzk = 0.5*( dz(k)+dz(k-1) )
586 qdz = MAX( qkw(k)-qmin, 0.0 )*dzk
594 vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq
595 vsc = ( gtr*elt*MAX( vflx, 0.0 ) )**(1.0/3.0)
597 ! ** Strictly, el(i,j,1) is not zero. **
601 IF ( BLmod .GT. 0. ) THEN
602 ! COMPUTE BouLac mixing length
603 CALL boulac_length(kts,kte,zw,dz,qtke,theta,elBLmin,elBLavg)
610 !JOE- BouLac Start - add blending to only use elt in the boundary
611 ! layer and use the BouLac mixing length in free atmos
612 ! [defined relative to the PBLH (zi) + transition layer (h1)].
613 IF ( BLmod .GT. 0. ) THEN
614 wt=.5*TANH((zwk - (zi2+h1))/h2) + .5
615 elt0=elt*(1.-wt) + elBLmin(k)*wt
621 ! ** Length scale limited by the buoyancy effect **
622 IF ( dtv(k) .GT. 0.0 ) THEN
623 bv = SQRT( gtr*dtv(k) )
624 elb = alp2*qkw(k) / bv &
625 & *( 1.0 + alp3/alp2*&
626 &SQRT( vsc/( bv*elt ) ) )
628 elf = alp2 * qkw(k)/bv
634 !JOE- BouLac Start - only use BL ML in free atmos.
635 IF ( BLmod .GT. 0. ) THEN
636 wt=.5*TANH((zwk - (zi2+h1))/h2) + .5
637 elb=elb*(1.-wt) + elBLmin(k)*wt
638 !TEST: turn off mixing aloft
639 !elb=elb*(1.-wt) + 0.01*wt
643 ! ** Length scale in the surface layer **
644 IF ( rmo .GT. 0.0 ) THEN
646 & /( 1.0 + cns*MIN( zwk*rmo, zmax ) )
649 & *( 1.0 - alp4* zwk*rmo )**0.2
654 ! el(k) = MIN(elb/( elb/elt+elb/els+1.0 ),elf)
655 el(k) = MIN(elb/( elb/elt0+elb/els+1.0 ),elf)
656 ! el(k) = elb/( elb/elt+elb/els+1.0 )
663 END SUBROUTINE mym_length
665 !JOE- BouLac Code Start -
666 ! ==================================================================
667 SUBROUTINE boulac_length(kts,kte,zw,dz,qtke,theta,lb1,lb2)
669 ! NOTE: This subroutine was taken from the BouLac scheme in WRF-ARW
670 ! and modified for integration into the MYNN PBL scheme.
671 ! WHILE loops were added to reduce the computational expense.
672 ! This subroutine computes the length scales up and down
673 ! and then computes the min, average of the up/down
674 ! length scales, and also considers the distance to the
677 ! dlu = the distance a parcel can be lifted upwards give a finite
679 ! dld = the distance a parcel can be displaced downwards given a
680 ! finite amount of TKE.
681 ! lb1 = the minimum of the length up and length down
682 ! lb2 = the average of the length up and length down
683 !-------------------------------------------------------------------
685 INTEGER, INTENT(IN) :: kts,kte
686 REAL, DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta
687 REAL, DIMENSION(kts:kte), INTENT(OUT) :: lb1,lb2
688 REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw
691 INTEGER :: iz, izz, found
692 REAL, DIMENSION(kts:kte) :: dlu,dld
693 !REAL, PARAMETER :: g=9.81
694 REAL :: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz
696 !print*,"IN MYNN-BouLac",kts, kte
700 !----------------------------------
701 ! FIND DISTANCE UPWARD
702 !----------------------------------
704 dlu(iz)=zw(kte+1)-zw(iz)-dz(iz)/2.
707 beta=g/theta(iz) !Buoyancy coefficient
709 if (iz .lt. kte) then !cant integrate upwards from highest level
711 !do izz=iz,kte-1 !integrate upwards to find dlu
714 DO WHILE (found .EQ. 0)
716 if (izz .lt. kte) then
717 dzt=(dz(izz+1)+dz(izz))/2. ! avg layer depth of above and below layer
718 zup=zup-beta*theta(iz)*dzt ! initial PE the parcel has at iz
719 !print*," ",iz,izz,theta(izz)
720 zup=zup+beta*(theta(izz+1)+theta(izz))*dzt/2. ! PE gained by lifting a parcel to izz+1
721 zzz=zzz+dzt ! depth of layer iz to izz+1
722 if (qtke(iz).lt.zup .and. qtke(iz).ge.zup_inf) then
723 bbb=(theta(izz+1)-theta(izz))/dzt
724 if (bbb .ne. 0.) then
725 tl=(-beta*(theta(izz)-theta(iz)) + &
726 & sqrt( max(0.,(beta*(theta(izz)-theta(iz)))**2. + &
727 & 2.*bbb*beta*(qtke(iz)-zup_inf))))/bbb/beta
729 if (theta(izz) .ne. theta(iz))then
730 tl=(qtke(iz)-zup_inf)/(beta*(theta(izz)-theta(iz)))
748 !----------------------------------
750 !----------------------------------
753 dld(iz)=zw(iz)+dz(iz)/2.
756 if (iz .gt. kts) then !cant integrate downwards from lowest level
758 !do izz=iz,kts+1,-1 !integrate downwards to find dld
761 DO WHILE (found .EQ. 0)
763 if (izz .gt. kts) then
764 dzt=(dz(izz-1)+dz(izz))/2.
765 zdo=zdo+beta*theta(iz)*dzt
766 zdo=zdo-beta*(theta(izz-1)+theta(izz))*dzt/2.
768 if (qtke(iz).lt.zdo .and. qtke(iz).ge.zdo_sup) then
769 bbb=(theta(izz)-theta(izz-1))/dzt
770 if (bbb .ne. 0.) then
771 tl=(beta*(theta(izz)-theta(iz))+ &
772 & sqrt( max(0.,(beta*(theta(izz)-theta(iz)))**2. + &
773 & 2.*bbb*beta*(qtke(iz)-zdo_sup))))/bbb/beta
775 if (theta(izz) .ne. theta(iz)) then
776 tl=(qtke(iz)-zdo_sup)/(beta*(theta(izz)-theta(iz)))
793 !----------------------------------
794 ! GET MINIMUM (OR AVERAGE)
795 !----------------------------------
796 !The surface layer length scale can exceed z for large z/L,
797 !so keep maximum distance down > z.
798 dld(iz) = min(dld(iz),zw(iz+1))
799 lb1(iz) = min(dlu(iz),dld(iz)) !minimum
800 lb2(iz) = sqrt(dlu(iz)*dld(iz)) !average - biased towards smallest
801 !lb2(iz) = 0.5*(dlu(iz)+dld(iz)) !average
803 if (iz .eq. kte) then
804 lb1(kte) = lb1(kte-1)
805 lb2(kte) = lb2(kte-1)
807 !print*,"IN MYNN-BouLac",kts, kte,lb1(iz)
808 !print*,"IN MYNN-BouLac",iz,dld(iz),dlu(iz)
812 END SUBROUTINE boulac_length
816 ! ==================================================================
817 ! SUBROUTINE mym_turbulence:
819 ! Input variables: see subroutine mym_initialize
820 ! levflag : <>3; Level 2.5
823 ! # ql, vt, vq, qke, tsq, qsq and cov are changed to input variables.
825 ! Output variables: see subroutine mym_initialize
826 ! dfm(mx,my,nz) : Diffusivity coefficient for momentum,
827 ! divided by dz (not dz*h(i,j)) (m/s)
828 ! dfh(mx,my,nz) : Diffusivity coefficient for heat,
829 ! divided by dz (not dz*h(i,j)) (m/s)
830 ! dfq(mx,my,nz) : Diffusivity coefficient for q^2,
831 ! divided by dz (not dz*h(i,j)) (m/s)
832 ! tcd(mx,my,nz) : Countergradient diffusion term for Theta_l
834 ! qcd(mx,my,nz) : Countergradient diffusion term for Q_w
836 ! pd?(mx,my,nz) : Half of the production terms
838 ! Only tcd and qcd are defined at the center of the grid boxes
840 ! # DO NOT forget that tcd and qcd are added on the right-hand side
841 ! of the equations for Theta_l and Q_w, respectively.
843 ! Work arrays: see subroutine mym_initialize and level2
845 ! # dtl, dqw, dtv, gm and gh are allowed to share storage units with
846 ! dfm, dfh, dfq, tcd and qcd, respectively, for saving memory.
848 SUBROUTINE mym_turbulence ( kts,kte,&
851 & u, v, thl, ql, qw, &
852 & qke, tsq, qsq, cov, &
855 !JOE-BouLac/PBLH test
859 & Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, &
861 & qWT1D,qSHEAR1D,qBUOY1D,qDISS1D)
864 !-------------------------------------------------------------------
866 INTEGER, INTENT(IN) :: kts,kte
867 INTEGER, INTENT(IN) :: levflag
868 REAL, DIMENSION(kts:kte), INTENT(in) :: dz
869 REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw
870 REAL, INTENT(in) :: rmo,flt,flq
871 REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,&
872 &ql,vt,vq,qke,tsq,qsq,cov
874 REAL, DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq,&
875 &pdk,pdt,pdq,pdc,tcd,qcd,el
877 REAL, DIMENSION(kts:kte), INTENT(out) :: qWT1D,&
878 &qSHEAR1D,qBUOY1D,qDISS1D
879 REAL :: q3sq_old,dlsq1,qWTP_old,qWTP_new
880 REAL :: dudz,dvdz,dTdz,&
884 REAL, DIMENSION(kts:kte) :: qkw,dtl,dqw,dtv,gm,gh,sm,sh
887 ! REAL :: cc2,cc3,e1c,e2c,e3c,e4c,e5c
888 REAL :: e6c,dzk,afk,abk,vtt,vqq,&
889 &cw25,clow,cupp,gamt,gamq,smd,gamv,elq,elh
891 !JOE-added for BouLac/PBLH test
893 REAL, DIMENSION(kts:kte), INTENT(in) :: theta
895 !JOE-Canuto/Kitamura mod
896 REAL :: a2den, duz, ri
899 DOUBLE PRECISION q2sq, t2sq, r2sq, c2sq, elsq, gmel, ghel
900 DOUBLE PRECISION q3sq, t3sq, r3sq, c3sq, dlsq, qdiv
901 DOUBLE PRECISION e1, e2, e3, e4, enum, eden, wden
908 ! e1c = 3.0*a2*b2*cc3
909 ! e2c = 9.0*a1*a2*cc2
910 ! e3c = 9.0*a2*a2*cc2*( 1.0-c5 )
911 ! e4c = 12.0*a1*a2*cc2
915 CALL mym_level2 (kts,kte,&
919 & dtl, dqw, dtv, gm, gh, sm, sh )
921 CALL mym_length (kts,kte, &
928 !JOE BouLac/PBLH test
935 dzk = 0.5 *( dz(k)+dz(k-1) )
936 afk = dz(k)/( dz(k)+dz(k-1) )
939 q2sq = b1*elsq*( sm(k)*gm(k)+sh(k)*gh(k) )
942 !JOE-Canuto/Kitamura mod
943 duz = ( u(k)-u(k-1) )**2 +( v(k)-v(k-1) )**2
945 ! ** Gradient Richardson number **
946 ri = -gh(k)/MAX( duz, 1.0e-10 )
947 IF (CKmod .eq. 1) THEN
948 a2den = 1. + MAX(ri,0.0)
954 ! Modified: Dec/22/2005, from here, (dlsq -> elsq)
957 ! Modified: Dec/22/2005, up to here
959 ! ** Since qkw is set to more than 0.0, q3sq > 0.0. **
960 IF ( q3sq .LT. q2sq ) THEN
961 qdiv = SQRT( q3sq/q2sq )
965 !JOE-Canuto/Kitamura mod
966 ! e1 = q3sq - e1c*ghel * qdiv**2
967 ! e2 = q3sq - e2c*ghel * qdiv**2
968 ! e3 = e1 + e3c*ghel * qdiv**2
969 ! e4 = e1 - e4c*ghel * qdiv**2
970 e1 = q3sq - e1c*ghel/a2den * qdiv**2
971 e2 = q3sq - e2c*ghel/a2den * qdiv**2
972 e3 = e1 + e3c*ghel/(a2den**2) * qdiv**2
973 e4 = e1 - e4c*ghel/a2den * qdiv**2
975 eden = e2*e4 + e3*e5c*gmel * qdiv**2
976 eden = MAX( eden, 1.0d-20 )
978 !JOE-Canuto/Kitamura mod
979 ! e1 = q3sq - e1c*ghel
980 ! e2 = q3sq - e2c*ghel
983 e1 = q3sq - e1c*ghel/a2den
984 e2 = q3sq - e2c*ghel/a2den
985 e3 = e1 + e3c*ghel/(a2den**2)
986 e4 = e1 - e4c*ghel/a2den
988 eden = e2*e4 + e3*e5c*gmel
989 eden = MAX( eden, 1.0d-20 )
992 sm(k) = q3sq*a1*( e3-3.0*c1*e4 )/eden
993 !JOE-Canuto/Kitamura mod
994 ! sh(k) = q3sq*a2*( e2+3.0*c1*e5c*gmel )/eden
995 sh(k) = q3sq*(a2/a2den)*( e2+3.0*c1*e5c*gmel )/eden
999 ! ** Level 3 : start **
1000 IF ( levflag .EQ. 3 ) THEN
1001 t2sq = qdiv*b2*elsq*sh(k)*dtl(k)**2
1002 r2sq = qdiv*b2*elsq*sh(k)*dqw(k)**2
1003 c2sq = qdiv*b2*elsq*sh(k)*dtl(k)*dqw(k)
1004 t3sq = MAX( tsq(k)*abk+tsq(k-1)*afk, 0.0 )
1005 r3sq = MAX( qsq(k)*abk+qsq(k-1)*afk, 0.0 )
1006 c3sq = cov(k)*abk+cov(k-1)*afk
1008 ! Modified: Dec/22/2005, from here
1009 c3sq = SIGN( MIN( ABS(c3sq), SQRT(t3sq*r3sq) ), c3sq )
1011 vtt = 1.0 +vt(k)*abk +vt(k-1)*afk
1012 vqq = tv0 +vq(k)*abk +vq(k-1)*afk
1013 t2sq = vtt*t2sq +vqq*c2sq
1014 r2sq = vtt*c2sq +vqq*r2sq
1015 c2sq = MAX( vtt*t2sq+vqq*r2sq, 0.0d0 )
1016 t3sq = vtt*t3sq +vqq*c3sq
1017 r3sq = vtt*c3sq +vqq*r3sq
1018 c3sq = MAX( vtt*t3sq+vqq*r3sq, 0.0d0 )
1020 cw25 = e1*( e2 + 3.0*c1*e5c*gmel*qdiv**2 )/( 3.0*eden )
1022 ! ** Limitation on q, instead of L/q **
1024 IF ( q3sq/dlsq .LT. -gh(k) ) q3sq = -dlsq*gh(k)
1026 ! ** Limitation on c3sq (0.12 =< cw =< 0.76) **
1027 !JOE-Canuto/Kitamura mod
1028 ! e2 = q3sq - e2c*ghel * qdiv**2
1029 ! e3 = q3sq + e3c*ghel * qdiv**2
1030 ! e4 = q3sq - e4c*ghel * qdiv**2
1031 e2 = q3sq - e2c*ghel/a2den * qdiv**2
1032 e3 = q3sq + e3c*ghel/(a2den**2) * qdiv**2
1033 e4 = q3sq - e4c*ghel/a2den * qdiv**2
1035 eden = e2*e4 + e3 *e5c*gmel * qdiv**2
1037 !JOE-Canuto/Kitamura mod
1038 ! wden = cc3*gtr**2 * dlsq**2/elsq * qdiv**2 &
1039 ! & *( e2*e4c - e3c*e5c*gmel * qdiv**2 )
1040 wden = cc3*gtr**2 * dlsq**2/elsq * qdiv**2 &
1041 & *( e2*e4c/a2den - e3c*e5c*gmel/(a2den**2) * qdiv**2 )
1044 IF ( wden .NE. 0.0 ) THEN
1045 clow = q3sq*( 0.12-cw25 )*eden/wden
1046 cupp = q3sq*( 0.76-cw25 )*eden/wden
1048 IF ( wden .GT. 0.0 ) THEN
1049 c3sq = MIN( MAX( c3sq, c2sq+clow ), c2sq+cupp )
1051 c3sq = MAX( MIN( c3sq, c2sq+clow ), c2sq+cupp )
1055 e1 = e2 + e5c*gmel * qdiv**2
1056 eden = MAX( eden, 1.0d-20 )
1057 ! Modified: Dec/22/2005, up to here
1059 !JOE-Canuto/Kitamura mod
1060 ! e6c = 3.0*a2*cc3*gtr * dlsq/elsq
1061 e6c = 3.0*(a2/a2den)*cc3*gtr * dlsq/elsq
1064 ! ** for Gamma_theta **
1065 !! enum = qdiv*e6c*( t3sq-t2sq )
1066 IF ( t2sq .GE. 0.0 ) THEN
1067 enum = MAX( qdiv*e6c*( t3sq-t2sq ), 0.0d0 )
1069 enum = MIN( qdiv*e6c*( t3sq-t2sq ), 0.0d0 )
1072 gamt =-e1 *enum /eden
1075 !! enum = qdiv*e6c*( r3sq-r2sq )
1076 IF ( r2sq .GE. 0.0 ) THEN
1077 enum = MAX( qdiv*e6c*( r3sq-r2sq ), 0.0d0 )
1079 enum = MIN( qdiv*e6c*( r3sq-r2sq ), 0.0d0 )
1082 gamq =-e1 *enum /eden
1084 ! ** for Sm' and Sh'd(Theta_V)/dz **
1085 !! enum = qdiv*e6c*( c3sq-c2sq )
1086 enum = MAX( qdiv*e6c*( c3sq-c2sq ), 0.0d0)
1088 !JOE-Canuto/Kitamura mod
1089 ! smd = dlsq*enum*gtr/eden * qdiv**2 * (e3c+e4c)*a1/a2
1090 smd = dlsq*enum*gtr/eden * qdiv**2 * (e3c/(a2den**2) + e4c/a2den)*a1/(a2/a2den)
1092 gamv = e1 *enum*gtr/eden
1097 ! ** For elh (see below), qdiv at Level 3 is reset to 1.0. **
1099 ! ** Level 3 : end **
1102 ! ** At Level 2.5, qdiv is not reset. **
1111 pdk(k) = elq*( sm(k)*gm (k) &
1112 & +sh(k)*gh (k)+gamv )
1113 pdt(k) = elh*( sh(k)*dtl(k)+gamt )*dtl(k)
1114 pdq(k) = elh*( sh(k)*dqw(k)+gamq )*dqw(k)
1115 pdc(k) = elh*( sh(k)*dtl(k)+gamt )&
1117 &+elh*( sh(k)*dqw(k)+gamq )*dtl(k)*0.5
1122 dfm(k) = elq*sm (k) / dzk
1123 dfh(k) = elq*sh (k) / dzk
1124 ! Modified: Dec/22/2005, from here
1125 ! ** In sub.mym_predict, dfq for the TKE and scalar variance **
1126 ! ** are set to 3.0*dfm and 1.0*dfm, respectively. (Sqfac) **
1128 ! Modified: Dec/22/2005, up to here
1131 dudz = ( u(k)-u(k-1) )/dzk
1132 dvdz = ( v(k)-v(k-1) )/dzk
1133 dTdz = ( thl(k)-thl(k-1) )/dzk
1135 upwp = -elq*sm(k)*dudz
1136 vpwp = -elq*sm(k)*dvdz
1137 Tpwp = -elq*sh(k)*dTdz
1138 Tpwp = SIGN(MAX(ABS(Tpwp),1.E-6),Tpwp)
1140 IF ( k .EQ. kts+1 ) THEN
1144 !** Limitation on q, instead of L/q **
1145 dlsq1 = MAX(el(kts)**2,1.0)
1146 IF ( q3sq_old/dlsq1 .LT. -gh(k) ) q3sq_old = -dlsq1*gh(k)
1149 !!!Vertical Transport Term
1150 qWTP_new = elq*Sqfac*sm(k)*(q3sq - q3sq_old)/dzk
1151 qWT1D(k) = 0.5*(qWTP_new - qWTP_old)/dzk
1152 qWTP_old = elq*Sqfac*sm(k)*(q3sq - q3sq_old)/dzk
1156 !!!qSHEAR1D(k)=-(upwp*dudz + vpwp*dvdz)
1157 qSHEAR1D(k) = elq*sm(k)*gm(k)
1160 !!!qBUOY1D(k)=g*Tpwp/thl(k)
1161 !qBUOY1D(k)= elq*(sh(k)*gh(k) + gamv)
1162 qBUOY1D(k) = elq*(sh(k)*(-dTdz*g/thl(k)) + gamv)
1165 qDISS1D(k) = (q3sq**(3./2.))/(b1*MAX(el(k),1.))
1183 tcd(k) = ( tcd(k+1)-tcd(k) )/( dzk )
1184 qcd(k) = ( qcd(k+1)-qcd(k) )/( dzk )
1189 qSHEAR1D(kts)=qSHEAR1D(kts+1)
1190 qBUOY1D(kts)=qBUOY1D(kts+1)
1191 qDISS1D(kts)=qDISS1D(kts+1)
1196 END SUBROUTINE mym_turbulence
1198 ! ==================================================================
1199 ! SUBROUTINE mym_predict:
1201 ! Input variables: see subroutine mym_initialize and turbulence
1202 ! qke(mx,my,nz) : qke at (n)th time level
1203 ! tsq, ...cov : ditto
1206 ! qke(mx,my,nz) : qke at (n+1)th time level
1207 ! tsq, ...cov : ditto
1210 ! qkw(mx,my,nz) : q at the center of the grid boxes (m/s)
1211 ! bp (mx,my,nz) : = 1/2*F, see below
1212 ! rp (mx,my,nz) : = P-1/2*F*Q, see below
1214 ! # The equation for a turbulent quantity Q can be expressed as
1215 ! dQ/dt + Ah + Av = Dh + Dv + P - F*Q, (1)
1216 ! where A is the advection, D the diffusion, P the production,
1217 ! F*Q the dissipation and h and v denote horizontal and vertical,
1218 ! respectively. If Q is q^2, F is 2q/B_1L.
1219 ! Using the Crank-Nicholson scheme for Av, Dv and F*Q, a finite
1220 ! difference equation is written as
1221 ! Q{n+1} - Q{n} = dt *( Dh{n} - Ah{n} + P{n} )
1222 ! + dt/2*( Dv{n} - Av{n} - F*Q{n} )
1223 ! + dt/2*( Dv{n+1} - Av{n+1} - F*Q{n+1} ), (2)
1224 ! where n denotes the time level.
1225 ! When the advection and diffusion terms are discretized as
1226 ! dt/2*( Dv - Av ) = a(k)Q(k+1) - b(k)Q(k) + c(k)Q(k-1), (3)
1227 ! Eq.(2) can be rewritten as
1228 ! - a(k)Q(k+1) + [ 1 + b(k) + dt/2*F ]Q(k) - c(k)Q(k-1)
1229 ! = Q{n} + dt *( Dh{n} - Ah{n} + P{n} )
1230 ! + dt/2*( Dv{n} - Av{n} - F*Q{n} ), (4)
1231 ! where Q on the left-hand side is at (n+1)th time level.
1233 ! In this subroutine, a(k), b(k) and c(k) are obtained from
1234 ! subprogram coefvu and are passed to subprogram tinteg via
1235 ! common. 1/2*F and P-1/2*F*Q are stored in bp and rp,
1236 ! respectively. Subprogram tinteg solves Eq.(4).
1238 ! Modify this subroutine according to your numerical integration
1241 !-------------------------------------------------------------------
1242 SUBROUTINE mym_predict (kts,kte,&
1246 & ust, flt, flq, pmz, phh, &
1248 & pdk, pdt, pdq, pdc,&
1249 & qke, tsq, qsq, cov,&
1254 !-------------------------------------------------------------------
1255 INTEGER, INTENT(IN) :: kts,kte
1256 INTEGER, INTENT(IN) :: levflag
1257 REAL, INTENT(IN) :: delt
1258 REAL, DIMENSION(kts:kte), INTENT(IN) :: dz, dfq,el
1259 REAL, DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc
1260 REAL, INTENT(IN) :: flt, flq, ust, pmz, phh
1261 REAL, DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov
1263 REAL, DIMENSION(kts:kte), INTENT(OUT) :: dqke1D
1267 REAL, DIMENSION(kts:kte) :: qkw, bp, rp, df3q
1268 REAL :: vkz,pdk1,phm,pdt1,pdq1,pdc1,b1l,b2l
1269 REAL, DIMENSION(kts:kte) :: dtz
1270 REAL, DIMENSION(1:kte-kts+1) :: a,b,c,d
1274 ! ** Strictly, vkz*h(i,j) -> vk*( 0.5*dz(1)*h(i,j)+z0 ) **
1275 vkz = vk*0.5*dz(kts)
1277 ! Modified: Dec/22/2005, from here
1278 ! ** dfq for the TKE is 3.0*dfm. **
1279 ! CALL coefvu ( dfq, 3.0 ) ! make change here
1280 ! Modified: Dec/22/2005, up to here
1283 !! qke(k) = MAX(qke(k), 0.0)
1284 qkw(k) = SQRT( MAX( qke(k), 0.0 ) )
1286 df3q(k)=Sqfac*dfq(k)
1290 pdk1 = 2.0*ust**3*pmz/( vkz )
1291 phm = 2.0/ust *phh/( vkz )
1296 ! ** pdk(i,j,1)+pdk(i,j,2) corresponds to pdk1. **
1297 pdk(kts) = pdk1 -pdk(kts+1)
1299 !! pdt(kts) = pdt1 -pdt(kts+1)
1300 !! pdq(kts) = pdq1 -pdq(kts+1)
1301 !! pdc(kts) = pdc1 -pdc(kts+1)
1302 pdt(kts) = pdt(kts+1)
1303 pdq(kts) = pdq(kts+1)
1304 pdc(kts) = pdc(kts+1)
1306 ! ** Prediction of twice the turbulent kinetic energy **
1307 !! DO k = kts+1,kte-1
1309 b1l = b1*0.5*( el(k+1)+el(k) )
1310 bp(k) = 2.*qkw(k) / b1l
1311 rp(k) = pdk(k+1) + pdk(k)
1319 ! Since df3q(kts)=0.0, a(1)=0.0 and b(1)=1.+dtz(k)*df3q(k+1)+bp(k)*delt.
1321 a(k-kts+1)=-dtz(k)*df3q(k)
1322 b(k-kts+1)=1.+dtz(k)*(df3q(k)+df3q(k+1))+bp(k)*delt
1323 c(k-kts+1)=-dtz(k)*df3q(k+1)
1324 d(k-kts+1)=rp(k)*delt + qke(k)
1328 !! a(k-kts+1)=-dtz(k)*df3q(k)
1329 !! b(k-kts+1)=1.+dtz(k)*(df3q(k)+df3q(k+1))
1330 !! c(k-kts+1)=-dtz(k)*df3q(k+1)
1331 !! d(k-kts+1)=rp(k)*delt + qke(k) - qke(k)*bp(k)*delt
1339 CALL tridiag(nz,a,b,c,d)
1347 dqke1D(k)=(qke(k)-dqke1D(k))*0.5
1352 IF ( levflag .EQ. 3 ) THEN
1354 ! Modified: Dec/22/2005, from here
1355 ! ** dfq for the scalar variance is 1.0*dfm. **
1356 ! CALL coefvu ( dfq, 1.0 ) make change here
1357 ! Modified: Dec/22/2005, up to here
1359 ! ** Prediction of the temperature variance **
1360 !! DO k = kts+1,kte-1
1362 b2l = b2*0.5*( el(k+1)+el(k) )
1363 bp(k) = 2.*qkw(k) / b2l
1364 rp(k) = pdt(k+1) + pdt(k)
1367 !zero gradient for tsq at bottom and top
1374 ! Since dfq(kts)=0.0, a(1)=0.0 and b(1)=1.+dtz(k)*dfq(k+1)+bp(k)*delt.
1376 a(k-kts+1)=-dtz(k)*dfq(k)
1377 b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))+bp(k)*delt
1378 c(k-kts+1)=-dtz(k)*dfq(k+1)
1379 d(k-kts+1)=rp(k)*delt + tsq(k)
1383 !! a(k-kts+1)=-dtz(k)*dfq(k)
1384 !! b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))
1385 !! c(k-kts+1)=-dtz(k)*dfq(k+1)
1386 !! d(k-kts+1)=rp(k)*delt + tsq(k) - tsq(k)*bp(k)*delt
1394 CALL tridiag(nz,a,b,c,d)
1400 ! ** Prediction of the moisture variance **
1401 !! DO k = kts+1,kte-1
1403 b2l = b2*0.5*( el(k+1)+el(k) )
1404 bp(k) = 2.*qkw(k) / b2l
1405 rp(k) = pdq(k+1) +pdq(k)
1408 !zero gradient for qsq at bottom and top
1415 ! Since dfq(kts)=0.0, a(1)=0.0 and b(1)=1.+dtz(k)*dfq(k+1)+bp(k)*delt.
1417 a(k-kts+1)=-dtz(k)*dfq(k)
1418 b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))+bp(k)*delt
1419 c(k-kts+1)=-dtz(k)*dfq(k+1)
1420 d(k-kts+1)=rp(k)*delt + qsq(k)
1424 !! a(k-kts+1)=-dtz(k)*dfq(k)
1425 !! b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))
1426 !! c(k-kts+1)=-dtz(k)*dfq(k+1)
1427 !! d(k-kts+1)=rp(k)*delt + qsq(k) -qsq(k)*bp(k)*delt
1435 CALL tridiag(nz,a,b,c,d)
1441 ! ** Prediction of the temperature-moisture covariance **
1442 !! DO k = kts+1,kte-1
1444 b2l = b2*0.5*( el(k+1)+el(k) )
1445 bp(k) = 2.*qkw(k) / b2l
1446 rp(k) = pdc(k+1) + pdc(k)
1449 !zero gradient for tqcov at bottom and top
1456 ! Since dfq(kts)=0.0, a(1)=0.0 and b(1)=1.+dtz(k)*dfq(k+1)+bp(k)*delt.
1458 a(k-kts+1)=-dtz(k)*dfq(k)
1459 b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))+bp(k)*delt
1460 c(k-kts+1)=-dtz(k)*dfq(k+1)
1461 d(k-kts+1)=rp(k)*delt + cov(k)
1465 !! a(k-kts+1)=-dtz(k)*dfq(k)
1466 !! b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))
1467 !! c(k-kts+1)=-dtz(k)*dfq(k+1)
1468 !! d(k-kts+1)=rp(k)*delt + cov(k) - cov(k)*bp(k)*delt
1476 CALL tridiag(nz,a,b,c,d)
1483 !! DO k = kts+1,kte-1
1485 IF ( qkw(k) .LE. 0.0 ) THEN
1488 b2l = b2*0.25*( el(k+1)+el(k) )/qkw(k)
1491 tsq(k) = b2l*( pdt(k+1)+pdt(k) )
1492 qsq(k) = b2l*( pdq(k+1)+pdq(k) )
1493 cov(k) = b2l*( pdc(k+1)+pdc(k) )
1496 !! tsq(kts)=tsq(kts+1)
1497 !! qsq(kts)=qsq(kts+1)
1498 !! cov(kts)=cov(kts+1)
1506 END SUBROUTINE mym_predict
1508 ! ==================================================================
1509 ! SUBROUTINE mym_condensation:
1511 ! Input variables: see subroutine mym_initialize and turbulence
1512 ! pi (mx,my,nz) : Perturbation of the Exner function (J/kg K)
1513 ! defined on the walls of the grid boxes
1514 ! This is usually computed by integrating
1515 ! d(pi)/dz = h*g*tv/tref**2
1516 ! from the upper boundary, where tv is the
1517 ! virtual potential temperature minus tref.
1519 ! Output variables: see subroutine mym_initialize
1520 ! cld(mx,my,nz) : Cloud fraction
1523 ! qmq(mx,my,nz) : Q_w-Q_{sl}, where Q_{sl} is the saturation
1524 ! specific humidity at T=Tl
1525 ! alp(mx,my,nz) : Functions in the condensation process
1526 ! bet(mx,my,nz) : ditto
1527 ! sgm(mx,my,nz) : Combined standard deviation sigma_s
1528 ! multiplied by 2/alp
1530 ! # qmq, alp, bet and sgm are allowed to share storage units with
1531 ! any four of other work arrays for saving memory.
1533 ! # Results are sensitive particularly to values of cp and rd.
1534 ! Set these values to those adopted by you.
1536 !-------------------------------------------------------------------
1537 SUBROUTINE mym_condensation (kts,kte, &
1544 !-------------------------------------------------------------------
1545 INTEGER, INTENT(IN) :: kts,kte
1547 REAL, DIMENSION(kts:kte), INTENT(IN) :: dz
1548 REAL, DIMENSION(kts:kte), INTENT(IN) :: p,exner, thl, qw, &
1551 REAL, DIMENSION(kts:kte), INTENT(OUT) :: vt,vq
1553 REAL, DIMENSION(kts:kte) :: qmq,alp,bet,sgm,ql,cld
1555 DOUBLE PRECISION :: t3sq, r3sq, c3sq
1558 REAL :: p2a,t,esl,qsl,dqsl,q1,cld0,eq1,qll,&
1564 ! Note: kte needs to be larger than kts, i.e., kte >= kts+1.
1570 !x if ( ct .gt. 0.0 ) then
1578 ! ** 3.8 = 0.622*6.11 (hPa) **
1579 esl=svp11*EXP(svp2*(t-svpt0)/(t-svp3))
1580 qsl=ep_2*esl/(p(k)-ep_3*esl)
1581 ! qsl = 3.8*EXP( a*ct/( b+ct ) ) / ( 1000.0*p2a**rk )
1582 dqsl = qsl*ep_2*ev/( rd*t**2 )
1586 alp(k) = 1.0/( 1.0+dqsl*xlvcp )
1589 t3sq = MAX( tsq(k), 0.0 )
1590 r3sq = MAX( qsq(k), 0.0 )
1592 c3sq = SIGN( MIN( ABS(c3sq), SQRT(t3sq*r3sq) ), c3sq )
1594 r3sq = r3sq +bet(k)**2*t3sq -2.0*bet(k)*c3sq
1595 sgm(k) = SQRT( MAX( r3sq, 1.0d-10 ) )
1599 q1 = qmq(k) / sgm(k)
1600 cld0 = 0.5*( 1.0+erf( q1*rr2 ) )
1604 eq1 = rrp*EXP( -0.5*q1*q1 )
1605 qll = MAX( cld0*q1 + eq1, 0.0 )
1608 ql (k) = alp(k)*sgm(k)*qll
1610 q2p = xlvcp/exner( k )
1611 pt = thl(k) +q2p*ql(k)
1612 qt = 1.0 +p608*qw(k) -(1.+p608)*ql(k)
1613 rac = alp(k)*( cld0-qll*eq1 )*( q2p*qt-(1.+p608)*pt )
1615 vt (k) = qt-1.0 -rac*bet(k)
1616 vq (k) = p608*pt-tv0 +rac
1620 cld(kte) = cld(kte-1)
1627 END SUBROUTINE mym_condensation
1629 ! ==================================================================
1630 SUBROUTINE mynn_tendencies(kts,kte,&
1631 &levflag,grav_settling,&
1634 &u,v,th,qv,qc,p,exner,&
1636 &ust,flt,flq,wspd,qcg,&
1642 !-------------------------------------------------------------------
1643 INTEGER, INTENT(in) :: kts,kte
1644 INTEGER, INTENT(in) :: grav_settling,levflag
1646 !! grav_settling = 1 for gravitational settling of droplets
1647 !! grav_settling = 0 otherwise
1648 ! thl - liquid water potential temperature
1650 ! dfm,dfh,dfq - as above
1651 ! flt - surface flux of thl
1652 ! flq - surface flux of qw
1654 REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,th,qv,qc,p,exner,&
1655 &dfm,dfh,dfq,dz,tsq,qsq,cov,tcd,qcd
1656 REAL, DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc
1657 REAL, DIMENSION(kts:kte), INTENT(out) :: du,dv,dth,dqv,dqc
1658 REAL, INTENT(IN) :: delt,ust,flt,flq,wspd,qcg
1660 ! REAL, INTENT(IN) :: delt,ust,flt,flq,qcg,&
1661 ! &gradu_top,gradv_top,gradth_top,gradqv_top
1665 REAL, DIMENSION(kts:kte) :: dtz,vt,vq
1667 REAL, DIMENSION(1:kte-kts+1) :: a,b,c,d
1669 REAL :: rhs,gfluxm,gfluxp,dztop
1674 dztop=.5*(dz(kte)+dz(kte-1))
1685 b(1)=1.+dtz(k)*(dfm(k+1)+ust**2/wspd)
1686 c(1)=-dtz(k)*dfm(k+1)
1690 !! b(1)=1.+dtz(k)*dfm(k+1)
1691 !! c(1)=-dtz(k)*dfm(k+1)
1692 !! d(1)=u(k)*(1.-ust**2/wspd*dtz(k))
1696 a(kk)=-dtz(k)*dfm(k)
1697 b(kk)=1.+dtz(k)*(dfm(k)+dfm(k+1))
1698 c(kk)=-dtz(k)*dfm(k+1)
1702 !! no flux at the top
1709 !! specified gradient at the top
1714 ! d(nz)=gradu_top*dztop
1723 CALL tridiag(nz,a,b,c,d)
1726 du(k)=(d(k-kts+1)-u(k))/delt
1734 b(1)=1.+dtz(k)*(dfm(k+1)+ust**2/wspd)
1735 c(1)=-dtz(k)*dfm(k+1)
1739 !! b(1)=1.+dtz(k)*dfm(k+1)
1740 !! c(1)=-dtz(k)*dfm(k+1)
1741 !! d(1)=v(k)*(1.-ust**2/wspd*dtz(k))
1745 a(kk)=-dtz(k)*dfm(k)
1746 b(kk)=1.+dtz(k)*(dfm(k)+dfm(k+1))
1747 c(kk)=-dtz(k)*dfm(k+1)
1751 !! no flux at the top
1759 !! specified gradient at the top
1764 ! d(nz)=gradv_top*dztop
1773 CALL tridiag(nz,a,b,c,d)
1776 dv(k)=(d(k-kts+1)-v(k))/delt
1784 b(1)=1.+dtz(k)*dfh(k+1)
1785 c(1)=-dtz(k)*dfh(k+1)
1787 ! if qcg not used then assume constant flux in the surface layer
1789 IF (qcg < qcgmin) THEN
1790 IF (sqc(k) > qcgmin) THEN
1791 gfluxm=grav_settling*gno*sqc(k)**gpw
1796 gfluxm=grav_settling*gno*(qcg/(1.+qcg))**gpw
1799 IF (.5*(sqc(k+1)+sqc(k)) > qcgmin) THEN
1800 gfluxp=grav_settling*gno*(.5*(sqc(k+1)+sqc(k)))**gpw
1805 rhs=-xlvcp/exner(k)&
1807 &(gfluxp - gfluxm)/dz(k)&
1810 d(1)=thl(k)+dtz(k)*flt+rhs*delt
1814 a(kk)=-dtz(k)*dfh(k)
1815 b(kk)=1.+dtz(k)*(dfh(k)+dfh(k+1))
1816 c(kk)=-dtz(k)*dfh(k+1)
1818 IF (.5*(sqc(k+1)+sqc(k)) > qcgmin) THEN
1819 gfluxp=grav_settling*gno*(.5*(sqc(k+1)+sqc(k)))**gpw
1824 IF (.5*(sqc(k-1)+sqc(k)) > qcgmin) THEN
1825 gfluxm=grav_settling*gno*(.5*(sqc(k-1)+sqc(k)))**gpw
1830 rhs=-xlvcp/exner(k)&
1832 &(gfluxp - gfluxm)/dz(k)&
1834 d(kk)=thl(k)+rhs*delt
1837 !! no flux at the top
1844 !! specified gradient at the top
1846 !assume gradthl_top=gradth_top
1851 ! d(nz)=gradth_top*dztop
1860 CALL tridiag(nz,a,b,c,d)
1871 b(1)=1.+dtz(k)*dfh(k+1)
1872 c(1)=-dtz(k)*dfh(k+1)
1874 IF (qcg < qcgmin) THEN
1875 IF (sqc(k) > qcgmin) THEN
1876 gfluxm=grav_settling*gno*sqc(k)**gpw
1881 gfluxm=grav_settling*gno*(qcg/(1.+qcg))**gpw
1884 IF (.5*(sqc(k+1)+sqc(k)) > qcgmin) THEN
1885 gfluxp=grav_settling*gno*(.5*(sqc(k+1)+sqc(k)))**gpw
1892 &(gfluxp - gfluxm)/dz(k)&
1895 d(1)=sqw(k)+dtz(k)*flq+rhs*delt
1899 a(kk)=-dtz(k)*dfh(k)
1900 b(kk)=1.+dtz(k)*(dfh(k)+dfh(k+1))
1901 c(kk)=-dtz(k)*dfh(k+1)
1903 IF (.5*(sqc(k+1)+sqc(k)) > qcgmin) THEN
1904 gfluxp=grav_settling*gno*(.5*(sqc(k+1)+sqc(k)))**gpw
1909 IF (.5*(sqc(k-1)+sqc(k)) > qcgmin) THEN
1910 gfluxm=grav_settling*gno*(.5*(sqc(k-1)+sqc(k)))**gpw
1917 &(gfluxp - gfluxm)/dz(k)&
1919 d(kk)=sqw(k) + rhs*delt
1923 !! no flux at the top
1930 !! specified gradient at the top
1931 !assume gradqw_top=gradqv_top
1936 ! d(nz)=gradqv_top*dztop
1945 CALL tridiag(nz,a,b,c,d)
1947 !convert to mixing ratios for wrf
1951 sqv(k)=sqw(k)-sqc(k)
1952 Dqv(k)=(sqv(k)/(1.-sqv(k))-qv(k))/delt
1953 ! Dqc(k)=(sqc(k)/(1.-sqc(k))-qc(k))/delt
1955 Dth(k)=(thl(k)+xlvcp/exner(k)*sqc(k)-th(k))/delt
1958 END SUBROUTINE mynn_tendencies
1960 ! ==================================================================
1961 SUBROUTINE retrieve_exchange_coeffs(kts,kte,&
1965 !-------------------------------------------------------------------
1967 INTEGER , INTENT(in) :: kts,kte
1969 REAL, DIMENSION(KtS:KtE), INTENT(in) :: dz,dfm,dfh,dfq
1971 REAL, DIMENSION(KtS:KtE), INTENT(out) :: &
1983 dzk = 0.5 *( dz(k)+dz(k-1) )
1989 END SUBROUTINE retrieve_exchange_coeffs
1991 ! ==================================================================
1992 SUBROUTINE tridiag(n,a,b,c,d)
1994 !! to solve system of linear eqs on tridiagonal matrix n times n
1995 !! after Peaceman and Rachford, 1955
1996 !! a,b,c,d - are vectors of order n
1997 !! a,b,c - are coefficients on the LHS
1998 !! d - is initially RHS on the output becomes a solution vector
2000 !-------------------------------------------------------------------
2002 INTEGER, INTENT(in):: n
2003 REAL, DIMENSION(n), INTENT(in) :: a,b
2004 REAL, DIMENSION(n), INTENT(inout) :: c,d
2008 REAL, DIMENSION(n) :: q
2015 p=1./(b(i)+a(i)*q(i-1))
2017 d(i)=(d(i)-a(i)*d(i-1))*p
2021 d(i)=d(i)+q(i)*d(i+1)
2024 END SUBROUTINE tridiag
2026 ! ==================================================================
2027 SUBROUTINE mynn_bl_driver(&
2034 &xland,ts,qsfc,qcg,ps,&
2035 &ust,ch,hfx,qfx,rmol,wspd,&
2042 !JOE-added for extra ouput
2046 &,dqke,qWT,qSHEAR,qBUOY,qDISS&
2048 &,IDS,IDE,JDS,JDE,KDS,KDE &
2049 &,IMS,IME,JMS,JME,KMS,KME &
2050 &,ITS,ITE,JTS,JTE,KTS,KTE)
2052 !-------------------------------------------------------------------
2054 INTEGER, INTENT(in) :: initflag
2055 INTEGER, INTENT(in) :: grav_settling
2057 INTEGER,INTENT(IN) :: &
2058 & IDS,IDE,JDS,JDE,KDS,KDE &
2059 &,IMS,IME,JMS,JME,KMS,KME &
2060 &,ITS,ITE,JTS,JTE,KTS,KTE
2063 ! initflag > 0 for TRUE
2065 ! levflag : <>3; Level 2.5
2067 ! grav_settling = 1 when gravitational settling accounted for
2068 ! grav_settling = 0 when gravitational settling NOT accounted for
2070 REAL, INTENT(in) :: delt
2071 REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(in) :: dz,&
2072 &u,v,th,qv,qc,p,exner,rho
2073 REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(in) :: xland,ust,&
2074 &ch,rmol,ts,qsfc,qcg,ps,hfx,qfx, wspd
2076 REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(inout) :: &
2078 REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(out) :: &
2081 REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(out) :: &
2084 REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(inout) :: &
2087 !JOE-added for extra output
2088 REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(inout) :: &
2092 REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(inout) :: &
2093 &qWT,qSHEAR,qBUOY,qDISS,dqke
2097 INTEGER :: ITF,JTF,KTF
2099 REAL, DIMENSION(KMS:KME) :: thl,sqv,sqc,sqw,&
2100 &El, Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, Vt, Vq
2102 REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME) :: K_q
2104 REAL, DIMENSION(KMS:KME+1) :: zw
2106 REAL :: cpm,sqcg,flt,flq,pmz,phh,exnerg,zet
2108 REAL, DIMENSION(KMS:KME) :: thetav
2110 INTEGER, SAVE :: levflag
2118 IF (initflag > 0) THEN
2123 sqv(k)=qv(i,k,j)/(1.+qv(i,k,j))
2126 thetav(k)=th(i,k,j)*(1.+0.61*qv(i,k,j))
2131 zw(k)=zw(k-1)+dz(i,k-1,j)
2137 !JOE-added for extra output
2150 zw(ktf+1)=zw(ktf)+dz(i,ktf,j)
2153 CALL GET_PBLH(KTS,KTE,PBLH(i,j),thetav(kts:kte),&
2154 & Qke(i,kts:kte,j),zw(kts:kte+1),dz(i,kts:kte,j),xland(i,j))
2157 CALL mym_initialize ( kts,kte,&
2158 &dz(i,kts:kte,j), zw(kts:kte+1), &
2159 &u(i,kts:kte,j), v(i,kts:kte,j), &
2160 &thl(kts:kte), sqv(kts:kte),&
2162 &PBLH(i,j),th(i,kts:kte,j),&
2164 &ust(i,j), rmol(i,j),&
2165 &Qke(i,kts:kte,j), Tsq(i,kts:kte,j), &
2166 &Qsq(i,kts:kte,j), Cov(i,kts:kte,j))
2171 ENDIF ! end initflag
2176 sqv(k)=qv(i,k,j)/(1.+qv(i,k,j))
2177 sqc(k)=qc(i,k,j)/(1.+qc(i,k,j))
2178 sqw(k)=sqv(k)+sqc(k)
2179 thl(k)=th(i,k,j)-xlvcp/exner(i,k,j)*sqc(k)
2181 thetav(k)=th(i,k,j)*(1.+0.61*qv(i,k,j))
2187 zw(k)=zw(k-1)+dz(i,k-1,j)
2191 zw(ktf+1)=zw(ktf)+dz(i,ktf,j)
2194 CALL GET_PBLH(KTS,KTE,PBLH(i,j),thetav(kts:kte),&
2195 & Qke(i,kts:kte,j),zw(kts:kte+1),dz(i,kts:kte,j),xland(i,j))
2198 sqcg=qcg(i,j)/(1.+qcg(i,j))
2199 cpm=cp*(1.+0.8*qv(i,kts,j))
2201 ! The exchange coefficient for cloud water is assumed to be the same as
2202 ! that for heat. CH is multiplied by WSPD. See module_sf_mynn.F
2203 exnerg=(ps(i,j)/p1000mb)**rcp
2204 flt = hfx(i,j)/( rho(i,kts,j)*cpm ) &
2205 +xlvcp*ch(i,j)*(sqc(kts)/exner(i,kts,j)-sqcg/exnerg)
2206 flq = qfx(i,j)/ rho(i,kts,j) &
2207 -ch(i,j)*(sqc(kts) -sqcg )
2210 zet = 0.5*dz(i,kts,j)*rmol(i,j)
2211 if ( zet >= 0.0 ) then
2212 pmz = 1.0 + (cphm_st-1.0) * zet
2213 phh = 1.0 + cphh_st * zet
2215 pmz = 1.0/ (1.0-cphm_unst*zet)**0.25 - zet
2216 phh = 1.0/SQRT(1.0-cphh_unst*zet)
2220 CALL mym_condensation ( kts,kte,&
2222 &thl(kts:kte), sqw(kts:kte), &
2223 &p(i,kts:kte,j),exner(i,kts:kte,j), &
2224 &tsq(i,kts:kte,j), qsq(i,kts:kte,j), cov(i,kts:kte,j), &
2225 &Vt(kts:kte), Vq(kts:kte))
2227 CALL mym_turbulence ( kts,kte,&
2229 &dz(i,kts:kte,j), zw(kts:kte+1), &
2230 &u(i,kts:kte,j), v(i,kts:kte,j), thl(kts:kte),&
2231 &sqc(kts:kte), sqw(kts:kte), &
2232 &qke(i,kts:kte,j), tsq(i,kts:kte,j), &
2233 &qsq(i,kts:kte,j), cov(i,kts:kte,j), &
2234 &vt(kts:kte), vq(kts:kte),&
2235 &rmol(i,j), flt, flq, &
2237 &PBLH(i,j),th(i,kts:kte,j),&
2239 &el_mynn(i,kts:kte,j), &
2240 &Dfm(kts:kte),Dfh(kts:kte),Dfq(kts:kte), &
2241 &Tcd(kts:kte),Qcd(kts:kte),Pdk(kts:kte), &
2242 &Pdt(kts:kte),Pdq(kts:kte),Pdc(kts:kte),&
2244 &qWT(i,kts:kte,j),qSHEAR(i,kts:kte,j),&
2245 &qBUOY(i,kts:kte,j),qDISS(i,kts:kte,j))
2248 CALL mym_predict (kts,kte,&
2252 &ust(i,j), flt, flq, pmz, phh, &
2253 &el_mynn(i,kts:kte,j), dfq(kts:kte), pdk(kts:kte), &
2254 &pdt(kts:kte), pdq(kts:kte), pdc(kts:kte),&
2255 &Qke(i,kts:kte,j), Tsq(i,kts:kte,j), &
2256 &Qsq(i,kts:kte,j), Cov(i,kts:kte,j), &
2261 CALL mynn_tendencies(kts,kte,&
2262 &levflag,grav_settling,&
2265 &u(i,kts:kte,j),v(i,kts:kte,j),&
2266 &th(i,kts:kte,j),qv(i,kts:kte,j),qc(i,kts:kte,j),&
2267 &p(i,kts:kte,j),exner(i,kts:kte,j),&
2268 &thl(kts:kte),sqv(kts:kte),sqc(kts:kte),sqw(kts:kte),&
2269 &ust(i,j),flt,flq,wspd(i,j),qcg(i,j),&
2270 &tsq(i,kts:kte,j),qsq(i,kts:kte,j),cov(i,kts:kte,j),&
2271 &tcd(kts:kte),qcd(kts:kte),&
2272 &dfm(kts:kte),dfh(kts:kte),dfq(kts:kte),&
2273 &Du(i,kts:kte,j),Dv(i,kts:kte,j),Dth(i,kts:kte,j),&
2274 &Dqv(i,kts:kte,j),Dqc(i,kts:kte,j))
2276 CALL retrieve_exchange_coeffs(kts,kte,&
2277 &dfm(kts:kte),dfh(kts:kte),dfq(kts:kte),dz(i,kts:kte,j),&
2278 &K_m(i,kts:kte,j),K_h(i,kts:kte,j),K_q(i,kts:kte,j))
2281 qWT(i,k,j)= qWT(i,k,j)*delt
2282 qSHEAR(i,k,j)= qSHEAR(i,k,j)*delt
2283 qBUOY(i,k,j)= qBUOY(i,k,j)*delt
2284 qDISS(i,k,j)= qDISS(i,k,j)*delt
2289 END SUBROUTINE mynn_bl_driver
2291 ! ==================================================================
2292 SUBROUTINE mynn_bl_init_driver(&
2295 &,RESTART,ALLOWED_TO_READ,LEVEL&
2296 &,IDS,IDE,JDS,JDE,KDS,KDE &
2297 &,IMS,IME,JMS,JME,KMS,KME &
2298 &,ITS,ITE,JTS,JTE,KTS,KTE)
2300 !---------------------------------------------------------------
2301 LOGICAL,INTENT(IN) :: ALLOWED_TO_READ,RESTART
2302 INTEGER,INTENT(IN) :: LEVEL
2304 INTEGER,INTENT(IN) :: IDS,IDE,JDS,JDE,KDS,KDE, &
2305 & IMS,IME,JMS,JME,KMS,KME, &
2306 & ITS,ITE,JTS,JTE,KTS,KTE
2309 REAL,DIMENSION(IMS:IME,KMS:KME,JMS:JME),INTENT(OUT) :: &
2312 INTEGER :: I,J,K,ITF,JTF,KTF
2318 IF(.NOT.RESTART)THEN
2334 END SUBROUTINE mynn_bl_init_driver
2336 ! ==================================================================
2338 SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea)
2340 !---------------------------------------------------------------
2341 ! NOTES ON THE PBLH FORMULATION
2343 !The 1.5-theta-increase method defines PBL heights as the level at
2344 !which the potential temperature first exceeds the minimum potential
2345 !temperature within the boundary layer by 1.5 K. When applied to
2346 !observed temperatures, this method has been shown to produce PBL-
2347 !height estimates that are unbiased relative to profiler-based
2348 !estimates (Nielsen-Gammon et al. 2008). However, their study did not
2349 !include LLJs. Banta and Pichugina (2008) show that a TKE-based
2350 !threshold is a good estimate of the PBL height in LLJs. Therefore,
2351 !a hybrid definition is implemented that uses both methods, weighting
2352 !the TKE-method more during stable conditions (PBLH < 400 m).
2353 !A variable tke threshold (TKEeps) is used since no hard-wired
2354 !value could be found to work best in all conditions.
2355 !---------------------------------------------------------------
2357 INTEGER,INTENT(IN) :: KTS,KTE
2358 REAL, INTENT(OUT) :: zi
2359 REAL, INTENT(IN) :: landsea
2360 REAL, DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D
2361 REAL, DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D
2363 REAL :: PBLH_TKE,qtke,qtkem1,wt,maxqke,TKEeps,minthv
2364 REAL :: delt_thv !delta theta-v; dependent on land/sea point
2365 REAL, PARAMETER :: sbl_lim = 200. !Theta-v PBL lower limit of trust (m).
2366 REAL, PARAMETER :: sbl_damp = 400. !Damping range for averaging with TKE-based PBLH (m).
2367 INTEGER :: I,J,K,kthv,ktke
2369 !FIND MAX TKE AND MIN THETAV IN THE LOWEST 500 M
2375 DO WHILE (zw1D(k) .LE. 500.)
2376 qtke =MAX(Qke1D(k),0.) ! maximum QKE
2377 IF (maxqke < qtke) then
2381 IF (minthv > thetav1D(k)) then
2382 minthv = thetav1D(k)
2387 !TKEeps = maxtke/20. = maxqke/40.
2389 TKEeps = MAX(TKEeps,0.025)
2390 TKEeps = MIN(TKEeps,0.25)
2392 !FIND THETAV-BASED PBLH (BEST FOR DAYTIME).
2395 IF((landsea-1.5).GE.0)THEN
2405 DO WHILE (zi .EQ. 0.)
2406 IF (thetav1D(k) .GE. (minthv + delt_thv))THEN
2407 zi = zw1D(k) - dz1D(k-1)* &
2408 & MIN((thetav1D(k)-(minthv + delt_thv))/MAX(thetav1D(k)-thetav1D(k-1),1E-6),1.0)
2411 IF (k .EQ. kte-1) zi = zw1D(kts+1) !EXIT SAFEGUARD
2413 !print*,"IN GET_PBLH:",thsfc,zi
2415 !FOR STABLE BOUNDARY LAYERS, USE TKE METHOD TO COMPLEMENT THE
2416 !THETAV-BASED DEFINITION (WHEN THE THETA-V BASED PBLH IS BELOW ~0.5 KM).
2417 !THE TANH WEIGHTING FUNCTION WILL MAKE THE TKE-BASED DEFINITION NEGLIGIBLE
2418 !WHEN THE THETA-V-BASED DEFINITION IS ABOVE ~1 KM.
2419 !FIND TKE-BASED PBLH (BEST FOR NOCTURNAL/STABLE CONDITIONS).
2423 DO WHILE (PBLH_TKE .EQ. 0.)
2424 !QKE CAN BE NEGATIVE (IF CKmod == 0)... MAKE TKE NON-NEGATIVE.
2425 qtke =MAX(Qke1D(k)/2.,0.) ! maximum TKE
2426 qtkem1=MAX(Qke1D(k-1)/2.,0.)
2427 IF (qtke .LE. TKEeps) THEN
2428 PBLH_TKE = zw1D(k) - dz1D(k-1)* &
2429 & MIN((TKEeps-qtke)/MAX(qtkem1-qtke, 1E-6), 1.0)
2430 !IN CASE OF NEAR ZERO TKE, SET PBLH = LOWEST LEVEL.
2431 PBLH_TKE = MAX(PBLH_TKE,zw1D(kts+1))
2432 !print *,"PBLH_TKE:",i,j,PBLH_TKE, Qke1D(k)/2., zw1D(kts+1)
2435 IF (k .EQ. kte-1) PBLH_TKE = zw1D(kts+1) !EXIT SAFEGUARD
2438 !BLEND THE TWO PBLH TYPES HERE:
2440 wt=.5*TANH((zi - sbl_lim)/sbl_damp) + .5
2441 zi=PBLH_TKE*(1.-wt) + zi*wt
2443 END SUBROUTINE GET_PBLH
2445 ! ==================================================================
2447 END MODULE module_bl_mynn