PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 0ms 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

Large files files are truncated, but you can click here to view the full file

  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)

Large files files are truncated, but you can click here to view the full file