PageRenderTime 37ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/wrfv2_fire/phys/module_bl_mynn.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 2447 lines | 1189 code | 332 blank | 926 comment | 12 complexity | 4aa2c388ac225c52e27a7df5cc04ae31 MD5 | raw file
Possible License(s): AGPL-1.0
  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:
  4. ! 1. code is 1d (in z)
  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
  8. ! distances in z[m]
  9. ! 5. cosmetic changes to adhere to WRF standard (remove common blocks,
  10. ! intent etc)
  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. !-------------------------------------------------------------------
  24. MODULE module_bl_mynn
  25. USE module_model_constants, only: &
  26. &karman, g, p1000mb, &
  27. &cp, r_d, rcp, xlv, &
  28. &svp1, svp2, svp3, svpt0, ep_1, ep_2
  29. !-------------------------------------------------------------------
  30. IMPLICIT NONE
  31. !-------------------------------------------------------------------
  32. ! The parameters below depend on stability functions of module_sf_mynn.
  33. REAL, PARAMETER :: cphm_st=5.0, cphm_unst=16.0, &
  34. cphh_st=5.0, cphh_unst=16.0
  35. REAL, PARAMETER :: xlvcp=xlv/cp, ev=xlv, rd=r_d, rk=cp/rd, &
  36. &svp11=svp1*1.e3, p608=ep_1, ep_3=1.-ep_2
  37. REAL, PARAMETER :: tref=300.0 ! reference temperature (K)
  38. REAL, PARAMETER :: tv0=p608*tref, tv1=(1.+p608)*tref, gtr=g/tref
  39. ! Closure constants
  40. REAL, PARAMETER :: &
  41. &vk = karman, &
  42. &pr = 0.74, &
  43. &g1 = 0.235, &
  44. &b1 = 24.0, &
  45. &b2 = 15.0, & ! CKmod NN2009
  46. &c2 = 0.729, & ! 0.729, & !0.75, &
  47. &c3 = 0.340, & ! 0.340, & !0.352, &
  48. &c4 = 0.0, &
  49. &c5 = 0.2, &
  50. &a1 = b1*( 1.0-3.0*g1 )/6.0, &
  51. ! &c1 = g1 -1.0/( 3.0*a1*b1**(1.0/3.0) ), &
  52. &c1 = g1 -1.0/( 3.0*a1*2.88449914061481660), &
  53. &a2 = a1*( g1-c1 )/( g1*pr ), &
  54. &g2 = b2/b1*( 1.0-c3 ) +2.0*a1/b1*( 3.0-2.0*c2 )
  55. REAL, PARAMETER :: &
  56. &cc2 = 1.0-c2, &
  57. &cc3 = 1.0-c3, &
  58. &e1c = 3.0*a2*b2*cc3, &
  59. &e2c = 9.0*a1*a2*cc2, &
  60. &e3c = 9.0*a2*a2*cc2*( 1.0-c5 ), &
  61. &e4c = 12.0*a1*a2*cc2, &
  62. &e5c = 6.0*a1*a1
  63. ! Constants for length scale
  64. REAL, PARAMETER :: qmin=0.0, zmax=1.0, cns=2.7, &
  65. !NN2009: &alp1=0.23, alp2=1.0, alp3=5.0, alp4=100.0, Sqfac=3.0
  66. &alp1=0.23, alp2=0.53, alp3=5.0, alp4=100.0, Sqfac=2.0
  67. ! Constants for gravitational settling
  68. ! REAL, PARAMETER :: gno=1.e6/(1.e8)**(2./3.), gpw=5./3., qcgmin=1.e-8
  69. REAL, PARAMETER :: gno=4.64158883361278196
  70. REAL, PARAMETER :: gpw=5./3., qcgmin=1.e-8,qkemin=1.e-12
  71. ! REAL, PARAMETER :: pblh_ref=1500.
  72. REAL, PARAMETER :: rr2=0.7071068, rrp=0.3989423
  73. !JOE's mods
  74. !Use Canuto/Kitamura mod (remove Ric and negative TKE) (1:yes, 0:no)
  75. !For more info, see Canuto et al. (2008 JAS) and Kitamura (Journal of the
  76. !Meteorological Society of Japan, Vol. 88, No. 5, pp. 857-864, 2010).
  77. !Note that this change required further modification of other parameters
  78. !above (c2, c3, alp2, and Sqfac). If you want to remove this option, set these
  79. !parameters back to NN2009 values (see commented out lines next to the
  80. !parameters above). This only removes the negative TKE problem
  81. !but does not necessarily improve performance - neutral impact.
  82. REAL, PARAMETER :: CKmod=1.
  83. !Use BouLac mixing length in free atmosphere (1:yes, 0:no)
  84. !This helps remove excessively large mixing in unstable layers aloft.
  85. REAL, PARAMETER :: BLmod=1.
  86. !JOE-end
  87. INTEGER :: mynn_level
  88. CONTAINS
  89. ! **********************************************************************
  90. ! * An improved Mellor-Yamada turbulence closure model *
  91. ! * *
  92. ! * Aug/2005 M. Nakanishi (N.D.A) *
  93. ! * Modified: Dec/2005 M. Nakanishi (N.D.A) *
  94. ! * naka@nda.ac.jp *
  95. ! * *
  96. ! * Contents: *
  97. ! * 1. mym_initialize (to be called once initially) *
  98. ! * gives the closure constants and initializes the turbulent *
  99. ! * quantities. *
  100. ! * (2) mym_level2 (called in the other subroutines) *
  101. ! * calculates the stability functions at Level 2. *
  102. ! * (3) mym_length (called in the other subroutines) *
  103. ! * calculates the master length scale. *
  104. ! * 4. mym_turbulence *
  105. ! * calculates the vertical diffusivity coefficients and the *
  106. ! * production terms for the turbulent quantities. *
  107. ! * 5. mym_predict *
  108. ! * predicts the turbulent quantities at the next step. *
  109. ! * 6. mym_condensation *
  110. ! * determines the liquid water content and the cloud fraction *
  111. ! * diagnostically. *
  112. ! * *
  113. ! * call mym_initialize *
  114. ! * | *
  115. ! * |<----------------+ *
  116. ! * | | *
  117. ! * call mym_condensation | *
  118. ! * call mym_turbulence | *
  119. ! * call mym_predict | *
  120. ! * | | *
  121. ! * |-----------------+ *
  122. ! * | *
  123. ! * end *
  124. ! * *
  125. ! * Variables worthy of special mention: *
  126. ! * tref : Reference temperature *
  127. ! * thl : Liquid water potential temperature *
  128. ! * qw : Total water (water vapor+liquid water) content *
  129. ! * ql : Liquid water content *
  130. ! * vt, vq : Functions for computing the buoyancy flux *
  131. ! * *
  132. ! * If the water contents are unnecessary, e.g., in the case of *
  133. ! * ocean models, thl is the potential temperature and qw, ql, vt *
  134. ! * and vq are all zero. *
  135. ! * *
  136. ! * Grid arrangement: *
  137. ! * k+1 +---------+ *
  138. ! * | | i = 1 - nx *
  139. ! * (k) | * | j = 1 - ny *
  140. ! * | | k = 1 - nz *
  141. ! * k +---------+ *
  142. ! * i (i) i+1 *
  143. ! * *
  144. ! * All the predicted variables are defined at the center (*) of *
  145. ! * the grid boxes. The diffusivity coefficients are, however, *
  146. ! * defined on the walls of the grid boxes. *
  147. ! * # Upper boundary values are given at k=nz. *
  148. ! * *
  149. ! * References: *
  150. ! * 1. Nakanishi, M., 2001: *
  151. ! * Boundary-Layer Meteor., 99, 349-378. *
  152. ! * 2. Nakanishi, M. and H. Niino, 2004: *
  153. ! * Boundary-Layer Meteor., 112, 1-31. *
  154. ! * 3. Nakanishi, M. and H. Niino, 2006: *
  155. ! * Boundary-Layer Meteor., (in press). *
  156. ! * 4. Nakanishi, M. and H. Niino, 2009: *
  157. ! * Jour. Meteor. Soc. Japan, 87, 895-912. *
  158. ! **********************************************************************
  159. !
  160. ! SUBROUTINE mym_initialize:
  161. !
  162. ! Input variables:
  163. ! iniflag : <>0; turbulent quantities will be initialized
  164. ! = 0; turbulent quantities have been already
  165. ! given, i.e., they will not be initialized
  166. ! mx, my : Maximum numbers of grid boxes
  167. ! in the x and y directions, respectively
  168. ! nx, ny, nz : Numbers of the actual grid boxes
  169. ! in the x, y and z directions, respectively
  170. ! tref : Reference temperature (K)
  171. ! dz(nz) : Vertical grid spacings (m)
  172. ! # dz(nz)=dz(nz-1)
  173. ! zw(nz+1) : Heights of the walls of the grid boxes (m)
  174. ! # zw(1)=0.0 and zw(k)=zw(k-1)+dz(k-1)
  175. ! h(mx,ny) : G^(1/2) in the terrain-following coordinate
  176. ! # h=1-zg/zt, where zg is the height of the
  177. ! terrain and zt the top of the model domain
  178. ! pi0(mx,my,nz) : Exner function at zw*h+zg (J/kg K)
  179. ! defined by c_p*( p_basic/1000hPa )^kappa
  180. ! This is usually computed by integrating
  181. ! d(pi0)/dz = -h*g/tref.
  182. ! rmo(mx,ny) : Inverse of the Obukhov length (m^(-1))
  183. ! flt, flq(mx,ny) : Turbulent fluxes of sensible and latent heat,
  184. ! respectively, e.g., flt=-u_*Theta_* (K m/s)
  185. !! flt - liquid water potential temperature surface flux
  186. !! flq - total water flux surface flux
  187. ! ust(mx,ny) : Friction velocity (m/s)
  188. ! pmz(mx,ny) : phi_m-zeta at z1*h+z0, where z1 (=0.5*dz(1))
  189. ! is the first grid point above the surafce, z0
  190. ! the roughness length and zeta=(z1*h+z0)*rmo
  191. ! phh(mx,ny) : phi_h at z1*h+z0
  192. ! u, v(mx,my,nz): Components of the horizontal wind (m/s)
  193. ! thl(mx,my,nz) : Liquid water potential temperature
  194. ! (K)
  195. ! qw(mx,my,nz) : Total water content Q_w (kg/kg)
  196. !
  197. ! Output variables:
  198. ! ql(mx,my,nz) : Liquid water content (kg/kg)
  199. ! v?(mx,my,nz) : Functions for computing the buoyancy flux
  200. ! qke(mx,my,nz) : Twice the turbulent kinetic energy q^2
  201. ! (m^2/s^2)
  202. ! tsq(mx,my,nz) : Variance of Theta_l (K^2)
  203. ! qsq(mx,my,nz) : Variance of Q_w
  204. ! cov(mx,my,nz) : Covariance of Theta_l and Q_w (K)
  205. ! el(mx,my,nz) : Master length scale L (m)
  206. ! defined on the walls of the grid boxes
  207. ! bsh : no longer used
  208. ! via common : Closure constants
  209. !
  210. ! Work arrays: see subroutine mym_level2
  211. ! pd?(mx,my,nz) : Half of the production terms at Level 2
  212. ! defined on the walls of the grid boxes
  213. ! qkw(mx,my,nz) : q on the walls of the grid boxes (m/s)
  214. !
  215. ! # As to dtl, ...gh, see subroutine mym_turbulence.
  216. !
  217. !-------------------------------------------------------------------
  218. SUBROUTINE mym_initialize ( kts,kte,&
  219. & dz, zw, &
  220. & u, v, thl, qw, &
  221. ! & ust, rmo, pmz, phh, flt, flq,&
  222. !JOE-BouLac/PBLH mod
  223. & zi,theta,&
  224. !JOE-end
  225. & ust, rmo, &
  226. & Qke, Tsq, Qsq, Cov)
  227. !
  228. !-------------------------------------------------------------------
  229. INTEGER, INTENT(IN) :: kts,kte
  230. ! REAL, INTENT(IN) :: ust, rmo, pmz, phh, flt, flq
  231. REAL, INTENT(IN) :: ust, rmo
  232. REAL, DIMENSION(kts:kte), INTENT(in) :: dz
  233. REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw
  234. REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw
  235. REAL, DIMENSION(kts:kte), INTENT(out) :: qke,tsq,qsq,cov
  236. REAL, DIMENSION(kts:kte) :: &
  237. &ql,el,pdk,pdt,pdq,pdc,dtl,dqw,dtv,&
  238. &gm,gh,sm,sh,qkw,vt,vq
  239. INTEGER :: k,l,lmax
  240. REAL :: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1.,flt=0.,flq=0.,tmpq
  241. !JOE-BouLac and PBLH mod
  242. REAL :: zi
  243. REAL, DIMENSION(kts:kte) :: theta
  244. !JOE-end
  245. ! ** At first ql, vt and vq are set to zero. **
  246. DO k = kts,kte
  247. ql(k) = 0.0
  248. vt(k) = 0.0
  249. vq(k) = 0.0
  250. END DO
  251. !
  252. CALL mym_level2 ( kts,kte,&
  253. & dz, &
  254. & u, v, thl, qw, &
  255. & ql, vt, vq, &
  256. & dtl, dqw, dtv, gm, gh, sm, sh )
  257. !
  258. ! ** Preliminary setting **
  259. el (kts) = 0.0
  260. qke(kts) = ust**2 * ( b1*pmz )**(2.0/3.0)
  261. !
  262. phm = phh*b2 / ( b1*pmz )**(1.0/3.0)
  263. tsq(kts) = phm*( flt/ust )**2
  264. qsq(kts) = phm*( flq/ust )**2
  265. cov(kts) = phm*( flt/ust )*( flq/ust )
  266. !
  267. DO k = kts+1,kte
  268. vkz = vk*zw(k)
  269. el (k) = vkz/( 1.0 + vkz/100.0 )
  270. qke(k) = 0.0
  271. !
  272. tsq(k) = 0.0
  273. qsq(k) = 0.0
  274. cov(k) = 0.0
  275. END DO
  276. !
  277. ! ** Initialization with an iterative manner **
  278. ! ** lmax is the iteration count. This is arbitrary. **
  279. lmax = 5 !!kte +3
  280. !
  281. DO l = 1,lmax
  282. !
  283. CALL mym_length ( kts,kte,&
  284. & dz, zw, &
  285. & rmo, flt, flq, &
  286. & vt, vq, &
  287. & qke, &
  288. & dtv, &
  289. & el, &
  290. !JOE-added for BouLac/PBHL Test
  291. & zi,theta,&
  292. !JOE-end
  293. & qkw)
  294. !
  295. DO k = kts+1,kte
  296. elq = el(k)*qkw(k)
  297. pdk(k) = elq*( sm(k)*gm (k)+&
  298. &sh(k)*gh (k) )
  299. pdt(k) = elq* sh(k)*dtl(k)**2
  300. pdq(k) = elq* sh(k)*dqw(k)**2
  301. pdc(k) = elq* sh(k)*dtl(k)*dqw(k)
  302. END DO
  303. !
  304. ! ** Strictly, vkz*h(i,j) -> vk*( 0.5*dz(1)*h(i,j)+z0 ) **
  305. vkz = vk*0.5*dz(kts)
  306. !
  307. elv = 0.5*( el(kts+1)+el(kts) ) / vkz
  308. qke(kts) = ust**2 * ( b1*pmz*elv )**(2.0/3.0)
  309. !
  310. phm = phh*b2 / ( b1*pmz/elv**2 )**(1.0/3.0)
  311. tsq(kts) = phm*( flt/ust )**2
  312. qsq(kts) = phm*( flq/ust )**2
  313. cov(kts) = phm*( flt/ust )*( flq/ust )
  314. !
  315. DO k = kts+1,kte-1
  316. b1l = b1*0.25*( el(k+1)+el(k) )
  317. tmpq=MAX(b1l*( pdk(k+1)+pdk(k) ),qkemin)
  318. ! PRINT *,'tmpqqqqq',tmpq,pdk(k+1),pdk(k)
  319. qke(k) = tmpq**(2.0/3.0)
  320. !
  321. IF ( qke(k) .LE. 0.0 ) THEN
  322. b2l = 0.0
  323. ELSE
  324. b2l = b2*( b1l/b1 ) / SQRT( qke(k) )
  325. END IF
  326. !
  327. tsq(k) = b2l*( pdt(k+1)+pdt(k) )
  328. qsq(k) = b2l*( pdq(k+1)+pdq(k) )
  329. cov(k) = b2l*( pdc(k+1)+pdc(k) )
  330. END DO
  331. !
  332. END DO
  333. !! qke(kts)=qke(kts+1)
  334. !! tsq(kts)=tsq(kts+1)
  335. !! qsq(kts)=qsq(kts+1)
  336. !! cov(kts)=cov(kts+1)
  337. qke(kte)=qke(kte-1)
  338. tsq(kte)=tsq(kte-1)
  339. qsq(kte)=qsq(kte-1)
  340. cov(kte)=cov(kte-1)
  341. !
  342. ! RETURN
  343. END SUBROUTINE mym_initialize
  344. !
  345. ! ==================================================================
  346. ! SUBROUTINE mym_level2:
  347. !
  348. ! Input variables: see subroutine mym_initialize
  349. !
  350. ! Output variables:
  351. ! dtl(mx,my,nz) : Vertical gradient of Theta_l (K/m)
  352. ! dqw(mx,my,nz) : Vertical gradient of Q_w
  353. ! dtv(mx,my,nz) : Vertical gradient of Theta_V (K/m)
  354. ! gm (mx,my,nz) : G_M divided by L^2/q^2 (s^(-2))
  355. ! gh (mx,my,nz) : G_H divided by L^2/q^2 (s^(-2))
  356. ! sm (mx,my,nz) : Stability function for momentum, at Level 2
  357. ! sh (mx,my,nz) : Stability function for heat, at Level 2
  358. !
  359. ! These are defined on the walls of the grid boxes.
  360. !
  361. SUBROUTINE mym_level2 (kts,kte,&
  362. & dz, &
  363. & u, v, thl, qw, &
  364. & ql, vt, vq, &
  365. & dtl, dqw, dtv, gm, gh, sm, sh )
  366. !
  367. !-------------------------------------------------------------------
  368. INTEGER, INTENT(IN) :: kts,kte
  369. REAL, DIMENSION(kts:kte), INTENT(in) :: dz
  370. REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,ql,vt,vq
  371. REAL, DIMENSION(kts:kte), INTENT(out) :: &
  372. &dtl,dqw,dtv,gm,gh,sm,sh
  373. INTEGER :: k
  374. REAL :: rfc,f1,f2,rf1,rf2,smc,shc,&
  375. &ri1,ri2,ri3,ri4,duz,dtz,dqz,vtt,vqq,dtq,dzk,afk,abk,ri,rf
  376. !JOE-Canuto/Kitamura mod
  377. REAL :: a2den
  378. !JOE-end
  379. ! ev = 2.5e6
  380. ! tv0 = 0.61*tref
  381. ! tv1 = 1.61*tref
  382. ! gtr = 9.81/tref
  383. !
  384. rfc = g1/( g1+g2 )
  385. f1 = b1*( g1-c1 ) +3.0*a2*( 1.0 -c2 )*( 1.0-c5 ) &
  386. & +2.0*a1*( 3.0-2.0*c2 )
  387. f2 = b1*( g1+g2 ) -3.0*a1*( 1.0 -c2 )
  388. rf1 = b1*( g1-c1 )/f1
  389. rf2 = b1* g1 /f2
  390. smc = a1 /a2* f1/f2
  391. shc = 3.0*a2*( g1+g2 )
  392. !
  393. ri1 = 0.5/smc
  394. ri2 = rf1*smc
  395. ri3 = 4.0*rf2*smc -2.0*ri2
  396. ri4 = ri2**2
  397. !
  398. DO k = kts+1,kte
  399. dzk = 0.5 *( dz(k)+dz(k-1) )
  400. afk = dz(k)/( dz(k)+dz(k-1) )
  401. abk = 1.0 -afk
  402. duz = ( u(k)-u(k-1) )**2 +( v(k)-v(k-1) )**2
  403. duz = duz /dzk**2
  404. dtz = ( thl(k)-thl(k-1) )/( dzk )
  405. dqz = ( qw(k)-qw(k-1) )/( dzk )
  406. !
  407. vtt = 1.0 +vt(k)*abk +vt(k-1)*afk
  408. vqq = tv0 +vq(k)*abk +vq(k-1)*afk
  409. dtq = vtt*dtz +vqq*dqz
  410. !
  411. dtl(k) = dtz
  412. dqw(k) = dqz
  413. dtv(k) = dtq
  414. !? dtv(i,j,k) = dtz +tv0*dqz
  415. !? : +( ev/pi0(i,j,k)-tv1 )
  416. !? : *( ql(i,j,k)-ql(i,j,k-1) )/( dzk*h(i,j) )
  417. !
  418. gm (k) = duz
  419. gh (k) = -dtq*gtr
  420. !
  421. ! ** Gradient Richardson number **
  422. ri = -gh(k)/MAX( duz, 1.0e-10 )
  423. !JOE-Canuto/Kitamura mod
  424. IF (CKmod .eq. 1) THEN
  425. a2den = 1. + MAX(ri,0.0)
  426. ELSE
  427. a2den = 1. + 0.0
  428. ENDIF
  429. rfc = g1/( g1+g2 )
  430. f1 = b1*( g1-c1 ) +3.0*(a2/a2den)*( 1.0 -c2 )*( 1.0-c5 ) &
  431. & +2.0*a1*( 3.0-2.0*c2 )
  432. f2 = b1*( g1+g2 ) -3.0*a1*( 1.0 -c2 )
  433. rf1 = b1*( g1-c1 )/f1
  434. rf2 = b1* g1 /f2
  435. smc = a1 /(a2/a2den)* f1/f2
  436. shc = 3.0*(a2/a2den)*( g1+g2 )
  437. ri1 = 0.5/smc
  438. ri2 = rf1*smc
  439. ri3 = 4.0*rf2*smc -2.0*ri2
  440. ri4 = ri2**2
  441. !JOE-end
  442. ! ** Flux Richardson number **
  443. rf = MIN( ri1*( ri+ri2-SQRT(ri**2-ri3*ri+ri4) ), rfc )
  444. !
  445. sh (k) = shc*( rfc-rf )/( 1.0-rf )
  446. sm (k) = smc*( rf1-rf )/( rf2-rf ) * sh(k)
  447. END DO
  448. !
  449. RETURN
  450. END SUBROUTINE mym_level2
  451. ! ==================================================================
  452. ! SUBROUTINE mym_length:
  453. !
  454. ! Input variables: see subroutine mym_initialize
  455. !
  456. ! Output variables: see subroutine mym_initialize
  457. !
  458. ! Work arrays:
  459. ! elt(mx,ny) : Length scale depending on the PBL depth (m)
  460. ! vsc(mx,ny) : Velocity scale q_c (m/s)
  461. ! at first, used for computing elt
  462. !
  463. SUBROUTINE mym_length ( kts,kte,&
  464. & dz, zw, &
  465. & rmo, flt, flq, &
  466. & vt, vq, &
  467. & qke, &
  468. & dtv, &
  469. & el, &
  470. !JOE-added for BouLac ML (PBLH)
  471. & zi,theta,&
  472. !JOE-end
  473. & qkw)
  474. !-------------------------------------------------------------------
  475. INTEGER, INTENT(IN) :: kts,kte
  476. REAL, DIMENSION(kts:kte), INTENT(in) :: dz
  477. REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw
  478. REAL, INTENT(in) :: rmo,flt,flq
  479. REAL, DIMENSION(kts:kte), INTENT(IN) :: qke,vt,vq
  480. REAL, DIMENSION(kts:kte), INTENT(out) :: qkw, el
  481. REAL, DIMENSION(kts:kte), INTENT(in) :: dtv
  482. REAL :: elt,vsc
  483. !JOE-added for BouLac ML
  484. REAL, DIMENSION(kts:kte), INTENT(IN) :: theta
  485. REAL, DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg
  486. REAL :: wt,zi,zi2,elt0,h1,h2,alp1mod
  487. !THE FOLLOWING LIMITS DO NOT DIRECTLY AFFECT THE ACTUAL PBLH.
  488. !THEY ONLY IMPOSE LIMITS ON THE CALCULATION OF THE MIXING LENGTH
  489. !SCALES SO THAT THE BOULAC MIXING LENGTH (IN FREE ATMOS) DOES
  490. !NOT ENCROACH UPON THE BOUNDARY LAYER MIXING LENGTH (els, elb & elt).
  491. REAL, PARAMETER :: minzi = 300. !min mixed-layer height
  492. REAL, PARAMETER :: maxdz = 750. !max (half) transition layer depth
  493. !=0.3*2500 m PBLH, so the transition
  494. !layer stops growing for PBLHs > 2.5 km.
  495. REAL, PARAMETER :: mindz = 300. !min (half) transition layer depth
  496. !Joe-end
  497. INTEGER :: i,j,k
  498. REAL :: afk,abk,zwk,dzk,qdz,vflx,bv,elb,els,elf
  499. ! tv0 = 0.61*tref
  500. ! gtr = 9.81/tref
  501. !
  502. !JOE-added to impose limits on the height integration for lt as well
  503. ! as the transition layer depth - limit artificial gradients.
  504. zi2=MAX(zi,minzi)
  505. h1=MAX(0.3*zi2,mindz)
  506. h1=MIN(h1,maxdz) !limit (1/2) transition layer depth
  507. h2=h1/2.0 !~1/4 of the transition layer depth
  508. !Joe-end
  509. !JOE-added for BouLac ML
  510. qtke(kts)=MAX(qke(kts)/2.,0.01)
  511. !JOE-end
  512. DO k = kts+1,kte
  513. afk = dz(k)/( dz(k)+dz(k-1) )
  514. abk = 1.0 -afk
  515. qkw(k) = SQRT(MAX(qke(k)*abk+qke(k-1)*&
  516. &afk,1.0e-10))
  517. !JOE- BouLac Start
  518. qtke(k) = MAX(qke(k)/2.,0.001)
  519. !JOE- BouLac End
  520. END DO
  521. !
  522. elt = 1.0e-5
  523. vsc = 1.0e-5
  524. !
  525. ! ** Strictly, zwk*h(i,j) -> ( zwk*h(i,j)+z0 ) **
  526. !JOE-Lt mod: only integrate to top of PBL (+ transition/entrainment
  527. ! layer), since TKE aloft is not relevant. Make WHILE loop, so it
  528. ! exits after looping through the boundary layer.
  529. !
  530. k = kts+1
  531. zwk = zw(k)
  532. DO WHILE (zwk .LE. (zi2+h1))
  533. dzk = 0.5*( dz(k)+dz(k-1) )
  534. qdz = MAX( qkw(k)-qmin, 0.0 )*dzk
  535. elt = elt +qdz*zwk
  536. vsc = vsc +qdz
  537. k = k+1
  538. zwk = zw(k)
  539. END DO
  540. !
  541. elt = alp1*elt/vsc
  542. vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq
  543. vsc = ( gtr*elt*MAX( vflx, 0.0 ) )**(1.0/3.0)
  544. !
  545. ! ** Strictly, el(i,j,1) is not zero. **
  546. el(kts) = 0.0
  547. !
  548. !JOE- BouLac Start
  549. IF ( BLmod .GT. 0. ) THEN
  550. ! COMPUTE BouLac mixing length
  551. CALL boulac_length(kts,kte,zw,dz,qtke,theta,elBLmin,elBLavg)
  552. ENDIF
  553. !JOE- BouLac END
  554. DO k = kts+1,kte
  555. zwk = zw(k)
  556. !JOE- BouLac Start - add blending to only use elt in the boundary
  557. ! layer and use the BouLac mixing length in free atmos
  558. ! [defined relative to the PBLH (zi) + transition layer (h1)].
  559. IF ( BLmod .GT. 0. ) THEN
  560. wt=.5*TANH((zwk - (zi2+h1))/h2) + .5
  561. elt0=elt*(1.-wt) + elBLmin(k)*wt
  562. ELSE
  563. elt0=elt
  564. ENDIF
  565. !JOE- BouLac END
  566. ! ** Length scale limited by the buoyancy effect **
  567. IF ( dtv(k) .GT. 0.0 ) THEN
  568. bv = SQRT( gtr*dtv(k) )
  569. elb = alp2*qkw(k) / bv &
  570. & *( 1.0 + alp3/alp2*&
  571. &SQRT( vsc/( bv*elt ) ) )
  572. elf = alp2 * qkw(k)/bv
  573. ELSE
  574. elb = 1.0e10
  575. elf = elb
  576. END IF
  577. !
  578. !JOE- BouLac Start - only use BL ML in free atmos.
  579. IF ( BLmod .GT. 0. ) THEN
  580. wt=.5*TANH((zwk - (zi2+h1))/h2) + .5
  581. elb=elb*(1.-wt) + elBLmin(k)*wt
  582. !TEST: turn off mixing aloft
  583. !elb=elb*(1.-wt) + 0.01*wt
  584. ENDIF
  585. !!JOE- BouLac END
  586. ! ** Length scale in the surface layer **
  587. IF ( rmo .GT. 0.0 ) THEN
  588. els = vk*zwk &
  589. & /( 1.0 + cns*MIN( zwk*rmo, zmax ) )
  590. ELSE
  591. els = vk*zwk &
  592. & *( 1.0 - alp4* zwk*rmo )**0.2
  593. END IF
  594. !
  595. !JOE- BouLac Start
  596. ! el(k) = MIN(elb/( elb/elt+elb/els+1.0 ),elf)
  597. el(k) = MIN(elb/( elb/elt0+elb/els+1.0 ),elf)
  598. ! el(k) = elb/( elb/elt+elb/els+1.0 )
  599. !JOE- BouLac End
  600. END DO
  601. !
  602. RETURN
  603. END SUBROUTINE mym_length
  604. !JOE- BouLac Code Start -
  605. ! ==================================================================
  606. SUBROUTINE boulac_length(kts,kte,zw,dz,qtke,theta,lb1,lb2)
  607. !
  608. ! NOTE: This subroutine was taken from the BouLac scheme in WRF-ARW
  609. ! and modified for integration into the MYNN PBL scheme.
  610. ! WHILE loops were added to reduce the computational expense.
  611. ! This subroutine computes the length scales up and down
  612. ! and then computes the min, average of the up/down
  613. ! length scales, and also considers the distance to the
  614. ! surface.
  615. !
  616. ! dlu = the distance a parcel can be lifted upwards give a finite
  617. ! amount of TKE.
  618. ! dld = the distance a parcel can be displaced downwards given a
  619. ! finite amount of TKE.
  620. ! lb1 = the minimum of the length up and length down
  621. ! lb2 = the average of the length up and length down
  622. !-------------------------------------------------------------------
  623. INTEGER, INTENT(IN) :: kts,kte
  624. REAL, DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta
  625. REAL, DIMENSION(kts:kte), INTENT(OUT) :: lb1,lb2
  626. REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw
  627. !LOCAL VARS
  628. INTEGER :: iz, izz, found
  629. REAL, DIMENSION(kts:kte) :: dlu,dld
  630. !REAL, PARAMETER :: g=9.81
  631. REAL :: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz
  632. !print*,"IN MYNN-BouLac",kts, kte
  633. do iz=kts,kte
  634. !----------------------------------
  635. ! FIND DISTANCE UPWARD
  636. !----------------------------------
  637. zup=0.
  638. dlu(iz)=zw(kte+1)-zw(iz)-dz(iz)/2.
  639. zzz=0.
  640. zup_inf=0.
  641. beta=g/theta(iz) !Buoyancy coefficient
  642. if (iz .lt. kte) then !cant integrate upwards from highest level
  643. !do izz=iz,kte-1 !integrate upwards to find dlu
  644. found = 0
  645. izz=iz
  646. DO WHILE (found .EQ. 0)
  647. if (izz .lt. kte) then
  648. dzt=(dz(izz+1)+dz(izz))/2. ! avg layer depth of above and below layer
  649. zup=zup-beta*theta(iz)*dzt ! initial PE the parcel has at iz
  650. !print*," ",iz,izz,theta(izz)
  651. zup=zup+beta*(theta(izz+1)+theta(izz))*dzt/2. ! PE gained by lifting a parcel to izz+1
  652. zzz=zzz+dzt ! depth of layer iz to izz+1
  653. if (qtke(iz).lt.zup .and. qtke(iz).ge.zup_inf) then
  654. bbb=(theta(izz+1)-theta(izz))/dzt
  655. if (bbb .ne. 0.) then
  656. tl=(-beta*(theta(izz)-theta(iz)) + &
  657. & sqrt( max(0.,(beta*(theta(izz)-theta(iz)))**2. + &
  658. & 2.*bbb*beta*(qtke(iz)-zup_inf))))/bbb/beta
  659. else
  660. if (theta(izz) .ne. theta(iz))then
  661. tl=(qtke(iz)-zup_inf)/(beta*(theta(izz)-theta(iz)))
  662. else
  663. tl=0.
  664. endif
  665. endif
  666. dlu(iz)=zzz-dzt+tl
  667. found = 1
  668. endif
  669. zup_inf=zup
  670. izz=izz+1
  671. ELSE
  672. found = 1
  673. ENDIF
  674. ENDDO
  675. endif
  676. !----------------------------------
  677. ! FIND DISTANCE DOWN
  678. !----------------------------------
  679. zdo=0.
  680. zdo_sup=0.
  681. dld(iz)=zw(iz)+dz(iz)/2.
  682. zzz=0.
  683. if (iz .gt. kts) then !cant integrate downwards from lowest level
  684. !do izz=iz,kts+1,-1 !integrate downwards to find dld
  685. found = 0
  686. izz=iz
  687. DO WHILE (found .EQ. 0)
  688. if (izz .gt. kts) then
  689. dzt=(dz(izz-1)+dz(izz))/2.
  690. zdo=zdo+beta*theta(iz)*dzt
  691. zdo=zdo-beta*(theta(izz-1)+theta(izz))*dzt/2.
  692. zzz=zzz+dzt
  693. if (qtke(iz).lt.zdo .and. qtke(iz).ge.zdo_sup) then
  694. bbb=(theta(izz)-theta(izz-1))/dzt
  695. if (bbb .ne. 0.) then
  696. tl=(beta*(theta(izz)-theta(iz))+ &
  697. & sqrt( max(0.,(beta*(theta(izz)-theta(iz)))**2. + &
  698. & 2.*bbb*beta*(qtke(iz)-zdo_sup))))/bbb/beta
  699. else
  700. if (theta(izz) .ne. theta(iz)) then
  701. tl=(qtke(iz)-zdo_sup)/(beta*(theta(izz)-theta(iz)))
  702. else
  703. tl=0.
  704. endif
  705. endif
  706. dld(iz)=zzz-dzt+tl
  707. found = 1
  708. endif
  709. zdo_sup=zdo
  710. izz=izz-1
  711. ELSE
  712. found = 1
  713. ENDIF
  714. ENDDO
  715. endif
  716. !----------------------------------
  717. ! GET MINIMUM (OR AVERAGE)
  718. !----------------------------------
  719. !The surface layer length scale can exceed z for large z/L,
  720. !so keep maximum distance down > z.
  721. dld(iz) = min(dld(iz),zw(iz+1))
  722. lb1(iz) = min(dlu(iz),dld(iz)) !minimum
  723. lb2(iz) = sqrt(dlu(iz)*dld(iz)) !average - biased towards smallest
  724. !lb2(iz) = 0.5*(dlu(iz)+dld(iz)) !average
  725. if (iz .eq. kte) then
  726. lb1(kte) = lb1(kte-1)
  727. lb2(kte) = lb2(kte-1)
  728. endif
  729. !print*,"IN MYNN-BouLac",kts, kte,lb1(iz)
  730. !print*,"IN MYNN-BouLac",iz,dld(iz),dlu(iz)
  731. ENDDO
  732. END SUBROUTINE boulac_length
  733. !
  734. !JOE-END BOULAC CODE
  735. ! ==================================================================
  736. ! SUBROUTINE mym_turbulence:
  737. !
  738. ! Input variables: see subroutine mym_initialize
  739. ! levflag : <>3; Level 2.5
  740. ! = 3; Level 3
  741. !
  742. ! # ql, vt, vq, qke, tsq, qsq and cov are changed to input variables.
  743. !
  744. ! Output variables: see subroutine mym_initialize
  745. ! dfm(mx,my,nz) : Diffusivity coefficient for momentum,
  746. ! divided by dz (not dz*h(i,j)) (m/s)
  747. ! dfh(mx,my,nz) : Diffusivity coefficient for heat,
  748. ! divided by dz (not dz*h(i,j)) (m/s)
  749. ! dfq(mx,my,nz) : Diffusivity coefficient for q^2,
  750. ! divided by dz (not dz*h(i,j)) (m/s)
  751. ! tcd(mx,my,nz) : Countergradient diffusion term for Theta_l
  752. ! (K/s)
  753. ! qcd(mx,my,nz) : Countergradient diffusion term for Q_w
  754. ! (kg/kg s)
  755. ! pd?(mx,my,nz) : Half of the production terms
  756. !
  757. ! Only tcd and qcd are defined at the center of the grid boxes
  758. !
  759. ! # DO NOT forget that tcd and qcd are added on the right-hand side
  760. ! of the equations for Theta_l and Q_w, respectively.
  761. !
  762. ! Work arrays: see subroutine mym_initialize and level2
  763. !
  764. ! # dtl, dqw, dtv, gm and gh are allowed to share storage units with
  765. ! dfm, dfh, dfq, tcd and qcd, respectively, for saving memory.
  766. !
  767. SUBROUTINE mym_turbulence ( kts,kte,&
  768. & levflag, &
  769. & dz, zw, &
  770. & u, v, thl, ql, qw, &
  771. & qke, tsq, qsq, cov, &
  772. & vt, vq,&
  773. & rmo, flt, flq, &
  774. !JOE-BouLac/PBLH test
  775. & zi,theta,&
  776. !JOE-end
  777. & El,&
  778. & Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, &
  779. !JOE-TKE_BUDGET
  780. & qWT1D,qSHEAR1D,qBUOY1D,qDISS1D)
  781. !JOE-end
  782. !-------------------------------------------------------------------
  783. !
  784. INTEGER, INTENT(IN) :: kts,kte
  785. INTEGER, INTENT(IN) :: levflag
  786. REAL, DIMENSION(kts:kte), INTENT(in) :: dz
  787. REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw
  788. REAL, INTENT(in) :: rmo,flt,flq
  789. REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,&
  790. &ql,vt,vq,qke,tsq,qsq,cov
  791. REAL, DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq,&
  792. &pdk,pdt,pdq,pdc,tcd,qcd,el
  793. !JOE-TKE-BUDGET
  794. REAL, DIMENSION(kts:kte), INTENT(out) :: qWT1D,&
  795. &qSHEAR1D,qBUOY1D,qDISS1D
  796. REAL :: q3sq_old,dlsq1,qWTP_old,qWTP_new
  797. REAL :: dudz,dvdz,dTdz,&
  798. upwp,vpwp,Tpwp
  799. !JOE-end
  800. REAL, DIMENSION(kts:kte) :: qkw,dtl,dqw,dtv,gm,gh,sm,sh
  801. INTEGER :: k
  802. ! REAL :: cc2,cc3,e1c,e2c,e3c,e4c,e5c
  803. REAL :: e6c,dzk,afk,abk,vtt,vqq,&
  804. &cw25,clow,cupp,gamt,gamq,smd,gamv,elq,elh
  805. !JOE-added for BouLac/PBLH test
  806. REAL :: zi
  807. REAL, DIMENSION(kts:kte), INTENT(in) :: theta
  808. !JOE-end
  809. !JOE-Canuto/Kitamura mod
  810. REAL :: a2den, duz, ri
  811. !JOE-end
  812. DOUBLE PRECISION q2sq, t2sq, r2sq, c2sq, elsq, gmel, ghel
  813. DOUBLE PRECISION q3sq, t3sq, r3sq, c3sq, dlsq, qdiv
  814. DOUBLE PRECISION e1, e2, e3, e4, enum, eden, wden
  815. !
  816. ! tv0 = 0.61*tref
  817. ! gtr = 9.81/tref
  818. !
  819. ! cc2 = 1.0-c2
  820. ! cc3 = 1.0-c3
  821. ! e1c = 3.0*a2*b2*cc3
  822. ! e2c = 9.0*a1*a2*cc2
  823. ! e3c = 9.0*a2*a2*cc2*( 1.0-c5 )
  824. ! e4c = 12.0*a1*a2*cc2
  825. ! e5c = 6.0*a1*a1
  826. !
  827. CALL mym_level2 (kts,kte,&
  828. & dz, &
  829. & u, v, thl, qw, &
  830. & ql, vt, vq, &
  831. & dtl, dqw, dtv, gm, gh, sm, sh )
  832. !
  833. CALL mym_length (kts,kte, &
  834. & dz, zw, &
  835. & rmo, flt, flq, &
  836. & vt, vq, &
  837. & qke, &
  838. & dtv, &
  839. & el, &
  840. !JOE BouLac/PBLH test
  841. & zi,theta,&
  842. !JOE-end
  843. & qkw)
  844. !
  845. DO k = kts+1,kte
  846. dzk = 0.5 *( dz(k)+dz(k-1) )
  847. afk = dz(k)/( dz(k)+dz(k-1) )
  848. abk = 1.0 -afk
  849. elsq = el (k)**2
  850. q2sq = b1*elsq*( sm(k)*gm(k)+sh(k)*gh(k) )
  851. q3sq = qkw(k)**2
  852. !JOE-Canuto/Kitamura mod
  853. duz = ( u(k)-u(k-1) )**2 +( v(k)-v(k-1) )**2
  854. duz = duz /dzk**2
  855. ! ** Gradient Richardson number **
  856. ri = -gh(k)/MAX( duz, 1.0e-10 )
  857. IF (CKmod .eq. 1) THEN
  858. a2den = 1. + MAX(ri,0.0)
  859. ELSE
  860. a2den = 1. + 0.0
  861. ENDIF
  862. !JOE-end
  863. !
  864. ! Modified: Dec/22/2005, from here, (dlsq -> elsq)
  865. gmel = gm (k)*elsq
  866. ghel = gh (k)*elsq
  867. ! Modified: Dec/22/2005, up to here
  868. !
  869. ! ** Since qkw is set to more than 0.0, q3sq > 0.0. **
  870. IF ( q3sq .LT. q2sq ) THEN
  871. qdiv = SQRT( q3sq/q2sq )
  872. sm(k) = sm(k) * qdiv
  873. sh(k) = sh(k) * qdiv
  874. !
  875. !JOE-Canuto/Kitamura mod
  876. ! e1 = q3sq - e1c*ghel * qdiv**2
  877. ! e2 = q3sq - e2c*ghel * qdiv**2
  878. ! e3 = e1 + e3c*ghel * qdiv**2
  879. ! e4 = e1 - e4c*ghel * qdiv**2
  880. e1 = q3sq - e1c*ghel/a2den * qdiv**2
  881. e2 = q3sq - e2c*ghel/a2den * qdiv**2
  882. e3 = e1 + e3c*ghel/(a2den**2) * qdiv**2
  883. e4 = e1 - e4c*ghel/a2den * qdiv**2
  884. !JOE-end
  885. eden = e2*e4 + e3*e5c*gmel * qdiv**2
  886. eden = MAX( eden, 1.0d-20 )
  887. ELSE
  888. !JOE-Canuto/Kitamura mod
  889. ! e1 = q3sq - e1c*ghel
  890. ! e2 = q3sq - e2c*ghel
  891. ! e3 = e1 + e3c*ghel
  892. ! e4 = e1 - e4c*ghel
  893. e1 = q3sq - e1c*ghel/a2den
  894. e2 = q3sq - e2c*ghel/a2den
  895. e3 = e1 + e3c*ghel/(a2den**2)
  896. e4 = e1 - e4c*ghel/a2den
  897. !JOE-end
  898. eden = e2*e4 + e3*e5c*gmel
  899. eden = MAX( eden, 1.0d-20 )
  900. !
  901. qdiv = 1.0
  902. sm(k) = q3sq*a1*( e3-3.0*c1*e4 )/eden
  903. !JOE-Canuto/Kitamura mod
  904. ! sh(k) = q3sq*a2*( e2+3.0*c1*e5c*gmel )/eden
  905. sh(k) = q3sq*(a2/a2den)*( e2+3.0*c1*e5c*gmel )/eden
  906. !JOE-end
  907. END IF
  908. !
  909. ! ** Level 3 : start **
  910. IF ( levflag .EQ. 3 ) THEN
  911. t2sq = qdiv*b2*elsq*sh(k)*dtl(k)**2
  912. r2sq = qdiv*b2*elsq*sh(k)*dqw(k)**2
  913. c2sq = qdiv*b2*elsq*sh(k)*dtl(k)*dqw(k)
  914. t3sq = MAX( tsq(k)*abk+tsq(k-1)*afk, 0.0 )
  915. r3sq = MAX( qsq(k)*abk+qsq(k-1)*afk, 0.0 )
  916. c3sq = cov(k)*abk+cov(k-1)*afk
  917. !
  918. ! Modified: Dec/22/2005, from here
  919. c3sq = SIGN( MIN( ABS(c3sq), SQRT(t3sq*r3sq) ), c3sq )
  920. !
  921. vtt = 1.0 +vt(k)*abk +vt(k-1)*afk
  922. vqq = tv0 +vq(k)*abk +vq(k-1)*afk
  923. t2sq = vtt*t2sq +vqq*c2sq
  924. r2sq = vtt*c2sq +vqq*r2sq
  925. c2sq = MAX( vtt*t2sq+vqq*r2sq, 0.0d0 )
  926. t3sq = vtt*t3sq +vqq*c3sq
  927. r3sq = vtt*c3sq +vqq*r3sq
  928. c3sq = MAX( vtt*t3sq+vqq*r3sq, 0.0d0 )
  929. !
  930. cw25 = e1*( e2 + 3.0*c1*e5c*gmel*qdiv**2 )/( 3.0*eden )
  931. !
  932. ! ** Limitation on q, instead of L/q **
  933. dlsq = elsq
  934. IF ( q3sq/dlsq .LT. -gh(k) ) q3sq = -dlsq*gh(k)
  935. !
  936. ! ** Limitation on c3sq (0.12 =< cw =< 0.76) **
  937. !JOE-Canuto/Kitamura mod
  938. ! e2 = q3sq - e2c*ghel * qdiv**2
  939. ! e3 = q3sq + e3c*ghel * qdiv**2
  940. ! e4 = q3sq - e4c*ghel * qdiv**2
  941. e2 = q3sq - e2c*ghel/a2den * qdiv**2
  942. e3 = q3sq + e3c*ghel/(a2den**2) * qdiv**2
  943. e4 = q3sq - e4c*ghel/a2den * qdiv**2
  944. !JOE-end
  945. eden = e2*e4 + e3 *e5c*gmel * qdiv**2
  946. !
  947. !JOE-Canuto/Kitamura mod
  948. ! wden = cc3*gtr**2 * dlsq**2/elsq * qdiv**2 &
  949. ! & *( e2*e4c - e3c*e5c*gmel * qdiv**2 )
  950. wden = cc3*gtr**2 * dlsq**2/elsq * qdiv**2 &
  951. & *( e2*e4c/a2den - e3c*e5c*gmel/(a2den**2) * qdiv**2 )
  952. !JOE-end
  953. !
  954. IF ( wden .NE. 0.0 ) THEN
  955. clow = q3sq*( 0.12-cw25 )*eden/wden
  956. cupp = q3sq*( 0.76-cw25 )*eden/wden
  957. !
  958. IF ( wden .GT. 0.0 ) THEN
  959. c3sq = MIN( MAX( c3sq, c2sq+clow ), c2sq+cupp )
  960. ELSE
  961. c3sq = MAX( MIN( c3sq, c2sq+clow ), c2sq+cupp )
  962. END IF
  963. END IF
  964. !
  965. e1 = e2 + e5c*gmel * qdiv**2
  966. eden = MAX( eden, 1.0d-20 )
  967. ! Modified: Dec/22/2005, up to here
  968. !
  969. !JOE-Canuto/Kitamura mod
  970. ! e6c = 3.0*a2*cc3*gtr * dlsq/elsq
  971. e6c = 3.0*(a2/a2den)*cc3*gtr * dlsq/elsq
  972. !JOE-end
  973. !
  974. ! ** for Gamma_theta **
  975. !! enum = qdiv*e6c*( t3sq-t2sq )
  976. IF ( t2sq .GE. 0.0 ) THEN
  977. enum = MAX( qdiv*e6c*( t3sq-t2sq ), 0.0d0 )
  978. ELSE
  979. enum = MIN( qdiv*e6c*( t3sq-t2sq ), 0.0d0 )
  980. ENDIF
  981. gamt =-e1 *enum /eden
  982. !
  983. ! ** for Gamma_q **
  984. !! enum = qdiv*e6c*( r3sq-r2sq )
  985. IF ( r2sq .GE. 0.0 ) THEN
  986. enum = MAX( qdiv*e6c*( r3sq-r2sq ), 0.0d0 )
  987. ELSE
  988. enum = MIN( qdiv*e6c*( r3sq-r2sq ), 0.0d0 )
  989. ENDIF
  990. gamq =-e1 *enum /eden
  991. !
  992. ! ** for Sm' and Sh'd(Theta_V)/dz **
  993. !! enum = qdiv*e6c*( c3sq-c2sq )
  994. enum = MAX( qdiv*e6c*( c3sq-c2sq ), 0.0d0)
  995. !JOE-Canuto/Kitamura mod
  996. ! smd = dlsq*enum*gtr/eden * qdiv**2 * (e3c+e4c)*a1/a2
  997. smd = dlsq*enum*gtr/eden * qdiv**2 * (e3c/(a2den**2) + e4c/a2den)*a1/(a2/a2den)
  998. !JOE-end
  999. gamv = e1 *enum*gtr/eden
  1000. !
  1001. sm(k) = sm(k) +smd
  1002. !
  1003. ! ** For elh (see below), qdiv at Level 3 is reset to 1.0. **
  1004. qdiv = 1.0
  1005. ! ** Level 3 : end **
  1006. !
  1007. ELSE
  1008. ! ** At Level 2.5, qdiv is not reset. **
  1009. gamt = 0.0
  1010. gamq = 0.0
  1011. gamv = 0.0
  1012. END IF
  1013. !
  1014. elq = el(k)*qkw(k)
  1015. elh = elq*qdiv
  1016. !
  1017. pdk(k) = elq*( sm(k)*gm (k) &
  1018. & +sh(k)*gh (k)+gamv )
  1019. pdt(k) = elh*( sh(k)*dtl(k)+gamt )*dtl(k)
  1020. pdq(k) = elh*( sh(k)*dqw(k)+gamq )*dqw(k)
  1021. pdc(k) = elh*( sh(k)*dtl(k)+gamt )&
  1022. &*dqw(k)*0.5 &
  1023. &+elh*( sh(k)*dqw(k)+gamq )*dtl(k)*0.5
  1024. !
  1025. tcd(k) = elq*gamt
  1026. qcd(k) = elq*gamq
  1027. !
  1028. dfm(k) = elq*sm (k) / dzk
  1029. dfh(k) = elq*sh (k) / dzk
  1030. ! Modified: Dec/22/2005, from here
  1031. ! ** In sub.mym_predict, dfq for the TKE and scalar variance **
  1032. ! ** are set to 3.0*dfm and 1.0*dfm, respectively. (Sqfac) **
  1033. dfq(k) = dfm(k)
  1034. ! Modified: Dec/22/2005, up to here
  1035. !TKE BUDGET-start
  1036. dudz = ( u(k)-u(k-1) )/dzk
  1037. dvdz = ( v(k)-v(k-1) )/dzk
  1038. dTdz = ( thl(k)-thl(k-1) )/dzk
  1039. upwp = -elq*sm(k)*dudz
  1040. vpwp = -elq*sm(k)*dvdz
  1041. Tpwp = -elq*sh(k)*dTdz
  1042. Tpwp = SIGN(MAX(ABS(Tpwp),1.E-6),Tpwp)
  1043. IF ( k .EQ. kts+1 ) THEN
  1044. qWT1D(kts)=0.
  1045. q3sq_old =0.
  1046. qWTP_old =0.
  1047. !** Limitation on q, instead of L/q **
  1048. dlsq1 = MAX(el(kts)**2,1.0)
  1049. IF ( q3sq_old/dlsq1 .LT. -gh(k) ) q3sq_old = -dlsq1*gh(k)
  1050. ENDIF
  1051. !!!Vertical Transport Term
  1052. qWTP_new = elq*Sqfac*sm(k)*(q3sq - q3sq_old)/dzk
  1053. qWT1D(k) = 0.5*(qWTP_new - qWTP_old)/dzk
  1054. qWTP_old = elq*Sqfac*sm(k)*(q3sq - q3sq_old)/dzk
  1055. q3sq_old = q3sq
  1056. !!!Shear Term
  1057. !!!qSHEAR1D(k)=-(upwp*dudz + vpwp*dvdz)
  1058. qSHEAR1D(k) = elq*sm(k)*gm(k)
  1059. !!!Buoyancy Term
  1060. !!!qBUOY1D(k)=g*Tpwp/thl(k)
  1061. !qBUOY1D(k)= elq*(sh(k)*gh(k) + gamv)
  1062. qBUOY1D(k) = elq*(sh(k)*(-dTdz*g/thl(k)) + gamv)
  1063. !!!Dissipation Term
  1064. qDISS1D(k) = (q3sq**(3./2.))/(b1*MAX(el(k),1.))
  1065. !TKE BUDGET-end
  1066. END DO
  1067. !
  1068. dfm(kts) = 0.0
  1069. dfh(kts) = 0.0
  1070. dfq(kts) = 0.0
  1071. tcd(kts) = 0.0
  1072. qcd(kts) = 0.0
  1073. tcd(kte) = 0.0
  1074. qcd(kte) = 0.0
  1075. !
  1076. DO k = kts,kte-1
  1077. dzk = dz(k)
  1078. tcd(k) = ( tcd(k+1)-tcd(k) )/( dzk )
  1079. qcd(k) = ( qcd(k+1)-qcd(k) )/( dzk )
  1080. END DO
  1081. !
  1082. !JOE-TKE-BUDGET
  1083. qWT1D(kts)=0.
  1084. qSHEAR1D(kts)=qSHEAR1D(kts+1)
  1085. qBUOY1D(kts)=qBUOY1D(kts+1)
  1086. qDISS1D(kts)=qDISS1D(kts+1)
  1087. !JOE-end
  1088. RETURN
  1089. END SUBROUTINE mym_turbulence
  1090. ! ==================================================================
  1091. ! SUBROUTINE mym_predict:
  1092. !
  1093. ! Input variables: see subroutine mym_initialize and turbulence
  1094. ! qke(mx,my,nz) : qke at (n)th time level
  1095. ! tsq, ...cov : ditto
  1096. !
  1097. ! Output variables:
  1098. ! qke(mx,my,nz) : qke at (n+1)th time level
  1099. ! tsq, ...cov : ditto
  1100. !
  1101. ! Work arrays:
  1102. ! qkw(mx,my,nz) : q at the center of the grid boxes (m/s)
  1103. ! bp (mx,my,nz) : = 1/2*F, see below
  1104. ! rp (mx,my,nz) : = P-1/2*F*Q, see below
  1105. !
  1106. ! # The equation for a turbulent quantity Q can be expressed as
  1107. ! dQ/dt + Ah + Av = Dh + Dv + P - F*Q, (1)
  1108. ! where A is the advection, D the diffusion, P the production,
  1109. ! F*Q the dissipation and h and v denote horizontal and vertical,
  1110. ! respectively. If Q is q^2, F is 2q/B_1L.
  1111. ! Using the Crank-Nicholson scheme for Av, Dv and F*Q, a finite
  1112. ! difference equation is written as
  1113. ! Q{n+1} - Q{n} = dt *( Dh{n} - Ah{n} + P{n} )
  1114. ! + dt/2*( Dv{n} - Av{n} - F*Q{n} )
  1115. ! + dt/2*( Dv{n+1} - Av{n+1} - F*Q{n+1} ), (2)
  1116. ! where n denotes the time level.
  1117. ! When the advection and diffusion terms are discretized as
  1118. ! dt/2*( Dv - Av ) = a(k)Q(k+1) - b(k)Q(k) + c(k)Q(k-1), (3)
  1119. ! Eq.(2) can be rewritten as
  1120. ! - a(k)Q(k+1) + [ 1 + b(k) + dt/2*F ]Q(k) - c(k)Q(k-1)
  1121. ! = Q{n} + dt *( Dh{n} - Ah{n} + P{n} )
  1122. ! + dt/2*( Dv{n} - Av{n} - F*Q{n} ), (4)
  1123. ! where Q on the left-hand side is at (n+1)th time level.
  1124. !
  1125. ! In this subroutine, a(k), b(k) and c(k) are obtained from
  1126. ! subprogram coefvu and are passed to subprogram tinteg via
  1127. ! common. 1/2*F and P-1/2*F*Q are stored in bp and rp,
  1128. ! respectively. Subprogram tinteg solves Eq.(4).
  1129. !
  1130. ! Modify this subroutine according to your numerical integration
  1131. ! scheme (program).
  1132. !
  1133. !-------------------------------------------------------------------
  1134. SUBROUTINE mym_predict (kts,kte,&
  1135. & levflag, &
  1136. & delt,&
  1137. & dz, &
  1138. & ust, flt, flq, pmz, phh, &
  1139. & el, dfq, &
  1140. & pdk, pdt, pdq, pdc,&
  1141. & qke, tsq, qsq, cov,&
  1142. !JOE-TKE-BUDGET
  1143. & dqke1D)
  1144. !JOE-end
  1145. !-------------------------------------------------------------------
  1146. INTEGER, INTENT(IN) :: kts,kte
  1147. INTEGER, INTENT(IN) :: levflag
  1148. REAL, INTENT(IN) :: delt
  1149. REAL, DIMENSION(kts:kte), INTENT(IN) :: dz, dfq,el
  1150. REAL, DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc
  1151. REAL, INTENT(IN) :: flt, flq, ust, pmz, phh
  1152. REAL, DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov
  1153. !JOE-TKE-BUDGET
  1154. REAL, DIMENSION(kts:kte), INTENT(OUT) :: dqke1D
  1155. !JOE-end
  1156. INTEGER :: k,nz
  1157. REAL, DIMENSION(kts:kte) :: qkw, bp, rp, df3q
  1158. REAL :: vkz,pdk1,phm,pdt1,pdq1,pdc1,b1l,b2l
  1159. REAL, DIMENSION(kts:kte) :: dtz
  1160. REAL, DIMENSION(1:kte-kts+1) :: a,b,c,d
  1161. nz=kte-kts+1
  1162. ! ** Strictly, vkz*h(i,j) -> vk*( 0.5*dz(1)*h(i,j)+z0 ) **
  1163. vkz = vk*0.5*dz(kts)
  1164. !
  1165. ! Modified: Dec/22/2005, from here
  1166. ! ** dfq for the TKE is 3.0*dfm. **
  1167. ! CALL coefvu ( dfq, 3.0 ) ! make change here
  1168. ! Modified: Dec/22/2005, up to here
  1169. !
  1170. DO k = kts,kte
  1171. !! qke(k) = MAX(qke(k), 0.0)
  1172. qkw(k) = SQRT( MAX( qke(k), 0.0 ) )
  1173. !df3q(k)=3.*dfq(k)
  1174. df3q(k)=Sqfac*dfq(k)
  1175. dtz(k)=delt/dz(k)
  1176. END DO
  1177. !
  1178. pdk1 = 2.0*ust**3*pmz/( vkz )
  1179. phm = 2.0/ust *phh/( vkz )
  1180. pdt1 = phm*flt**2
  1181. pdq1 = phm*flq**2
  1182. pdc1 = phm*flt*flq
  1183. !
  1184. ! ** pdk(i,j,1)+pdk(i,j,2) corresponds to pdk1. **
  1185. pdk(kts) = pdk1 -pdk(kts+1)
  1186. !! pdt(kts) = pdt1 -pdt(kts+1)
  1187. !! pdq(kts) = pdq1 -pdq(kts+1)
  1188. !! pdc(kts) = pdc1 -pdc(kts+1)
  1189. pdt(kts) = pdt(kts+1)
  1190. pdq(kts) = pdq(kts+1)
  1191. pdc(kts) = pdc(kts+1)
  1192. !
  1193. ! ** Prediction of twice the turbulent kinetic energy **
  1194. !! DO k = kts+1,kte-1
  1195. DO k = kts,kte-1
  1196. b1l = b1*0.5*( el(k+1)+el(k) )
  1197. bp(k) = 2.*qkw(k) / b1l
  1198. rp(k) = pdk(k+1) + pdk(k)
  1199. END DO
  1200. !! a(1)=0.
  1201. !! b(1)=1.
  1202. !! c(1)=-1.
  1203. !! d(1)=0.
  1204. ! Since df3q(kts)=0.0, a(1)=0.0 and b(1)=1.+dtz(k)*df3q(k+1)+bp(k)*delt.
  1205. DO k=kts,kte-1
  1206. a(k-kts+1)=-dtz(k)*df3q(k)
  1207. b(k-kts+1)=1.+dtz(k)*(df3q(k)+df3q(k+1))+bp(k)*delt
  1208. c(k-kts+1)=-dtz(k)*df3q(k+1)
  1209. d(k-kts+1)=rp(k)*delt + qke(k)
  1210. ENDDO
  1211. !! DO k=kts+1,kte-1
  1212. !! a(k-kts+1)=-dtz(k)*df3q(k)
  1213. !! b(k-kts+1)=1.+dtz(k)*(df3q(k)+df3q(k+1))
  1214. !! c(k-kts+1)=-dtz(k)*df3q(k+1)
  1215. !! d(k-kts+1)=rp(k)*delt + qke(k) - qke(k)*bp(k)*delt
  1216. !! ENDDO
  1217. a(nz)=-1. !0.
  1218. b(nz)=1.
  1219. c(nz)=0.
  1220. d(nz)=0.
  1221. CALL tridiag(nz,a,b,c,d)
  1222. DO k=kts,kte
  1223. !JOE-TKE_BUDGET
  1224. dqke1D(k)=qke(k)
  1225. !JOE-end
  1226. qke(k)=d(k-kts+1)
  1227. !JOE-TKE_BUDGET
  1228. dqke1D(k)=(qke(k)-dqke1D(k))*0.5
  1229. !JOE-end
  1230. ENDDO
  1231. IF ( levflag .EQ. 3 ) THEN
  1232. !
  1233. ! Modified: Dec/22/2005, from here
  1234. ! ** dfq for the scalar variance is 1.0*dfm. **
  1235. ! CALL coefvu ( dfq, 1.0 ) make change here
  1236. ! Modified: Dec/22/2005, up to here
  1237. !
  1238. ! ** Prediction of the temperature variance **
  1239. !! DO k = kts+1,kte-1
  1240. DO k = kts,kte-1
  1241. b2l = b2*0.5*( el(k+1)+el(k) )
  1242. bp(k) = 2.*qkw(k) / b2l
  1243. rp(k) = pdt(k+1) + pdt(k)
  1244. END DO
  1245. !zero gradient for tsq at bottom and top
  1246. !! a(1)=0.
  1247. !! b(1)=1.
  1248. !! c(1)=-1.
  1249. !! d(1)=0.
  1250. ! Since dfq(kts)=0.0, a(1)=0.0 and b(1)=1.+dtz(k)*dfq(k+1)+bp(k)*delt.
  1251. DO k=kts,kte-1
  1252. a(k-kts+1)=-dtz(k)*dfq(k)
  1253. b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))+bp(k)*delt
  1254. c(k-kts+1)=-dtz(k)*dfq(k+1)
  1255. d(k-kts+1)=rp(k)*delt + tsq(k)
  1256. ENDDO
  1257. !! DO k=kts+1,kte-1
  1258. !! a(k-kts+1)=-dtz(k)*dfq(k)
  1259. !! b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))
  1260. !! c(k-kts+1)=-dtz(k)*dfq(k+1)
  1261. !! d(k-kts+1)=rp(k)*delt + tsq(k) - tsq(k)*bp(k)*delt
  1262. !! ENDDO
  1263. a(nz)=-1. !0.
  1264. b(nz)=1.
  1265. c(nz)=0.
  1266. d(nz)=0.
  1267. CALL tridiag(nz,a,b,c,d)
  1268. DO k=kts,kte
  1269. tsq(k)=d(k-kts+1)
  1270. ENDDO
  1271. ! ** Prediction of the moisture variance **
  1272. !! DO k = kts+1,kte-1
  1273. DO k = kts,kte-1
  1274. b2l = b2*0.5*( el(k+1)+el(k) )
  1275. bp(k) = 2.*qkw(k) / b2l
  1276. rp(k) = pdq(k+1) +pdq(k)
  1277. END DO
  1278. !zero gradient for qsq at bottom and top
  1279. !! a(1)=0.
  1280. !! b(1)=1.
  1281. !! c(1)=-1.
  1282. !! d(1)=0.
  1283. ! Since dfq(kts)=0.0, a(1)=0.0 and b(1)=1.+dtz(k)*dfq(k+1)+bp(k)*delt.
  1284. DO k=kts,kte-1
  1285. a(k-kts+1)=-dtz(k)*dfq(k)
  1286. b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))+bp(k)*delt
  1287. c(k-kts+1)=-dtz(k)*dfq(k+1)
  1288. d(k-kts+1)=rp(k)*delt + qsq(k)
  1289. ENDDO
  1290. !! DO k=kts+1,kte-1
  1291. !! a(k-kts+1)=-dtz(k)*dfq(k)
  1292. !! b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))
  1293. !! c(k-kts+1)=-dtz(k)*dfq(k+1)
  1294. !! d(k-kts+1)=rp(k)*delt + qsq(k) -qsq(k)*bp(k)*delt
  1295. !! ENDDO
  1296. a(nz)=-1. !0.
  1297. b(nz)=1.
  1298. c(nz)=0.
  1299. d(nz)=0.
  1300. CALL tridiag(nz,a,b,c,d)
  1301. DO k=kts,kte
  1302. qsq(k)=d(k-kts+1)
  1303. ENDDO
  1304. ! ** Prediction of the temperature-moisture covariance **
  1305. !! DO k = kts+1,kte-1
  1306. DO k = kts,kte-1
  1307. b2l = b2*0.5*( el(k+1)+el(k) )
  1308. bp(k) = 2.*qkw(k) / b2l
  1309. rp(k) = pdc(k+1) + pdc(k)
  1310. END DO
  1311. !zero gradient for tqcov at bottom and top
  1312. !! a(1)=0.
  1313. !! b(1)=1.
  1314. !! c(1)=-1.
  1315. !! d(1)=0.
  1316. ! Since dfq(kts)=0.0, a(1)=0.0 and b(1)=1.+dtz(k)*dfq(k+1)+bp(k)*delt.
  1317. DO k=kts,kte-1
  1318. a(k-kts+1)=-dtz(k)*dfq(k)
  1319. b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))+bp(k)*delt
  1320. c(k-kts+1)=-dtz(k)*dfq(k+1)
  1321. d(k-kts+1)=rp(k)*delt + cov(k)
  1322. ENDDO
  1323. !! DO k=kts+1,kte-1
  1324. !! a(k-kts+1)=-dtz(k)*dfq(k)
  1325. !! b(k-kts+1)=1.+dtz(k)*(dfq(k)+dfq(k+1))
  1326. !! c(k-kts+1)=-dtz(k)*dfq(k+1)
  1327. !! d(k-kts+1)=rp(k)*delt + cov(k) - cov(k)*bp(k)*delt
  1328. !! ENDDO
  1329. a(nz)=-1. !0.
  1330. b(nz)=1.
  1331. c(nz)=0.
  1332. d(nz)=0.
  1333. CALL tridiag(nz,a,b,c,d)
  1334. DO k=kts,kte
  1335. cov(k)=d(k-kts+1)
  1336. ENDDO
  1337. ELSE
  1338. !! DO k = kts+1,kte-1
  1339. DO k = kts,kte-1
  1340. IF ( qkw(k) .LE. 0.0 ) THEN
  1341. b2l = 0.0
  1342. ELSE
  1343. b2l = b2*0.25*( el(k+1)+el(k) )/qkw(k)
  1344. END IF
  1345. !
  1346. tsq(k) = b2l*( pdt(k+1)+pdt(k) )
  1347. qsq(k) = b2l*( pdq(k+1)+pdq(k) )
  1348. cov(k) = b2l*( pdc(k+1)+pdc(k) )
  1349. END DO
  1350. !! tsq(kts)=tsq(kts+1)
  1351. !! qsq(kts)=qsq(kts+1)
  1352. !! cov(kts)=cov(kts+1)
  1353. tsq(kte)=tsq(kte-1)
  1354. qsq(kte)=qsq(kte-1)
  1355. cov(kte)=cov(kte-1)
  1356. END IF
  1357. END SUBROUTINE mym_predict
  1358. ! ==================================================================
  1359. ! SUBROUTINE mym_condensation:
  1360. !
  1361. ! Input variables: see subroutine mym_initialize and turbulence
  1362. ! pi (mx,my,nz) : Perturbation of the Exner function (J/kg K)
  1363. ! defined on the walls of the grid boxes
  1364. ! This is usually computed by integrating
  1365. ! d(pi)/dz = h*g*tv/tref**2
  1366. ! from the upper boundary, where tv is the
  1367. ! virtual potential temperature minus tref.
  1368. !
  1369. ! Output variables: see subroutine mym_initialize
  1370. ! cld(mx,my,nz) : Cloud fraction
  1371. !
  1372. ! Work arrays:
  1373. ! qmq(mx,my,nz) : Q_w-Q_{sl}, where Q_{sl} is the saturation
  1374. ! specific humidity at T=Tl
  1375. ! alp(mx,my,nz) : Functions in the condensation process
  1376. ! bet(mx,my,nz) : ditto
  1377. ! sgm(mx,my,nz) : Combined standard deviation sigma_s
  1378. ! multiplied by 2/alp
  1379. !
  1380. ! # qmq, alp, bet and sgm are allowed to share storage units with
  1381. ! any four of other work arrays for saving memory.
  1382. !
  1383. ! # Results are sensitive particularly to values of cp and rd.
  1384. ! Set these values to those adopted by you.
  1385. !
  1386. !-------------------------------------------------------------------
  1387. SUBROUTINE mym_condensation (kts,kte, &
  1388. & dz, &
  1389. & thl, qw, &
  1390. & p,exner, &
  1391. & tsq, qsq, cov, &
  1392. & Vt, Vq)
  1393. !-------------------------------------------------------------------
  1394. INTEGER, INTENT(IN) :: kts,kte
  1395. REAL, DIMENSION(kts:kte), INTENT(IN) :: dz
  1396. REAL, DIMENSION(kts:kte), INTENT(IN) :: p,exner, thl, qw, &
  1397. &tsq, qsq, cov
  1398. REAL, DIMENSION(kts:kte), INTENT(OUT) :: vt,vq
  1399. REAL, DIMENSION(kts:kte) :: qmq,alp,bet,sgm,ql,cld
  1400. DOUBLE PRECISION :: t3sq, r3sq, c3sq
  1401. !
  1402. REAL :: p2a,t,esl,qsl,dqsl,q1,cld0,eq1,qll,&
  1403. &q2p,pt,rac,qt
  1404. INTEGER :: i,j,k
  1405. REAL :: erf
  1406. ! Note: kte needs to be larger than kts, i.e., kte >= kts+1.
  1407. DO k = kts,kte-1
  1408. p2a = exner(k)
  1409. t = thl(k)*p2a
  1410. !x if ( ct .gt. 0.0 ) then
  1411. ! a = 17.27
  1412. ! b = 237.3
  1413. !x else
  1414. !x a = 21.87
  1415. !x b = 265.5
  1416. !x end if
  1417. !
  1418. ! ** 3.8 = 0.622*6.11 (hPa) **
  1419. esl=svp11*EXP(svp2*(t-svpt0)/(t-svp3))
  1420. qsl=ep_2*esl/(p(k)-ep_3*esl)
  1421. ! qsl = 3.8*EXP( a*ct/( b+ct ) ) / ( 1000.0*p2a**rk )
  1422. dqsl = qsl*ep_2*ev/( rd*t**2 )
  1423. !
  1424. qmq(k) = qw(k) -qsl
  1425. alp(k) = 1.0/( 1.0+dqsl*xlvcp )
  1426. bet(k) = dqsl*p2a
  1427. !
  1428. t3sq = MAX( tsq(k), 0.0 )
  1429. r3sq = MAX( qsq(k), 0.0 )
  1430. c3sq = cov(k)
  1431. c3sq = SIGN( MIN( ABS(c3sq), SQRT(t3sq*r3sq) ), c3sq )
  1432. !
  1433. r3sq = r3sq +bet(k)**2*t3sq -2.0*bet(k)*c3sq
  1434. sgm(k) = SQRT( MAX( r3sq, 1.0d-10 ) )
  1435. END DO
  1436. !
  1437. DO k = kts,kte-1
  1438. q1 = qmq(k) / sgm(k)
  1439. cld0 = 0.5*( 1.0+erf( q1*rr2 ) )
  1440. ! q1=0.
  1441. ! cld0=0.
  1442. eq1 = rrp*EXP( -0.5*q1*q1 )
  1443. qll = MAX( cld0*q1 + eq1, 0.0 )
  1444. cld(k) = cld0
  1445. ql (k) = alp(k)*sgm(k)*qll
  1446. !
  1447. q2p = xlvcp/exner( k )
  1448. pt = thl(k) +q2p*ql(k)
  1449. qt = 1.0 +p608*qw(k) -(1.+p608)*ql(k)
  1450. rac = alp(k)*( cld0-qll*eq1 )*( q2p*qt-(1.+p608)*pt )
  1451. !
  1452. vt (k) = qt-1.0 -rac*bet(k)
  1453. vq (k) = p608*pt-tv0 +rac
  1454. END DO
  1455. !
  1456. cld(kte) = cld(kte-1)
  1457. ql(kte) = ql(kte-1)
  1458. vt(kte) = vt(kte-1)
  1459. vq(kte) = vq(kte-1)
  1460. RETURN
  1461. END SUBROUTINE mym_condensation
  1462. ! ==================================================================
  1463. SUBROUTINE mynn_tendencies(kts,kte,&
  1464. &levflag,grav_settling,&
  1465. &delt,&
  1466. &dz,&
  1467. &u,v,th,qv,qc,p,exner,&
  1468. &thl,sqv,sqc,sqw,&
  1469. &ust,flt,flq,wspd,qcg,&
  1470. &tsq,qsq,cov,&
  1471. &tcd,qcd,&
  1472. &dfm,dfh,dfq,&
  1473. &Du,Dv,Dth,Dqv,Dqc)
  1474. !-------------------------------------------------------------------
  1475. INTEGER, INTENT(in) :: kts,kte
  1476. INTEGER, INTENT(in) :: grav_settling,levflag
  1477. !! grav_settling = 1 for gravitational settling of droplets
  1478. !! grav_settling = 0 otherwise
  1479. ! thl - liquid water potential temperature
  1480. ! qw - total water
  1481. ! dfm,dfh,dfq - as above
  1482. ! flt - surface flux of thl
  1483. ! flq - surface flux of qw
  1484. REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,th,qv,qc,p,exner,&
  1485. &dfm,dfh,dfq,dz,tsq,qsq,cov,tcd,qcd
  1486. REAL, DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc
  1487. REAL, DIMENSION(kts:kte), INTENT(out) :: du,dv,dth,dqv,dqc
  1488. REAL, INTENT(IN) :: delt,ust,flt,flq,wspd,qcg
  1489. ! REAL, INTENT(IN) :: delt,ust,flt,flq,qcg,&
  1490. ! &gradu_top,gradv_top,gradth_top,gradqv_top
  1491. !local vars
  1492. REAL, DIMENSION(kts:kte) :: dtz,vt,vq
  1493. REAL, DIMENSION(1:kte-kts+1) :: a,b,c,d
  1494. REAL :: rhs,gfluxm,gfluxp,dztop
  1495. INTEGER :: k,kk,nz
  1496. nz=kte-kts+1
  1497. dztop=.5*(dz(kte)+dz(kte-1))
  1498. DO k=kts,kte
  1499. dtz(k)=delt/dz(k)
  1500. ENDDO
  1501. !! u
  1502. k=kts
  1503. a(1)=0.
  1504. b(1)=1.+dtz(k)*(dfm(k+1)+ust**2/wspd)
  1505. c(1)=-dtz(k)*dfm(k+1)
  1506. d(1)=u(k)
  1507. !! a(1)=0.
  1508. !! b(1)=1.+dtz(k)*dfm(k+1)
  1509. !! c(1)=-dtz(k)*dfm(k+1)
  1510. !! d(1)=u(k)*(1.-ust**2/wspd*dtz(k))
  1511. DO k=kts+1,kte-1
  1512. kk=k-kts+1
  1513. a(kk)=-dtz(k)*dfm(k)
  1514. b(kk)=1.+dtz(k)*(dfm(k)+dfm(k+1))
  1515. c(kk)=-dtz(k)*dfm(k+1)
  1516. d(kk)=u(k)
  1517. ENDDO
  1518. !! no flux at the top
  1519. ! a(nz)=-1.
  1520. ! b(nz)=1.
  1521. ! c(nz)=0.
  1522. ! d(nz)=0.
  1523. !! specified gradient at the top
  1524. ! a(nz)=-1.
  1525. ! b(nz)=1.
  1526. ! c(nz)=0.
  1527. ! d(nz)=gradu_top*dztop
  1528. !! prescribed value
  1529. a(nz)=0
  1530. b(nz)=1.
  1531. c(nz)=0.
  1532. d(nz)=u(kte)
  1533. CALL tridiag(nz,a,b,c,d)
  1534. DO k=kts,kte
  1535. du(k)=(d(k-kts+1)-u(k))/delt
  1536. ENDDO
  1537. !! v
  1538. k=kts
  1539. a(1)=0.
  1540. b(1)=1.+dtz(k)*(dfm(k+1)+ust**2/wspd)
  1541. c(1)=-dtz(k)*dfm(k+1)
  1542. d(1)=v(k)
  1543. !! a(1)=0.
  1544. !! b(1)=1.+dtz(k)*dfm(k+1)
  1545. !! c(1)=-dtz(k)*dfm(k+1)
  1546. !! d(1)=v(k)*(1.-ust**2/wspd*dtz(k))
  1547. DO k=kts+1,kte-1
  1548. kk=k-kts+1
  1549. a(kk)=-dtz(k)*dfm(k)
  1550. b(kk)=1.+dtz(k)*(dfm(k)+dfm(k+1))
  1551. c(kk)=-dtz(k)*dfm(k+1)
  1552. d(kk)=v(k)
  1553. ENDDO
  1554. !! no flux at the top
  1555. ! a(nz)=-1.
  1556. ! b(nz)=1.
  1557. ! c(nz)=0.
  1558. ! d(nz)=0.
  1559. !! specified gradient at the top
  1560. ! a(nz)=-1.
  1561. ! b(nz)=1.
  1562. ! c(nz)=0.
  1563. ! d(nz)=gradv_top*dztop
  1564. !! prescribed value
  1565. a(nz)=0
  1566. b(nz)=1.
  1567. c(nz)=0.
  1568. d(nz)=v(kte)
  1569. CALL tridiag(nz,a,b,c,d)
  1570. DO k=kts,kte
  1571. dv(k)=(d(k-kts+1)-v(k))/delt
  1572. ENDDO
  1573. !! thl
  1574. k=kts
  1575. a(1)=0.
  1576. b(1)=1.+dtz(k)*dfh(k+1)
  1577. c(1)=-dtz(k)*dfh(k+1)
  1578. ! if qcg not used then assume constant flux in the surface layer
  1579. IF (qcg < qcgmin) THEN
  1580. IF (sqc(k) > qcgmin) THEN
  1581. gfluxm=grav_settling*gno*sqc(k)**gpw
  1582. ELSE
  1583. gfluxm=0.
  1584. ENDIF
  1585. ELSE
  1586. gfluxm=grav_settling*gno*(qcg/(1.+qcg))**gpw
  1587. ENDIF
  1588. IF (.5*(sqc(k+1)+sqc(k)) > qcgmin) THEN
  1589. gfluxp=grav_settling*gno*(.5*(sqc(k+1)+sqc(k)))**gpw
  1590. ELSE
  1591. gfluxp=0.
  1592. ENDIF
  1593. rhs=-xlvcp/exner(k)&
  1594. &*( &
  1595. &(gfluxp - gfluxm)/dz(k)&
  1596. & ) + tcd(k)
  1597. d(1)=thl(k)+dtz(k)*flt+rhs*delt
  1598. DO k=kts+1,kte-1
  1599. kk=k-kts+1
  1600. a(kk)=-dtz(k)*dfh(k)
  1601. b(kk)=1.+dtz(k)*(dfh(k)+dfh(k+1))
  1602. c(kk)=-dtz(k)*dfh(k+1)
  1603. IF (.5*(sqc(k+1)+sqc(k)) > qcgmin) THEN
  1604. gfluxp=grav_settling*gno*(.5*(sqc(k+1)+sqc(k)))**gpw
  1605. ELSE
  1606. gfluxp=0.
  1607. ENDIF
  1608. IF (.5*(sqc(k-1)+sqc(k)) > qcgmin) THEN
  1609. gfluxm=grav_settling*gno*(.5*(sqc(k-1)+sqc(k)))**gpw
  1610. ELSE
  1611. gfluxm=0.
  1612. ENDIF
  1613. rhs=-xlvcp/exner(k)&
  1614. &*( &
  1615. &(gfluxp - gfluxm)/dz(k)&
  1616. & ) + tcd(k)
  1617. d(kk)=thl(k)+rhs*delt
  1618. ENDDO
  1619. !! no flux at the top
  1620. ! a(nz)=-1.
  1621. ! b(nz)=1.
  1622. ! c(nz)=0.
  1623. ! d(nz)=0.
  1624. !! specified gradient at the top
  1625. !assume gradthl_top=gradth_top
  1626. ! a(nz)=-1.
  1627. ! b(nz)=1.
  1628. ! c(nz)=0.
  1629. ! d(nz)=gradth_top*dztop
  1630. !! prescribed value
  1631. a(nz)=0.
  1632. b(nz)=1.
  1633. c(nz)=0.
  1634. d(nz)=thl(kte)
  1635. CALL tridiag(nz,a,b,c,d)
  1636. DO k=kts,kte
  1637. thl(k)=d(k-kts+1)
  1638. ENDDO
  1639. !! total water
  1640. k=kts
  1641. a(1)=0.
  1642. b(1)=1.+dtz(k)*dfh(k+1)
  1643. c(1)=-dtz(k)*dfh(k+1)
  1644. IF (qcg < qcgmin) THEN
  1645. IF (sqc(k) > qcgmin) THEN
  1646. gfluxm=grav_settling*gno*sqc(k)**gpw
  1647. ELSE
  1648. gfluxm=0.
  1649. ENDIF
  1650. ELSE
  1651. gfluxm=grav_settling*gno*(qcg/(1.+qcg))**gpw
  1652. ENDIF
  1653. IF (.5*(sqc(k+1)+sqc(k)) > qcgmin) THEN
  1654. gfluxp=grav_settling*gno*(.5*(sqc(k+1)+sqc(k)))**gpw
  1655. ELSE
  1656. gfluxp=0.
  1657. ENDIF
  1658. rhs=&
  1659. &( &
  1660. &(gfluxp - gfluxm)/dz(k)&
  1661. & ) + qcd(k)
  1662. d(1)=sqw(k)+dtz(k)*flq+rhs*delt
  1663. DO k=kts+1,kte-1
  1664. kk=k-kts+1
  1665. a(kk)=-dtz(k)*dfh(k)
  1666. b(kk)=1.+dtz(k)*(dfh(k)+dfh(k+1))
  1667. c(kk)=-dtz(k)*dfh(k+1)
  1668. IF (.5*(sqc(k+1)+sqc(k)) > qcgmin) THEN
  1669. gfluxp=grav_settling*gno*(.5*(sqc(k+1)+sqc(k)))**gpw
  1670. ELSE
  1671. gfluxp=0.
  1672. ENDIF
  1673. IF (.5*(sqc(k-1)+sqc(k)) > qcgmin) THEN
  1674. gfluxm=grav_settling*gno*(.5*(sqc(k-1)+sqc(k)))**gpw
  1675. ELSE
  1676. gfluxm=0.
  1677. ENDIF
  1678. rhs=&
  1679. &( &
  1680. &(gfluxp - gfluxm)/dz(k)&
  1681. & ) + qcd(k)
  1682. d(kk)=sqw(k) + rhs*delt
  1683. ENDDO
  1684. !! no flux at the top
  1685. ! a(nz)=-1.
  1686. ! b(nz)=1.
  1687. ! c(nz)=0.
  1688. ! d(nz)=0.
  1689. !! specified gradient at the top
  1690. !assume gradqw_top=gradqv_top
  1691. ! a(nz)=-1.
  1692. ! b(nz)=1.
  1693. ! c(nz)=0.
  1694. ! d(nz)=gradqv_top*dztop
  1695. !! prescribed value
  1696. a(nz)=0.
  1697. b(nz)=1.
  1698. c(nz)=0.
  1699. d(nz)=sqw(kte)
  1700. CALL tridiag(nz,a,b,c,d)
  1701. !convert to mixing ratios for wrf
  1702. DO k=kts,kte
  1703. sqw(k)=d(k-kts+1)
  1704. sqv(k)=sqw(k)-sqc(k)
  1705. Dqv(k)=(sqv(k)/(1.-sqv(k))-qv(k))/delt
  1706. ! Dqc(k)=(sqc(k)/(1.-sqc(k))-qc(k))/delt
  1707. Dqc(k)=0.
  1708. Dth(k)=(thl(k)+xlvcp/exner(k)*sqc(k)-th(k))/delt
  1709. ENDDO
  1710. END SUBROUTINE mynn_tendencies
  1711. ! ==================================================================
  1712. SUBROUTINE retrieve_exchange_coeffs(kts,kte,&
  1713. &dfm,dfh,dfq,dz,&
  1714. &K_m,K_h,K_q)
  1715. !-------------------------------------------------------------------
  1716. INTEGER , INTENT(in) :: kts,kte
  1717. REAL, DIMENSION(KtS:KtE), INTENT(in) :: dz,dfm,dfh,dfq
  1718. REAL, DIMENSION(KtS:KtE), INTENT(out) :: &
  1719. &K_m, K_h, K_q
  1720. INTEGER :: k
  1721. REAL :: dzk
  1722. K_m(kts)=0.
  1723. K_h(kts)=0.
  1724. K_q(kts)=0.
  1725. DO k=kts+1,kte
  1726. dzk = 0.5 *( dz(k)+dz(k-1) )
  1727. K_m(k)=dfm(k)*dzk
  1728. K_h(k)=dfh(k)*dzk
  1729. K_q(k)=dfq(k)*dzk
  1730. ENDDO
  1731. END SUBROUTINE retrieve_exchange_coeffs
  1732. ! ==================================================================
  1733. SUBROUTINE tridiag(n,a,b,c,d)
  1734. !! to solve system of linear eqs on tridiagonal matrix n times n
  1735. !! after Peaceman and Rachford, 1955
  1736. !! a,b,c,d - are vectors of order n
  1737. !! a,b,c - are coefficients on the LHS
  1738. !! d - is initially RHS on the output becomes a solution vector
  1739. !-------------------------------------------------------------------
  1740. INTEGER, INTENT(in):: n
  1741. REAL, DIMENSION(n), INTENT(in) :: a,b
  1742. REAL, DIMENSION(n), INTENT(inout) :: c,d
  1743. INTEGER :: i
  1744. REAL :: p
  1745. REAL, DIMENSION(n) :: q
  1746. c(n)=0.
  1747. q(1)=-c(1)/b(1)
  1748. d(1)=d(1)/b(1)
  1749. DO i=2,n
  1750. p=1./(b(i)+a(i)*q(i-1))
  1751. q(i)=-c(i)*p
  1752. d(i)=(d(i)-a(i)*d(i-1))*p
  1753. ENDDO
  1754. DO i=n-1,1,-1
  1755. d(i)=d(i)+q(i)*d(i+1)
  1756. ENDDO
  1757. END SUBROUTINE tridiag
  1758. ! ==================================================================
  1759. SUBROUTINE mynn_bl_driver(&
  1760. &initflag,&
  1761. &grav_settling,&
  1762. &delt,&
  1763. &dz,&
  1764. &u,v,th,qv,qc,&
  1765. &p,exner,rho,&
  1766. &xland,ts,qsfc,qcg,ps,&
  1767. &ust,ch,hfx,qfx,rmol,wspd,&
  1768. &Qke,Tsq,Qsq,Cov,&
  1769. &Du,Dv,Dth,&
  1770. &Dqv,Dqc,&
  1771. ! &K_m,K_h,K_q&
  1772. &K_h,k_m,&
  1773. &Pblh&
  1774. !JOE-added for extra ouput
  1775. &,el_mynn&
  1776. !JOE-end
  1777. !JOE-TKE-BUDGET
  1778. &,dqke,qWT,qSHEAR,qBUOY,qDISS&
  1779. !JOE-end
  1780. &,IDS,IDE,JDS,JDE,KDS,KDE &
  1781. &,IMS,IME,JMS,JME,KMS,KME &
  1782. &,ITS,ITE,JTS,JTE,KTS,KTE)
  1783. !-------------------------------------------------------------------
  1784. INTEGER, INTENT(in) :: initflag
  1785. INTEGER, INTENT(in) :: grav_settling
  1786. INTEGER,INTENT(IN) :: &
  1787. & IDS,IDE,JDS,JDE,KDS,KDE &
  1788. &,IMS,IME,JMS,JME,KMS,KME &
  1789. &,ITS,ITE,JTS,JTE,KTS,KTE
  1790. ! initflag > 0 for TRUE
  1791. ! else for FALSE
  1792. ! levflag : <>3; Level 2.5
  1793. ! = 3; Level 3
  1794. ! grav_settling = 1 when gravitational settling accounted for
  1795. ! grav_settling = 0 when gravitational settling NOT accounted for
  1796. REAL, INTENT(in) :: delt
  1797. REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(in) :: dz,&
  1798. &u,v,th,qv,qc,p,exner,rho
  1799. REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(in) :: xland,ust,&
  1800. &ch,rmol,ts,qsfc,qcg,ps,hfx,qfx, wspd
  1801. !
  1802. REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(inout) :: &
  1803. &Qke,Tsq,Qsq,Cov
  1804. REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(out) :: &
  1805. &Du,Dv,Dth,Dqv,Dqc
  1806. REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(out) :: &
  1807. &K_h,K_m
  1808. REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(inout) :: &
  1809. &Pblh
  1810. !JOE-added for extra output
  1811. REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(inout) :: &
  1812. &el_mynn
  1813. !JOE-end
  1814. !JOE-TKE-BUDGET
  1815. REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME), INTENT(inout) :: &
  1816. &qWT,qSHEAR,qBUOY,qDISS,dqke
  1817. !JOE-end
  1818. !local vars
  1819. INTEGER :: ITF,JTF,KTF
  1820. INTEGER :: i,j,k
  1821. REAL, DIMENSION(KMS:KME) :: thl,sqv,sqc,sqw,&
  1822. &El, Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, Vt, Vq
  1823. REAL, DIMENSION(IMS:IME,KMS:KME,JMS:JME) :: K_q
  1824. REAL, DIMENSION(KMS:KME+1) :: zw
  1825. REAL :: cpm,sqcg,flt,flq,pmz,phh,exnerg,zet
  1826. REAL, DIMENSION(KMS:KME) :: thetav
  1827. INTEGER, SAVE :: levflag
  1828. JTF=MIN0(JTE,JDE-1)
  1829. ITF=MIN0(ITE,IDE-1)
  1830. KTF=MIN0(KTE,KDE-1)
  1831. levflag=mynn_level
  1832. IF (initflag > 0) THEN
  1833. DO j=JTS,JTF
  1834. DO i=ITS,ITF
  1835. DO k=KTS,KTF
  1836. sqv(k)=qv(i,k,j)/(1.+qv(i,k,j))
  1837. thl(k)=th(i,k,j)
  1838. !JOE-for PBLH
  1839. thetav(k)=th(i,k,j)*(1.+0.61*qv(i,k,j))
  1840. !JOE-end
  1841. IF (k==kts) THEN
  1842. zw(k)=0.
  1843. ELSE
  1844. zw(k)=zw(k-1)+dz(i,k-1,j)
  1845. ENDIF
  1846. k_m(i,k,j)=0.
  1847. k_h(i,k,j)=0.
  1848. k_q(i,k,j)=0.
  1849. !JOE-added for extra output
  1850. el_mynn(i,k,j)=0.
  1851. !JOE-end
  1852. !JOE-TKE-BUDGET
  1853. qWT(i,k,j)=0.
  1854. qSHEAR(i,k,j)=0.
  1855. qBUOY(i,k,j)=0.
  1856. qDISS(i,k,j)=0.
  1857. dqke(i,k,j)=0.
  1858. !JOE-end
  1859. ENDDO
  1860. zw(ktf+1)=zw(ktf)+dz(i,ktf,j)
  1861. !JOE-PBLH begin
  1862. CALL GET_PBLH(KTS,KTE,PBLH(i,j),thetav(kts:kte),&
  1863. & Qke(i,kts:kte,j),zw(kts:kte+1),dz(i,kts:kte,j),xland(i,j))
  1864. !JOE-PBLH end
  1865. CALL mym_initialize ( kts,kte,&
  1866. &dz(i,kts:kte,j), zw(kts:kte+1), &
  1867. &u(i,kts:kte,j), v(i,kts:kte,j), &
  1868. &thl(kts:kte), sqv(kts:kte),&
  1869. !JOE-BouLac mod
  1870. &PBLH(i,j),th(i,kts:kte,j),&
  1871. !JOE-end
  1872. &ust(i,j), rmol(i,j),&
  1873. &Qke(i,kts:kte,j), Tsq(i,kts:kte,j), &
  1874. &Qsq(i,kts:kte,j), Cov(i,kts:kte,j))
  1875. ENDDO
  1876. ENDDO
  1877. ENDIF ! end initflag
  1878. DO j=JTS,JTF
  1879. DO i=ITS,ITF
  1880. DO k=KTS,KTF
  1881. sqv(k)=qv(i,k,j)/(1.+qv(i,k,j))
  1882. sqc(k)=qc(i,k,j)/(1.+qc(i,k,j))
  1883. sqw(k)=sqv(k)+sqc(k)
  1884. thl(k)=th(i,k,j)-xlvcp/exner(i,k,j)*sqc(k)
  1885. !JOE-for PBLH
  1886. thetav(k)=th(i,k,j)*(1.+0.61*qv(i,k,j))
  1887. !JOE-end
  1888. IF (k==kts) THEN
  1889. zw(k)=0.
  1890. ELSE
  1891. zw(k)=zw(k-1)+dz(i,k-1,j)
  1892. ENDIF
  1893. ENDDO
  1894. zw(ktf+1)=zw(ktf)+dz(i,ktf,j)
  1895. !JOE-PBLH begin
  1896. CALL GET_PBLH(KTS,KTE,PBLH(i,j),thetav(kts:kte),&
  1897. & Qke(i,kts:kte,j),zw(kts:kte+1),dz(i,kts:kte,j),xland(i,j))
  1898. !JOE-PBLH end
  1899. sqcg=qcg(i,j)/(1.+qcg(i,j))
  1900. cpm=cp*(1.+0.8*qv(i,kts,j))
  1901. ! The exchange coefficient for cloud water is assumed to be the same as
  1902. ! that for heat. CH is multiplied by WSPD. See module_sf_mynn.F
  1903. exnerg=(ps(i,j)/p1000mb)**rcp
  1904. flt = hfx(i,j)/( rho(i,kts,j)*cpm ) &
  1905. +xlvcp*ch(i,j)*(sqc(kts)/exner(i,kts,j)-sqcg/exnerg)
  1906. flq = qfx(i,j)/ rho(i,kts,j) &
  1907. -ch(i,j)*(sqc(kts) -sqcg )
  1908. !!!!!
  1909. zet = 0.5*dz(i,kts,j)*rmol(i,j)
  1910. if ( zet >= 0.0 ) then
  1911. pmz = 1.0 + (cphm_st-1.0) * zet
  1912. phh = 1.0 + cphh_st * zet
  1913. else
  1914. pmz = 1.0/ (1.0-cphm_unst*zet)**0.25 - zet
  1915. phh = 1.0/SQRT(1.0-cphh_unst*zet)
  1916. end if
  1917. !!!!!
  1918. CALL mym_condensation ( kts,kte,&
  1919. &dz(i,kts:kte,j), &
  1920. &thl(kts:kte), sqw(kts:kte), &
  1921. &p(i,kts:kte,j),exner(i,kts:kte,j), &
  1922. &tsq(i,kts:kte,j), qsq(i,kts:kte,j), cov(i,kts:kte,j), &
  1923. &Vt(kts:kte), Vq(kts:kte))
  1924. CALL mym_turbulence ( kts,kte,&
  1925. &levflag, &
  1926. &dz(i,kts:kte,j), zw(kts:kte+1), &
  1927. &u(i,kts:kte,j), v(i,kts:kte,j), thl(kts:kte),&
  1928. &sqc(kts:kte), sqw(kts:kte), &
  1929. &qke(i,kts:kte,j), tsq(i,kts:kte,j), &
  1930. &qsq(i,kts:kte,j), cov(i,kts:kte,j), &
  1931. &vt(kts:kte), vq(kts:kte),&
  1932. &rmol(i,j), flt, flq, &
  1933. !JOE-BouLac mod
  1934. &PBLH(i,j),th(i,kts:kte,j),&
  1935. !JOE-end
  1936. &el_mynn(i,kts:kte,j), &
  1937. &Dfm(kts:kte),Dfh(kts:kte),Dfq(kts:kte), &
  1938. &Tcd(kts:kte),Qcd(kts:kte),Pdk(kts:kte), &
  1939. &Pdt(kts:kte),Pdq(kts:kte),Pdc(kts:kte),&
  1940. !JOE-TKE-BUDGET
  1941. &qWT(i,kts:kte,j),qSHEAR(i,kts:kte,j),&
  1942. &qBUOY(i,kts:kte,j),qDISS(i,kts:kte,j))
  1943. !JOE-end
  1944. CALL mym_predict (kts,kte,&
  1945. &levflag, &
  1946. &delt,&
  1947. &dz(i,kts:kte,j), &
  1948. &ust(i,j), flt, flq, pmz, phh, &
  1949. &el_mynn(i,kts:kte,j), dfq(kts:kte), pdk(kts:kte), &
  1950. &pdt(kts:kte), pdq(kts:kte), pdc(kts:kte),&
  1951. &Qke(i,kts:kte,j), Tsq(i,kts:kte,j), &
  1952. &Qsq(i,kts:kte,j), Cov(i,kts:kte,j), &
  1953. !JOE-TKE-BUDGET
  1954. &dqke(i,kts:kte,j))
  1955. !JOE-end
  1956. CALL mynn_tendencies(kts,kte,&
  1957. &levflag,grav_settling,&
  1958. &delt,&
  1959. &dz(i,kts:kte,j),&
  1960. &u(i,kts:kte,j),v(i,kts:kte,j),&
  1961. &th(i,kts:kte,j),qv(i,kts:kte,j),qc(i,kts:kte,j),&
  1962. &p(i,kts:kte,j),exner(i,kts:kte,j),&
  1963. &thl(kts:kte),sqv(kts:kte),sqc(kts:kte),sqw(kts:kte),&
  1964. &ust(i,j),flt,flq,wspd(i,j),qcg(i,j),&
  1965. &tsq(i,kts:kte,j),qsq(i,kts:kte,j),cov(i,kts:kte,j),&
  1966. &tcd(kts:kte),qcd(kts:kte),&
  1967. &dfm(kts:kte),dfh(kts:kte),dfq(kts:kte),&
  1968. &Du(i,kts:kte,j),Dv(i,kts:kte,j),Dth(i,kts:kte,j),&
  1969. &Dqv(i,kts:kte,j),Dqc(i,kts:kte,j))
  1970. CALL retrieve_exchange_coeffs(kts,kte,&
  1971. &dfm(kts:kte),dfh(kts:kte),dfq(kts:kte),dz(i,kts:kte,j),&
  1972. &K_m(i,kts:kte,j),K_h(i,kts:kte,j),K_q(i,kts:kte,j))
  1973. DO k=KTS,KTF
  1974. qWT(i,k,j)= qWT(i,k,j)*delt
  1975. qSHEAR(i,k,j)= qSHEAR(i,k,j)*delt
  1976. qBUOY(i,k,j)= qBUOY(i,k,j)*delt
  1977. qDISS(i,k,j)= qDISS(i,k,j)*delt
  1978. ENDDO
  1979. ENDDO
  1980. ENDDO
  1981. END SUBROUTINE mynn_bl_driver
  1982. ! ==================================================================
  1983. SUBROUTINE mynn_bl_init_driver(&
  1984. &Du,Dv,Dth,&
  1985. &Dqv,Dqc&
  1986. &,RESTART,ALLOWED_TO_READ,LEVEL&
  1987. &,IDS,IDE,JDS,JDE,KDS,KDE &
  1988. &,IMS,IME,JMS,JME,KMS,KME &
  1989. &,ITS,ITE,JTS,JTE,KTS,KTE)
  1990. !---------------------------------------------------------------
  1991. LOGICAL,INTENT(IN) :: ALLOWED_TO_READ,RESTART
  1992. INTEGER,INTENT(IN) :: LEVEL
  1993. INTEGER,INTENT(IN) :: IDS,IDE,JDS,JDE,KDS,KDE, &
  1994. & IMS,IME,JMS,JME,KMS,KME, &
  1995. & ITS,ITE,JTS,JTE,KTS,KTE
  1996. REAL,DIMENSION(IMS:IME,KMS:KME,JMS:JME),INTENT(OUT) :: &
  1997. &Du,Dv,Dth,Dqv,Dqc
  1998. INTEGER :: I,J,K,ITF,JTF,KTF
  1999. JTF=MIN0(JTE,JDE-1)
  2000. KTF=MIN0(KTE,KDE-1)
  2001. ITF=MIN0(ITE,IDE-1)
  2002. IF(.NOT.RESTART)THEN
  2003. DO J=JTS,JTF
  2004. DO K=KTS,KTF
  2005. DO I=ITS,ITF
  2006. Du(i,k,j)=0.
  2007. Dv(i,k,j)=0.
  2008. Dth(i,k,j)=0.
  2009. Dqv(i,k,j)=0.
  2010. Dqc(i,k,j)=0.
  2011. ENDDO
  2012. ENDDO
  2013. ENDDO
  2014. ENDIF
  2015. mynn_level=level
  2016. END SUBROUTINE mynn_bl_init_driver
  2017. ! ==================================================================
  2018. SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea)
  2019. !---------------------------------------------------------------
  2020. ! NOTES ON THE PBLH FORMULATION
  2021. !
  2022. !The 1.5-theta-increase method defines PBL heights as the level at
  2023. !which the potential temperature first exceeds the minimum potential
  2024. !temperature within the boundary layer by 1.5 K. When applied to
  2025. !observed temperatures, this method has been shown to produce PBL-
  2026. !height estimates that are unbiased relative to profiler-based
  2027. !estimates (Nielsen-Gammon et al. 2008). However, their study did not
  2028. !include LLJs. Banta and Pichugina (2008) show that a TKE-based
  2029. !threshold is a good estimate of the PBL height in LLJs. Therefore,
  2030. !a hybrid definition is implemented that uses both methods, weighting
  2031. !the TKE-method more during stable conditions (PBLH < 400 m).
  2032. !A variable tke threshold (TKEeps) is used since no hard-wired
  2033. !value could be found to work best in all conditions.
  2034. !---------------------------------------------------------------
  2035. INTEGER,INTENT(IN) :: KTS,KTE
  2036. REAL, INTENT(OUT) :: zi
  2037. REAL, INTENT(IN) :: landsea
  2038. REAL, DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D
  2039. REAL, DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D
  2040. !LOCAL VARS
  2041. REAL :: PBLH_TKE,qtke,qtkem1,wt,maxqke,TKEeps,minthv
  2042. REAL :: delt_thv !delta theta-v; dependent on land/sea point
  2043. REAL, PARAMETER :: sbl_lim = 200. !Theta-v PBL lower limit of trust (m).
  2044. REAL, PARAMETER :: sbl_damp = 400. !Damping range for averaging with TKE-based PBLH (m).
  2045. INTEGER :: I,J,K,kthv,ktke
  2046. !FIND MAX TKE AND MIN THETAV IN THE LOWEST 500 M
  2047. k = kts+1
  2048. kthv = 1
  2049. ktke = 1
  2050. maxqke = 0.
  2051. minthv = 9.E9
  2052. DO WHILE (zw1D(k) .LE. 500.)
  2053. qtke =MAX(Qke1D(k),0.) ! maximum QKE
  2054. IF (maxqke < qtke) then
  2055. maxqke = qtke
  2056. ktke = k
  2057. ENDIF
  2058. IF (minthv > thetav1D(k)) then
  2059. minthv = thetav1D(k)
  2060. kthv = k
  2061. ENDIF
  2062. k = k+1
  2063. ENDDO
  2064. !TKEeps = maxtke/20. = maxqke/40.
  2065. TKEeps = maxqke/40.
  2066. TKEeps = MAX(TKEeps,0.025)
  2067. TKEeps = MIN(TKEeps,0.25)
  2068. !FIND THETAV-BASED PBLH (BEST FOR DAYTIME).
  2069. zi=0.
  2070. k = kthv+1
  2071. IF((landsea-1.5).GE.0)THEN
  2072. ! WATER
  2073. delt_thv = 0.75
  2074. ELSE
  2075. ! LAND
  2076. delt_thv = 1.5
  2077. ENDIF
  2078. zi=0.
  2079. k = kthv+1
  2080. DO WHILE (zi .EQ. 0.)
  2081. IF (thetav1D(k) .GE. (minthv + delt_thv))THEN
  2082. zi = zw1D(k) - dz1D(k-1)* &
  2083. & MIN((thetav1D(k)-(minthv + delt_thv))/MAX(thetav1D(k)-thetav1D(k-1),1E-6),1.0)
  2084. ENDIF
  2085. k = k+1
  2086. IF (k .EQ. kte-1) zi = zw1D(kts+1) !EXIT SAFEGUARD
  2087. ENDDO
  2088. !print*,"IN GET_PBLH:",thsfc,zi
  2089. !FOR STABLE BOUNDARY LAYERS, USE TKE METHOD TO COMPLEMENT THE
  2090. !THETAV-BASED DEFINITION (WHEN THE THETA-V BASED PBLH IS BELOW ~0.5 KM).
  2091. !THE TANH WEIGHTING FUNCTION WILL MAKE THE TKE-BASED DEFINITION NEGLIGIBLE
  2092. !WHEN THE THETA-V-BASED DEFINITION IS ABOVE ~1 KM.
  2093. !FIND TKE-BASED PBLH (BEST FOR NOCTURNAL/STABLE CONDITIONS).
  2094. PBLH_TKE=0.
  2095. k = ktke+1
  2096. DO WHILE (PBLH_TKE .EQ. 0.)
  2097. !QKE CAN BE NEGATIVE (IF CKmod == 0)... MAKE TKE NON-NEGATIVE.
  2098. qtke =MAX(Qke1D(k)/2.,0.) ! maximum TKE
  2099. qtkem1=MAX(Qke1D(k-1)/2.,0.)
  2100. IF (qtke .LE. TKEeps) THEN
  2101. PBLH_TKE = zw1D(k) - dz1D(k-1)* &
  2102. & MIN((TKEeps-qtke)/MAX(qtkem1-qtke, 1E-6), 1.0)
  2103. !IN CASE OF NEAR ZERO TKE, SET PBLH = LOWEST LEVEL.
  2104. PBLH_TKE = MAX(PBLH_TKE,zw1D(kts+1))
  2105. !print *,"PBLH_TKE:",i,j,PBLH_TKE, Qke1D(k)/2., zw1D(kts+1)
  2106. ENDIF
  2107. k = k+1
  2108. IF (k .EQ. kte-1) PBLH_TKE = zw1D(kts+1) !EXIT SAFEGUARD
  2109. ENDDO
  2110. !BLEND THE TWO PBLH TYPES HERE:
  2111. wt=.5*TANH((zi - sbl_lim)/sbl_damp) + .5
  2112. zi=PBLH_TKE*(1.-wt) + zi*wt
  2113. END SUBROUTINE GET_PBLH
  2114. ! ==================================================================
  2115. END MODULE module_bl_mynn