PageRenderTime 51ms CodeModel.GetById 34ms RepoModel.GetById 2ms app.codeStats 14ms

/wrfv2_fire/phys/module_mp_milbrandt2mom.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 4438 lines | 2761 code | 561 blank | 1116 comment | 341 complexity | 0d6118d58a2e2fcb63fb635577f6d68e MD5 | raw file
Possible License(s): AGPL-1.0
  1. !_______________________________________________________________________________!
  2. ! !
  3. ! This module contains the microphysics sub-driver for the 2-moment version of !
  4. ! the Milbrandt-Yau (2005, JAS) microphysics scheme, along with all associated !
  5. ! subprograms. The main subroutine, 'mp_milbrandt2mom_main', is essentially !
  6. ! directly from the RPN-CMC physics library of the Canadian GEM model. It is !
  7. ! called by the wrapper 'mp_milbrandt2mom_driver' which makes the necessary !
  8. ! adjustments to the calling parameters for the interface to WRF. !
  9. ! !
  10. ! For questions, bug reports, etc. pertaining to the scheme, or to request !
  11. ! updates to the code (before the next offical WRF release) please contact !
  12. ! Jason Milbrandt (Environment Canada) at jason.milbrandt@ec.gc.ca !
  13. ! !
  14. ! Last modified: 2011-03-02 !
  15. !_______________________________________________________________________________!
  16. module my_fncs_mod
  17. !==============================================================================!
  18. ! The following functions are used by the schemes in the multimoment package. !
  19. ! !
  20. ! Package version: 2.19.0 (internal bookkeeping) !
  21. ! Last modified : 2009-04-27 !
  22. !==============================================================================!
  23. implicit none
  24. private
  25. public :: NccnFNC,SxFNC,gamma,gammaDP,gser,gammln,gammp,cfg,gamminc
  26. contains
  27. !==============================================================================!
  28. REAL FUNCTION NccnFNC(Win,Tin,Pin,CCNtype)
  29. !---------------------------------------------------------------------------!
  30. ! This function returns number concentration (activated aerosols) as a
  31. ! function of w,T,p, based on polynomial approximations of detailed
  32. ! approach using a hypergeometric function, following Cohard and Pinty (2000a).
  33. !---------------------------------------------------------------------------!
  34. IMPLICIT NONE
  35. ! PASSING PARAMETERS:
  36. real, intent(in) :: Win, Tin, Pin
  37. integer, intent(in) :: CCNtype
  38. ! LOCAL PARAMETERS:
  39. real :: T,p,x,y,a,b,c,d,e,f,g,h,T2,T3,T4,x2,x3,x4,p2
  40. x= log10(Win*100.); x2= x*x; x3= x2*x; x4= x2*x2
  41. T= Tin - 273.15; T2= T*T; T3= T2*T; T4= T2*T2
  42. p= Pin*0.01; p2= p*p
  43. if (CCNtype==1) then !Maritime
  44. a= 1.47e-9*T4 -6.944e-8*T3 -9.933e-7*T2 +2.7278e-4*T -6.6853e-4
  45. b=-1.41e-8*T4 +6.662e-7*T3 +4.483e-6*T2 -2.0479e-3*T +4.0823e-2
  46. c= 5.12e-8*T4 -2.375e-6*T3 +4.268e-6*T2 +3.9681e-3*T -3.2356e-1
  47. d=-8.25e-8*T4 +3.629e-6*T3 -4.044e-5*T2 +2.1846e-3*T +9.1227e-1
  48. e= 5.02e-8*T4 -1.973e-6*T3 +3.944e-5*T2 -9.0734e-3*T +1.1256e0
  49. f= -1.424e-6*p2 +3.631e-3*p -1.986
  50. g= -0.0212*x4 +0.1765*x3 -0.3770*x2 -0.2200*x +1.0081
  51. h= 2.47e-6*T3 -3.654e-5*T2 +2.3327e-3*T +0.1938
  52. y= a*x4 + b*x3 + c*x2 + d*x + e + f*g*h
  53. NccnFNC= 10.**min(2.,max(0.,y)) *1.e6 ![m-3]
  54. else if (CCNtype==2) then !Continental
  55. a= 0.
  56. b= 0.
  57. c=-2.112e-9*T4 +3.9836e-8*T3 +2.3703e-6*T2 -1.4542e-4*T -0.0698
  58. d=-4.210e-8*T4 +5.5745e-7*T3 +1.8460e-5*T2 +9.6078e-4*T +0.7120
  59. e= 1.434e-7*T4 -1.6455e-6*T3 -4.3334e-5*T2 -7.6720e-3*T +1.0056
  60. f= 1.340e-6*p2 -3.5114e-3*p +1.9453
  61. g= 4.226e-3*x4 -5.6012e-3*x3 -8.7846e-2*x2 +2.7435e-2*x +0.9932
  62. h= 5.811e-9*T4 +1.5589e-7*T3 -3.8623e-5*T2 +1.4471e-3*T +0.1496
  63. y= a*x4 +b*x3 +c*x2 + d*x + e + (f*g*h)
  64. NccnFNC= 10.**max(0.,y) *1.e6
  65. else
  66. print*, '*** STOPPED in MODULE ### NccnFNC *** '
  67. print*, ' Parameter CCNtype incorrectly specified'
  68. stop
  69. endif
  70. END FUNCTION NccnFNC
  71. !======================================================================!
  72. real FUNCTION SxFNC(Win,Tin,Pin,Qsw,Qsi,CCNtype,WRT)
  73. !---------------------------------------------------------------------------!
  74. ! This function returns the peak supersaturation achieved during ascent with
  75. ! activation of CCN aerosols as a function of w,T,p, based on polynomial
  76. ! approximations of detailed approach using a hypergeometric function,
  77. ! following Cohard and Pinty (2000a).
  78. !---------------------------------------------------------------------------!
  79. IMPLICIT NONE
  80. ! PASSING PARAMETERS:
  81. integer, intent(IN) :: WRT
  82. integer, intent(IN) :: CCNtype
  83. real, intent(IN) :: Win, Tin, Pin, Qsw, Qsi
  84. ! LOCAL PARAMETERS:
  85. real :: Si,Sw,Qv,T,p,x,a,b,c,d,f,g,h,Pcorr,T2corr,T2,T3,T4,x2,x3,x4,p2
  86. real, parameter :: TRPL= 273.15
  87. x= log10(max(Win,1.e-20)*100.); x2= x*x; x3= x2*x; x4= x2*x2
  88. T= Tin; T2= T*T; T3= T2*T; T4= T2*T2
  89. p= Pin*0.01; p2= p*p
  90. if (CCNtype==1) then !Maritime
  91. a= -5.109e-7*T4 -3.996e-5*T3 -1.066e-3*T2 -1.273e-2*T +0.0659
  92. b= 2.014e-6*T4 +1.583e-4*T3 +4.356e-3*T2 +4.943e-2*T -0.1538
  93. c= -2.037e-6*T4 -1.625e-4*T3 -4.541e-3*T2 -5.118e-2*T +0.1428
  94. d= 3.812e-7*T4 +3.065e-5*T3 +8.795e-4*T2 +9.440e-3*T +6.14e-3
  95. f= -2.012e-6*p2 + 4.1913e-3*p - 1.785e0
  96. g= 2.832e-1*x3 -5.6990e-1*x2 +5.1105e-1*x -4.1747e-4
  97. h= 1.173e-6*T3 +3.2174e-5*T2 -6.8832e-4*T +6.7888e-2
  98. Pcorr= f*g*h
  99. T2corr= 0.9581-4.449e-3*T-2.016e-4*T2-3.307e-6*T3-1.725e-8*T4
  100. else if (CCNtype==2) then !Continental [computed for -35<T<-5C]
  101. a= 3.80e-5*T2 +1.65e-4*T +9.88e-2
  102. b= -7.38e-5*T2 -2.53e-3*T -3.23e-1
  103. c= 8.39e-5*T2 +3.96e-3*T +3.50e-1
  104. d= -1.88e-6*T2 -1.33e-3*T -3.73e-2
  105. f= -1.9761e-6*p2 + 4.1473e-3*p - 1.771e0
  106. g= 0.1539*x4 -0.5575*x3 +0.9262*x2 -0.3498*x -0.1293
  107. h=-8.035e-9*T4+3.162e-7*T3+1.029e-5*T2-5.931e-4*T+5.62e-2
  108. Pcorr= f*g*h
  109. T2corr= 0.98888-5.0525e-4*T-1.7598e-5*T2-8.3308e-8*T3
  110. else
  111. print*, '*** STOPPED in MODULE ### SxFNC *** '
  112. print*, ' Parameter CCNtype incorrectly specified'
  113. stop
  114. endif
  115. Sw= (a*x3 + b*x2 +c*x + d) + Pcorr
  116. Sw= 1. + 0.01*Sw
  117. Qv= Qsw*Sw
  118. Si= Qv/Qsi
  119. Si= Si*T2corr
  120. if (WRT.eq.1) then
  121. SxFNC= Sw
  122. else
  123. SxFNC= Si
  124. endif
  125. if (Win.le.0.) SxFNC= 1.
  126. END function SxFNC
  127. !======================================================================!
  128. real FUNCTION gamma(xx)
  129. ! Modified from "Numerical Recipes"
  130. IMPLICIT NONE
  131. ! PASSING PARAMETERS:
  132. real, intent(IN) :: xx
  133. ! LOCAL PARAMETERS:
  134. integer :: j
  135. real*8 :: ser,stp,tmp,x,y,cof(6),gammadp
  136. SAVE cof,stp
  137. DATA cof,stp/76.18009172947146d0,-86.50532032941677d0, &
  138. 24.01409824083091d0,-1.231739572450155d0,.1208650973866179d-2, &
  139. -.5395239384953d-5,2.5066282746310005d0/
  140. x=dble(xx)
  141. y=x
  142. tmp=x+5.5d0
  143. tmp=(x+0.5d0)*log(tmp)-tmp
  144. ser=1.000000000190015d0
  145. ! do j=1,6 !original
  146. do j=1,4
  147. !!do j=1,3 !gives result to within ~ 3 %
  148. y=y+1.d0
  149. ser=ser+cof(j)/y
  150. enddo
  151. gammadp=tmp+log(stp*ser/x)
  152. gammadp= exp(gammadp)
  153. #if (DWORDSIZE == 8 && RWORDSIZE == 8)
  154. gamma = gammadp
  155. #elif (DWORDSIZE == 8 && RWORDSIZE == 4)
  156. gamma = sngl(gammadp)
  157. #else
  158. This is a temporary hack assuming double precision is 8 bytes.
  159. #endif
  160. END FUNCTION gamma
  161. !======================================================================!
  162. ! ! !
  163. ! ! ! -- USED BY DIAGNOSTIC-ALPHA DOUBLE-MOMENT (SINGLE-PRECISION) VERSION --
  164. ! ! ! FOR FUTURE VERSIONS OF M-Y PACKAGE WITH, THIS S/R CAN BE USED
  165. ! ! !
  166. ! ! ! real FUNCTION diagAlpha(Dm,x)
  167. ! ! !
  168. ! ! ! IMPLICIT NONE
  169. ! ! !
  170. ! ! ! integer :: x
  171. ! ! ! real :: Dm
  172. ! ! ! real, dimension(5) :: c1,c2,c3,c4
  173. ! ! ! real, parameter :: pi = 3.14159265
  174. ! ! ! real, parameter :: alphaMAX= 80.e0
  175. ! ! ! data c1 /19.0, 12.0, 4.5, 5.5, 3.7/
  176. ! ! ! data c2 / 0.6, 0.7, 0.5, 0.7, 0.3/
  177. ! ! ! data c3 / 1.8, 1.7, 5.0, 4.5, 9.0/
  178. ! ! ! data c4 /17.0, 11.0, 5.5, 8.5, 6.5/
  179. ! ! ! diagAlpha= c1(x)*tanh(c2(x)*(1.e3*Dm-c3(x)))+c4(x)
  180. ! ! ! if (x==5.and.Dm>0.008) diagAlpha= 1.e3*Dm-2.6
  181. ! ! ! diagAlpha= min(diagAlpha, alphaMAX)
  182. ! ! !
  183. ! ! ! END function diagAlpha
  184. ! ! !
  185. ! ! ! !======================================================================!
  186. ! ! !
  187. ! ! ! -- USED BY DIAGNOSTIC-ALPHA DOUBLE-MOMENT (SINGLE-PRECISION) VERSION --
  188. ! ! ! FOR FUTURE VERSIONS OF M-Y PACKAGE WITH, THIS S/R CAN BE USED
  189. ! ! !
  190. ! ! ! real FUNCTION solveAlpha(Q,N,Z,Cx,rho)
  191. ! ! !
  192. ! ! ! IMPLICIT NONE
  193. ! ! !
  194. ! ! ! ! PASSING PARAMETERS:
  195. ! ! ! real, intent(IN) :: Q, N, Z, Cx, rho
  196. ! ! !
  197. ! ! ! ! LOCAL PARAMETERS:
  198. ! ! ! real :: a,g,a1,g1,g2,tmp1
  199. ! ! ! integer :: i
  200. ! ! ! real, parameter :: alphaMax= 40.
  201. ! ! ! real, parameter :: epsQ = 1.e-14
  202. ! ! ! real, parameter :: epsN = 1.e-3
  203. ! ! ! real, parameter :: epsZ = 1.e-32
  204. ! ! !
  205. ! ! ! ! Q mass mixing ratio
  206. ! ! ! ! N total concentration
  207. ! ! ! ! Z reflectivity
  208. ! ! ! ! Cx (pi/6)*RHOx
  209. ! ! ! ! rho air density
  210. ! ! ! ! a alpha (returned as solveAlpha)
  211. ! ! ! ! g function g(a)= [(6+a)(5+a)(4+a)]/[(3+a)(2+a)(1+a)],
  212. ! ! ! ! where g = (Cx/(rho*Q))**2.*(Z*N)
  213. ! ! !
  214. ! ! !
  215. ! ! ! if (Q==0. .or. N==0. .or. Z==0. .or. Cx==0. .or. rho==0.) then
  216. ! ! ! ! For testing/debugging only; this module should never be called
  217. ! ! ! ! if the above condition is true.
  218. ! ! ! print*,'*** STOPPED in MODULE ### solveAlpha *** '
  219. ! ! ! print*,'*** : ',Q,N,Z,Cx*1.9099,rho
  220. ! ! ! stop
  221. ! ! ! endif
  222. ! ! !
  223. ! ! ! IF (Q>epsQ .and. N>epsN .and. Z>epsZ ) THEN
  224. ! ! !
  225. ! ! ! tmp1= Cx/(rho*Q)
  226. ! ! ! g = tmp1*Z*tmp1*N ! g = (Z*N)*[Cx / (rho*Q)]^2
  227. ! ! !
  228. ! ! ! !Note: The above order avoids OVERFLOW, since tmp1*tmp1 is very large
  229. ! ! !
  230. ! ! ! !----------------------------------------------------------!
  231. ! ! ! ! !Solve alpha numerically: (brute-force; for testing only)
  232. ! ! ! ! a= 0.
  233. ! ! ! ! g2= 999.
  234. ! ! ! ! do i=0,4000
  235. ! ! ! ! a1= i*0.01
  236. ! ! ! ! g1= (6.+a1)*(5.+a1)*(4.+a1)/((3.+a1)*(2.+a1)*(1.+a1))
  237. ! ! ! ! if(abs(g-g1)<abs(g-g2)) then
  238. ! ! ! ! a = a1
  239. ! ! ! ! g2= g1
  240. ! ! ! ! endif
  241. ! ! ! ! enddo
  242. ! ! ! !----------------------------------------------------------!
  243. ! ! !
  244. ! ! ! !Piecewise-polynomial approximation of g(a) to solve for a: [2004-11-29]
  245. ! ! ! if (g>=20.) then
  246. ! ! ! a= 0.
  247. ! ! ! else
  248. ! ! ! g2= g*g
  249. ! ! ! if (g<20. .and.g>=13.31) a= 3.3638e-3*g2 - 1.7152e-1*g + 2.0857e+0
  250. ! ! ! if (g<13.31.and.g>=7.123) a= 1.5900e-2*g2 - 4.8202e-1*g + 4.0108e+0
  251. ! ! ! if (g<7.123.and.g>=4.200) a= 1.0730e-1*g2 - 1.7481e+0*g + 8.4246e+0
  252. ! ! ! if (g<4.200.and.g>=2.946) a= 5.9070e-1*g2 - 5.7918e+0*g + 1.6919e+1
  253. ! ! ! if (g<2.946.and.g>=1.793) a= 4.3966e+0*g2 - 2.6659e+1*g + 4.5477e+1
  254. ! ! ! if (g<1.793.and.g>=1.405) a= 4.7552e+1*g2 - 1.7958e+2*g + 1.8126e+2
  255. ! ! ! if (g<1.405.and.g>=1.230) a= 3.0889e+2*g2 - 9.0854e+2*g + 6.8995e+2
  256. ! ! ! if (g<1.230) a= alphaMax
  257. ! ! ! endif
  258. ! ! !
  259. ! ! ! solveAlpha= max(0.,min(a,alphaMax))
  260. ! ! !
  261. ! ! ! ELSE
  262. ! ! !
  263. ! ! ! solveAlpha= 0.
  264. ! ! !
  265. ! ! ! ENDIF
  266. ! ! !
  267. ! ! ! END FUNCTION solveAlpha
  268. !======================================================================!
  269. FUNCTION gammaDP(xx)
  270. ! Modified from "Numerical Recipes"
  271. IMPLICIT NONE
  272. ! PASSING PARAMETERS:
  273. DOUBLE PRECISION, INTENT(IN) :: xx
  274. ! LOCAL PARAMETERS:
  275. DOUBLE PRECISION :: gammaDP
  276. INTEGER :: j
  277. DOUBLE PRECISION :: ser,stp,tmp,x,y,cof(6)
  278. SAVE cof,stp
  279. DATA cof,stp/76.18009172947146d0,-86.50532032941677d0, &
  280. 24.01409824083091d0,-1.231739572450155d0,.1208650973866179d-2, &
  281. -.5395239384953d-5,2.5066282746310005d0/
  282. x=xx
  283. y=x
  284. tmp=x+5.5d0
  285. tmp=(x+0.5d0)*log(tmp)-tmp
  286. ser=1.000000000190015d0
  287. ! do j=1,6 !original
  288. do j=1,4
  289. !!do j=1,3 !gives result to within ~ 3 %
  290. y=y+1.d0
  291. ser=ser+cof(j)/y
  292. enddo
  293. gammaDP=tmp+log(stp*ser/x)
  294. gammaDP= exp(gammaDP)
  295. END FUNCTION gammaDP
  296. !======================================================================!
  297. SUBROUTINE gser(gamser,a,x,gln)
  298. ! USES gammln
  299. ! Returns the incomplete gamma function P(a,x) evaluated by its series
  300. ! representation as gamser. Also returns GAMMA(a) as gln.
  301. implicit none
  302. integer :: itmax
  303. real :: a,gamser,gln,x,eps
  304. parameter (itmax=100, eps=3.e-7)
  305. integer :: n
  306. real :: ap,de1,summ
  307. gln=gammln(a)
  308. if(x.le.0.)then
  309. if(x.lt.0.)pause 'x <0 in gser'
  310. gamser=0.
  311. return
  312. endif
  313. ap=a
  314. summ=1./a
  315. de1=summ
  316. do n=1,itmax
  317. ap=ap+1.
  318. de1=de1*x/ap
  319. summ=summ+de1
  320. if(abs(de1).lt.abs(summ)*eps) goto 1
  321. enddo
  322. pause 'a too large, itmax too small in gser'
  323. 1 gamser=summ*exp(-x+a*log(x)-gln)
  324. return
  325. END SUBROUTINE gser
  326. !======================================================================!
  327. real FUNCTION gammln(xx)
  328. ! Returns value of ln(GAMMA(xx)) for xx>0
  329. ! (modified from "Numerical Recipes")
  330. IMPLICIT NONE
  331. ! PASSING PARAMETERS:
  332. real, intent(IN) :: xx
  333. ! LOCAL PARAMETERS:
  334. integer :: j
  335. real*8 :: ser,stp,tmp,x,y,cof(6)
  336. SAVE cof,stp
  337. DATA cof,stp/76.18009172947146d0,-86.50532032941677d0, &
  338. 24.01409824083091d0,-1.231739572450155d0,.1208650973866179d-2, &
  339. -.5395239384953d-5,2.5066282746310005d0/
  340. x=dble(xx)
  341. y=x
  342. tmp=x+5.5d0
  343. tmp=(x+0.5d0)*log(tmp)-tmp
  344. ser=1.000000000190015d0
  345. do j=1,6 !original
  346. ! do j=1,4
  347. y=y+1.d0
  348. ser=ser+cof(j)/y
  349. enddo
  350. #if (DWORDSIZE == 8 && RWORDSIZE == 8)
  351. gammln= tmp+log(stp*ser/x)
  352. #elif (DWORDSIZE == 8 && RWORDSIZE == 4)
  353. gammln= sngl( tmp+log(stp*ser/x) )
  354. #else
  355. This is a temporary hack assuming double precision is 8 bytes.
  356. #endif
  357. END FUNCTION gammln
  358. !======================================================================!
  359. real FUNCTION gammp(a,x)
  360. ! USES gcf,gser
  361. ! Returns the incomplete gamma function P(a,x)
  362. implicit none
  363. real :: a,x,gammcf,gamser,gln
  364. if(x.lt.0..or.a.le.0.) pause 'bad arguments in gammq'
  365. if(x.lt.a+1.)then
  366. call gser(gamser,a,x,gln)
  367. gammp=gamser
  368. else
  369. call cfg(gammcf,a,x,gln)
  370. gammp=1.-gammcf
  371. endif
  372. return
  373. END FUNCTION gammp
  374. !======================================================================!
  375. SUBROUTINE cfg(gammcf,a,x,gln)
  376. ! USES gammln
  377. ! Returns the incomplete gamma function (Q(a,x) evaluated by tis continued fraction
  378. ! representation as gammcf. Also returns ln(GAMMA(a)) as gln. ITMAX is the maximum
  379. ! allowed number of iterations; EPS is the relative accuracy; FPMIN is a number near
  380. ! the smallest representable floating-point number.
  381. implicit none
  382. integer :: i,itmax
  383. real :: a,gammcf,gln,x,eps,fpmin
  384. real :: an,b,c,d,de1,h
  385. parameter (itmax=100,eps=3.e-7)
  386. gln=gammln(a)
  387. b=x+1.-a
  388. c=1./fpmin
  389. d=1./b
  390. h=d
  391. do i= 1,itmax
  392. an=-i*(i-a)
  393. b=b+2.
  394. d=an*d+b
  395. if(abs(d).lt.fpmin)d=fpmin
  396. c=b+an/c
  397. if(abs(c).lt.fpmin) c=fpmin
  398. d=1./d
  399. de1=d*c
  400. h=h*de1
  401. if(abs(de1-1.).lt.eps) goto 1
  402. enddo
  403. pause 'a too large, itmax too small in gcf'
  404. 1 gammcf=exp(-x+a*log(x)-gln)*h
  405. return
  406. END SUBROUTINE cfg
  407. !======================================================================!
  408. real FUNCTION gamminc(p,xmax)
  409. ! USES gammp, gammln
  410. ! Returns incomplete gamma function, gamma(p,xmax)= P(p,xmax)*GAMMA(p)
  411. real :: p,xmax
  412. gamminc= gammp(p,xmax)*exp(gammln(p))
  413. end FUNCTION gamminc
  414. !======================================================================!
  415. ! real function x_tothe_y(x,y)
  416. !
  417. ! implicit none
  418. ! real, intent(in) :: x,y
  419. ! x_tothe_y= exp(y*log(x))
  420. !
  421. ! end function x_tothe_y
  422. !======================================================================!
  423. end module my_fncs_mod
  424. !________________________________________________________________________________________!
  425. module my_sedi_mod
  426. !================================================================================!
  427. ! The following subroutines are used by the schemes in the multimoment package. !
  428. ! !
  429. ! Package version: 2.19.0 (internal bookkeeping) !
  430. ! Last modified : 2011-01-07 !
  431. !================================================================================!
  432. implicit none
  433. private
  434. public :: SEDI_main_1b,SEDI_main_2,countColumns
  435. contains
  436. !=====================================================================================!
  437. SUBROUTINE SEDI_main_2(QX,NX,cat,Q,T,DE,iDE,gamfact,epsQ,epsN,afx,bfx,cmx,dmx, &
  438. ckQx1,ckQx2,ckQx4,LXP,ni,nk,VxMax,DxMax,dt,DZ,massFlux, &
  439. ktop_sedi,GRAV,massFlux3D)
  440. !-------------------------------------------------------------------------------------!
  441. ! DOUBLE-MOMENT version of sedimentation subroutine for categories whose
  442. ! fall velocity equation is V(D) = gamfact * afx * D^bfx
  443. !-------------------------------------------------------------------------------------!
  444. ! Passing parameters:
  445. !
  446. ! VAR Description
  447. ! --- ------------
  448. ! QX mass mixing ratio of category x
  449. ! NX number concentration of category x
  450. ! cat: hydrometeor category:
  451. ! 1 rain
  452. ! 2 ice
  453. ! 3 snow
  454. ! 4 graupel
  455. ! 5 hail
  456. !-------------------------------------------------------------------------------------!
  457. use my_fncs_mod
  458. implicit none
  459. ! PASSING PARAMETERS:
  460. real, dimension(:,:), intent(inout) :: QX,NX,Q,T
  461. real, dimension(:), intent(out) :: massFlux
  462. real, optional, dimension(:,:), intent(out) :: massFlux3D
  463. real, dimension(:,:), intent(in) :: DE,iDE,DZ
  464. real, intent(in) :: epsQ,epsN,VxMax,LXP,afx,bfx,cmx,dmx,ckQx1,ckQx2,ckQx4,DxMax,dt,GRAV
  465. integer, dimension(:), intent(in) :: ktop_sedi
  466. integer, intent(in) :: ni,nk,cat
  467. ! LOCAL PARAMETERS:
  468. logical :: slabHASmass,locallim,QxPresent
  469. integer :: nnn,a,i,k,counter,l,km1,kp1,ks,kw,idzmin
  470. integer, dimension(nk) :: flim_Q,flim_N
  471. integer, dimension(ni) :: activeColumn,npassx,ke
  472. real :: VqMax,VnMax,iLAMx,iLAMxB0,tmp1,tmp2,tmp3,Dx,iDxMax,icmx, &
  473. VincFact,ratio_Vn2Vq,zmax_Q,zmax_N,tempo,idmx,Nos_Thompson, &
  474. No_s,iLAMs
  475. real, dimension(ni,nk) :: VVQ,VVN,RHOQX,gamfact
  476. real, dimension(ni) :: dzMIN,dtx,VxMaxx
  477. real, dimension(nk) :: vp_Q,vp_N,zt_Q,zt_N,zb_Q,zb_N,dzi,Q_star,N_star
  478. real, dimension(0:nk) :: zz
  479. real, parameter :: epsilon = 1.e-2
  480. real, parameter :: thrd = 1./3.
  481. real, parameter :: sxth = 1./6.
  482. real, parameter :: CoMAX = 2.0
  483. !-------------------------------------------------------------------------------------!
  484. massFlux = 0.
  485. !Factor to estimate increased V from size-sorting:
  486. ! - this factor should be higher for categories with more time-splitting, since Vmax
  487. ! increases after each sedimentation split step (to be tuned)
  488. VincFact = 1.
  489. if (present(massFlux3D)) massFlux3D= 0. !(for use in MAIN for diagnostics)
  490. !Determine for which slabs and columns sedimentation should be computes:
  491. call countColumns(QX,ni,nk,epsQ,counter,activeColumn,ktop_sedi)
  492. ratio_Vn2Vq= ckQx2/ckQx1
  493. iDxMax= 1./DxMax
  494. icmx = 1./cmx
  495. idmx = 1./dmx
  496. ks = nk
  497. ke = ktop_sedi !(i-array) - formerly ke=1; now depends on max. level with hydrometeor
  498. kw = -1 !direction of vertical leveling; -1 implies nk is bottom
  499. VVQ = 0.
  500. VVN = 0.
  501. VqMax= 0.
  502. VnMax= 0.
  503. DO a= 1,counter
  504. i= activeColumn(a)
  505. VVQ(i,:) = 0.
  506. do k= ktop_sedi(i),nk !formerly do k= 1,nk
  507. QxPresent = (QX(i,k)>epsQ .and. NX(i,k)>epsN)
  508. if (QxPresent) VVQ(i,k)= calcVV()*ckQx1
  509. if (present(massFlux3D)) massFlux3D(i,k)= VVQ(i,k)*DE(i,k)*QX(i,k) !(for use in MAIN)
  510. enddo !k-loop
  511. Vxmaxx(i)= min( VxMax, maxval(VVQ(i,:))*VincFact )
  512. !note: dzMIN is min. value in column (not necessarily lowest layer in general)
  513. dzMIN(i) = minval(DZ(i,:))
  514. npassx(i)= max(1, nint( dt*Vxmaxx(i)/(CoMAX*dzMIN(i)) ))
  515. dtx(i) = dt/float(npassx(i))
  516. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  517. DO nnn= 1,npassx(i)
  518. locallim = (nnn==1)
  519. do k= ktop_sedi(i),nk !formerly do k= 1,nk
  520. RHOQX(i,k) = DE(i,k)*QX(i,k)
  521. QxPresent = (QX(i,k)>epsQ .and. NX(i,k)>epsN)
  522. if (QxPresent) then
  523. if (locallim) then !to avoid re-computing VVQ on first pass
  524. VVQ(i,k)= -VVQ(i,k)
  525. else
  526. VVQ(i,k)= -calcVV()*ckQx1
  527. endif
  528. VVN(i,k)= VVQ(i,k)*ratio_Vn2Vq
  529. VqMax = max(VxMAX,-VVQ(i,k))
  530. VnMax = max(VxMAX,-VVN(i,k))
  531. else
  532. VVQ(i,k)= 0.
  533. VVN(i,k)= 0.
  534. VqMax = 0.
  535. VnMax = 0.
  536. endif
  537. enddo !k-loop
  538. !sum instantaneous surface mass flux at each split step: (for division later)
  539. massFlux(i)= massFlux(i) - VVQ(i,nk)*DE(i,nk)*QX(i,nk)
  540. !-- Perform single split sedimentation step:
  541. ! (formerly by calls to s/r 'blg4sedi', a modified [JM] version of 'blg2.ftn')
  542. zz(ks)= 0.
  543. do k= ks,ke(i),kw
  544. zz(k+kw)= zz(k)+dz(i,k)
  545. dzi(k) = 1./dz(i,k)
  546. vp_Q(k) = 0.
  547. vp_N(k) = 0.
  548. enddo
  549. do k=ks,ke(i),kw
  550. zb_Q(k)= zz(k) + VVQ(i,k)*dtx(i)
  551. zb_N(k)= zz(k) + VVN(i,k)*dtx(i)
  552. enddo
  553. zt_Q(ke(i))= zb_Q(ke(i)) + dz(i,ke(i))
  554. zt_N(ke(i))= zb_N(ke(i)) + dz(i,ke(i))
  555. do k= ks,ke(i)-kw,kw
  556. zb_Q(k)= min(zb_Q(k+kw)-epsilon*dz(i,k), zz(k)+VVQ(i,k)*dtx(i))
  557. zb_N(k)= min(zb_N(k+kw)-epsilon*dz(i,k), zz(k)+VVN(i,k)*dtx(i))
  558. zt_Q(k)= zb_Q(k+kw)
  559. zt_N(k)= zb_N(k+kw)
  560. enddo
  561. do k=ks,ke(i),kw !formerly k=1,nk
  562. Q_star(k)= RHOQX(i,k)*dz(i,k)/(zt_Q(k)-zb_Q(k))
  563. N_star(k)= NX(i,k)*dz(i,k)/(zt_N(k)-zb_N(k))
  564. enddo
  565. if (locallim) then
  566. zmax_Q= abs(VqMax*dtx(i))
  567. zmax_N= abs(VnMax*dtx(i))
  568. do l=ks,ke(i),kw
  569. flim_Q(l)= l
  570. flim_N(l)= l
  571. do k= l,ke(i),kw
  572. if (zmax_Q.ge.zz(k)-zz(l+kw)) flim_Q(l)= k
  573. if (zmax_N.ge.zz(k)-zz(l+kw)) flim_N(l)= k
  574. enddo
  575. enddo
  576. endif
  577. do l=ks,ke(i),kw
  578. do k=l,flim_Q(l),kw
  579. vp_Q(l)= vp_Q(l) + Q_star(k)*max(0.,min(zz(l+kw),zt_Q(k))-max(zz(l),zb_Q(k)))
  580. enddo
  581. do k=l,flim_N(l),kw
  582. vp_N(l)= vp_N(l) + N_star(k)*max(0.,min(zz(l+kw),zt_N(k))-max(zz(l),zb_N(k)))
  583. enddo
  584. enddo
  585. do k=ks,ke(i),kw
  586. RHOQX(i,k)= vp_Q(k)*dzi(k)
  587. NX(i,k)= vp_N(k)*dzi(k)
  588. enddo
  589. !--
  590. do k= ktop_sedi(i),nk !formerly do k= 1,nk
  591. QX(i,k)= RHOQX(i,k)*iDE(i,k)
  592. !Prevent levels with zero N and nonzero Q and size-limiter:
  593. QxPresent= (QX(i,k)>epsQ .and. NX(i,k)>epsN)
  594. if (QxPresent) then !size limiter
  595. Dx= (DE(i,k)*QX(i,k)/(NX(i,k)*cmx))**idmx
  596. if (cat==1 .and. Dx>3.e-3) then
  597. tmp1 = Dx-3.e-3; tmp1= tmp1*tmp1
  598. tmp2 = (Dx/DxMAX); tmp2= tmp2*tmp2*tmp2
  599. NX(i,k)= NX(i,k)*max((1.+2.e4*tmp1),tmp2)
  600. else
  601. NX(i,k)= NX(i,k)*(max(Dx,DxMAX)*iDxMAX)**dmx !impose Dx_max
  602. endif
  603. else !here, "QxPresent" implies correlated QX and NX
  604. Q(i,k) = Q(i,k) + QX(i,k)
  605. T(i,k) = T(i,k) - LXP*QX(i,k) !LCP for rain; LSP for i,s,g,h
  606. QX(i,k)= 0.
  607. NX(i,k)= 0.
  608. endif
  609. enddo
  610. ENDDO !nnn-loop
  611. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  612. !compute average mass flux during the full time step: (used to compute the
  613. !instantaneous sedimentation rate [liq. equiv. volume flux] in the main s/r)
  614. massFlux(i)= massFlux(i)/float(npassx(i))
  615. ENDDO !a(i)-loop
  616. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  617. CONTAINS
  618. real function calcVV()
  619. !Calculates portion of moment-weighted fall velocities
  620. iLAMx = ((QX(i,k)*DE(i,k)/NX(i,k))*ckQx4)**idmx
  621. iLAMxB0 = iLAMx**bfx
  622. calcVV = gamfact(i,k)*iLAMxB0
  623. end function calcVV
  624. END SUBROUTINE SEDI_main_2
  625. !=====================================================================================!
  626. SUBROUTINE SEDI_main_1b(QX,cat,T,DE,iDE,gamfact,epsQ,afx,bfx,icmx,dmx,ckQx1,ckQx4, &
  627. ni,nk,VxMax,DxMax,dt,DZ,massFlux,No_x,ktop_sedi,GRAV, &
  628. massFlux3D)
  629. !-------------------------------------------------------------------------------------!
  630. ! SINGLE-MOMENT version of sedimentation subroutine for categories whose
  631. ! fall velocity equation is V(D) = gamfact * afx * D^bfx
  632. !-------------------------------------------------------------------------------------!
  633. ! Passing parameters:
  634. !
  635. ! VAR Description
  636. ! --- ------------
  637. ! QX mass mixing ratio of category x
  638. ! cat: hydrometeor category:
  639. ! 1 rain
  640. ! 2 ice
  641. ! 3 snow
  642. ! 4 graupel
  643. ! 5 hail
  644. !-------------------------------------------------------------------------------------!
  645. use my_fncs_mod
  646. implicit none
  647. ! PASSING PARAMETERS:
  648. real, dimension(:,:), intent(inout) :: QX,T
  649. real, dimension(:), intent(out) :: massFlux
  650. real, optional, dimension(:,:), intent(out) :: massFlux3D
  651. real, dimension(:,:), intent(in) :: DE,iDE,DZ
  652. real, intent(in) :: epsQ,VxMax,afx,bfx,icmx,dmx,ckQx1,ckQx4,DxMax,dt,GRAV,No_x
  653. integer, dimension(:), intent(in) :: ktop_sedi
  654. integer, intent(in) :: ni,nk,cat !,ktop_sedi
  655. ! LOCAL PARAMETERS:
  656. logical :: slabHASmass,locallim,QxPresent
  657. integer :: nnn,a,i,k,counter,l,km1,kp1,ks,kw,idzmin !,ke
  658. integer, dimension(nk) :: flim_Q
  659. integer, dimension(ni) :: activeColumn,npassx,ke
  660. real :: VqMax,iLAMx,iLAMxB0,tmp1,tmp2,Dx,iDxMax,VincFact,NX,iNo_x, &
  661. zmax_Q,zmax_N,tempo
  662. real, dimension(ni,nk) :: VVQ,RHOQX,gamfact
  663. real, dimension(ni) :: dzMIN,dtx,VxMaxx
  664. real, dimension(nk) :: vp_Q,zt_Q,zb_Q,dzi,Q_star
  665. real, dimension(0:nk) :: zz
  666. real, parameter :: epsilon = 1.e-2
  667. real, parameter :: thrd = 1./3.
  668. real, parameter :: sxth = 1./6.
  669. real, parameter :: CoMAX = 2.0
  670. !-------------------------------------------------------------------------------------!
  671. massFlux= 0.
  672. !Factor to estimate increased V from size-sorting:
  673. ! - this factor should be higher for categories with more time-splitting, since Vmax
  674. ! increases after each sedimentation split step (to be tuned)
  675. VincFact= 1.
  676. if (present(massFlux3D)) massFlux3D= 0. !(for use in MAIN for diagnostics)
  677. !Determine for which slabs and columns sedimentation should be computes:
  678. call countColumns(QX,ni,nk,epsQ,counter,activeColumn,ktop_sedi)
  679. iNo_x = 1./No_x
  680. iDxMax= 1./DxMax
  681. ks = nk
  682. ke = ktop_sedi !(i-array) - old: ke=1
  683. kw = -1 !direction of vertical leveling
  684. VVQ = 0.
  685. VqMax= 0.
  686. DO a= 1,counter
  687. i= activeColumn(a)
  688. VVQ(i,:) = 0.
  689. do k= ktop_sedi(i),nk !do k= 1,nk
  690. QxPresent = (QX(i,k)>epsQ)
  691. ! if (QxPresent) VVQ(i,k)= calcVV()*ckQx1
  692. if (QxPresent) then
  693. !ice:
  694. if (cat==2) then
  695. NX = 5.*exp(0.304*(273.15-max(233.,T(i,k))))
  696. iLAMx = (ckQx4*QX(i,k)*DE(i,k)/NX)**thrd
  697. !snow:
  698. else if (cat==3) then
  699. iNo_x = 1./min(2.e+8, 2.e+6*exp(-0.12*min(-0.001,T(i,k)-273.15)))
  700. iLAMx = sqrt(sqrt(QX(i,k)*DE(i,k)*icmx*sxth*iNo_x))
  701. !rain, graupel, hail:
  702. else
  703. iLAMx = sqrt(sqrt(QX(i,k)*DE(i,k)*icmx*sxth*iNo_x))
  704. endif
  705. VVQ(i,k) = -gamfact(i,k)*ckQx1*iLAMx**bfx
  706. ! VqMax = max(VxMAX,-VVQ(i,k))
  707. endif
  708. if (present(massFlux3D)) massFlux3D(i,k)= -VVQ(i,k)*DE(i,k)*QX(i,k) !(for use in MAIN)
  709. enddo !k-loop
  710. Vxmaxx(i)= min( VxMax, maxval(VVQ(i,:))*VincFact )
  711. !note: dzMIN is min. value in column (not necessarily lowest layer in general)
  712. dzMIN(i) = minval(DZ(i,:))
  713. npassx(i)= max(1, nint( dt*Vxmaxx(i)/(CoMAX*dzMIN(i)) ))
  714. dtx(i) = dt/float(npassx(i))
  715. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  716. DO nnn= 1,npassx(i)
  717. locallim = (nnn==1)
  718. do k= ktop_sedi(i),nk !do k= 1,nk
  719. RHOQX(i,k) = DE(i,k)*QX(i,k)
  720. QxPresent = (QX(i,k)>epsQ)
  721. if (QxPresent) then
  722. !ice:
  723. if (cat==2) then
  724. NX = 5.*exp(0.304*(273.15-max(233.,T(i,k))))
  725. iLAMx = (ckQx4*QX(i,k)*DE(i,k)/NX)**thrd
  726. !snow:
  727. else if (cat==3) then
  728. iNo_x = 1./min(2.e+8, 2.e+6*exp(-0.12*min(-0.001,T(i,k)-273.15)))
  729. iLAMx = sqrt(sqrt(QX(i,k)*DE(i,k)*icmx*sxth*iNo_x))
  730. !rain, graupel, hail:
  731. else
  732. iLAMx = sqrt(sqrt(QX(i,k)*DE(i,k)*icmx*sxth*iNo_x))
  733. endif
  734. VVQ(i,k) = -gamfact(i,k)*ckQx1*iLAMx**bfx
  735. VqMax = max(VxMAX,-VVQ(i,k))
  736. endif
  737. enddo !k-loop
  738. !-- Perform single split sedimentation step: (formerly by calls to s/r 'blg4sedi')
  739. zz(ks)= 0.
  740. do k= ks,ke(i),kw
  741. zz(k+kw)= zz(k)+dz(i,k)
  742. dzi(k) = 1./dz(i,k)
  743. vp_Q(k) = 0.
  744. enddo
  745. do k=ks,ke(i),kw
  746. zb_Q(k)= zz(k) + VVQ(i,k)*dtx(i)
  747. enddo
  748. zt_Q(ke(i))= zb_Q(ke(i)) + dz(i,ke(i))
  749. do k= ks,ke(i)-kw,kw
  750. zb_Q(k)= min(zb_Q(k+kw)-epsilon*dz(i,k), zz(k)+VVQ(i,k)*dtx(i))
  751. zt_Q(k)= zb_Q(k+kw)
  752. enddo
  753. do k=ks,ke(i),kw !k=1,nk
  754. Q_star(k)= RHOQX(i,k)*dz(i,k)/(zt_Q(k)-zb_Q(k))
  755. enddo
  756. if (locallim) then
  757. zmax_Q= abs(VqMax*dtx(i))
  758. do l=ks,ke(i),kw
  759. flim_Q(l)= l
  760. do k= l,ke(i),kw
  761. if (zmax_Q.ge.zz(k)-zz(l+kw)) flim_Q(l)= k
  762. enddo
  763. enddo
  764. endif
  765. do l=ks,ke(i),kw
  766. do k=l,flim_Q(l),kw
  767. vp_Q(l)= vp_Q(l) + Q_star(k)*max(0.,min(zz(l+kw),zt_Q(k))-max(zz(l),zb_Q(k)))
  768. enddo
  769. enddo
  770. do k=ks,ke(i),kw
  771. RHOQX(i,k)= vp_Q(k)*dzi(k)
  772. enddo
  773. !--
  774. do k= ktop_sedi(i),nk ! do k= 1,nk
  775. QX(i,k)= RHOQX(i,k)*iDE(i,k)
  776. enddo
  777. !sum instantaneous flux at each split step: (for division later)
  778. massFlux(i)= massFlux(i) - VVQ(i,nk)*DE(i,nk)*QX(i,nk)
  779. ENDDO !nnn-loop
  780. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  781. !compute average flux during the full time step: (this will be used to compute
  782. ! the instantaneous sedimentation rate [volume flux] in the main s/r)
  783. massFlux(i)= massFlux(i)/float(npassx(i))
  784. ENDDO !a(i)-loop
  785. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  786. END SUBROUTINE SEDI_main_1b
  787. !=====================================================================================!
  788. SUBROUTINE countColumns(QX,ni,nk,minQX,counter,activeColumn,ktop_sedi)
  789. ! Searches the hydrometeor array QX(ni,nk) for non-zero (>minQX) values.
  790. ! Returns the array if i-indices (activeColumn) for the columns (i)
  791. ! which contain at least one non-zero value, as well as the number of such
  792. ! columns (counter).
  793. implicit none
  794. !PASSING PARAMETERS:
  795. integer, intent(in) :: ni,nk !,ktop_sedi
  796. integer, dimension(:), intent(in) :: ktop_sedi
  797. integer, intent(out) :: counter
  798. integer, dimension(:), intent(out) :: activeColumn
  799. real, dimension(:,:), intent(in) :: QX
  800. real, intent(in) :: minQX
  801. !LOCAL PARAMETERS:
  802. integer :: i !,k
  803. integer, dimension(ni) :: k
  804. ! k= ktop_sedi-1 ! k=0
  805. counter = 0
  806. activeColumn= 0
  807. do i=1,ni
  808. k(i)= ktop_sedi(i)-1 ! k=0
  809. do
  810. k(i)=k(i)+1
  811. if (QX(i,k(i))>minQX) then
  812. counter=counter+1
  813. activeColumn(counter)=i
  814. k(i)=0
  815. exit
  816. else
  817. if (k(i)==nk) then
  818. k(i)=0
  819. exit
  820. endif
  821. endif
  822. enddo
  823. enddo !i-loop
  824. END SUBROUTINE countColumns
  825. !=====================================================================================!
  826. end module my_sedi_mod
  827. !________________________________________________________________________________________!
  828. module my_dmom_mod
  829. implicit none
  830. private
  831. public :: mp_milbrandt2mom_main
  832. contains
  833. !_______________________________________________________________________________________!
  834. SUBROUTINE mp_milbrandt2mom_main(W_omega,T,Q,QC,QR,QI,QN,QG,QH,NC,NR,NY,NN,NG,NH,PS,TM, &
  835. QM,QCM,QRM,QIM,QNM,QGM,QHM,NCM,NRM,NYM,NNM,NGM,NHM,PSM,S,RT_rn1,RT_rn2,RT_fr1,RT_fr2,&
  836. RT_sn1,RT_sn2,RT_sn3,RT_pe1,RT_pe2,RT_peL,RT_snd,GZ,T_TEND,Q_TEND,QCTEND,QRTEND, &
  837. QITEND,QNTEND,QGTEND,QHTEND,NCTEND,NRTEND,NYTEND,NNTEND,NGTEND,NHTEND,dt,NI,N,NK, &
  838. J,KOUNT,CCNtype,precipDiag_ON,sedi_ON,warmphase_ON,autoconv_ON,icephase_ON,snow_ON, &
  839. initN,dblMom_c,dblMom_r,dblMom_i,dblMom_s,dblMom_g,dblMom_h,Dm_c,Dm_r,Dm_i,Dm_s, &
  840. Dm_g,Dm_h,ZET,ZEC,SLW,VIS,VIS1,VIS2,VIS3,h_CB,h_ML1,h_ML2,h_SN,SS01,SS02,SS03,SS04, &
  841. SS05,SS06,SS07,SS08,SS09,SS10,SS11,SS12,SS13,SS14,SS15,SS16,SS17,SS18,SS19,SS20)
  842. use my_fncs_mod
  843. use my_sedi_mod
  844. !--WRF:
  845. use module_model_constants, ONLY: CPD => cp, CPV => cpv, RGASD => r_d, RGASV => r_v, &
  846. EPS1 => EP_2, DELTA => EP_1, CAPPA => rcp, GRAV => g, CHLC => XLV, CHLF => XLF
  847. !==
  848. implicit none
  849. !CALLING PARAMETERS:
  850. integer, intent(in) :: NI,NK,N,J,KOUNT,CCNtype
  851. real, intent(in) :: dt
  852. real, dimension(:), intent(in) :: PS,PSM
  853. real, dimension(:), intent(out) :: h_CB,h_ML1,h_ML2,h_SN
  854. real, dimension(:), intent(out) :: RT_rn1,RT_rn2,RT_fr1,RT_fr2,RT_sn1,RT_sn2, &
  855. RT_sn3,RT_pe1,RT_pe2,RT_peL,ZEC,RT_snd
  856. real, dimension(:,:), intent(in) :: W_omega,S,GZ
  857. real, dimension(:,:), intent(inout) :: T,Q,QC,QR,QI,QN,QG,QH,NC,NR,NY,NN,NG,NH, &
  858. TM,QM,QCM,QRM,QIM,QNM,QGM,QHM,NCM,NRM,NYM,NNM,NGM,NHM
  859. real, dimension(:,:), intent(out) :: T_TEND,QCTEND,QRTEND,QITEND,QNTEND, &
  860. QGTEND,QHTEND,Q_TEND,NCTEND,NRTEND,NYTEND,NNTEND,NGTEND,NHTEND,ZET,Dm_c, &
  861. Dm_r,Dm_i,Dm_s,Dm_g,Dm_h,SLW,VIS,VIS1,VIS2,VIS3,SS01,SS02,SS03,SS04,SS05,SS06, &
  862. SS07,SS08,SS09,SS10,SS11,SS12,SS13,SS14,SS15,SS16,SS17,SS18,SS19,SS20
  863. logical, intent(in) :: dblMom_c,dblMom_r,dblMom_i,dblMom_s, &
  864. dblMom_g,dblMom_h,precipDiag_ON,sedi_ON,icephase_ON,snow_ON,warmphase_ON, &
  865. autoconv_ON,initN
  866. !_______________________________________________________________________________________
  867. ! !
  868. ! Milbrandt-Yau Multimoment Bulk Microphysics Scheme !
  869. ! - double-moment version - !
  870. !_______________________________________________________________________________________!
  871. ! Package version: 2.19.0 (internal bookkeeping) !
  872. ! Last modified : 2011-03-02 !
  873. !_______________________________________________________________________________________!
  874. !
  875. ! Author:
  876. ! J. Milbrandt, McGill University (August 2004)
  877. !
  878. ! Major revisions:
  879. !
  880. ! 001 J. Milbrandt (Dec 2006) - Converted the full Milbrandt-Yau (2005) multimoment
  881. ! (RPN) scheme to an efficient fixed-dispersion double-moment
  882. ! version
  883. ! 002 J. Milbrandt (Mar 2007) - Added options for single-moment/double-moment for
  884. ! each hydrometeor category
  885. ! 003 J. Milbrandt (Feb 2008) - Modified single-moment version for use in GEM-LAM-2.5
  886. ! 004 J. Milbrandt (Nov 2008) - Modified double-moment version for use in 2010 Vancouver
  887. ! Olympics GEM-LAM configuration
  888. ! 005 J. Milbrandt (Aug 2009) - Modified (dmom) for PHY_v5.0.4, for use in V2010 system:
  889. ! + reduced ice/snow capacitance to C=0.25D (from C=0.5D)
  890. ! + added diagnostic fields (VIS, levels, etc.)
  891. ! + added constraints to snow size distribution (No_s and
  892. ! LAMDA_s limits, plus changed m-D parameters
  893. ! + modified solid-to-liquid ratio calculation, based on
  894. ! volume flux (and other changes)
  895. ! + added back sedimentation of ice category
  896. ! + modified condition for conversion of graupel to hail
  897. ! + corrected bug it diagnostic "ice pellets" vs. "hail"
  898. ! + minor bug corrections (uninitialized values, etc.)
  899. ! 006 J. Milbrandt (Jan 2011) - Bug fixes and minor code clean-up from PHY_v5.1.3 version
  900. ! + corrected latent heat constants in thermodynamic functions
  901. ! (ABi and ABw) for sublimation and evaporation
  902. ! + properly initialized variables No_g and No_h
  903. ! + changed max ice crystal size (fallspeed) to 5 mm (2 m s-1)
  904. ! + imposed maximum ice number concentration of 1.e+7 m-3
  905. ! + removed unused supersaturation reduction
  906. !
  907. ! Object:
  908. ! Computes changes to the temperature, water vapor mixing ratio, and the
  909. ! mixing ratios and total number concentrations of six hydrometeor species
  910. ! resulting from cloud microphysical interactions at saturated grid points.
  911. ! Liquid and solid surface precipitation rates from sedimenting hydrometeor
  912. ! categories are also computed.
  913. !
  914. ! This subroutine and the associated modules form the single/double-moment
  915. ! switchable verion of the multimoment bulk microphysics package, the full
  916. ! version of which is described in the references below.
  917. !
  918. ! References: Milbrandt and Yau, (2005a), J. Atmos. Sci., vol.62, 3051-3064
  919. ! --------- and ---, (2005b), J. Atmos. Sci., vol.62, 3065-3081
  920. ! (and references therein)
  921. !
  922. ! Please report bugs to: jason.milbrandt@ec.gc.ca
  923. !_______________________________________________________________________________________!
  924. !
  925. ! Arguments: Description: Units:
  926. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  927. ! - Input -
  928. !
  929. ! NI number of x-dir points (in local subdomain)
  930. ! NK number of vertical levels
  931. ! N not used (to be removed)
  932. ! J y-dir index (local subdomain)
  933. ! KOUNT current model time step number
  934. ! dt model time step [s]
  935. ! CCNtype switch for airmass type
  936. ! 1 = maritime --> N_c = 80 cm-3 (1-moment cloud)
  937. ! 2 = continental 1 --> N_c = 200 cm-3 " "
  938. ! 3 = continental 2 (polluted) --> N_c = 500 cm-3 " "
  939. ! 4 = land-sea-mask-dependent (TBA)
  940. ! W_omega vertical velocity [Pa s-1]
  941. ! S sigma (=p/p_sfc)
  942. ! GZ geopotential
  943. ! dblMom_(x) logical switch for double(T)-single(F)-moment for category (x)
  944. ! precipDiag_ON logical switch, .F. to suppress calc. of sfc precip types
  945. ! sedi_ON logical switch, .F. to suppress sedimentation
  946. ! warmphase_ON logical switch, .F. to suppress warm-phase (Part II)
  947. ! autoconv_ON logical switch, .F. to supppress autoconversion (cld->rn)
  948. ! icephase_ON logical switch, .F. to suppress ice-phase (Part I)
  949. ! snow_ON logical switch, .F. to suppress snow initiation
  950. !
  951. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  952. ! - Input/Output -
  953. !
  954. ! T air temperature at time (t*) [K]
  955. ! TM air temperature at time (t-dt) [K]
  956. ! Q water vapor mixing ratio at (t*) [kg kg-1]
  957. ! QM water vapor mixing ratio at (t-dt) [kg kg-1]
  958. ! PS surface pressure at time (t*) [Pa]
  959. ! PSM surface pressure at time (t-dt) [Pa]
  960. !
  961. ! For x = (C,R,I,N,G,H): C = cloud
  962. ! R = rain
  963. ! I = ice (pristine) [except 'NY', not 'NI']
  964. ! N = snow
  965. ! G = graupel
  966. ! H = hail
  967. !
  968. ! Q(x) mixing ratio for hydrometeor x at (t*) [kg kg-1]
  969. ! Q(x)M mixing ratio for hydrometeor x at (t-dt) [kg kg-1]
  970. ! N(x) total number concentration for hydrometeor x (t*) [m-3]
  971. ! N(x)M total number concentration for hydrometeor x (t-dt) [m-3]
  972. !
  973. ! Note: The arrays "VM" (e.g. variables TM,QM,QCM etc.) are declared as INTENT(INOUT)
  974. ! such that their values are modified in the code [VM = 0.5*(VM + V)].
  975. ! This is to approxiate the values at time level (t), which are needed by
  976. ! this routine but are unavailable to the PHYSICS. The new values are discared
  977. ! by the calling routine ('vkuocon6.ftn'). However, care should be taken with
  978. ! interfacing with other modelling systems. For GEM/MC2, it does not matter if
  979. ! VM is modified since the calling module passes back only the tendencies
  980. ! (VTEND) to the model.
  981. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  982. ! - Output -
  983. !
  984. ! Q_TEND tendency for water vapor mixing ratio [kg kg-1 s-1]
  985. ! T_TEND tendency for air temperature [K s-1]
  986. ! Q(x)TEND tendency for mixing ratio for hydrometeor x [kg kg-1 s-1]
  987. ! N(x)TEND tendency for number concentration for hydrometeor x [m-3 s-1]
  988. ! Dm_(x) mean-mass diameter for hydrometeor x [m]
  989. ! H_CB height of cloud base [m]
  990. ! h_ML1 height of first melting level from ground [m]
  991. ! h_ML2 height of first melting level from top [m]
  992. ! h_SN height of snow level [m]
  993. ! RT_rn1 precipitation rate (at sfc) of liquid rain [m+3 m-2 s-1]
  994. ! RT_rn2 precipitation rate (at sfc) of liquid drizzle [m+3 m-2 s-1]
  995. ! RT_fr1 precipitation rate (at sfc) of freezing rain [m+3 m-2 s-1]
  996. ! RT_fr2 precipitation rate (at sfc) of freezing drizzle [m+3 m-2 s-1]
  997. ! RT_sn1 precipitation rate (at sfc) of ice crystals (liq-eq) [m+3 m-2 s-1]
  998. ! RT_sn2 precipitation rate (at sfc) of snow (liq-equiv) [m+3 m-2 s-1]
  999. ! RT_sn3 precipitation rate (at sfc) of graupel (liq-equiv) [m+3 m-2 s-1]
  1000. ! RT_snd precipitation rate (at sfc) of snow (frozen) [m+3 m-2 s-1]
  1001. ! RT_pe1 precipitation rate (at sfc) of ice pellets (liq-eq) [m+3 m-2 s-1]
  1002. ! RT_pe2 precipitation rate (at sfc) of hail (total; liq-eq) [m+3 m-2 s-1]
  1003. ! RT_peL precipitation rate (at sfc) of hail (large only) [m+3 m-2 s-1]
  1004. ! SSxx S/S terms (for testing purposes)
  1005. ! SLW supercooled liquid water content [kg m-3]
  1006. ! VIS visibility resulting from fog, rain, snow [m]
  1007. ! VIS1 visibility component through liquid cloud (fog) [m]
  1008. ! VIS2 visibility component through rain [m]
  1009. ! VIS3 visibility component through snow [m]
  1010. ! ZET total equivalent radar reflectivity [dBZ]
  1011. ! ZEC composite (column-max) of ZET [dBZ]
  1012. !_______________________________________________________________________________________!
  1013. !LOCAL VARIABLES:
  1014. !Variables to count active grid points:
  1015. logical :: log1,log2,log3,log4,doneK,rainPresent,calcDiag,CB_found,ML_found, &
  1016. SN_found
  1017. logical, dimension(size(QC,dim=1),size(QC,dim=2)) :: activePoint
  1018. integer, dimension(size(QC,dim=1)) :: ktop_sedi
  1019. integer :: i,k,niter,ll,start
  1020. real :: tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,tmp9,tmp10, &
  1021. VDmax,NNUmax,X,D,DEL,QREVP,NuDEPSOR,NuCONTA,NuCONTB,NuCONTC,iMUkin,Ecg,Erg, &
  1022. NuCONT,GG,Na,Tcc,F1,F2,Kdiff,PSIa,Kn,source,sink,sour,ratio,qvs0,Kstoke, &
  1023. DELqvs,ft,esi,Si,Simax,Vq,Vn,Vz,LAMr,No_r_DM,No_i,No_s,No_g,No_h,D_sll, &
  1024. iABi,ABw,VENTr,VENTs,VENTg,VENTi,VENTh,Cdiff,Ka,MUdyn,MUkin,DEo,Ng_tail, &
  1025. gam,ScTHRD,Tc,mi,ff,Ec,Ntr,Dho,DMrain,Ech,DMice,DMsnow,DMgrpl,DMhail, &
  1026. ssat,Swmax,dey,Esh,Eii,Eis,Ess,Eig,Eih,FRAC,JJ,Dirg,Dirh,Dsrs,Dsrg,Dsrh, &
  1027. Dgrg,Dgrh,SIGc,L,TAU,DrAUT,DrINIT,Di,Ds,Dg,Dh,qFact,nFact,Ki,Rz,NgCNgh, &
  1028. vr0,vi0,vs0,vg0,vh0,Dc,Dr,QCLcs,QCLrs,QCLis,QCLcg,QCLrg,QCLig,NhCNgh, &
  1029. QCLch,QCLrh,QCLsh,QMLir,QMLsr,QMLgr,QMLhr,QCLih,QVDvg,QVDvh,QSHhr, &
  1030. QFZci,QNUvi,QVDvi,QCNis,QCNis1,QCNis2,QCLir,QCLri,QCNsg,QCLsr,QCNgh, &
  1031. QCLgr,QHwet,QVDvs,QFZrh,QIMsi,QIMgi,NMLhr,NVDvh,NCLir,NCLri,NCLrh, &
  1032. NCLch,NCLsr,NCLirg,NCLirh,NrFZrh,NhFZrh,NCLsrs,NCLsrg,NCLsrh,NCLgrg, &
  1033. NCLgrh,NVDvg,NMLgr,NiCNis,NsCNis,NVDvs,NMLsr,NCLsh,NCLss,NNUvi,NFZci,NVDvi, &
  1034. NCLis,NCLig,NCLih,NMLir,NCLrs,NCNsg,NCLcs,NCLcg,NIMsi,NIMgi,NCLgr,NCLrg, &
  1035. NSHhr,RCAUTR,RCACCR,CCACCR,CCSCOC,CCAUTR,CRSCOR,ALFx,des_pmlt,Ecs,des,ides, &
  1036. LAMx,iLAMx,iLAMxB0,Dx,ffx,iLAMc,iNCM,iNRM,iNYM,iNNM,iNGM,iLAMs_D3, &
  1037. iLAMg,iLAMg2,iLAMgB0,iLAMgB1,iLAMgB2,iLAMh,iLAMhB0,iLAMhB1,iLAMhB2,iNHM, &
  1038. iLAMi,iLAMi2,iLAMi3,iLAMi4,iLAMi5,iLAMiB0,iLAMiB1,iLAMiB2,iLAMr6,iLAMh2, &
  1039. iLAMs,iLAMs2,iLAMsB0,iLAMsB1,iLAMsB2,iLAMr,iLAMr2,iLAMr3,iLAMr4,iLAMr5, &
  1040. iLAMc2,iLAMc3,iLAMc4,iLAMc5,iLAMc6,iQCM,iQRM,iQIM,iQNM,iQGM,iQHM,iEih,iEsh, &
  1041. N_c,N_r,N_i,N_s,N_g,N_h,fluxV_i,fluxV_g,fluxV_s,rhos_mlt,fracLiq
  1042. !Variables that only need to be calulated on the first step (and saved):
  1043. real, save :: idt,iMUc,cmr,cmi,cms,cmg,cmh,icmr,icmi,icmg,icms,icmh,idew,idei, &
  1044. ideh,ideg,GC1,imso,icexc9,cexr1,cexr2,cexr3,No_s_SM,No_r,idms,imgo,icexs2, &
  1045. cexr4,cexr5,cexr6,cexr9,icexr9,ckQr1,ckQr2,ckQr3,ckQi1,ckQi2,ckQi3,ckQi4, &
  1046. icexi9,ckQs1,ckQs2,cexs1,cexs2,ckQg1,ckQg2,ckQg4,ckQh1,ckQh2,ckQh4,GR37,dms, &
  1047. LCP,LFP,LSP,ck5,ck6,PI2,PIov4,PIov6,CHLS,iCHLF,cxr,cxi,Gzr,Gzi,Gzs,Gzg,Gzh, &
  1048. N_c_SM,iGC1,GC2,GC3,GC4,GC5,iGC5,GC6,GC7,GC8,GC11,GC12,GC13,GC14,iGR34,mso, &
  1049. GC15,GR1,GR3,GR13,GR14,GR15,GR17,GR31,iGR31,GR32,GR33,GR34,GR35,GR36,GI4, &
  1050. GI6,GI20,GI21,GI22,GI31,GI32,GI33,GI34,GI35,iGI31,GI11,GI36,GI37,GI40,iGG34, &
  1051. GS09,GS11,GS12,GS13,iGS20,GS31,iGS31,GS32,GS33,GS34,GS35,GS36,GS40,iGS40, &
  1052. GS50,GG09,GG11,GG12,GG13,GG31,iGG31,GG32,GG33,GG34,GG35,GG36,GG40,iGG99,GH09,&
  1053. GH11,GH12,GH13,GH31,GH32,GH33,GH40,GR50,GG50,iGH34,GH50,iGH99,iGH31,iGS34, &
  1054. iGS20_D3,GS40_D3,cms_D3,eds,fds,rfact_FvFm
  1055. !Size distribution parameters:
  1056. real, parameter :: MUc = 3. !shape parameter for cloud
  1057. real, parameter :: alpha_c = 1. !shape parameter for cloud
  1058. real, parameter :: alpha_r = 0. !shape parameter for rain
  1059. real, parameter :: alpha_i = 0. !shape parameter for ice
  1060. real, parameter :: alpha_s = 0. !shape parameter for snow
  1061. real, parameter :: alpha_g = 0. !shape parameter for graupel
  1062. real, parameter :: alpha_h = 0. !shape parameter for hail
  1063. real, parameter :: No_s_max = 1.e+8 !max. allowable intercept for snow [m-4]
  1064. real, parameter :: lamdas_min= 500. !min. allowable LAMDA_s [m-1]
  1065. !For single-moment:
  1066. real, parameter :: No_r_SM = 1.e+7 !intercept parameter for rain [m-4]
  1067. real, parameter :: No_g_SM = 4.e+6 !intercept parameter for graupel [m-4]
  1068. real, parameter :: No_h_SM = 1.e+5 !intercept parameter for hail [m-4]
  1069. !note: No_s = f(T), rather than a fixed value
  1070. !------------------------------------!
  1071. ! Symbol convention: (dist. params.) ! MY05: Milbrandt & Yau, 2005a,b (JAS)
  1072. ! MY05 F94 CP00 ! F94: Ferrier, 1994 (JAS)
  1073. ! ------ -------- ------ ! CP00: Cohard & Pinty, 2000a,b (QJGR)
  1074. ! ALFx ALPHAx MUx-1 !
  1075. ! MUx (1) ALPHAx !
  1076. ! ALFx+1 ALPHAx+1 MUx !
  1077. !------------------------------------!
  1078. ! Note: The symbols for MU and ALPHA are REVERSED from that of CP2000a,b
  1079. ! Explicit appearance of MUr = 1. has been removed.
  1080. ! Fallspeed parameters:
  1081. real, parameter :: afr= 149.100, bfr= 0.5000 !Tripoloi and Cotton (1980)
  1082. real, parameter :: afi= 71.340, bfi= 0.6635 !Ferrier (1994)
  1083. real, parameter :: afs= 11.720, bfs= 0.4100 !Locatelli and Hobbs (1974)
  1084. real, parameter :: afg= 19.300, bfg= 0.3700 !Ferrier (1994)
  1085. real, parameter :: afh= 206.890, bfh= 0.6384 !Ferrier (1994)
  1086. !options:
  1087. !real, parameter :: afs= 8.996, bfs= 0.4200 !Ferrier (1994)
  1088. !real, parameter :: afg= 6.4800, bfg= 0.2400 !LH74 (grpl-like snow of lump type)
  1089. real, parameter :: epsQ = 1.e-14 !kg kg-1, min. allowable mixing ratio
  1090. real, parameter :: epsN = 1.e-3 !m-3, min. allowable number concentration
  1091. real, parameter :: epsQ2 = 1.e-6 !kg kg-1, mixing ratio threshold for diagnostics
  1092. real, parameter :: epsVIS= 1. !m, min. allowable visibility
  1093. real, parameter :: iLAMmin1= 1.e-6 !min. iLAMx (prevents underflow in Nox and VENTx calcs)
  1094. real, parameter :: iLAMmin2= 1.e-10 !min. iLAMx (prevents underflow in Nox and VENTx calcs)
  1095. real, parameter :: eps = 1.e-32
  1096. real, parameter :: k1 = 0.001
  1097. real, parameter :: k2 = 0.0005
  1098. real, parameter :: k3 = 2.54
  1099. real, parameter :: CPW = 4218., CPI=2093.
  1100. real, parameter :: deg = 400., mgo= 1.6e-10
  1101. real, parameter :: deh = 900.
  1102. real, parameter :: dei = 500., mio=1.e-12, Nti0=1.e3
  1103. real, parameter :: dew = 1000.
  1104. real, parameter :: desFix= 100. !used for snowSpherical = .true.
  1105. real, parameter :: desMax= 500.
  1106. real, parameter :: Dso = 125.e-6 ![m]; embryo snow diameter (mean-volume particle)
  1107. real, parameter :: dmr = 3., dmi= 3., dmg= 3., dmh= 3.
  1108. ! NOTE: VxMAX below are the max.allowable mass-weighted fallspeeds for sedimentation.
  1109. ! Thus, Vx corresponds to DxMAX (at sea-level) times the max. density factor, GAM.
  1110. ! [GAMmax=sqrt(DEo/DEmin)=sqrt(1.25/0.4)~2.] e.g. VrMAX = 2.*8.m/s = 16.m/s
  1111. real, parameter :: DrMax= 5.e-3, VrMax= 16., epsQr_sedi= 1.e-8
  1112. real, parameter :: DiMax= 5.e-3, ViMax= 2., epsQi_sedi= 1.e-10
  1113. real, parameter :: DsMax= 5.e-3, VsMax= 2., epsQs_sedi= 1.e-8
  1114. real, parameter :: DgMax= 50.e-3, VgMax= 8., epsQg_sedi= 1.e-8
  1115. real, parameter :: DhMax= 80.e-3, VhMax= 25., epsQh_sedi= 1.e-10
  1116. real, parameter :: thrd = 1./3.
  1117. real, parameter :: sixth = 0.5*thrd
  1118. real, parameter :: Ers = 1., Eci= 1. !collection efficiencies, Exy, between categories x and y
  1119. real, parameter :: Eri = 1., Erh= 1.
  1120. real, parameter :: Xdisp = 0.25 !dispersion of the fall velocity of ice
  1121. real, parameter :: aa11 = 9.44e15, aa22= 5.78e3, Rh= 41.e-6
  1122. real, parameter :: Avx = 0.78, Bvx= 0.30 !ventilation coefficients [F94 (B.36)]
  1123. real, parameter :: Abigg = 0.66, Bbigg= 100. !parameters in probabilistic freezing
  1124. real, parameter :: fdielec = 4.464 !ratio of dielectric factor, |K|w**2/|K|i**2
  1125. real, parameter :: zfact = 1.e+18 !conversion factor for m-3 to mm2 m-6 for Ze
  1126. real, parameter :: minZET = -99. ![dBZ] min threshold for ZET
  1127. real, parameter :: maxVIS = 99.e+3 ![m] max. allowable VIS (visibility)
  1128. real, parameter :: Drshed = 0.001 ![m] mean diam. of drop shed during wet growth
  1129. real, parameter :: SIGcTHRS = 15.e-6 !threshold cld std.dev. before autoconversion
  1130. real, parameter :: KK1 = 3.03e3 !parameter in Long (1974) kernel
  1131. real, parameter :: KK2 = 2.59e15 !parameter in Long (1974) kernel
  1132. real, parameter :: Dhh = 82.e-6 ![m] diameter that rain hump first appears
  1133. real, parameter :: gzMax_sedi = 200000. !GZ value below which sedimentation is computed
  1134. real, parameter :: Dr_large = 200.e-6 ![m] size threshold to distinguish rain/drizzle for precip rates
  1135. real, parameter :: Ds_large = 200.e-6 ![m] size threshold to distinguish snow/snow-grains for precip rates
  1136. real, parameter :: Dh_large = 1.0e-2 ![m] size threshold for "large" hail precipitation rate
  1137. real, parameter :: Dh_min = 5.0e-3 ![m] size threhsold for below which hail converts to graupel
  1138. real, parameter :: Dr_3cmpThrs = 2.5e-3 ![m] size threshold for hail production from 3-comp freezing
  1139. real, parameter :: w_CNgh = 3. ![m s-1] vertical motion threshold for CNgh
  1140. ! real, parameter :: r_CNgh = 0.05 !Dg/Dho ratio threshold for CNgh
  1141. real, parameter :: Ngh_crit = 0.01 ![m-3] critical graupel concentration for CNgh
  1142. real, parameter :: Tc_FZrh = -10. !temp-threshold (C) for FZrh
  1143. real, parameter :: CNsgThres = 1.0 !threshold for CLcs/VDvs ratio for CNsg
  1144. real, parameter :: capFact_i = 0.5 !capacitace factor for ice (C= 0.5*D*capFact_i)
  1145. real, parameter :: capFact_s = 0.5 !capacitace factor for snow (C= 0.5*D*capFact_s)
  1146. real, parameter :: noVal_h_XX = -1. !non-value indicator for h_CB, h_ML1, h_ML2, h_SN
  1147. real, parameter :: minSnowSize = 1.e-4 ![m] snow size threshold to compute h_SN
  1148. real, parameter :: Fv_Dsmin = 125.e-6 ![m] min snow size to compute volume flux
  1149. real, parameter :: Fv_Dsmax = 0.008 ![m] max snow size to compute volume flux
  1150. real, parameter :: Ni_max = 1.e+7 ![m-3] max ice crystal concentration
  1151. !-- For GEM:
  1152. !#include "consphy.cdk"
  1153. !#include "dintern.cdk"
  1154. !#include "fintern.cdk"
  1155. !-- For WRF:
  1156. !------------------------------------------------------------------------------!
  1157. !#include "consphy.cdk"
  1158. ! real, parameter :: CPD =.100546e+4 !J K-1 kg-1; specific heat of dry air
  1159. ! real, parameter :: CPV =.186946e+4 !J K-1 kg-1; specific heat of water vapour
  1160. ! real, parameter :: RGASD =.28705e+3 !J K-1 kg-1; gas constant for dry air
  1161. ! real, parameter :: RGASV =.46151e+3 !J K-1 kg-1; gas constant for water vapour
  1162. real, parameter :: TRPL =.27316e+3 !K; triple point of water
  1163. real, parameter :: TCDK =.27315e+3 !conversion from kelvin to celsius
  1164. real, parameter :: RAUW =.1e+4 !density of liquid H2O
  1165. ! real, parameter :: EPS1 =.62194800221014 !RGASD/RGASV
  1166. real, parameter :: EPS2 =.3780199778986 !1 - EPS1
  1167. ! real, parameter :: DELTA =.6077686814144 !1/EPS1 - 1
  1168. ! real, parameter :: CAPPA =.28549121795 !RGASD/CPD
  1169. real, parameter :: TGL =.27316e+3 !K; ice temperature in the atmosphere
  1170. real, parameter :: CONSOL =.1367e+4 !W m-2; solar constant
  1171. ! real, parameter :: GRAV =.980616e+1 !M s-2; gravitational acceleration
  1172. real, parameter :: RAYT =.637122e+7 !M; mean radius of the earth
  1173. real, parameter :: STEFAN =.566948e-7 !J m-2 s-1 K-4; Stefan-Boltzmann constant
  1174. real, parameter :: PI =.314159265359e+1 !PI constant = ACOS(-1)
  1175. real, parameter :: OMEGA =.7292e-4 !s-1; angular speed of rotation of the earth
  1176. real, parameter :: KNAMS =.514791 !conversion from knots to m/s
  1177. real, parameter :: STLO =.6628486583943e-3 !K s2 m-2; Schuman-Newell Lapse Rate
  1178. real, parameter :: KARMAN =.35 !Von Karman constant
  1179. real, parameter :: RIC =.2 !Critical Richardson number
  1180. ! real, parameter :: CHLC =.2501e+7 !J kg-1; latent heat of condensation
  1181. ! real, parameter :: CHLF =.334e+6 !J kg-1; latent heat of fusion
  1182. !------------------------------------------------------------------------------!
  1183. !#include "dintern.cdk"
  1184. REAL TTT, PRS, QQQ, EEE, TVI, QST, QQH
  1185. REAL T00, PR0, TF, PF,FFF , DDFF
  1186. REAL QSM , DLEMX
  1187. REAL*8 FOEW,FODLE,FOQST,FODQS,FOEFQ,FOQFE,FOTVT,FOTTV,FOHR
  1188. REAL*8 FOLV,FOLS,FOPOIT,FOPOIP,FOTTVH,FOTVHT
  1189. REAL*8 FOEWA,FODLA,FOQSA,FODQA,FOHRA
  1190. REAL*8 FESI,FDLESI,FESMX,FDLESMX,FQSMX,FDQSMX
  1191. !------------------------------------------------------------------------------!
  1192. !#include "fintern.cdk"
  1193. ! DEFINITION DES FONCTIONS THERMODYNAMIQUES DE BASE
  1194. ! POUR LES CONSTANTES, UTILISER LE COMMON /CONSPHY/
  1195. ! NOTE: TOUTES LES FONCTIONS TRAVAILLENT AVEC LES UNITES S.I.
  1196. ! I.E. TTT EN DEG K, PRS EN PA, QQQ EN KG/KG
  1197. ! *** N. BRUNET - MAI 90 ***
  1198. ! * REVISION 01 - MAI 94 - N. BRUNET
  1199. ! NOUVELLE VERSION POUR FAIBLES PRESSIONS
  1200. ! * REVISION 02 - AOUT 2000 - J-P TOVIESSI
  1201. ! CALCUL EN REAL*8
  1202. ! * REVISION 03 - SEPT 2000 - N. BRUNET
  1203. ! AJOUT DE NOUVELLES FONCTIONS
  1204. ! * REVISION 04 - JANV 2000 - J. MAILHOT
  1205. ! FONCTIONS EN PHASE MIXTE
  1206. ! * REVISION 05 - DEC 2001 - G. LEMAY
  1207. ! DOUBLE PRECISION POUR PHASE MIXTE
  1208. ! * REVISION 06 - AVR 2002 - A. PLANTE
  1209. ! AJOUT DES NOUVELLES FONCTIONS FOTTVH ET FOTVHT
  1210. !
  1211. ! FONCTION DE TENSION DE VAPEUR SATURANTE (TETENS) - EW OU EI SELON TT
  1212. FOEW(TTT) = 610.78D0*DEXP( DMIN1(DSIGN(17.269D0, &
  1213. DBLE(TTT)-DBLE(TRPL)),DSIGN &
  1214. (21.875D0,DBLE(TTT)-DBLE(TRPL)))*DABS(DBLE(TTT)-DBLE(TRPL))/ &
  1215. (DBLE(TTT)-35.86D0+DMAX1(0.D0,DSIGN &
  1216. (28.2D0,DBLE(TRPL)-DBLE(TTT)))))
  1217. !
  1218. ! FONCTION CALCULANT LA DERIVEE SELON T DE LN EW (OU LN EI)
  1219. FODLE(TTT)=(4097.93D0+DMAX1(0.D0,DSIGN(1709.88D0, &
  1220. DBLE(TRPL)-DBLE(TTT)))) &
  1221. /((DBLE(TTT)-35.86D0+DMAX1(0.D0,DSIGN(28.2D0, &
  1222. DBLE(TRPL)-DBLE(TTT))))*(DBLE(TTT)-35.86D0+DMAX1(0.D0 &
  1223. ,DSIGN(28.2D0,DBLE(TRPL)-DBLE(TTT)))))
  1224. !
  1225. ! FONCTION CALCULANT L'HUMIDITE SPECIFIQUE SATURANTE (QSAT)
  1226. FOQST(TTT,PRS) = DBLE(EPS1)/(DMAX1(1.D0,DBLE(PRS)/FOEW(TTT))- &
  1227. DBLE(EPS2))
  1228. !
  1229. ! FONCTION CALCULANT LA DERIVEE DE QSAT SELON T
  1230. FODQS(QST,TTT)=DBLE(QST)*(1.D0+DBLE(DELTA)*DBLE(QST))*FODLE(TTT)
  1231. ! QST EST LA SORTIE DE FOQST
  1232. !
  1233. ! FONCTION CALCULANT TENSION VAP (EEE) FN DE HUM SP (QQQ) ET PRS
  1234. FOEFQ(QQQ,PRS) = DMIN1(DBLE(PRS),(DBLE(QQQ)*DBLE(PRS)) / &
  1235. (DBLE(EPS1) + DBLE(EPS2)*DBLE(QQQ)))
  1236. !
  1237. ! FONCTION CALCULANT HUM SP (QQQ) DE TENS. VAP (EEE) ET PRES (PRS)
  1238. FOQFE(EEE,PRS) = DMIN1(1.D0,DBLE(EPS1)*DBLE(EEE)/(DBLE(PRS)- &
  1239. DBLE(EPS2)*DBLE(EEE)))
  1240. !
  1241. ! FONCTION CALCULANT TEMP VIRT. (TVI) DE TEMP (TTT) ET HUM SP (QQQ)
  1242. FOTVT(TTT,QQQ) = DBLE(TTT) * (1.0D0 + DBLE(DELTA)*DBLE(QQQ))
  1243. ! FONCTION CALCULANT TEMP VIRT. (TVI) DE TEMP (TTT), HUM SP (QQQ) ET
  1244. ! MASSE SP DES HYDROMETEORES.
  1245. FOTVHT(TTT,QQQ,QQH) = DBLE(TTT) * &
  1246. (1.0D0 + DBLE(DELTA)*DBLE(QQQ) - DBLE(QQH))
  1247. !
  1248. ! FONCTION CALCULANT TTT DE TEMP VIRT. (TVI) ET HUM SP (QQQ)
  1249. FOTTV(TVI,QQQ) = DBLE(TVI) / (1.0D0 + DBLE(DELTA)*DBLE(QQQ))
  1250. ! FONCTION CALCULANT TTT DE TEMP VIRT. (TVI), HUM SP (QQQ) ET
  1251. ! MASSE SP DES HYDROMETEORES (QQH)
  1252. FOTTVH(TVI,QQQ,QQH) = DBLE(TVI) / &
  1253. (1.0D0 + DBLE(DELTA)*DBLE(QQQ) - DBLE(QQH))
  1254. !
  1255. ! FONCTION CALCULANT HUM REL DE HUM SP (QQQ), TEMP (TTT) ET PRES (PRS)
  1256. ! HR = E/ESAT
  1257. #if (DWORDSIZE == 8 && RWORDSIZE == 8)
  1258. FOHR(QQQ,TTT,PRS) = MIN( PRS ,FOEFQ(QQQ,PRS)) / FOEW(TTT)
  1259. #elif (DWORDSIZE == 8 && RWORDSIZE == 4)
  1260. FOHR(QQQ,TTT,PRS) = MIN(DBLE(PRS),FOEFQ(QQQ,PRS)) / FOEW(TTT)
  1261. #else
  1262. This is a temporary hack assuming double precision is 8 bytes.
  1263. #endif
  1264. !
  1265. ! FONCTION CALCULANT LA CHALEUR LATENTE DE CONDENSATION
  1266. FOLV(TTT) =DBLE(CHLC) - 2317.D0*(DBLE(TTT)-DBLE(TRPL))
  1267. !
  1268. ! FONCTION CALCULANT LA CHALEUR LATENTE DE SUBLIMATION
  1269. FOLS(TTT) = DBLE(CHLC)+DBLE(CHLF)+(DBLE(CPV)- &
  1270. (7.24D0*DBLE(TTT)+128.4D0))*(DBLE(TTT)-DBLE(TRPL))
  1271. !
  1272. ! FONCTION RESOLVANT L'EQN. DE POISSON POUR LA TEMPERATURE
  1273. ! NOTE: SI PF=1000*100, "FOPOIT" DONNE LE THETA STANDARD
  1274. FOPOIT(T00,PR0,PF)=DBLE(T00)*(DBLE(PR0)/DBLE(PF))** &
  1275. (-DBLE(CAPPA))
  1276. !
  1277. ! FONCTION RESOLVANT L'EQN. DE POISSON POUR LA PRESSION
  1278. FOPOIP(T00,TF,PR0)=DBLE(PR0)*DEXP(-(DLOG(DBLE(T00)/DBLE(TF))/ &
  1279. DBLE(CAPPA)))
  1280. !
  1281. ! LES 5 FONCTIONS SUIVANTES SONT VALIDES DANS LE CONTEXTE OU ON
  1282. ! NE DESIRE PAS TENIR COMPTE DE LA PHASE GLACE DANS LES CALCULS
  1283. ! DE SATURATION.
  1284. ! FONCTION DE VAPEUR SATURANTE (TETENS)
  1285. FOEWA(TTT)=610.78D0*DEXP(17.269D0*(DBLE(TTT)-DBLE(TRPL))/ &
  1286. (DBLE(TTT)-35.86D0))
  1287. ! FONCTION CALCULANT LA DERIVEE SELON T DE LN EW
  1288. FODLA(TTT)=17.269D0*(DBLE(TRPL)-35.86D0)/(DBLE(TTT)-35.86D0)**2
  1289. ! FONCTION CALCULANT L'HUMIDITE SPECIFIQUE SATURANTE
  1290. FOQSA(TTT,PRS)=DBLE(EPS1)/(DMAX1(1.D0,DBLE(PRS)/FOEWA(TTT))- &
  1291. DBLE(EPS2))
  1292. ! FONCTION CALCULANT LA DERIVEE DE QSAT SELON T
  1293. FODQA(QST,TTT)=DBLE(QST)*(1.D0+DBLE(DELTA)*DBLE(QST))*FODLA(TTT)
  1294. ! FONCTION CALCULANT L'HUMIDITE RELATIVE
  1295. #if (DWORDSIZE == 8 && RWORDSIZE == 8)
  1296. FOHRA(QQQ,TTT,PRS)=MIN( PRS ,FOEFQ(QQQ,PRS))/FOEWA(TTT)
  1297. #elif (DWORDSIZE == 8 && RWORDSIZE == 4)
  1298. FOHRA(QQQ,TTT,PRS)=MIN(DBLE(PRS),FOEFQ(QQQ,PRS))/FOEWA(TTT)
  1299. #else
  1300. This is a temporary hack assuming double precision is 8 bytes.
  1301. #endif
  1302. !
  1303. !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  1304. !
  1305. ! Definition of basic thermodynamic functions in mixed-phase mode
  1306. ! FFF is the fraction of ice and DDFF its derivative w/r to T
  1307. ! NOTE: S.I. units are used
  1308. ! i.e. TTT in deg K, PRS in Pa
  1309. ! *** J. Mailhot - Jan. 2000 ***
  1310. !
  1311. ! Saturation calculations in presence of liquid phase only
  1312. ! Function for saturation vapor pressure (TETENS)
  1313. FESI(TTT)=610.78D0*DEXP(21.875D0*(DBLE(TTT)-DBLE(TRPL))/ &
  1314. (DBLE(TTT)-7.66D0) )
  1315. FDLESI(TTT)=21.875D0*(DBLE(TRPL)-7.66D0)/(DBLE(TTT)-7.66D0)**2
  1316. FESMX(TTT,FFF) = (1.D0-DBLE(FFF))*FOEWA(TTT)+DBLE(FFF)*FESI(TTT)
  1317. FDLESMX(TTT,FFF,DDFF) = ( (1.D0-DBLE(FFF))*FOEWA(TTT)*FODLA(TTT) &
  1318. + DBLE(FFF)*FESI(TTT)*FDLESI(TTT) &
  1319. + DBLE(DDFF)*(FESI(TTT)-FOEWA(TTT)) )/FESMX(TTT,FFF)
  1320. FQSMX(TTT,PRS,FFF) = DBLE(EPS1)/ &
  1321. (DMAX1(1.D0,DBLE(PRS)/FESMX(TTT,FFF) ) - DBLE(EPS2) )
  1322. FDQSMX(QSM,DLEMX) = DBLE(QSM ) *(1.D0 + DBLE(DELTA)* DBLE(QSM ) ) &
  1323. * DBLE(DLEMX )
  1324. !
  1325. ! ! !------------------------------------------------------------------------------!
  1326. !***** END of Replace 3 #includes (for WRF) ***
  1327. ! Constants used for contact ice nucleation:
  1328. real, parameter :: LAMa0 = 6.6e-8 ![m] mean free path at T0 and p0 [W95_eqn58]
  1329. real, parameter :: T0 = 293.15 ![K] ref. temp.
  1330. real, parameter :: p0 = 101325. ![Pa] ref. pres.
  1331. real, parameter :: Ra = 1.e-6 ![m] aerosol (IN) radius [M92 p.713; W95_eqn60]
  1332. real, parameter :: kBoltz = 1.381e-23 !Boltzmann's constant
  1333. real, parameter :: KAPa = 5.39e5 !aerosol thermal conductivity
  1334. !Test switches:
  1335. logical, parameter :: iceDep_ON = .true. !.false. to suppress depositional growth of ice
  1336. logical, parameter :: grpl_ON = .true. !.false. to suppress graupel initiation
  1337. logical, parameter :: hail_ON = .true. !.false. to suppress hail initiation
  1338. logical, parameter :: rainAccr_ON = .true. ! rain accretion and self-collection ON/OFF
  1339. logical, parameter :: snowSpherical = .false. !.true.: m(D)=(pi/6)*const_des*D^3 | .false.: m(D)= 0.069*D^2
  1340. integer, parameter :: primIceNucl = 1 !1= Meyers+contact ; 2= Cooper
  1341. real, parameter :: outfreq = 60. !frequency to compute output diagnostics [s]
  1342. !Passed as physics namelist parameters:
  1343. ! logical, parameter :: precipDiag_ON = .true. !.false. to suppress calc. of sfc precip types
  1344. ! logical, parameter :: sedi_ON = .true. !.false. to suppress sedimentation
  1345. ! logical, parameter :: warmphase_ON = .true. !.false. to suppress warm-phase (Part II)
  1346. ! logical, parameter :: autoconv_ON = .true. ! autoconversion ON/OFF
  1347. ! logical, parameter :: icephase_ON = .true. !.false. to suppress ice-phase (Part I)
  1348. ! logical, parameter :: snow_ON = .true. !.false. to suppress snow initiation
  1349. ! logical, parameter :: initN = .true. !.true. to initialize Nx of Qx>0 and Nx=0
  1350. real, dimension(size(QC,dim=1),size(QC,dim=2)) :: DE,iDE,DP,QSS,QSW,QSI,WZ,DZ,RHOQX,FLIM, &
  1351. VQQ,gamfact,gamfact_r,massFlux3D_r,massFlux3D_s
  1352. real, dimension(size(QC,dim=1)) :: fluxM_r,fluxM_i,fluxM_s,fluxM_g,fluxM_h, &
  1353. HPS,dum
  1354. integer, dimension(size(QC,dim=1)) :: activeColumn
  1355. !==================================================================================!
  1356. !----------------------------------------------------------------------------------!
  1357. ! PART 1: Prelimiary Calculations !
  1358. !----------------------------------------------------------------------------------!
  1359. !-------------
  1360. !Convert N from #/kg to #/m3:
  1361. do k= 1,nk
  1362. do i= 1,ni
  1363. tmp1= S(i,k)*PSM(i)/(RGASD*TM(i,k)) !air density at time (t-1)
  1364. tmp2= S(i,k)*PS(i)/(RGASD*T(i,k)) !air density at time (*)
  1365. NCM(i,k)= NCM(i,k)*tmp1; NC(i,k)= NC(i,k)*tmp2
  1366. NRM(i,k)= NRM(i,k)*tmp1; NR(i,k)= NR(i,k)*tmp2
  1367. NYM(i,k)= NYM(i,k)*tmp1; NY(i,k)= NY(i,k)*tmp2
  1368. NNM(i,k)= NNM(i,k)*tmp1; NN(i,k)= NN(i,k)*tmp2
  1369. NGM(i,k)= NGM(i,k)*tmp1; NG(i,k)= NG(i,k)*tmp2
  1370. NHM(i,k)= NHM(i,k)*tmp1; NH(i,k)= NH(i,k)*tmp2
  1371. enddo
  1372. enddo
  1373. !=============
  1374. ! The SSxx arrays are for passed to the volatile bus for output as 3-D diagnostic
  1375. ! output variables, for testing purposes. For example, to output the
  1376. ! instantanous value of the deposition rate, add 'SS01(i,k) = QVDvi' in the
  1377. ! appropriate place. It can then be output as a 3-D physics variable by adding
  1378. ! it to the sortie_p list in 'outcfgs.out'
  1379. SS01= 0.; SS02= 0.; SS03= 0.; SS04= 0.; SS05= 0.; SS06= 0.; SS07= 0.; SS08= 0.
  1380. SS09= 0.; SS10= 0.; SS11= 0.; SS12= 0.; SS13= 0.; SS14= 0.; SS15= 0.; SS16= 0.
  1381. SS17= 0.; SS18= 0.; SS19= 0.; SS20= 0.
  1382. !Determine the upper-most level in each column to which to compute sedimentation:
  1383. ktop_sedi= 0
  1384. do i=1,ni
  1385. do k=1,nk
  1386. ktop_sedi(i)= k
  1387. if (GZ(i,k)<gzMax_sedi) exit
  1388. enddo
  1389. enddo
  1390. !Compute diagnostic values only every 'outfreq' minutes:
  1391. !calcDiag= (mod(DT*float(KOUNT),outfreq)==0.)
  1392. calcDiag = .true. !compute diagnostics every step (for time-series output)
  1393. !#### These need only to be computed once per model integration:
  1394. ! (note: These variables must be declared with the SAVE attribute)
  1395. ! if (KOUNT==0) then
  1396. !*** For restarts, these values are not saved. Therefore, the condition statement
  1397. ! must be modified to something like: IF (MOD(Step_rsti,KOUNT).eq.0) THEN
  1398. ! in order that these be computed only on the first step of a given restart.
  1399. ! (...to be done. For now, changing condition to IF(TRUE) to compute at each step.)
  1400. if (.TRUE.) then
  1401. PI2 = PI*2.
  1402. PIov4 = 0.25*PI
  1403. PIov6 = PI*sixth
  1404. CHLS = CHLC+CHLF !J k-1; latent heat of sublimation
  1405. LCP = CHLC/CPD
  1406. LFP = CHLF/CPD
  1407. iCHLF = 1./CHLF
  1408. LSP = LCP+LFP
  1409. ck5 = 4098.170*LCP
  1410. ck6 = 5806.485*LSP
  1411. idt = 1./dt
  1412. imgo = 1./mgo
  1413. idew = 1./dew
  1414. idei = 1./dei
  1415. ideg = 1./deg
  1416. ideh = 1./deh
  1417. !Constants based on size distribution parameters:
  1418. ! Mass parameters [ m(D) = cD^d ]
  1419. cmr = PIov6*dew; icmr= 1./cmr
  1420. cmi = 440.; icmi= 1./cmi
  1421. cmg = PIov6*deg; icmg= 1./cmg
  1422. cmh = PIov6*deh; icmh= 1./cmh
  1423. cms_D3 = PIov6*desFix !used for snowSpherical = .T. or .F.
  1424. if (snowSpherical) then
  1425. cms = cms_D3
  1426. dms = 3.
  1427. else
  1428. ! cms = 0.0690; dms = 2.000 !Cox, 1988 (QJRMS)
  1429. cms = 0.1597; dms = 2.078 !Brandes et al., 2007 (JAMC)
  1430. endif
  1431. icms = 1./cms
  1432. idms = 1./dms
  1433. mso = cms*Dso**dms
  1434. imso = 1./mso
  1435. !bulk density parameters: [rho(D) = eds*D^fds]
  1436. ! These are implied by the mass-diameter parameters, by computing the bulk
  1437. ! density of a sphere with the equaivalent mass.
  1438. ! e.g. m(D) = cD^d = (pi/6)rhoD^3 and solve for rho(D)
  1439. eds = cms/PIov6
  1440. fds = dms-3.
  1441. if (fds/=-1. .and..not.snowSpherical) GS50= gamma(1.+fds+alpha_s)
  1442. ! Cloud:
  1443. iMUc = 1./MUc
  1444. GC1 = gamma(alpha_c+1.0)
  1445. iGC1 = 1./GC1
  1446. GC2 = gamma(alpha_c+1.+3.0*iMUc) !i.e. gamma(alf + 4)
  1447. GC3 = gamma(alpha_c+1.+6.0*iMUc) !i.e. gamma(alf + 7)
  1448. GC4 = gamma(alpha_c+1.+9.0*iMUc) !i.e. gamma(alf + 10)
  1449. GC11 = gamma(1.0*iMUc+1.0+alpha_c)
  1450. GC12 = gamma(2.0*iMUc+1.0+alpha_c)
  1451. GC5 = gamma(1.0+alpha_c)
  1452. iGC5 = 1./GC5
  1453. GC6 = gamma(1.0+alpha_c+1.0*iMUc)
  1454. GC7 = gamma(1.0+alpha_c+2.0*iMUc)
  1455. GC8 = gamma(1.0+alpha_c+3.0*iMUc)
  1456. GC13 = gamma(3.0*iMUc+1.0+alpha_c)
  1457. GC14 = gamma(4.0*iMUc+1.0+alpha_c)
  1458. GC15 = gamma(5.0*iMUc+1.0+alpha_c)
  1459. icexc9 = 1./(GC2*iGC1*PIov6*dew)
  1460. !specify cloud droplet number concentration [m-3] based on 'CCNtype' (1-moment):
  1461. if (CCNtype==1) then
  1462. N_c_SM = 0.8e+8 !maritime
  1463. elseif (CCNtype==2) then
  1464. N_c_SM = 2.0e+8 !continental 1
  1465. elseif (CCNtype==3) then
  1466. N_c_SM = 5.0e+8 !continental 2 (polluted)
  1467. else
  1468. N_c_SM = 2.0e+8 !default (cont1), if 'CCNtype' specified incorrectly
  1469. endif
  1470. ! Rain:
  1471. cexr1 = 1.+alpha_r+dmr+bfr
  1472. cexr2 = 1.+alpha_r+dmr
  1473. GR17 = gamma(2.5+alpha_r+0.5*bfr)
  1474. GR31 = gamma(1.+alpha_r)
  1475. iGR31 = 1./GR31
  1476. GR32 = gamma(2.+alpha_r)
  1477. GR33 = gamma(3.+alpha_r)
  1478. GR34 = gamma(4.+alpha_r)
  1479. iGR34 = 1./GR34
  1480. GR35 = gamma(5.+alpha_r)
  1481. GR36 = gamma(6.+alpha_r)
  1482. GR37 = gamma(7.+alpha_r)
  1483. GR50 = (No_r_SM*GR31)**0.75 !for 1-moment or Nr-initialization
  1484. cexr5 = 2.+alpha_r
  1485. cexr6 = 2.5+alpha_r+0.5*bfr
  1486. cexr9 = cmr*GR34*iGR31; icexr9= 1./cexr9
  1487. cexr3 = 1.+bfr+alpha_r
  1488. cexr4 = 1.+alpha_r
  1489. ckQr1 = afr*gamma(1.+alpha_r+dmr+bfr)/gamma(1.+alpha_r+dmr)
  1490. ckQr2 = afr*gamma(1.+alpha_r+bfr)*GR31
  1491. ckQr3 = afr*gamma(7.+alpha_r+bfr)/GR37
  1492. if (.not.dblMom_r) then
  1493. No_r = No_r_SM
  1494. endif
  1495. ! Ice:
  1496. GI4 = gamma(alpha_i+dmi+bfi)
  1497. GI6 = gamma(2.5+bfi*0.5+alpha_i)
  1498. GI11 = gamma(1.+bfi+alpha_i)
  1499. GI20 = gamma(0.+bfi+1.+alpha_i)
  1500. GI21 = gamma(1.+bfi+1.+alpha_i)
  1501. GI22 = gamma(2.+bfi+1.+alpha_i)
  1502. GI31 = gamma(1.+alpha_i)
  1503. iGI31 = 1./GI31
  1504. GI32 = gamma(2.+alpha_i)
  1505. GI33 = gamma(3.+alpha_i)
  1506. GI34 = gamma(4.+alpha_i)
  1507. GI35 = gamma(5.+alpha_i)
  1508. GI36 = gamma(6.+alpha_i)
  1509. GI40 = gamma(1.+alpha_i+dmi)
  1510. icexi9 = 1./(cmi*gamma(1.+alpha_i+dmi)*iGI31)
  1511. ckQi1 = afi*gamma(1.+alpha_i+dmi+bfi)/GI40
  1512. ckQi2 = afi*GI11*iGI31
  1513. ckQi4 = 1./(cmi*GI40*iGI31)
  1514. ! Snow:
  1515. cexs1 = 2.5+0.5*bfs+alpha_s
  1516. cexs2 = 1.+alpha_s+dms
  1517. icexs2 = 1./cexs2
  1518. GS09 = gamma(2.5+bfs*0.5+alpha_s)
  1519. GS11 = gamma(1.+bfs+alpha_s)
  1520. GS12 = gamma(2.+bfs+alpha_s)
  1521. GS13 = gamma(3.+bfs+alpha_s)
  1522. GS31 = gamma(1.+alpha_s)
  1523. iGS31 = 1./GS31
  1524. GS32 = gamma(2.+alpha_s)
  1525. GS33 = gamma(3.+alpha_s)
  1526. GS34 = gamma(4.+alpha_s)
  1527. iGS34 = 1./GS34
  1528. GS35 = gamma(5.+alpha_s)
  1529. GS36 = gamma(6.+alpha_s)
  1530. GS40 = gamma(1.+alpha_s+dms)
  1531. iGS40 = 1./GS40
  1532. iGS20 = 1./(GS40*iGS31*cms)
  1533. ckQs1 = afs*gamma(1.+alpha_s+dms+bfs)*iGS40
  1534. ckQs2 = afs*GS11*iGS31
  1535. GS40_D3 = gamma(1.+alpha_s+3.)
  1536. iGS20_D3= 1./(GS40_D3*iGS31*cms_D3)
  1537. rfact_FvFm= PIov6*icms*gamma(4.+bfs+alpha_s)/gamma(1.+dms+bfs+alpha_s)
  1538. ! Graupel:
  1539. GG09 = gamma(2.5+0.5*bfg+alpha_g)
  1540. GG11 = gamma(1.+bfg+alpha_g)
  1541. GG12 = gamma(2.+bfg+alpha_g)
  1542. GG13 = gamma(3.+bfg+alpha_g)
  1543. GG31 = gamma(1.+alpha_g)
  1544. iGG31 = 1./GG31
  1545. GG32 = gamma(2.+alpha_g)
  1546. GG33 = gamma(3.+alpha_g)
  1547. GG34 = gamma(4.+alpha_g)
  1548. iGG34 = 1./GG34
  1549. GG35 = gamma(5.+alpha_g)
  1550. GG36 = gamma(6.+alpha_g)
  1551. GG40 = gamma(1.+alpha_g+dmg)
  1552. iGG99 = 1./(GG40*iGG31*cmg)
  1553. GG50 = (No_g_SM*GG31)**0.75 !for 1-moment only
  1554. ckQg1 = afg*gamma(1.+alpha_g+dmg+bfg)/GG40
  1555. ckQg2 = afg*GG11*iGG31
  1556. ckQg4 = 1./(cmg*GG40*iGG31)
  1557. ! Hail:
  1558. GH09 = gamma(2.5+bfh*0.5+alpha_h)
  1559. GH11 = gamma(1.+bfh+alpha_h)
  1560. GH12 = gamma(2.+bfh+alpha_h)
  1561. GH13 = gamma(3.+bfh+alpha_h)
  1562. GH31 = gamma(1.+alpha_h)
  1563. iGH31 = 1./GH31
  1564. GH32 = gamma(2.+alpha_h)
  1565. GH33 = gamma(3.+alpha_h)
  1566. iGH34 = 1./gamma(4.+alpha_h)
  1567. GH40 = gamma(1.+alpha_h+dmh)
  1568. iGH99 = 1./(GH40*iGH31*cmh)
  1569. GH50 = (No_h_SM*GH31)**0.75 !for 1-moment only
  1570. ckQh1 = afh*gamma(1.+alpha_h+dmh+bfh)/GH40
  1571. ckQh2 = afh*GH11*iGH31
  1572. ckQh4 = 1./(cmh*GH40*iGH31)
  1573. endif !if (KOUNT=0)
  1574. !####
  1575. !=======================================================================================!
  1576. !Compute thickness of layers for sedimentation calcuation:
  1577. ! (note; 'GZ' passed in is geopotential, not geopotential height)
  1578. tmp1= 1./GRAV
  1579. do k=2,nk
  1580. DZ(:,k)= (GZ(:,k-1)-GZ(:,k))*tmp1
  1581. enddo
  1582. DZ(:,1)= DZ(:,2)
  1583. ! Temporarily store arrays at time (t*) in order to compute (at the end of subroutine)
  1584. ! the final VXTEND as VXTEND = ( VX{t+1} - VX{t*} )/dt :
  1585. T_TEND = T ; Q_TEND = Q
  1586. QCTEND = QC; QRTEND = QR; QITEND = QI; QNTEND = QN; QGTEND = QG; QHTEND = QH
  1587. NCTEND = NC; NRTEND = NR; NYTEND = NY; NNTEND = NN; NGTEND = NG; NHTEND = NH
  1588. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  1589. ! Initialize Nx if Qx>0 and Nx=0: (for nesting from 1-moment to 2-moment):
  1590. IF (initN) THEN
  1591. do k= 1,nk
  1592. do i= 1,ni
  1593. tmp1= S(i,k)*PSM(i)/(RGASD*TM(i,k)) !air density at time (t-1)
  1594. tmp2= S(i,k)*PS(i)/(RGASD*T(i,k)) !air density at time (*)
  1595. !cloud:
  1596. if (QCM(i,k)>epsQ .and. NCM(i,k)<epsN) &
  1597. NCM(i,k)= N_c_SM
  1598. if (QC(i,k)>epsQ .and. NC(i,k)<epsN) &
  1599. NC(i,k) = N_c_SM
  1600. !rain
  1601. if (QRM(i,k)>epsQ .and. NRM(i,k)<epsN) &
  1602. NRM(i,k)= (No_r_SM*GR31)**(3./(4.+alpha_r))*(GR31*iGR34*tmp1*QRM(i,k)* &
  1603. icmr)**((1.+alpha_r)/(4.+alpha_r))
  1604. if (QR(i,k)>epsQ .and. NR(i,k)<epsN) &
  1605. NR(i,k)= (No_r_SM*GR31)**(3./(4.+alpha_r))*(GR31*iGR34*tmp2*QR(i,k)* &
  1606. icmr)**((1.+alpha_r)/(4.+alpha_r))
  1607. !ice:
  1608. if (QIM(i,k)>epsQ .and. NYM(i,k)<epsN) &
  1609. NYM(i,k)= N_Cooper(TRPL,TM(i,k))
  1610. if (QI(i,k)>epsQ .and. NY(i,k)<epsN) &
  1611. NY(i,k)= N_Cooper(TRPL,T(i,k))
  1612. !snow:
  1613. if (QNM(i,k)>epsQ .and. NNM(i,k)<epsN) then
  1614. No_s= Nos_Thompson(TRPL,TM(i,k))
  1615. NNM(i,k)= (No_s*GS31)**(dms*icexs2)*(GS31*iGS40*icms*tmp1*QNM(i,k))** &
  1616. ((1.+alpha_s)*icexs2)
  1617. endif
  1618. if (QN(i,k)>epsQ .and. NN(i,k)<epsN) then
  1619. No_s= Nos_Thompson(TRPL,T(i,k))
  1620. NN(i,k)= (No_s*GS31)**(dms*icexs2)*(GS31*iGS40*icms*tmp2*QN(i,k))** &
  1621. ((1.+alpha_s)*icexs2)
  1622. endif
  1623. !grpl:
  1624. if (QGM(i,k)>epsQ .and. NGM(i,k)<epsN) &
  1625. NGM(i,k)= (No_g_SM*GG31)**(3./(4.+alpha_g))*(GG31*iGG34*tmp1*QGM(i,k)* &
  1626. icmg)**((1.+alpha_g)/(4.+alpha_g))
  1627. if (QG(i,k)>epsQ .and. NG(i,k)<epsN) &
  1628. NG(i,k)= (No_g_SM*GG31)**(3./(4.+alpha_g))*(GG31*iGG34*tmp2*QG(i,k)* &
  1629. icmg)**((1.+alpha_g)/(4.+alpha_g))
  1630. !hail:
  1631. if (QHM(i,k)>epsQ .and. NHM(i,k)<epsN) &
  1632. NHM(i,k)= (No_h_SM*GH31)**(3./(4.+alpha_h))*(GH31*iGH34*tmp1*QHM(i,k)* &
  1633. icmh)**((1.+alpha_h)/(4.+alpha_h))
  1634. if (QH(i,k)>epsQ .and. NH(i,k)<epsN) &
  1635. NH(i,k)= (No_h_SM*GH31)**(3./(4.+alpha_h))*(GH31*iGH34*tmp2*QH(i,k)* &
  1636. icmh)**((1.+alpha_h)/(4.+alpha_h))
  1637. enddo !i-loop
  1638. enddo !k-loop
  1639. ENDIF !N-initialization
  1640. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  1641. ! Clip all moments to zero if one or more corresponding category moments are less than
  1642. ! the minimum allowable value:
  1643. ! (Note: Clipped mass is added back to water vapor field to conserve total mass)
  1644. do k= 1,nk
  1645. do i= 1,ni
  1646. IF (dblMom_c) THEN
  1647. if(QC(i,k)<epsQ .or. NC(i,k)<epsN) then
  1648. Q(i,k) = Q(i,k) + QC(i,k)
  1649. QC(i,k)= 0.; NC(i,k)= 0.
  1650. endif
  1651. if(QCM(i,k)<epsQ .or. NCM(i,k)<epsN) then
  1652. QM(i,k) = QM(i,k) + QCM(i,k)
  1653. QCM(i,k)= 0.; NCM(i,k)= 0.
  1654. endif
  1655. ELSE
  1656. if(QC(i,k)<epsQ) then
  1657. Q(i,k) = Q(i,k) + QC(i,k)
  1658. QC(i,k)= 0.
  1659. endif
  1660. if(QCM(i,k)<epsQ) then
  1661. QM(i,k) = QM(i,k) + QCM(i,k)
  1662. QCM(i,k)= 0.
  1663. endif
  1664. ENDIF
  1665. IF (dblMom_r) THEN
  1666. if (QR(i,k)<epsQ .or. NR(i,k)<epsN) then
  1667. Q(i,k) = Q(i,k) + QR(i,k)
  1668. QR(i,k)= 0.; NR(i,k)= 0.
  1669. endif
  1670. if (QRM(i,k)<epsQ .or. NRM(i,k)<epsN) then
  1671. QM(i,k) = QM(i,k) + QRM(i,k)
  1672. QRM(i,k)= 0.; NRM(i,k)= 0.
  1673. endif
  1674. ELSE
  1675. if (QR(i,k)<epsQ) then
  1676. Q(i,k) = Q(i,k) + QR(i,k)
  1677. QR(i,k)= 0.
  1678. endif
  1679. if (QRM(i,k)<epsQ) then
  1680. QM(i,k) = QM(i,k) + QRM(i,k)
  1681. QRM(i,k)= 0.
  1682. endif
  1683. ENDIF
  1684. IF (dblMom_i) THEN
  1685. if (QI(i,k)<epsQ .or. NY(i,k)<epsN) then
  1686. Q(i,k) = Q(i,k) + QI(i,k)
  1687. QI(i,k)= 0.; NY(i,k)= 0.
  1688. endif
  1689. if (QIM(i,k)<epsQ .or. NYM(i,k)<epsN) then
  1690. QM(i,k) = QM(i,k) + QIM(i,k)
  1691. QIM(i,k)= 0.; NYM(i,k)= 0.
  1692. endif
  1693. ELSE
  1694. if (QI(i,k)<epsQ) then
  1695. Q(i,k) = Q(i,k) + QI(i,k)
  1696. QI(i,k)= 0.
  1697. endif
  1698. if (QIM(i,k)<epsQ) then
  1699. QM(i,k) = QM(i,k) + QIM(i,k)
  1700. QIM(i,k)= 0.
  1701. endif
  1702. ENDIF
  1703. IF (dblMom_s) THEN
  1704. if (QN(i,k)<epsQ .or. NN(i,k)<epsN) then
  1705. Q(i,k) = Q(i,k) + QN(i,k)
  1706. QN(i,k)= 0.; NN(i,k)= 0.
  1707. endif
  1708. if (QNM(i,k)<epsQ .or. NNM(i,k)<epsN) then
  1709. QM(i,k) = QM(i,k) + QNM(i,k)
  1710. QNM(i,k)= 0.; NNM(i,k)= 0.
  1711. endif
  1712. ELSE
  1713. if (QN(i,k)<epsQ) then
  1714. Q(i,k) = Q(i,k) + QN(i,k)
  1715. QN(i,k)= 0.
  1716. endif
  1717. if (QNM(i,k)<epsQ) then
  1718. QM(i,k) = QM(i,k) + QNM(i,k)
  1719. QNM(i,k)= 0.
  1720. endif
  1721. ENDIF
  1722. IF (dblMom_g) THEN
  1723. if (QG(i,k)<epsQ .or. NG(i,k)<epsN) then
  1724. Q(i,k) = Q(i,k) + QG(i,k)
  1725. QG(i,k)= 0.; NG(i,k)= 0.
  1726. endif
  1727. if (QGM(i,k)<epsQ .or. NGM(i,k)<epsN) then
  1728. QM(i,k) = QM(i,k) + QGM(i,k)
  1729. QGM(i,k)= 0.; NGM(i,k)= 0.
  1730. endif
  1731. ELSE
  1732. if (QG(i,k)<epsQ) then
  1733. Q(i,k) = Q(i,k) + QG(i,k)
  1734. QG(i,k)= 0.
  1735. endif
  1736. if (QGM(i,k)<epsQ) then
  1737. QM(i,k) = QM(i,k) + QGM(i,k)
  1738. QGM(i,k)= 0.
  1739. endif
  1740. ENDIF
  1741. IF (dblMom_h) THEN
  1742. if (QH(i,k)<epsQ .or. NH(i,k)<epsN) then
  1743. Q(i,k) = Q(i,k) + QH(i,k)
  1744. QH(i,k)= 0.; NH(i,k)= 0.
  1745. endif
  1746. if (QHM(i,k)<epsQ .or. NHM(i,k)<epsN) then
  1747. QM(i,k) = QM(i,k) + QHM(i,k)
  1748. QHM(i,k)= 0.; NHM(i,k)= 0.
  1749. endif
  1750. ELSE
  1751. if (QH(i,k)<epsQ) then
  1752. Q(i,k) = Q(i,k) + QH(i,k)
  1753. QH(i,k)= 0.
  1754. endif
  1755. if (QHM(i,k)<epsQ) then
  1756. QM(i,k) = QM(i,k) + QHM(i,k)
  1757. QHM(i,k)= 0.
  1758. endif
  1759. ENDIF
  1760. enddo !i-loop
  1761. enddo !k-loop; (clipping)
  1762. QM = max(QM,0.)
  1763. Q = max(Q ,0.)
  1764. !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!
  1765. ! Approximate values at time {t}:
  1766. ! [ ave. of values at {*} (advected, but no physics tendency added) and {t-dt} ]:
  1767. HPS= 0.5*(PSM+PS); TM = 0.5*(TM + T); QM = 0.5*(QM + Q)
  1768. QCM= 0.5*(QCM+QC); QRM= 0.5*(QRM+QR); QIM= 0.5*(QIM+QI)
  1769. QNM= 0.5*(QNM+QN); QGM= 0.5*(QGM+QG); QHM= 0.5*(QHM+QH)
  1770. if (dblMom_c) NCM= 0.5*(NCM+NC)
  1771. if (dblMom_r) NRM= 0.5*(NRM+NR)
  1772. if (dblMom_i) NYM= 0.5*(NYM+NY)
  1773. if (dblMom_s) NNM= 0.5*(NNM+NN)
  1774. if (dblMom_g) NGM= 0.5*(NGM+NG)
  1775. if (dblMom_h) NHM= 0.5*(NHM+NH)
  1776. do k=1,nk
  1777. do i=1,ni
  1778. !WRF:
  1779. #if (DWORDSIZE == 8 && RWORDSIZE == 8)
  1780. QSW(i,k)= FOQSA(TM(i,k),HPS(i)*S(i,k)) !wrt. liquid water at (t)
  1781. QSS(i,k)= FOQST( T(i,k), PS(i)*S(i,k)) !wrt. ice surface at (*)
  1782. QSI(i,k)= FOQST(TM(i,k),HPS(i)*S(i,k)) !wrt. ice surface at (t)
  1783. #elif (DWORDSIZE == 8 && RWORDSIZE == 4)
  1784. QSW(i,k)= sngl(FOQSA(TM(i,k),HPS(i)*S(i,k))) !wrt. liquid water at (t)
  1785. QSS(i,k)= sngl(FOQST( T(i,k), PS(i)*S(i,k))) !wrt. ice surface at (*)
  1786. QSI(i,k)= sngl(FOQST(TM(i,k),HPS(i)*S(i,k))) !wrt. ice surface at (t)
  1787. #else
  1788. !! This is a temporary hack assuming double precision is 8 bytes.
  1789. #endif
  1790. !Air density at time (t)
  1791. DE(i,k) = S(i,k)*HPS(i)/(RGASD*TM(i,k)) !air density at time (t)
  1792. iDE(i,k)= 1./DE(i,k)
  1793. enddo
  1794. enddo
  1795. do i= 1,ni
  1796. !Air-density factor: (for fall velocity computations)
  1797. DEo = DE(i,nk)
  1798. gamfact(i,:) = sqrt(DEo/(DE(i,:)))
  1799. gamfact_r(i,:)= sqrt( 1./(DE(i,:)))
  1800. !Convert 'W_omega' (on thermodynamic levels) to 'w' (on momentum):
  1801. do k= 2,nk-1
  1802. WZ(i,k)= -0.5/(DE(i,k)*GRAV)*(W_omega(i,k-1)+W_omega(i,k+1))
  1803. enddo
  1804. WZ(i,1) = -0.5/(DE(i,1) *GRAV)*W_omega(i,1)
  1805. WZ(i,nk)= -0.5/(DE(i,nk)*GRAV)*W_omega(i,nk)
  1806. enddo
  1807. !----------------------------------------------------------------------------------!
  1808. ! End of Preliminary Calculation section (Part 1) !
  1809. !----------------------------------------------------------------------------------!
  1810. !----------------------------------------------------------------------------------!
  1811. ! PART 2: Cold Microphysics Processes !
  1812. !----------------------------------------------------------------------------------!
  1813. ! Determine the active grid points (i.e. those which scheme should treat):
  1814. activePoint = .false.
  1815. DO k=2,nk
  1816. DO i=1,ni
  1817. log1= ((QIM(i,k)+QGM(i,k)+QNM(i,k)+QHM(i,k))<epsQ) !no solid (i,g,s,h)
  1818. log2= ((QCM(i,k)+QRM(i,k)) <epsQ) !no liquid (c,r)
  1819. log3= ((TM(i,k)>TRPL) .and. log1) !T>0C & no i,g,s,h
  1820. log4= log1.and.log2.and.(QM(i,k)<QSI(i,k)) !no sol. or liq.; subsat(i)
  1821. if (.not.( log3 .or. log4 ) .and. icephase_ON) then
  1822. activePoint(i,k)= .true.
  1823. endif
  1824. ENDDO
  1825. ENDDO
  1826. ! Size distribution parameters:
  1827. ! Note: + 'thrd' should actually be '1/dmx'(but dmx=3 for all categories x)
  1828. ! + If Qx=0, LAMx etc. are never be used in any calculations
  1829. ! (If Qc=0, CLcy etc. will never be calculated. iLAMx is set to 0
  1830. ! to avoid possible problems due to bugs.)
  1831. DO k= 2,nk !Main loop for Part 2
  1832. DO i= 1,ni
  1833. IF (activePoint(i,k)) THEN
  1834. Tc= TM(i,k)-TRPL
  1835. if (Tc<-120. .or. Tc>50.) &
  1836. print*, '***WARNING*** -- In MICROPHYSICS -- Ambient Temp.(C):',Tc
  1837. Cdiff = (2.2157e-5+0.0155e-5*Tc)*1.e5/(S(i,k)*HPS(i))
  1838. MUdyn = 1.72e-5*(393./(TM(i,k)+120.))*(TM(i,k)/TRPL)**1.5 !RYp.102
  1839. MUkin = MUdyn*iDE(i,k)
  1840. iMUkin= 1./MUkin
  1841. ScTHRD= (MUkin/Cdiff)**thrd ! i.e. Sc^(1/3)
  1842. Ka = 2.3971e-2 + 0.0078e-2*Tc !therm.cond.(air)
  1843. Kdiff = (9.1018e-11*TM(i,k)*TM(i,k)+8.8197e-8*TM(i,k)-(1.0654e-5)) !therm.diff.(air)
  1844. gam = gamfact(i,k)
  1845. !Collection efficiencies:
  1846. Eis = min(0.05*exp(0.1*Tc),1.) !Ferrier, 1995 (Table 1)
  1847. Eig = min(0.01*exp(0.1*Tc),1.) !dry (Eig=1.0 for wet growth)
  1848. Eii = 0.1*Eis
  1849. Ess = Eis; Eih = Eig; Esh = Eig
  1850. iEih = 1./Eih
  1851. iEsh = 1./Esh
  1852. !note: Eri=Ers=Erh=1. (constant parameters)
  1853. ! - Ecs is computed in CLcs section
  1854. ! - Ech is computed in CLch section
  1855. ! - Ecg is computed in CLcg section
  1856. ! - Erg is computed in CLrg section
  1857. !WRF:
  1858. #if (DWORDSIZE == 8 && RWORDSIZE == 8)
  1859. qvs0 = FOQSA(TRPL,HPS(i)*S(i,k)) !sat.mix.ratio at 0C
  1860. #elif (DWORDSIZE == 8 && RWORDSIZE == 4)
  1861. qvs0 = sngl(FOQSA(TRPL,HPS(i)*S(i,k))) !sat.mix.ratio at 0C
  1862. #else
  1863. !! This is a temporary hack assuming double precision is 8 bytes.
  1864. #endif
  1865. DELqvs= qvs0-(QM(i,k))
  1866. ! Cloud:
  1867. if (QCM(i,k)>epsQ) then
  1868. if (.not. dblMom_c) NCM(i,k)= N_c_SM
  1869. iQCM = 1./QCM(i,k)
  1870. iNCM = 1./NCM(i,k)
  1871. Dc = Dm_x(DE(i,k),QCM(i,k),iNCM,icmr,thrd)
  1872. iLAMc = iLAMDA_x(DE(i,k),QCM(i,k),iNCM,icexc9,thrd)
  1873. iLAMc2 = iLAMc *iLAMc
  1874. iLAMc3 = iLAMc2*iLAMc
  1875. iLAMc4 = iLAMc2*iLAMc2
  1876. iLAMc5 = iLAMc3*iLAMc2
  1877. else
  1878. Dc = 0.; iLAMc3= 0.
  1879. iLAMc = 0.; iLAMc4= 0.
  1880. iLAMc2 = 0.; iLAMc5= 0.
  1881. endif
  1882. ! Rain:
  1883. if (QRM(i,k)>epsQ) then
  1884. if (.not. dblMom_r) NRM(i,k)= GR50*sqrt(sqrt(GR31*iGR34*DE(i,k)*QRM(i,k)*icmr))
  1885. iQRM = 1./QRM(i,k)
  1886. iNRM = 1./NRM(i,k)
  1887. Dr = Dm_x(DE(i,k),QRM(i,k),iNRM,icmr,thrd)
  1888. iLAMr = max( iLAMmin1, iLAMDA_x(DE(i,k),QRM(i,k),iNRM,icexr9,thrd) )
  1889. tmp1 = 1./iLAMr
  1890. iLAMr2 = iLAMr *iLAMr
  1891. iLAMr3 = iLAMr2*iLAMr
  1892. iLAMr4 = iLAMr2*iLAMr2
  1893. iLAMr5 = iLAMr3*iLAMr2
  1894. if (Dr>40.e-6) then
  1895. vr0 = gamfact_r(i,k)*ckQr1*iLAMr**bfr
  1896. else
  1897. vr0 = 0.
  1898. endif
  1899. else
  1900. iLAMr = 0.; Dr = 0.; vr0 = 0.
  1901. iLAMr2 = 0.; iLAMr3= 0.; iLAMr4= 0.; iLAMr5 = 0.
  1902. endif
  1903. ! Ice:
  1904. if (QIM(i,k)>epsQ) then
  1905. if (.not. dblMom_i) NYM(i,k)= N_Cooper(TRPL,TM(i,k))
  1906. iQIM = 1./QIM(i,k)
  1907. iNYM = 1./NYM(i,k)
  1908. iLAMi = max( iLAMmin2, iLAMDA_x(DE(i,k),QIM(i,k),iNYM,icexi9,thrd) )
  1909. iLAMi2 = iLAMi *iLAMi
  1910. iLAMi3 = iLAMi2*iLAMi
  1911. iLAMi4 = iLAMi2*iLAMi2
  1912. iLAMi5 = iLAMi3*iLAMi2
  1913. iLAMiB0= iLAMi**(bfi)
  1914. iLAMiB1= iLAMi**(bfi+1.)
  1915. iLAMiB2= iLAMi**(bfi+2.)
  1916. vi0 = gamfact(i,k)*ckQi1*iLAMiB0
  1917. Di = Dm_x(DE(i,k),QIM(i,k),iNYM,icmi,thrd)
  1918. else
  1919. iLAMi = 0.; vi0 = 0.; Di = 0.
  1920. iLAMi2 = 0.; iLAMi3 = 0.; iLAMi4 = 0.; iLAMi5= 0.
  1921. iLAMiB0= 0.; iLAMiB1= 0.; iLAMiB2= 0.
  1922. endif
  1923. ! Snow:
  1924. if (QNM(i,k)>epsQ) then
  1925. if (.not.dblMom_s) then
  1926. No_s_SM = Nos_Thompson(TRPL,TM(i,k))
  1927. NNM(i,k)= (No_s*GS31)**(dms*icexs2)*(GS31*iGS40*icms*DE(i,k)*QNM(i,k))** &
  1928. ((1.+alpha_s)*icexs2)
  1929. endif
  1930. iQNM = 1./QNM(i,k)
  1931. iNNM = 1./NNM(i,k)
  1932. iLAMs = max( iLAMmin2, iLAMDA_x(DE(i,k),QNM(i,k),iNNM,iGS20,idms) )
  1933. iLAMs_D3= max(iLAMmin2, iLAMDA_x(DE(i,k),QNM(i,k),iNNM,iGS20_D3,thrd) )
  1934. iLAMs2 = iLAMs*iLAMs
  1935. iLAMsB0= iLAMs**(bfs)
  1936. iLAMsB1= iLAMs**(bfs+1.)
  1937. iLAMsB2= iLAMs**(bfs+2.)
  1938. vs0 = gamfact(i,k)*ckQs1*iLAMsB0
  1939. Ds = min(DsMax, Dm_x(DE(i,k),QNM(i,k),iNNM,icms,idms))
  1940. if (snowSpherical) then
  1941. des = desFix
  1942. else
  1943. des = des_OF_Ds(Ds,desMax,eds,fds)
  1944. endif
  1945. !!-- generalized equations (any alpha_s):
  1946. ! No_s = (NNM(i,k))*iGS31/iLAMs**(1.+alpha_s)
  1947. ! VENTs = Avx*GS32*iLAMs**(2.+alpha_s)+Bvx*ScTHRD*sqrt(gam*afs*iMUkin)* &
  1948. !!-- GS09*iLAMs**(2.5+0.5*bfs+alpha_s)
  1949. !The following equations for No_s and VENTs is based on m(D)=(pi/6)*100.*D**3 for snow.
  1950. ! Strict application of m(D)=c*D**2 would require re-derivation using implied
  1951. ! definition of D as the MAXIMUM DIMENSION of an ellipsoid, rather than a sphere.
  1952. ! For simplicity, the m-D^3 relation is applied -- used for VDvs and MLsr only.
  1953. if (dblMom_s) then
  1954. !No_s= NNM(i,k)*iGS31/iLAMs !optimized for alpha_s=0
  1955. No_s= NNM(i,k)*iGS31/iLAMs_D3 !based on m-D^3 (consistent with VENTs, below)
  1956. else
  1957. No_s= No_s_SM
  1958. endif
  1959. VENTs= Avx*GS32*iLAMs_D3**2. + Bvx*ScTHRD*sqrt(gamfact(i,k)*afs*iMUkin)*GS09* &
  1960. iLAMs_D3**cexs1
  1961. else
  1962. iLAMs = 0.; vs0 = 0.; Ds = 0.; iLAMs2= 0.
  1963. iLAMsB0= 0.; iLAMsB1= 0.; iLAMsB1= 0.
  1964. des = desFix !used for 3-component freezing if QNM=0 (even for snowSpherical=.F.)
  1965. endif
  1966. ides = 1./des
  1967. ! Graupel:
  1968. if (QGM(i,k)>epsQ) then
  1969. if (.not.dblMom_g) NGM(i,k)= GG50*sqrt(sqrt(GG31*GG34*DE(i,k)*QGM(i,k)*icmg))
  1970. iQGM = 1./QGM(i,k)
  1971. iNGM = 1./NGM(i,k)
  1972. iLAMg = max( iLAMmin1, iLAMDA_x(DE(i,k),QGM(i,k),iNGM,iGG99,thrd) )
  1973. iLAMg2 = iLAMg *iLAMg
  1974. iLAMgB0= iLAMg**(bfg)
  1975. iLAMgB1= iLAMg**(bfg+1.)
  1976. iLAMgB2= iLAMg**(bfg+2.)
  1977. if (dblMom_g) then
  1978. !No_g = (NGM(i,k))*iGG31/iLAMg**(1.+alpha_g)
  1979. No_g= NGM(i,k)*iGG31/iLAMg !optimized for alpha_g=0
  1980. else
  1981. No_g= No_g_SM
  1982. endif
  1983. vg0 = gamfact(i,k)*ckQg1*iLAMgB0
  1984. Dg = Dm_x(DE(i,k),QGM(i,k),iNGM,icmg,thrd)
  1985. else
  1986. iLAMg = 0.; vg0 = 0.; Dg = 0.; No_g = 0.
  1987. iLAMg2 = 0.; iLAMgB0= 0.; iLAMgB1= 0.; iLAMgB1= 0.
  1988. endif
  1989. ! Hail:
  1990. if (QHM(i,k)>epsQ) then
  1991. if (.not.dblMom_h) NHM(i,k)= GH50*sqrt(sqrt(GH31*iGH34*DE(i,k)*QHM(i,k)*icmh))
  1992. iQHM = 1./QHM(i,k)
  1993. iNHM = 1./NHM(i,k)
  1994. iLAMh = max( iLAMmin1, iLAMDA_x(DE(i,k),QHM(i,k),iNHM,iGH99,thrd) )
  1995. iLAMh2 = iLAMh*iLAMh
  1996. iLAMhB0= iLAMh**(bfh)
  1997. iLAMhB1= iLAMh**(bfh+1.)
  1998. iLAMhB2= iLAMh**(bfh+2.)
  1999. if (dblMom_h) then
  2000. No_h= NHM(i,k)*iGH31/iLAMh**(1.+alpha_h)
  2001. else
  2002. No_h= No_h_SM
  2003. endif
  2004. vh0 = gamfact(i,k)*ckQh1*iLAMhB0
  2005. Dh = Dm_x(DE(i,k),QHM(i,k),iNHM,icmh,thrd)
  2006. else
  2007. iLAMh = 0.; vh0 = 0.; Dh = 0.; No_h= 0.
  2008. iLAMhB0= 0.; iLAMhB1= 0.; iLAMhB1= 0.
  2009. endif
  2010. !------
  2011. !Calculating ice-phase source/sink terms:
  2012. ! Initialize all source terms to zero:
  2013. QNUvi=0.; QVDvi=0.; QVDvs=0.; QVDvg=0.; QVDvh=0.
  2014. QCLcs=0.; QCLcg=0.; QCLch=0.; QFZci=0.; QCLri=0.; QMLsr=0.
  2015. QCLrs=0.; QCLrg=0.; QMLgr=0.; QCLrh=0.; QMLhr=0.; QFZrh=0.
  2016. QMLir=0.; QCLsr=0.; QCLsh=0.; QCLgr=0.; QCNgh=0.
  2017. QCNis=0.; QCLir=0.; QCLis=0.; QCLih=0.
  2018. QIMsi=0.; QIMgi=0.; QCNsg=0.; QHwet=0.
  2019. NCLcs= 0.; NCLcg=0.; NCLch=0.; NFZci=0.; NMLhr=0.; NhCNgh=0.
  2020. NCLri= 0.; NCLrs=0.; NCLrg=0.; NCLrh=0.; NMLsr=0.; NMLgr=0.
  2021. NMLir= 0.; NSHhr=0.; NNUvi=0.; NVDvi=0.; NVDvh=0.; QCLig=0.
  2022. NCLir= 0.; NCLis=0.; NCLig=0.; NCLih=0.; NIMsi=0.; NIMgi=0.
  2023. NiCNis=0.; NsCNis=0.; NVDvs=0.; NCNsg=0.; NCLgr=0.; NCLsrh=0.
  2024. NCLss= 0.; NCLsr=0.; NCLsh=0.; NCLsrs=0.; NCLgrg=0.; NgCNgh=0.
  2025. NVDvg= 0.; NCLirg=0.; NCLsrg=0.; NCLgrh=0.; NrFZrh=0.; NhFZrh=0.
  2026. NCLirh=0.
  2027. Dirg=0.; Dirh=0.; Dsrs= 0.; Dsrg= 0.; Dsrh= 0.; Dgrg=0.; Dgrh=0.
  2028. !-------------------------------------------------------------------------------------------!
  2029. ! COLLECTION by snow, graupel, hail:
  2030. ! (i.e. wet or dry ice-categories [=> excludes ice crystals])
  2031. ! Collection by SNOW:
  2032. if (QNM(i,k)>epsQ) then
  2033. ! cloud:
  2034. if (QCM(i,k)>epsQ) then
  2035. !Approximation of Ecs based on Pruppacher & Klett (1997) Fig. 14-11
  2036. Ecs= min(Dc,30.e-6)*3.333e+4*sqrt(min(Ds,1.e-3)*1.e+3)
  2037. QCLcs= dt*gam*afs*cmr*Ecs*PIov4*iDE(i,k)*(NCM(i,k)*NNM(i,k))*iGC5*iGS31* &
  2038. (GC13*GS13*iLAMc3*iLAMsB2+2.*GC14*GS12*iLAMc4*iLAMsB1+GC15*GS11* &
  2039. iLAMc5*iLAMsB0)
  2040. NCLcs= dt*gam*afs*PIov4*Ecs*(NCM(i,k)*NNM(i,k))*iGC5*iGS31*(GC5*GS13* &
  2041. iLAMsB2+2.*GC11*GS12*iLAMc*iLAMsB1+GC12*GS11*iLAMc2*iLAMsB0)
  2042. !continuous collection: (alternative; gives values ~0.95 of SCE [above])
  2043. !QCLcs= dt*gam*Ecs*PIov4*afs*QCM(i,k)*NNM(i,k)*iLAMs**(2.+bfs)*GS13*iGS31
  2044. !NCLcs= QCLcs*NCM(i,k)/QCM(i,k)
  2045. !Correction factor for non-spherical snow [D = maximum dimension] which
  2046. !changes projected area: [assumption: A=0.50*D**2 (vs. A=(PI/4)*D**2)]
  2047. ! note: Strictly speaking, this correction should only be applied to
  2048. ! continuous growth approximation for cloud. [factor = 0.50/(pi/4)]
  2049. if (.not. snowSpherical) then
  2050. tmp1 = 0.6366 !factor = 0.50/(pi/4)
  2051. QCLcs= tmp1*QCLcs
  2052. NCLcs= tmp1*NCLcs
  2053. endif
  2054. QCLcs= min(QCLcs, QCM(i,k))
  2055. NCLcs= min(NCLcs, NCM(i,k))
  2056. else
  2057. QCLcs= 0.; NCLcs= 0.
  2058. endif
  2059. ! ice:
  2060. if (QIM(i,k)>epsQ) then
  2061. tmp1= vs0-vi0
  2062. tmp3= sqrt(tmp1*tmp1+0.04*vs0*vi0)
  2063. QCLis= dt*cmi*iDE(i,k)*PI*6.*Eis*(NYM(i,k)*NNM(i,k))*tmp3*iGI31*iGS31*(0.5* &
  2064. iLAMs2*iLAMi3+2.*iLAMs*iLAMi4+5.*iLAMi5)
  2065. NCLis= dt*PIov4*Eis*(NYM(i,k)*NNM(i,k))*GI31*GS31*tmp3*(GI33*GS31*iLAMi2+ &
  2066. 2.*GI32*GS32*iLAMi*iLAMs+GI31*GS33*iLAMs2)
  2067. QCLis= min(QCLis, (QIM(i,k)))
  2068. NCLis= min(QCLis*(NYM(i,k)*iQIM), NCLis)
  2069. else
  2070. QCLis= 0.; NCLis= 0.
  2071. endif
  2072. if (dblMom_s) then
  2073. !snow: (i.e. self-collection [aggregation])
  2074. NCLss= dt*0.93952*Ess*(DE(i,k)*(QNM(i,k)))**((2.+bfs)*thrd)*(NNM(i,k))** &
  2075. ((4.-bfs)*thrd)
  2076. !Note: 0.91226 = I(bfs)*afs*PI^((1-bfs)/3)*des^((-2-bfs)/3); I(bfs=0.41)=1138
  2077. ! 0.93952 = I(bfs)*afs*PI^((1-bfs)/3)*des^((-2-bfs)/3); I(bfs=0.42)=1172
  2078. ! [interpolated from 3rd-order polynomial approx. of values given in RRB98;
  2079. ! see eqn(A.35)]
  2080. NCLss= min(NCLss, 0.5*(NNM(i,k)))
  2081. endif
  2082. else
  2083. QCLcs= 0.; NCLcs= 0.; QCLis= 0.; NCLis= 0.; NCLss= 0.
  2084. endif
  2085. ! Collection by GRAUPEL:
  2086. if (QGM(i,k)>epsQ) then
  2087. ! cloud:
  2088. if (QCM(i,k)>epsQ) then
  2089. !(parameterization of Ecg based on Cober and List, 1993 [JAS])
  2090. Kstoke = dew*vg0*Dc*Dc/(9.*MUdyn*Dg)
  2091. Kstoke = max(1.5,min(10.,Kstoke))
  2092. Ecg = 0.55*log10(2.51*Kstoke)
  2093. QCLcg= dt*gam*afg*cmr*Ecg*PIov4*iDE(i,k)*(NCM(i,k)*NGM(i,k))*iGC5*iGG31* &
  2094. (GC13*GG13*iLAMc3*iLAMgB2+ 2.*GC14*GG12*iLAMc4*iLAMgB1+GC15*GG11* &
  2095. iLAMc5*iLAMgB0)
  2096. NCLcg= dt*gam*afg*PIov4*Ecg*(NCM(i,k)*NGM(i,k))*iGC5*iGG31*(GC5*GG13* &
  2097. iLAMgB2+2.*GC11*GG12*iLAMc*iLAMgB1+GC12*GG11*iLAMc2*iLAMgB0)
  2098. QCLcg= min(QCLcg, (QCM(i,k)))
  2099. NCLcg= min(NCLcg, (NCM(i,k)))
  2100. else
  2101. QCLcg= 0.; NCLcg= 0.
  2102. endif
  2103. ! ice:
  2104. if (QIM(i,k)>epsQ) then
  2105. tmp1= vg0-vi0
  2106. tmp3= sqrt(tmp1*tmp1+0.04*vg0*vi0)
  2107. QCLig= dt*cmi*iDE(i,k)*PI*6.*Eig*(NYM(i,k)*NGM(i,k))*tmp3*iGI31*iGG31*(0.5* &
  2108. iLAMg2*iLAMi3+2.*iLAMg*iLAMi4+5.*iLAMi5)
  2109. NCLig= dt*PIov4*Eig*(NYM(i,k)*NGM(i,k))*GI31*GG31*tmp3*(GI33*GG31*iLAMi2+ &
  2110. 2.*GI32*GG32*iLAMi*iLAMg+GI31*GG33*iLAMg2)
  2111. QCLig= min(QCLig, (QIM(i,k)))
  2112. NCLig= min(QCLig*(NYM(i,k)*iQIM), NCLig)
  2113. else
  2114. QCLig= 0.; NCLig= 0.
  2115. endif
  2116. else
  2117. QCLcg= 0.; QCLrg= 0.; QCLig= 0.
  2118. NCLcg= 0.; NCLrg= 0.; NCLig= 0.
  2119. endif
  2120. ! Collection by HAIL:
  2121. if (QHM(i,k)>epsQ) then
  2122. ! cloud:
  2123. if (QCM(i,k)>epsQ) then
  2124. Ech = exp(-8.68e-7*Dc**(-1.6)*Dh) !Ziegler (1985) A24
  2125. QCLch= dt*gam*afh*cmr*Ech*PIov4*iDE(i,k)*(NCM(i,k)*NHM(i,k))*iGC5*iGH31* &
  2126. (GC13*GH13*iLAMc3*iLAMhB2+2.*GC14*GH12*iLAMc4*iLAMhB1+GC15*GH11* &
  2127. iLAMc5*iLAMhB0)
  2128. NCLch= dt*gam*afh*PIov4*Ech*(NCM(i,k)*NHM(i,k))*iGC5*iGH31*(GC5*GH13* &
  2129. iLAMhB2+2.*GC11*GH12*iLAMc*iLAMhB1+GC12*GH11*iLAMc2*iLAMhB0)
  2130. QCLch= min(QCLch, QCM(i,k))
  2131. NCLch= min(NCLch, NCM(i,k))
  2132. else
  2133. QCLch= 0.; NCLch= 0.
  2134. endif
  2135. ! rain:
  2136. if (QRM(i,k)>epsQ) then
  2137. tmp1= vh0-vr0
  2138. tmp3= sqrt(tmp1*tmp1+0.04*vh0*vr0)
  2139. QCLrh= dt*cmr*Erh*PIov4*iDE(i,k)*(NHM(i,k)*NRM(i,k))*iGR31*iGH31*tmp3* &
  2140. (GR36*GH31*iLAMr5+2.*GR35*GH32*iLAMr4*iLAMh+GR34*GH33*iLAMr3*iLAMh2)
  2141. NCLrh= dt*PIov4*Erh*(NHM(i,k)*NRM(i,k))*iGR31*iGH31*tmp3*(GR33*GH31* &
  2142. iLAMr2+2.*GR32*GH32*iLAMr*iLAMh+GR31*GH33*iLAMh2)
  2143. QCLrh= min(QCLrh, QRM(i,k))
  2144. NCLrh= min(NCLrh, QCLrh*(NRM(i,k)*iQRM))
  2145. else
  2146. QCLrh= 0.; NCLrh= 0.
  2147. endif
  2148. ! ice:
  2149. if (QIM(i,k)>epsQ) then
  2150. tmp1 = vh0-vi0
  2151. tmp3 = sqrt(tmp1*tmp1+0.04*vh0*vi0)
  2152. QCLih= dt*cmi*iDE(i,k)*PI*6.*Eih*(NYM(i,k)*NHM(i,k))*tmp3*iGI31*iGH31*(0.5* &
  2153. iLAMh2*iLAMi3+2.*iLAMh*iLAMi4+5.*iLAMi5)
  2154. NCLih= dt*PIov4*Eih*(NYM(i,k)*NHM(i,k))*GI31*GH31*tmp3*(GI33*GH31*iLAMi2+ &
  2155. 2.*GI32*GH32*iLAMi*iLAMh+GI31*GH33*iLAMh2)
  2156. QCLih= min(QCLih, QIM(i,k))
  2157. NCLih= min(QCLih*(NYM(i,k)*iQIM), NCLih)
  2158. else
  2159. QCLih= 0.; NCLih= 0.
  2160. endif
  2161. ! snow:
  2162. if (QNM(i,k)>epsQ) then
  2163. tmp1 = vh0-vs0
  2164. tmp3 = sqrt(tmp1*tmp1+0.04*vh0*vs0)
  2165. tmp4 = iLAMs2*iLAMs2
  2166. if (snowSpherical) then
  2167. !hardcoded for dms=3:
  2168. QCLsh= dt*cms*iDE(i,k)*PI*6.*Esh*(NNM(i,k)*NHM(i,k))*tmp3*iGS31*iGH31* &
  2169. (0.5*iLAMh2*iLAMs2*iLAMs+2.*iLAMh*tmp4+5.*tmp4*iLAMs)
  2170. else
  2171. !hardcoded for dms=2:
  2172. QCLsh= dt*cms*iDE(i,k)*PI*0.25*Esh*tmp3*NNM(i,k)*NHM(i,k)*iGS31*iGH31* &
  2173. (GH33*GS33*iLAMh**2.*iLAMs**2. + 2.*GH32*GS34*iLAMh*iLAMs**3. + &
  2174. GH31*GS35*iLAMs**4.)
  2175. endif
  2176. NCLsh= dt*PIov4*Esh*(NNM(i,k)*NHM(i,k))*GS31*GH31*tmp3*(GS33*GH31*iLAMs2+ &
  2177. 2.*GS32*GH32*iLAMs*iLAMh+GS31*GH33*iLAMh2)
  2178. QCLsh= min(QCLsh, (QNM(i,k)))
  2179. NCLsh= min((NNM(i,k)*iQNM)*QCLsh, NCLsh, (NNM(i,k)))
  2180. else
  2181. QCLsh= 0.; NCLsh= 0.
  2182. endif
  2183. !wet growth:
  2184. VENTh= Avx*GH32*iLAMh**(2.+alpha_h) + Bvx*ScTHRD*sqrt(gam*afh*iMUkin)*GH09* &
  2185. iLAMh**(2.5+0.5*bfh+alpha_h)
  2186. QHwet= max(0., dt*PI2*(DE(i,k)*CHLC*Cdiff*DELqvs-Ka*Tc)*No_h*iDE(i,k)/(CHLF+ &
  2187. CPW*Tc)*VENTh+(QCLih*iEih+QCLsh*iEsh)*(1.-CPI*Tc/(CHLF+CPW*Tc)) )
  2188. else
  2189. QCLch= 0.; QCLrh= 0.; QCLih= 0.; QCLsh= 0.; QHwet= 0.
  2190. NCLch= 0.; NCLrh= 0.; NCLsh= 0.; NCLih= 0.
  2191. endif
  2192. IF (TM(i,k)>TRPL .and. warmphase_ON) THEN
  2193. !**********!
  2194. ! T > To !
  2195. !**********!
  2196. ! MELTING of frozen particles:
  2197. ! ICE:
  2198. QMLir = QIM(i,k) !all pristine ice melts in one time step
  2199. QIM(i,k)= 0.
  2200. NMLir = NYM(i,k)
  2201. ! SNOW:
  2202. if (QNM(i,k)>epsQ) then
  2203. QMLsr= dt*(PI2*iDE(i,k)*iCHLF*No_s*VENTs*(Ka*Tc-CHLC*Cdiff*DELqvs) + CPW* &
  2204. iCHLF*Tc*(QCLcs+QCLrs)*idt)
  2205. QMLsr= min(max(QMLsr,0.), QNM(i,k))
  2206. NMLsr= NNM(i,k)*iQNM*QMLsr
  2207. else
  2208. QMLsr= 0.; NMLsr= 0.
  2209. endif
  2210. ! GRAUPEL:
  2211. if (QGM(i,k)>epsQ) then
  2212. VENTg= Avx*GG32*iLAMg*iLAMg+Bvx*ScTHRD*sqrt(gam*afg*iMUkin)*GG09*iLAMg** &
  2213. (2.5+0.5*bfg+alpha_g)
  2214. QMLgr= dt*(PI2*iDE(i,k)*iCHLF*No_g*VENTg*(Ka*Tc-CHLC*Cdiff*DELqvs) + CPW* &
  2215. iCHLF*Tc*(QCLcg+QCLrg)*idt)
  2216. QMLgr= min(max(QMLgr,0.), QGM(i,k))
  2217. NMLgr= NGM(i,k)*iQGM*QMLgr
  2218. else
  2219. QMLgr= 0.; NMLgr= 0.
  2220. endif
  2221. ! HAIL:
  2222. if (QHM(i,k)>epsQ.and.Tc>5.) then
  2223. VENTh= Avx*GH32*iLAMh**(2.+alpha_h) + Bvx*ScTHRD*sqrt(gam*afh*iMUkin)*GH09* &
  2224. iLAMh**(2.5+0.5*bfh+alpha_h)
  2225. QMLhr= dt*(PI2*iDE(i,k)*iCHLF*No_h*VENTh*(Ka*Tc-CHLC*Cdiff*DELqvs) + CPW/ &
  2226. CHLF*Tc*(QCLch+QCLrh)*idt)
  2227. QMLhr= min(max(QMLhr,0.), QHM(i,k))
  2228. NMLhr= NHM(i,k)*iQHM*QMLhr
  2229. if(QCLrh>0.) NMLhr= NMLhr*0.1 !Prevents problems when hail is ML & CL
  2230. else
  2231. QMLhr= 0.; NMLhr= 0.
  2232. endif
  2233. ! Cold (sub-zero) source/sink terms:
  2234. QNUvi= 0.; QFZci= 0.; QVDvi= 0.; QVDvs= 0.; QVDvg= 0.
  2235. QCLis= 0.; QCNis1=0.; QCNis2=0.
  2236. QCNgh= 0.; QIMsi= 0.; QIMgi= 0.; QCLir= 0.; QCLri= 0.
  2237. QCLrs= 0.; QCLgr= 0.; QCLrg= 0.; QCNis= 0.; QVDvh= 0.
  2238. QCNsg= 0.; QCLsr= 0.
  2239. NNUvi= 0.; NFZci= 0.; NCLgr= 0.; NCLrg= 0.; NgCNgh= 0.
  2240. NCLis= 0.; NVDvi= 0.; NVDvs= 0.; NVDvg= 0.; NVDvh= 0.
  2241. NCNsg= 0.; NhCNgh= 0.; NiCNis=0.; NsCNis=0.; NCLrs= 0.
  2242. NIMsi= 0.; NIMgi= 0.; NCLir= 0.; NCLri= 0.; NCLsr= 0.
  2243. ELSE
  2244. !----------!
  2245. ! T < To !
  2246. !----------!
  2247. tmp1 = 1./QSI(i,k)
  2248. Si = QM(i,k) *tmp1
  2249. tmp2 = TM(i,k)*TM(i,k)
  2250. iABi = 1./( CHLS*CHLS/(Ka*RGASV*tmp2) + 1./(DE(i,k)*(QSI(i,k))*Cdiff) )
  2251. ! Warm-air-only source/sink terms:
  2252. QMLir= 0.; QMLsr= 0.; QMLgr= 0.; QMLhr= 0.
  2253. NMLir= 0.; NMLsr= 0.; NMLgr= 0.; NMLhr= 0.
  2254. !Probabilistic freezing (Bigg) of rain:
  2255. if (Tc<Tc_FZrh .and. QRM(i,k)>epsQ .and. hail_ON) then
  2256. !note: - (Tc<-10.C) condition is based on Pruppacher-Klett (1997) Fig. 9-41
  2257. ! - Small raindrops will freeze to hail. However, if after all S/S terms
  2258. ! are added Dh<Dh_min, then hail will be converted to graupel. Thus,
  2259. ! probabilistic freezing of small rain is effectively a source of graupel.
  2260. NrFZrh= -dt*Bbigg*(exp(Abigg*Tc)-1.)*DE(i,k)*QRM(i,k)*idew
  2261. Rz= 1. !N and Z (and Q) are conserved for FZrh with triple-moment
  2262. ! The Rz factor serves to conserve reflectivity when a rain distribution
  2263. ! converts to an distribution with a different shape parameter, alpha.
  2264. ! (e.g. when rain freezes to hail) The factor Rz non-conserves N while
  2265. ! acting to conserve Z for double-moment. See Ferrier, 1994 App. D)
  2266. ! Rz= (gamma(7.d0+alpha_h)*GH31*GR34*GR34)/(GR36(i,k)*GR31* &
  2267. ! gamma(4.d0+alpha_h)*gamma(4.d0+alpha_h))
  2268. NhFZrh= Rz*NrFZrh
  2269. QFZrh = NrFZrh*(QRM(i,k)*iNRM)
  2270. else
  2271. QFZrh= 0.; NrFZrh= 0.; NhFZrh= 0.
  2272. endif
  2273. !--------!
  2274. ! ICE: !
  2275. !--------!
  2276. ! Homogeneous freezing of cloud to ice:
  2277. if (dblMom_c) then
  2278. if (QCM(i,k)>epsQ) then
  2279. tmp2 = Tc*Tc; tmp3= tmp2*Tc; tmp4= tmp2*tmp2
  2280. JJ = (10.**max(-20.,(-606.3952-52.6611*Tc-1.7439*tmp2-0.0265*tmp3- &
  2281. 1.536e-4*tmp4)))
  2282. tmp1 = 1.e6*(DE(i,k)*(QCM(i,k)*iNCM)*icmr) !i.e. Dc[cm]**3
  2283. FRAC = 1.-exp(-JJ*PIov6*tmp1*dt)
  2284. if (Tc>-30.) FRAC= 0.
  2285. if (Tc<-50.) FRAC= 1.
  2286. QFZci= FRAC*QCM(i,k)
  2287. NFZci= FRAC*NCM(i,k)
  2288. else
  2289. QFZci= 0.; NFZci= 0.
  2290. endif
  2291. else
  2292. !Homogeneous freezing of cloud to ice: (simplified)
  2293. if (QCM(i,k)>epsQ .and. Tc<-35.) then
  2294. FRAC= 1. !if T<-35
  2295. QFZci= FRAC*QCM(i,k)
  2296. NFZci= FRAC*N_c_SM
  2297. else
  2298. QFZci= 0.; NFZci= 0.
  2299. endif
  2300. endif
  2301. if (dblMom_i) then
  2302. !Primary ice nucleation:
  2303. NNUvi= 0.; QNUvi= 0.
  2304. if (primIceNucl==1) then
  2305. NuDEPSOR= 0.; NuCONT= 0.
  2306. Simax = min(Si, SxFNC(WZ(i,k),Tc,HPS(i)*S(i,k),QSW(i,k),QSI(i,k),CCNtype, &
  2307. 2))
  2308. tmp1 = T(i,k)-7.66
  2309. NNUmax = max(0., DE(i,k)/mio*(Q(i,k)-QSS(i,k))/(1.+ck6*(QSS(i,k)/(tmp1* &
  2310. tmp1))))
  2311. !Deposition/sorption nucleation:
  2312. if (Tc<-5. .and. Si>1.) then
  2313. NuDEPSOR= max(0., 1.e3*exp(12.96*(Simax-1.)-0.639)-(NYM(i,k))) !Meyers(1992)
  2314. endif
  2315. !Contact nucleation:
  2316. if (QCM(i,k)>epsQ .and. Tc<-2.) then
  2317. GG = 1.*idew/(RGASV*(TM(i,k))/((QSW(i,k)*HPS(i)*S(i,k))/EPS1)/ &
  2318. Cdiff+CHLC/Ka/(TM(i,k))*(CHLC/RGASV/(TM(i,k))-1.)) !CP00a
  2319. Swmax = SxFNC(WZ(i,k),Tc,HPS(i)*S(i,k),QSW(i,k),QSI(i,k),CCNtype,1)
  2320. ssat = min((QM(i,k)/QSW(i,k)), Swmax) -1.
  2321. Tcc = Tc + GG*ssat*CHLC/Kdiff !C86_eqn64
  2322. Na = exp(4.11-0.262*Tcc) !W95_eqn60/M92_2.6
  2323. Kn = LAMa0*(TM(i,k))*p0/(T0*(HPS(i)*S(i,k))*Ra) !W95_eqn59
  2324. PSIa = -kBoltz*Tcc/(6.*pi*Ra*MUdyn)*(1.+Kn) !W95_eqn58
  2325. ft = 0.4*(1.+1.45*Kn+0.4*Kn*exp(-1./Kn))*(Ka+2.5*Kn*KAPa)/ &
  2326. (1.+3.*Kn)/(2.*Ka+5.*KAPa*Kn+KAPa) !W95_eqn57
  2327. Dc = (DE(i,k)*(QCM(i,k)*iNCM)*icmr)**thrd
  2328. F1 = PI2*Dc*Na*(NCM(i,k)) !W95_eqn55
  2329. F2 = Ka/(HPS(i)*S(i,k))*(Tc-Tcc) !W95_eqn56
  2330. NuCONTA= -F1*F2*RGASV*(TM(i,k))/CHLC*iDE(i,k) !diffusiophoresis
  2331. NuCONTB= F1*F2*ft*iDE(i,k) !thermeophoresis
  2332. NuCONTC= F1*PSIa !Brownian diffusion
  2333. NuCONT = max(0.,(NuCONTA+NuCONTB+NuCONTC)*dt)
  2334. endif
  2335. !Total primary ice nucleation:
  2336. if (icephase_ON) then
  2337. NNUvi= min(NNUmax, NuDEPSOR + NuCONT )
  2338. QNUvi= mio*iDE(i,k)*NNUvi
  2339. QNUvi= min(QNUvi,(Q(i,k)))
  2340. endif
  2341. elseif (primIceNucl==2) then
  2342. if (Tc<-5. .and. Si>1.08) then !following Thompson etal (2006)
  2343. NNUvi= max(N_Cooper(TRPL,T(i,k))-NYM(i,k),0.)
  2344. QNUvi= min(mio*iDE(i,k)*NNUvi, Q(i,k))
  2345. endif
  2346. !elseif (primIceNucl==3) then
  2347. !! (for alternative [future] ice nucleation parameterizations)
  2348. ! NNUvi=...
  2349. ! QNUvi=...
  2350. endif !if (primIceNucl==1)
  2351. else !dblMom_i
  2352. !Ice initiation (single-moment):
  2353. if (QIM(i,k)<=epsQ .and. Tc<-5. .and. Si>1.08) then !following Thompson etal (2006)
  2354. NNUvi = N_Cooper(TRPL,T(i,k))
  2355. QNUvi= mio*iDE(i,k)*NNUvi
  2356. QNUvi= min(QNUvi,Q(i,k))
  2357. endif
  2358. endif !dblMom_i
  2359. IF (QIM(i,k)>epsQ) THEN
  2360. !Deposition/sublimation:
  2361. ! No_i = NYM(i,k)*iGI31/iLAMi**(1.+alpha_i)
  2362. ! VENTi= Avx*GI32*iLAMi**(2.+alpha_i)+Bvx*ScTHRD*sqrt(gam*afi*iMUkin)*GI6* &
  2363. ! iLAMi**(2.5+0.5*bfi+alpha_i)
  2364. No_i = NYM(i,k)*iGI31/iLAMi !optimized for alpha_i=0
  2365. VENTi= Avx*GI32*iLAMi*iLAMi+Bvx*ScTHRD*sqrt(gam*afi*iMUkin)*GI6*iLAMi** &
  2366. (2.5+0.5*bfi+alpha_i)
  2367. !Note: ice crystal capacitance is implicitly C = 0.5*D*capFact_i
  2368. QVDvi= dt*capFact_i*iABi*(PI2*(Si-1.)*No_i*VENTi)
  2369. ! Prevent overdepletion of vapor:
  2370. tmp1 = T(i,k)-7.66
  2371. VDmax = (Q(i,k)-QSS(i,k))/(1.+ck6*(QSS(i,k))/(tmp1*tmp1))
  2372. if(Si>=1.) then
  2373. QVDvi= min(max(QVDvi,0.),VDmax)
  2374. else
  2375. if (VDmax<0.) QVDvi= max(QVDvi,VDmax)
  2376. !IF prevents subl.(QVDvi<0 at t) changing to dep.(VDmax>0 at t*) 2005-06-28
  2377. endif
  2378. if (.not. iceDep_ON) QVDvi= 0. !suppresses depositional growth
  2379. NVDvi= min(0., (NYM(i,k)*iQIM)*QVDvi) !dNi/dt=0 for deposition
  2380. ! Conversion to snow:
  2381. ! +depostion of ice:
  2382. mi= DE(i,k)*(QIM(i,k)*iNYM)
  2383. if (mi<=0.5*mso.and.abs(0.5*mso-mi)>1.e-20) then
  2384. QCNis1= (mi/(mso-mi))*QVDvi
  2385. else
  2386. QCNis1= QVDvi + (1.-0.5*mso/mi)*QIM(i,k)
  2387. endif
  2388. QCNis1= max(0., QCNis1)
  2389. ! +aggregation of ice:
  2390. if(Di<0.5*Dso) then
  2391. Ki = PIov6*Di*Di*vi0*Eii*Xdisp
  2392. tmp1 = log(Di/Dso)
  2393. tmp2 = tmp1*tmp1*tmp1
  2394. QCNis2= -dt*0.5*(QIM(i,k)*NYM(i,k))*Ki/tmp2
  2395. else
  2396. Ki= 0.; QCNis2= 0.
  2397. endif
  2398. ! +total conversion rate:
  2399. QCNis = QCNis1 + QCNis2
  2400. NsCNis= DE(i,k)*imso*QCNis !source for snow (Ns)
  2401. NiCNis= (DE(i,k)*imso*QCNis1 + 0.5*Ki*NYM(i,k)*NYM(i,k)) !sink for ice (Ni)
  2402. NiCNis= min(NiCNis, NYM(i,k)*0.1) !Prevents overdepl. of NY when final QI>0
  2403. if (.not.(snow_ON)) then
  2404. QCNis= 0.; NiCNis= 0.; NsCNis= 0. !Suppress SNOW initiation
  2405. endif
  2406. ! 3-component freezing (collisions with rain):
  2407. if (QRM(i,k)>epsQ .and. QIM(i,k)>epsQ) then
  2408. tmp1 = vr0-vi0
  2409. tmp3 = sqrt(tmp1*tmp1+0.04*vr0*vi0)
  2410. QCLir= dt*cmi*Eri*PIov4*iDE(i,k)*(NRM(i,k)*NYM(i,k))*iGI31*iGR31*tmp3* &
  2411. (GI36*GR31*iLAMi5+2.*GI35*GR32*iLAMi4*iLAMr+GI34*GR33*iLAMi3* &
  2412. iLAMr2)
  2413. NCLri= dt*PIov4*Eri*(NRM(i,k)*NYM(i,k))*iGI31*iGR31*tmp3*(GI33*GR31* &
  2414. iLAMi2+2.*GI32*GR32*iLAMi*iLAMr+GI31*GR33*iLAMr2)
  2415. QCLri= dt*cmr*Eri*PIov4*iDE(i,k)*(NYM(i,k)*NRM(i,k))*iGR31*iGI31*tmp3* &
  2416. (GR36*GI31 *iLAMr5+2.*GR35*GI32*iLAMr4*iLAMi+GR34*GI33*iLAMr3* &
  2417. iLAMi2)
  2418. !note: For explicit eqns, both NCLri and NCLir are mathematically identical)
  2419. NCLir= min(QCLir*(NYM(i,k)*iQIM), NCLri)
  2420. QCLri= min(QCLri, (QRM(i,k))); QCLir= min(QCLir, (QIM(i,k)))
  2421. NCLri= min(NCLri, (NRM(i,k))); NCLir= min(NCLir, (NYM(i,k)))
  2422. !Determine destination of 3-comp.freezing:
  2423. tmp1= max(Di,Dr)
  2424. dey= (dei*Di*Di*Di+dew*Dr*Dr*Dr)/(tmp1*tmp1*tmp1)
  2425. if (dey>0.5*(deg+deh) .and. Dr>Dr_3cmpThrs .and. hail_ON) then
  2426. Dirg= 0.; Dirh= 1.
  2427. else
  2428. Dirg= 1.; Dirh= 0.
  2429. endif
  2430. if (.not. grpl_ON) Dirg= 0.
  2431. else
  2432. QCLir= 0.; NCLir= 0.; QCLri= 0.
  2433. NCLri= 0.; Dirh = 0.; Dirg= 0.
  2434. endif
  2435. ! Rime-splintering (ice multiplication):
  2436. ff= 0.
  2437. if(Tc>=-8..and.Tc<=-5.) ff= 3.5e8*(Tc +8.)*thrd
  2438. if(Tc> -5..and.Tc< -3.) ff= 3.5e8*(-3.-Tc)*0.5
  2439. NIMsi= DE(i,k)*ff*QCLcs
  2440. NIMgi= DE(i,k)*ff*QCLcg
  2441. QIMsi= mio*iDE(i,k)*NIMsi
  2442. QIMgi= mio*iDE(i,k)*NIMgi
  2443. ELSE
  2444. QVDvi= 0.; QCNis= 0.
  2445. QIMsi= 0.; QIMgi= 0.; QCLri= 0.; QCLir= 0.
  2446. NVDvi= 0.; NCLir= 0.; NIMsi= 0.
  2447. NiCNis=0.; NsCNis=0.; NIMgi= 0.; NCLri= 0.
  2448. ENDIF
  2449. !---------!
  2450. ! SNOW: !
  2451. !---------!
  2452. IF (QNM(i,k)>epsQ) THEN
  2453. !Deposition/sublimation:
  2454. !note: - snow crystal capacitance is implicitly C = 0.5*D*capFact_s
  2455. ! - No_s and VENTs are computed above
  2456. QVDvs = dt*capFact_s*iABi*(PI2*(Si-1.)*No_s*VENTs - CHLS*CHLF/(Ka*RGASV* &
  2457. TM(i,k)*TM(i,k))*QCLcs*idt)
  2458. ! Prevent overdepletion of vapor:
  2459. tmp1 = T(i,k)-7.66
  2460. VDmax = (Q(i,k)-QSS(i,k))/(1.+ck6*(QSS(i,k))/(tmp1*tmp1)) !KY97_A.33
  2461. if(Si>=1.) then
  2462. QVDvs= min(max(QVDvs,0.),VDmax)
  2463. else
  2464. if (VDmax<0.) QVDvs= max(QVDvs,VDmax)
  2465. !IF prevents subl.(QVDvs<0 at t) changing to dep.(VDmax>0 at t*)
  2466. endif
  2467. NVDvs= -min(0.,(NNM(i,k)*iQNM)*QVDvs) !pos. quantity
  2468. ! Conversion to graupel:
  2469. if (QCLcs>CNsgThres*QVDvs .and. 0.99*deg>des) then
  2470. !note: The (deg>des) condition equates to (Ds>330microns) for m(D)=0.069D^2
  2471. ! relation for snow, which implies a variable bulk density. The physical
  2472. ! assumption in the QCNsg equation is that snow converts to graupel due
  2473. ! to densification from riming.
  2474. ! The 0.99 is to prevent overflow if des~deg
  2475. QCNsg= (deg/(deg-des))*QCLcs
  2476. else
  2477. QCNsg= 0.
  2478. endif
  2479. if (.not. grpl_ON) QCNsg= 0.
  2480. NCNsg= DE(i,k)*imgo*QCNsg
  2481. NCNsg= min(NCNsg, (0.5*NNM(i,k)*iQNM)*QCNsg) !Prevents incorrect Ns-depletion
  2482. ! 3-component freezing (collisions with rain):
  2483. if (QRM(i,k)>epsQ .and. QNM(i,k)>epsQ .and. Tc<-5.) then
  2484. tmp1 = vs0-vr0
  2485. tmp2 = sqrt(tmp1*tmp1+0.04*vs0*vr0)
  2486. tmp6 = iLAMs2*iLAMs2*iLAMs
  2487. QCLrs= dt*cmr*Ers*PIov4*iDE(i,k)*NNM(i,k)*NRM(i,k)*iGR31*iGS31*tmp2* &
  2488. (GR36*GS31*iLAMr5+2.*GR35*GS32*iLAMr4*iLAMs+GR34*GS33*iLAMr3* &
  2489. iLAMs2)
  2490. NCLrs= dt*0.25e0*PI*Ers*(NNM(i,k)*NRM(i,k))*iGR31*iGS31*tmp2*(GR33* &
  2491. GS31*iLAMr2+2.*GR32*GS32*iLAMr*iLAMs+GR31*GS33*iLAMs2)
  2492. if (snowSpherical) then
  2493. !hardcoded for dms=3:
  2494. QCLsr= dt*cms*Ers*PIov4*iDE(i,k)*(NRM(i,k)*NNM(i,k))*iGS31*iGR31* &
  2495. tmp2*(GS36*GR31*tmp6+2.*GS35*GR32*iLAMs2*iLAMs2*iLAMr+GS34* &
  2496. GR33*iLAMs2*iLAMs*iLAMr2)
  2497. else
  2498. !hardcoded for dms=2:
  2499. QCLsr= dt*cms*iDE(i,k)*PI*0.25*ERS*tmp2*NNM(i,k)*NRM(i,k)*iGS31* &
  2500. iGR31*(GR33*GS33*iLAMr**2.*iLAMs**2. + 2.*GR32*GS34*iLAMr* &
  2501. iLAMs**3. +GR31*GS35*iLAMs**4.)
  2502. endif
  2503. !note: For explicit eqns, NCLsr = NCLrs
  2504. NCLsr= min(QCLsr*(NNM(i,k)*iQNM), NCLrs)
  2505. QCLrs= min(QCLrs, QRM(i,k)); QCLsr= min(QCLsr, QNM(i,k))
  2506. NCLrs= min(NCLrs, NRM(i,k)); NCLsr= min(NCLsr, NNM(i,k))
  2507. ! Determine destination of 3-comp.freezing:
  2508. Dsrs= 0.; Dsrg= 0.; Dsrh= 0.
  2509. tmp1= max(Ds,Dr)
  2510. tmp2= tmp1*tmp1*tmp1
  2511. dey = (des*Ds*Ds*Ds + dew*Dr*Dr*Dr)/tmp2
  2512. if (dey<=0.5*(des+deg) ) Dsrs= 1. !snow
  2513. if (dey >0.5*(des+deg) .and. dey<0.5*(deg+deh)) Dsrg= 1. !graupel
  2514. if (dey>=0.5*(deg+deh)) then
  2515. Dsrh= 1. !hail
  2516. if (.not.hail_ON .or. Dr<Dr_3cmpThrs) then
  2517. Dsrg= 1.; Dsrh= 0. !graupel
  2518. endif
  2519. endif
  2520. if (.not. grpl_ON) Dsrg=0.
  2521. else
  2522. QCLrs= 0.; QCLsr= 0.; NCLrs= 0.; NCLsr= 0.
  2523. endif
  2524. ELSE
  2525. QVDvs= 0.; QCLcs= 0.; QCNsg= 0.; QCLsr= 0.; QCLrs= 0.
  2526. NVDvs= 0.; NCLcs= 0.; NCLsr= 0.; NCLrs= 0.; NCNsg= 0.
  2527. ENDIF
  2528. !------------!
  2529. ! GRAUPEL: !
  2530. !------------!
  2531. IF (QGM(i,k)>epsQ) THEN
  2532. !Conversion to hail: (D_sll given by S-L limit)
  2533. if (WZ(i,k)>w_CNgh .and. hail_ON) then
  2534. D_sll = 0.01*(exp(min(20.,-Tc/(1.1e4*DE(i,k)*(QCM(i,k)+QRM(i,k))-1.3e3* &
  2535. DE(i,k)*(QIM(i,k))+1.)))-1.)
  2536. !Add correction factor: [to account error in equation of Ziegler (1985), as per Young (1993)]
  2537. D_sll = 2.0*D_sll
  2538. D_sll = min(1., max(0.0001,D_sll)) !smallest D_sll=0.1mm; largest=1m
  2539. !Old approach: (pre-my-2.15.0)
  2540. ! ratio= Dg/D_sll
  2541. ! if (ratio>r_CNgh) then
  2542. ! QCNgh= (0.5*ratio)*(QCLcg+QCLrg+QCLig)
  2543. ! QCNgh= min(QCNgh,(QGM(i,k))+QCLcg+QCLrg+QCLig)
  2544. ! NCNgh= DE(i,k)*QCNgh*icmh/(D_sll*D_sll*D_sll)
  2545. ! else
  2546. ! QCNgh= 0.
  2547. ! NCNgh= 0.
  2548. ! endif
  2549. !New approach:
  2550. tmp1 = exp(-D_sll/iLAMg)
  2551. Ng_tail = No_g*iLAMg*tmp1 !integral(Dsll,inf) of N(D)dD
  2552. if (Ng_tail > Ngh_crit) then
  2553. QCNgh = idt*cmg*No_g*tmp1*(D_sll**3.*iLAMg + 3.*D_sll**2.*iLAMg**2. &
  2554. + 6.*D_sll*iLAMg**3. + 6.*iLAMg**4.)
  2555. NgCNgh= idt*No_g*iLAMg*tmp1
  2556. Rz= 1.
  2557. !---
  2558. ! The Rz factor (<>1) serves to conserve reflectivity when graupel
  2559. ! converts to hail with a a different shape parameter, alpha.
  2560. ! The factor Rz non-conserves N while acting to conserve Z for
  2561. ! double-moment. See Ferrier, 1994 App. D). However, Rz=1 is
  2562. ! used since it is deemed more important to conserve concentration
  2563. ! than reflectivity (see Milbrandt and McTaggart-Cowan, 2010 JAS).
  2564. !---
  2565. ! Code to conserve total reflectivity:
  2566. ! if (QHM(i,k)>epsQ) then
  2567. ! Rz= (gamma(7.+alpha_h)*GH31*GG34**2.)/(GG36*GG31*GH34**2.)
  2568. ! else
  2569. ! Rz= 1.
  2570. ! endif
  2571. !---
  2572. NhCNgh= Rz*NgCNgh
  2573. else
  2574. QCNgh = 0.; NgCNgh = 0.; NhCNgh = 0.
  2575. endif
  2576. endif
  2577. !3-component freezing (collisions with rain):
  2578. if (QRM(i,k)>epsQ) then
  2579. tmp1 = vg0-vr0
  2580. tmp2 = sqrt(tmp1*tmp1 + 0.04*vg0*vr0)
  2581. tmp8 = iLAMg2*iLAMg ! iLAMg**3
  2582. tmp9 = tmp8*iLAMg ! iLAMg**4
  2583. tmp10= tmp9*iLAMg ! iLAMg**5
  2584. !(parameterization of Erg based on Cober and List, 1993 [JAS])
  2585. Kstoke = dew*abs(vg0-vr0)*Dr*Dr/(9.*MUdyn*Dg)
  2586. Kstoke = max(1.5,min(10.,Kstoke))
  2587. Erg = 0.55*log10(2.51*Kstoke)
  2588. QCLrg= dt*cmr*Erg*PIov4*iDE(i,k)*(NGM(i,k)*NRM(i,k))*iGR31*iGG31*tmp2* &
  2589. (GR36*GG31*iLAMr5+2.*GR35*GG32*iLAMr4*iLAMg+GR34*GG33*iLAMr3* &
  2590. iLAMg2)
  2591. NCLrg= dt*PIov4*Erg*(NGM(i,k)*NRM(i,k))*iGR31*iGG31*tmp2*(GR33*GG31* &
  2592. iLAMr2+2.*GR32*GG32*iLAMr*iLAMg+GR31*GG33*iLAMg2)
  2593. QCLgr= dt*cmg*Erg*PIov4*iDE(i,k)*(NRM(i,k)*NGM(i,k))*iGG31*iGR31*tmp2* &
  2594. (GG36*GR31*tmp10+2.*GG35*GR32*tmp9*iLAMr+GG34*GR33*tmp8*iLAMr2)
  2595. !(note: For explicit eqns, NCLgr= NCLrg)
  2596. NCLgr= min(NCLrg, QCLgr*(NGM(i,k)*iQGM))
  2597. QCLrg= min(QCLrg, QRM(i,k)); QCLgr= min(QCLgr, QGM(i,k))
  2598. NCLrg= min(NCLrg, NRM(i,k)); NCLgr= min(NCLgr, NGM(i,k))
  2599. ! Determine destination of 3-comp.freezing:
  2600. tmp1= max(Dg,Dr)
  2601. tmp2= tmp1*tmp1*tmp1
  2602. dey = (deg*Dg*Dg*Dg + dew*Dr*Dr*Dr)/tmp2
  2603. if (dey>0.5*(deg+deh) .and. Dr>Dr_3cmpThrs .and. hail_ON) then
  2604. Dgrg= 0.; Dgrh= 1.
  2605. else
  2606. Dgrg= 1.; Dgrh= 0.
  2607. endif
  2608. else
  2609. QCLgr= 0.; QCLrg= 0.; NCLgr= 0.; NCLrg= 0.
  2610. endif
  2611. ELSE
  2612. QVDvg= 0.; QCNgh= 0.; QCLgr= 0.; QCLrg= 0.; NgCNgh= 0.
  2613. NVDvg= 0.; NhCNgh= 0.; NCLgr= 0.; NCLrg= 0.
  2614. ENDIF
  2615. !---------!
  2616. ! HAIL: !
  2617. !---------!
  2618. IF (QHM(i,k)>epsQ) THEN
  2619. !Wet growth:
  2620. if (QHwet<(QCLch+QCLrh+QCLih+QCLsh) .and. Tc>-40.) then
  2621. QCLih= min(QCLih*iEih, QIM(i,k)) !change Eih to 1. in CLih
  2622. NCLih= min(NCLih*iEih, NYM(i,k)) ! " "
  2623. QCLsh= min(QCLsh*iEsh, QNM(i,k)) !change Esh to 1. in CLsh
  2624. NCLsh= min(NCLsh*iEsh, NNM(i,k)) ! " "
  2625. tmp3 = QCLrh
  2626. QCLrh= QHwet-(QCLch+QCLih+QCLsh) !actual QCLrh minus QSHhr
  2627. QSHhr= tmp3-QCLrh !QSHhr used here only
  2628. NSHhr= DE(i,k)*QSHhr/(cmr*Drshed*Drshed*Drshed)
  2629. else
  2630. NSHhr= 0.
  2631. endif
  2632. ELSE
  2633. QVDvh= 0.; NVDvh= 0.; NSHhr= 0.
  2634. ENDIF
  2635. ENDIF ! ( if Tc<0C Block )
  2636. !------------ End of source/sink term calculation -------------!
  2637. !-- Adjustment of source/sink terms to prevent overdepletion: --!
  2638. do niter= 1,2
  2639. ! (1) Vapor:
  2640. source= Q(i,k) +dim(-QVDvi,0.)+dim(-QVDvs,0.)+dim(-QVDvg,0.)+dim(-QVDvh,0.)
  2641. sink = QNUvi+dim(QVDvi,0.)+dim(QVDvs,0.)
  2642. sour = max(source,0.)
  2643. if(sink>sour) then
  2644. ratio= sour/sink
  2645. QNUvi= ratio*QNUvi; NNUvi= ratio*NNUvi
  2646. if(QVDvi>0.) then
  2647. QVDvi= ratio*QVDvi; NVDvi= ratio*NVDvi
  2648. endif
  2649. if(QVDvs>0.) then
  2650. QVDvs=ratio*QVDvs; NVDvs=ratio*NVDvs
  2651. endif
  2652. QVDvg= ratio*QVDvg; NVDvg= ratio*NVDvg
  2653. QVDvh= ratio*QVDvh; NVDvh= ratio*NVDvh
  2654. endif
  2655. ! (2) Cloud:
  2656. source= QC(i,k)
  2657. sink = QCLcs+QCLcg+QCLch+QFZci
  2658. sour = max(source,0.)
  2659. if(sink>sour) then
  2660. ratio= sour/sink
  2661. QFZci= ratio*QFZci; NFZci= ratio*NFZci
  2662. QCLcs= ratio*QCLcs; NCLcs= ratio*NCLcs
  2663. QCLcg= ratio*QCLcg; NCLcg= ratio*NCLcg
  2664. QCLch= ratio*QCLch; NCLch= ratio*NCLch
  2665. endif
  2666. ! (3) Rain:
  2667. source= QR(i,k)+QMLsr+QMLgr+QMLhr+QMLir
  2668. sink = QCLri+QCLrs+QCLrg+QCLrh+QFZrh
  2669. sour = max(source,0.)
  2670. if(sink>sour) then
  2671. ratio= sour/sink
  2672. QCLrg= ratio*QCLrg; QCLri= ratio*QCLri; NCLri= ratio*NCLri
  2673. QCLrs= ratio*QCLrs; NCLrs= ratio*NCLrs; QCLrg= ratio*QCLrg
  2674. NCLrg= ratio*NCLrg; QCLrh= ratio*QCLrh; NCLrh= ratio*NCLrh
  2675. QFZrh= ratio*QFZrh; NrFZrh=ratio*NrFZrh; NhFZrh=ratio*NhFZrh
  2676. if (ratio==0.) then
  2677. Dirg= 0.; Dirh= 0.; Dgrg= 0.; Dgrh= 0.
  2678. Dsrs= 0.; Dsrg= 0.; Dsrh= 0.
  2679. endif
  2680. endif
  2681. ! (4) Ice:
  2682. source= QI(i,k)+QNUvi+dim(QVDvi,0.)+QFZci
  2683. sink = QCNis+QCLir+dim(-QVDvi,0.)+QCLis+QCLig+QCLih+QMLir
  2684. sour = max(source,0.)
  2685. if(sink>sour) then
  2686. ratio= sour/sink
  2687. QMLir= ratio*QMLir; NMLir= ratio*NMLir
  2688. if (QVDvi<0.) then
  2689. QVDvi= ratio*QVDvi; NVDvi= ratio*NVDvi
  2690. endif
  2691. QCNis= ratio*QCNis; NiCNis= ratio*NiCNis; NsCNis= ratio*NsCNis
  2692. QCLir= ratio*QCLir; NCLir= ratio*NCLir; QCLig= ratio*QCLig
  2693. QCLis= ratio*QCLis; NCLis= ratio*NCLis
  2694. QCLih= ratio*QCLih; NCLih= ratio*NCLih
  2695. if (ratio==0.) then
  2696. Dirg= 0.; Dirh= 0.
  2697. endif
  2698. endif
  2699. ! (5) Snow:
  2700. source= QN(i,k)+QCNis+dim(QVDvs,0.)+QCLis+Dsrs*(QCLrs+QCLsr)+QCLcs
  2701. sink = dim(-QVDvs,0.)+QCNsg+QMLsr+QCLsr+QCLsh
  2702. sour = max(source,0.)
  2703. if(sink>sour) then
  2704. ratio= sour/sink
  2705. if(QVDvs<=0.) then
  2706. QVDvs= ratio*QVDvs; NVDvs= ratio*NVDvs
  2707. endif
  2708. QCNsg= ratio*QCNsg; NCNsg= ratio*NCNsg; QMLsr= ratio*QMLsr
  2709. NMLsr= ratio*NMLsr; QCLsr= ratio*QCLsr; NCLsr= ratio*NCLsr
  2710. QCLsh= ratio*QCLsh; NCLsh= ratio*NCLsh
  2711. if (ratio==0.) then
  2712. Dsrs= 0.; Dsrg= 0.; Dsrh= 0.
  2713. endif
  2714. endif
  2715. ! (6) Graupel:
  2716. source= QG(i,k)+QCNsg+dim(QVDvg,0.)+Dirg*(QCLri+QCLir)+Dgrg*(QCLrg+QCLgr)+ &
  2717. QCLcg+Dsrg*(QCLrs+QCLsr)+QCLig
  2718. sink = dim(-QVDvg,0.)+QMLgr+QCNgh+QCLgr
  2719. sour = max(source,0.)
  2720. if(sink>sour) then
  2721. ratio= sour/sink
  2722. QVDvg= ratio*QVDvg; NVDvg= ratio*NVDvg; QMLgr = ratio*QMLgr
  2723. NMLgr= ratio*NMLgr; QCNgh= ratio*QCNgh; NgCNgh= ratio*NgCNgh
  2724. QCLgr= ratio*QCLgr; NCLgr= ratio*NCLgr; NhCNgh= ratio*NhCNgh
  2725. if (ratio==0.) then
  2726. Dgrg= 0.; Dgrh= 0.
  2727. endif
  2728. endif
  2729. ! (7) Hail:
  2730. source= QH(i,k)+dim(QVDvh,0.)+QCLch+QCLrh+Dirh*(QCLri+QCLir)+QCLih+QCLsh+ &
  2731. Dsrh*(QCLrs+QCLsr)+QCNgh+Dgrh*(QCLrg+QCLgr)+QFZrh
  2732. sink = dim(-QVDvh,0.)+QMLhr
  2733. sour = max(source,0.)
  2734. if(sink>sour) then
  2735. ratio= sour/sink
  2736. QVDvh= ratio*QVDvh; NVDvh= ratio*NVDvh
  2737. QMLhr= ratio*QMLhr; NMLhr= ratio*NMLhr
  2738. endif
  2739. enddo
  2740. !--------------- End of source/sink term adjustment ------------------!
  2741. !Compute N-tendencies for destination categories of 3-comp.freezing:
  2742. NCLirg= 0.; NCLirh= 0.; NCLsrs= 0.; NCLsrg= 0.
  2743. NCLsrh= 0.; NCLgrg= 0.; NCLgrh= 0.
  2744. if (QCLir+QCLri>0.) then
  2745. tmp1 = max(Dr,Di)
  2746. tmp2 = tmp1*tmp1*tmp1*PIov6
  2747. NCLirg= Dirg*DE(i,k)*(QCLir+QCLri)/(deg*tmp2)
  2748. NCLirh= Dirh*DE(i,k)*(QCLir+QCLri)/(deh*tmp2)
  2749. endif
  2750. if (QCLsr+QCLrs>0.) then
  2751. tmp1 = max(Dr,Ds)
  2752. tmp2 = tmp1*tmp1*tmp1*PIov6
  2753. NCLsrs= Dsrs*DE(i,k)*(QCLsr+QCLrs)/(des*tmp2)
  2754. NCLsrg= Dsrg*DE(i,k)*(QCLsr+QCLrs)/(deg*tmp2)
  2755. NCLsrh= Dsrh*DE(i,k)*(QCLsr+QCLrs)/(deh*tmp2)
  2756. endif
  2757. if (QCLgr+QCLrg>0.) then
  2758. tmp1 = max(Dr,Dg)
  2759. tmp2 = tmp1*tmp1*tmp1*PIov6
  2760. NCLgrg= Dgrg*DE(i,k)*(QCLgr+QCLrg)/(deg*tmp2)
  2761. NCLgrh= Dgrh*DE(i,k)*(QCLgr+QCLrg)/(deh*tmp2)
  2762. endif
  2763. !========================================================================!
  2764. ! Add all source/sink terms to all predicted moments: !
  2765. !========================================================================!
  2766. !Diagnostic S/S terms: (to facilitate output of 3D variables for diagnostics)
  2767. !SS01(i,k)= QVDvs*idt (e.g., for depositional growth rate of snow, kg kg-1 s-1)
  2768. ! Q-Source/Sink Terms:
  2769. Q(i,k) = Q(i,k) -QNUvi -QVDvi -QVDvs -QVDvg -QVDvh
  2770. QC(i,k)= QC(i,k) -QCLcs -QCLcg -QCLch -QFZci
  2771. QR(i,k)= QR(i,k) -QCLri +QMLsr -QCLrs -QCLrg +QMLgr -QCLrh +QMLhr -QFZrh +QMLir
  2772. QI(i,k)= QI(i,k) +QNUvi +QVDvi +QFZci -QCNis -QCLir -QCLis -QCLig &
  2773. -QMLir -QCLih +QIMsi +QIMgi
  2774. QG(i,k)= QG(i,k) +QCNsg +QVDvg +QCLcg -QCLgr-QMLgr -QCNgh -QIMgi +QCLig &
  2775. +Dirg*(QCLri+QCLir) +Dgrg*(QCLrg+QCLgr) +Dsrg*(QCLrs+QCLsr)
  2776. QN(i,k)= QN(i,k) +QCNis +QVDvs +QCLcs -QCNsg -QMLsr -QIMsi -QCLsr +QCLis -QCLsh &
  2777. +Dsrs*(QCLrs+QCLsr)
  2778. QH(i,k)= QH(i,k) +Dirh*(QCLri+QCLir) -QMLhr +QVDvh +QCLch +Dsrh*(QCLrs+QCLsr) &
  2779. +QCLih +QCLsh +QFZrh +QCLrh +QCNgh +Dgrh*(QCLrg+QCLgr)
  2780. ! N-Source/Sink Terms:
  2781. if (dblMom_c) NC(i,k)= NC(i,k) -NCLcs -NCLcg -NCLch -NFZci
  2782. if (dblMom_r) NR(i,k)= NR(i,k) -NCLri -NCLrs -NCLrg -NCLrh +NMLsr +NMLgr +NMLhr &
  2783. -NrFZrh +NMLir +NSHhr
  2784. if (dblMom_i) NY(i,k)= NY(i,k) +NNUvi +NVDvi +NFZci -NCLir -NCLis -NCLig -NCLih &
  2785. -NMLir +NIMsi +NIMgi -NiCNis
  2786. if (dblMom_s) NN(i,k)= NN(i,k) +NsCNis -NVDvs -NCNsg -NMLsr -NCLss -NCLsr -NCLsh &
  2787. +NCLsrs
  2788. if (dblMom_g) NG(i,k)= NG(i,k) +NCNsg -NCLgr -NVDvg -NMLgr +NCLirg +NCLsrg &
  2789. +NCLgrg -NgCNgh
  2790. if (dblMom_h) NH(i,k)= NH(i,k) +NhFZrh +NhCNgh -NMLhr -NVDvh +NCLirh +NCLsrh &
  2791. +NCLgrh
  2792. T(i,k)= T(i,k) +LFP*(QCLri+QCLcs+QCLrs+QFZci-QMLsr+QCLcg+QCLrg-QMLir-QMLgr &
  2793. -QMLhr+QCLch+QCLrh+QFZrh) +LSP*(QNUvi+QVDvi+QVDvs+QVDvg+QVDvh)
  2794. !Prevent overdepletion:
  2795. IF (dblMom_c) THEN
  2796. if(QC(i,k)<epsQ .or. NC(i,k)<epsN) then
  2797. Q(i,k) = Q(i,k) + QC(i,k)
  2798. T(i,k) = T(i,k) - LCP*QC(i,k)
  2799. QC(i,k)= 0.; NC(i,k)= 0.
  2800. endif
  2801. ELSE
  2802. if(QC(i,k)<epsQ) then
  2803. Q(i,k) = Q(i,k) + QC(i,k)
  2804. T(i,k) = T(i,k) - LCP*QC(i,k)
  2805. QC(i,k)= 0.
  2806. endif
  2807. ENDIF
  2808. IF (dblMom_r) THEN
  2809. if (QR(i,k)<epsQ .or. NR(i,k)<epsN) then
  2810. Q(i,k) = Q(i,k) + QR(i,k)
  2811. T(i,k) = T(i,k) - LCP*QR(i,k)
  2812. QR(i,k)= 0.; NR(i,k)= 0.
  2813. endif
  2814. ELSE
  2815. if (QR(i,k)<epsQ) then
  2816. Q(i,k) = Q(i,k) + QR(i,k)
  2817. T(i,k) = T(i,k) - LCP*QR(i,k)
  2818. QR(i,k)= 0.
  2819. endif
  2820. ENDIF
  2821. IF (dblMom_i) THEN
  2822. if (QI(i,k)<epsQ .or. NY(i,k)<epsN) then
  2823. Q(i,k) = Q(i,k) + QI(i,k)
  2824. T(i,k) = T(i,k) - LSP*QI(i,k)
  2825. QI(i,k)= 0.; NY(i,k)= 0.
  2826. endif
  2827. ELSE
  2828. if (QI(i,k)<epsQ) then
  2829. Q(i,k) = Q(i,k) + QI(i,k)
  2830. T(i,k) = T(i,k) - LSP*QI(i,k)
  2831. QI(i,k)= 0.
  2832. endif
  2833. ENDIF
  2834. IF (dblMom_s) THEN
  2835. if (QN(i,k)<epsQ .or. NN(i,k)<epsN) then
  2836. Q(i,k) = Q(i,k) + QN(i,k)
  2837. T(i,k) = T(i,k) - LSP*QN(i,k)
  2838. QN(i,k)= 0.; NN(i,k)= 0.
  2839. endif
  2840. ELSE
  2841. if (QN(i,k)<epsQ) then
  2842. Q(i,k) = Q(i,k) + QN(i,k)
  2843. T(i,k) = T(i,k) - LSP*QN(i,k)
  2844. QN(i,k)= 0.
  2845. endif
  2846. ENDIF
  2847. IF (dblMom_g) THEN
  2848. if (QG(i,k)<epsQ .or. NG(i,k)<epsN) then
  2849. Q(i,k) = Q(i,k) + QG(i,k)
  2850. T(i,k) = T(i,k) - LSP*QG(i,k)
  2851. QG(i,k)= 0.; NG(i,k)= 0.
  2852. endif
  2853. ELSE
  2854. if (QG(i,k)<epsQ) then
  2855. Q(i,k) = Q(i,k) + QG(i,k)
  2856. T(i,k) = T(i,k) - LSP*QG(i,k)
  2857. QG(i,k)= 0.
  2858. endif
  2859. ENDIF
  2860. IF (dblMom_h) THEN
  2861. if (QH(i,k)<epsQ .or. NH(i,k)<epsN) then
  2862. Q(i,k) = Q(i,k) + QH(i,k)
  2863. T(i,k) = T(i,k) - LSP*QH(i,k)
  2864. QH(i,k)= 0.; NH(i,k)= 0.
  2865. else if (QH(i,k)>epsQ .and. NH(i,k)>epsN) then
  2866. !Conversion to graupel of hail is small:
  2867. Dh= (DE(i,k)*QH(i,k)/NH(i,k)*icmh)**thrd
  2868. if (Dh<Dh_min) then
  2869. QG(i,k)= QG(i,k) + QH(i,k)
  2870. NG(i,k)= NG(i,k) + NH(i,k)
  2871. QH(i,k)= 0.; NH(i,k)= 0.
  2872. endif
  2873. endif
  2874. ELSE
  2875. if (QH(i,k)<epsQ) then
  2876. Q(i,k) = Q(i,k) + QH(i,k)
  2877. T(i,k) = T(i,k) - LSP*QH(i,k)
  2878. QH(i,k)= 0.
  2879. endif
  2880. ENDIF
  2881. Q(i,k)= max(Q(i,k),0.)
  2882. NY(i,k)= min(NY(i,k), Ni_max)
  2883. ENDIF !if (activePoint)
  2884. ENDDO
  2885. ENDDO
  2886. !----------------------------------------------------------------------------------!
  2887. ! End of ice phase microphysics (Part 2) !
  2888. !----------------------------------------------------------------------------------!
  2889. !----------------------------------------------------------------------------------!
  2890. ! PART 3: Warm Microphysics Processes !
  2891. ! !
  2892. ! Equations for warm-rain coalescence based on Cohard and Pinty (2000a,b; QJRMS) !
  2893. ! Condensation/evaportaion equations based on Kong and Yau (1997; Atmos-Ocean) !
  2894. ! Equations for rain reflectivity (ZR) based on Milbrandt and Yau (2005b; JAS) !
  2895. !----------------------------------------------------------------------------------!
  2896. ! Part 3a - Warm-rain Coallescence:
  2897. IF (warmphase_ON) THEN
  2898. DO k= 2,nk
  2899. DO i= 1,ni
  2900. RCAUTR= 0.; CCACCR= 0.; Dc= 0.; iLAMc= 0.; L = 0.
  2901. RCACCR= 0.; CCSCOC= 0.; Dr= 0.; iLAMr= 0.; TAU= 0.
  2902. CCAUTR= 0.; CRSCOR= 0.; SIGc= 0.; DrINIT= 0.
  2903. iLAMc3= 0.; iLAMc6= 0.; iLAMr3= 0.; iLAMr6= 0.
  2904. if (dblMom_r) then
  2905. rainPresent= (QRM(i,k)>epsQ .and. NRM(i,k)>epsN)
  2906. else
  2907. rainPresent= (QRM(i,k)>epsQ)
  2908. endif
  2909. if (.not. dblMom_c) NCM(i,k)= N_c_SM
  2910. if (QCM(i,k)>epsQ .and. NCM(i,k)>epsN) then
  2911. iLAMc = iLAMDA_x(DE(i,k),QCM(i,k),1./NCM(i,k),icexc9,thrd)
  2912. iLAMc3= iLAMc*iLAMc*iLAMc
  2913. iLAMc6= iLAMc3*iLAMc3
  2914. Dc = iLAMc*(GC2*iGC1)**thrd
  2915. SIGc = iLAMc*( GC3*iGC1- (GC2*iGC1)*(GC2*iGC1) )**sixth
  2916. L = 0.027*DE(i,k)*QCM(i,k)*(6.25e18*SIGc*SIGc*SIGc*Dc-0.4)
  2917. if (SIGc>SIGcTHRS) TAU= 3.7/(DE(i,k)*(QCM(i,k))*(0.5e6*SIGc-7.5))
  2918. endif
  2919. if (rainPresent) then
  2920. if (dblMom_r) then
  2921. Dr = Dm_x(DE(i,k),QRM(i,k),1./NRM(i,k),icmr,thrd)
  2922. !Drop-size limiter [prevents initially large drops from melted hail]
  2923. if (Dr>3.e-3) then
  2924. tmp1 = (Dr-3.e-3); tmp2= (Dr/DrMAX); tmp3= tmp2*tmp2*tmp2
  2925. NRM(i,k)= NRM(i,k)*max((1.+2.e4*tmp1*tmp1),tmp3)
  2926. tmp1 = DE(i,k)*QRM(i,k)*icmr
  2927. Dr = (tmp1/NRM(i,k))**thrd
  2928. endif
  2929. else
  2930. NRM(i,k)= GR50*sqrt(sqrt(GR31*iGR34*DE(i,k)*QRM(i,k)*icmr))
  2931. Dr = Dm_x(DE(i,k),QRM(i,k),1./NRM(i,k),icmr,thrd)
  2932. endif
  2933. iLAMr = iLAMDA_x(DE(i,k),QRM(i,k),1./NRM(i,k),icexr9,thrd)
  2934. iLAMr3= iLAMr*iLAMr*iLAMr
  2935. iLAMr6= iLAMr3*iLAMr3
  2936. endif
  2937. ! Autoconversion:
  2938. if (QCM(i,k)>epsQ .and. SIGc>SIGcTHRS .and. autoconv_ON) then
  2939. RCAUTR= min( max(L/TAU,0.), QCM(i,k)*idt )
  2940. DrINIT= max(83.e-6, 12.6e-4/(0.5e6*SIGc-3.5)) !initiation regime Dr
  2941. DrAUT = max(DrINIT, Dr) !init. or feeding DrAUT
  2942. CCAUTR= RCAUTR*DE(i,k)/(cmr*DrAUT*DrAUT*DrAUT)
  2943. ! ---------------------------------------------------------------------------- !
  2944. ! NOTE: The formulation for CCAUTR here (dNr/dt|initiation) does NOT follow
  2945. ! eqn (18) in CP2000a, but rather it comes from the F90 code provided
  2946. ! by J-P Pinty (subroutine: 'rain_c2r2.f90').
  2947. ! (See notes: 2001-10-17; 2001-10-22)
  2948. !
  2949. ! Similarly, the condition for the activation of accretion and self-
  2950. ! collection depends on whether or not autoconversion is in the feeding
  2951. ! regime (see notes 2002-01-07). This is apparent in the F90 code, but
  2952. ! NOT in CP2000a.
  2953. ! ---------------------------------------------------------------------------- !
  2954. ! cloud self-collection: (dNc/dt_autoconversion) {CP eqn(25)}
  2955. if (dblMom_c) CCSCOC= min(KK2*NCM(i,k)*NCM(i,k)*GC3*iGC1*iLAMc6, NCM(i,k)* &
  2956. idt) !{CP00a eqn(25)}
  2957. endif
  2958. ! Accretion, rain self-collection, and collisional breakup:
  2959. if (((QRM(i,k))>1.2*max(L,0.)*iDE(i,k).or.Dr>max(5.e-6,DrINIT)).and.rainAccr_ON &
  2960. .and. rainPresent) then
  2961. ! Accretion: !{CP00a eqn(22)}
  2962. if (QCM(i,k)>epsQ.and.L>0.) then
  2963. if (Dr.ge.100.e-6) then
  2964. CCACCR = KK1*(NCM(i,k)*NRM(i,k))*(GC2*iGC1*iLAMc3+GR34*iGR31*iLAMr3)
  2965. RCACCR = cmr*iDE(i,k)*KK1*(NCM(i,k)*NRM(i,k))*iLAMc3*(GC3*iGC1*iLAMc3+ &
  2966. GC2*iGC1*GR34*iGR31*iLAMr3)
  2967. else
  2968. CCACCR = KK2*(NCM(i,k)*NRM(i,k))*(GC3*iGC1*iLAMc6+GR37*iGR31*iLAMr6)
  2969. ! RCACCR= cmr*iDE(i,k)*KK2*(NCM(i,k)*NRM(i,k))*iLAMc3* &
  2970. ! (GC4*iGR31*iLAMc6+GC2*iGC1*GR37*iGR31*iLAMr6)
  2971. !++ The following calculation of RCACCR avoids overflow:
  2972. tmp1 = cmr*iDE(i,k)
  2973. tmp2 = KK2*(NCM(i,k)*NRM(i,k))*iLAMc3
  2974. RCACCR = tmp1 * tmp2
  2975. tmp1 = GC4*iGR31
  2976. tmp1 = (tmp1)*iLAMc6
  2977. tmp2 = GC2*iGC1
  2978. tmp2 = tmp2*GR37*iGR31
  2979. tmp2 = (tmp2)*iLAMr6
  2980. RCACCR = RCACCR * (tmp1 + tmp2)
  2981. !++
  2982. endif
  2983. CCACCR = min(CCACCR,(NC(i,k))*idt)
  2984. RCACCR = min(RCACCR,(QC(i,k))*idt)
  2985. endif
  2986. if (dblMom_r) then
  2987. !Rain self-collection:
  2988. tmp1= NRM(i,k)*NRM(i,k)
  2989. if (Dr.ge.100.e-6) then
  2990. CRSCOR= KK1*tmp1*GR34*iGR31*iLAMr3 !{CP00a eqn(24)}
  2991. else
  2992. CRSCOR= KK2*tmp1*GR37*iGR31*iLAMr6 !{CP00a eqn(25)}
  2993. endif
  2994. !Raindrop breakup: !{CP00a eqn(26)}
  2995. Ec= 1.
  2996. if (Dr >= 600.e-6) Ec= exp(-2.5e3*(Dr-6.e-4))
  2997. if (Dr >= 2000.e-6) Ec= 0.
  2998. CRSCOR= min(Ec*CRSCOR,(0.5*NR(i,k))*idt) !0.5 prevents depletion of NR
  2999. endif
  3000. endif !accretion/self-collection/breakup
  3001. ! Prevent overdepletion of cloud:
  3002. source= QC(i,k)
  3003. sink = (RCAUTR+RCACCR)*dt
  3004. if (sink>source) then
  3005. ratio = source/sink
  3006. RCAUTR= ratio*RCAUTR
  3007. RCACCR= ratio*RCACCR
  3008. CCACCR= ratio*CCACCR
  3009. endif
  3010. ! Apply tendencies:
  3011. QC(i,k)= max(0., QC(i,k)+(-RCAUTR-RCACCR)*dt )
  3012. QR(i,k)= max(0., QR(i,k)+( RCAUTR+RCACCR)*dt )
  3013. if (dblMom_c) NC(i,k)= max(0., NC(i,k)+(-CCACCR-CCSCOC)*dt )
  3014. if (dblMom_r) NR(i,k)= max(0., NR(i,k)+( CCAUTR-CRSCOR)*dt )
  3015. if (dblMom_r) then
  3016. if (QR(i,k)>epsQ .and. NR(i,k)>epsN) then
  3017. Dr = Dm_x(DE(i,k),QR(i,k),1./NR(i,k),icmr,thrd)
  3018. if (Dr>3.e-3) then
  3019. tmp1= (Dr-3.e-3); tmp2= tmp1*tmp1
  3020. tmp3= (Dr/DrMAX); tmp4= tmp3*tmp3*tmp3
  3021. NR(i,k)= NR(i,k)*(max((1.+2.e4*tmp2),tmp4))
  3022. elseif (Dr<Dhh) then
  3023. !Convert small raindrops to cloud:
  3024. QC(i,k)= QC(i,k) + QR(i,k)
  3025. NC(i,k)= NC(i,k) + NR(i,k)
  3026. QR(i,k)= 0.; NR(i,k)= 0.
  3027. endif
  3028. else
  3029. QR(i,k)= 0.; NR(i,k)= 0.
  3030. endif !(Qr,Nr>eps)
  3031. endif
  3032. ENDDO
  3033. ENDDO
  3034. ! Part 3b - Condensation/Evaporation:
  3035. DO k=1,nk
  3036. DO i=1,ni
  3037. DEo = DE(i,nk)
  3038. gam = sqrt(DEo*iDE(i,k))
  3039. #if (DWORDSIZE == 8 && RWORDSIZE == 8)
  3040. QSS(i,k)= FOQSA(T(i,k), PS(i)*S(i,k)) ! Re-calculates QS with new T (w.r.t. liquid)
  3041. #elif (DWORDSIZE == 8 && RWORDSIZE == 4)
  3042. QSS(i,k)= sngl(FOQSA(T(i,k), PS(i)*S(i,k))) ! Re-calculates QS with new T (w.r.t. liquid)
  3043. #else
  3044. This is a temporary hack assuming double precision is 8 bytes.
  3045. #endif
  3046. ssat = Q(i,k)/QSS(i,k)-1.
  3047. Tc = T(i,k)-TRPL
  3048. Cdiff = max(1.62e-5, (2.2157e-5 + 0.0155e-5*Tc)) *1.e5/(S(i,k)*PS(i))
  3049. MUdyn = max(1.51e-5, (1.7153e-5 + 0.0050e-5*Tc))
  3050. MUkin = MUdyn*iDE(i,k)
  3051. iMUkin = 1./MUkin
  3052. Ka = max(2.07e-2, (2.3971e-2 + 0.0078e-2*Tc))
  3053. ScTHRD = (MUkin/Cdiff)**thrd ! i.e. Sc^(1/3)
  3054. !Condensation/evaporation:
  3055. ! Capacity of evap/cond in one time step is determined by saturation
  3056. ! adjustment technique [Kong and Yau, 1997 App.A]. Equation for rain evaporation rate
  3057. ! comes from Cohard and Pinty, 2000a. Explicit condensation rate is not considered
  3058. ! (as it is in Ziegler, 1985), but rather complete removal of supersaturation is assumed.
  3059. X= Q(i,k)-QSS(i,k)
  3060. if (dblMom_r) then
  3061. rainPresent= (QR(i,k)>epsQ .and. NR(i,k)>epsN)
  3062. else
  3063. rainPresent= (QR(i,k)>epsQ)
  3064. endif
  3065. IF(X>0. .or. QC(i,k)>epsQ .or. rainPresent) THEN
  3066. tmp1 = T(i,k)-35.86
  3067. X = X/(1.+ck5*QSS(i,k)/(tmp1*tmp1))
  3068. if (X<(-QC(i,k))) then
  3069. D= 0.
  3070. if(rainPresent) then
  3071. if(QM(i,k)<QSW(i,k)) then
  3072. MUkin = (1.715e-5+5.e-8*Tc)*iDE(i,k)
  3073. iMUkin= 1./MUkin
  3074. if (dblMom_r) then
  3075. Dr = Dm_x(DE(i,k),QR(i,k),1./NR(i,k),icmr,thrd)
  3076. iLAMr= iLAMDA_x(DE(i,k),QR(i,k),1./NR(i,k),icexr9,thrd)
  3077. LAMr = 1./iLAMr
  3078. !note: The following coding of 'No_r=...' prevents overflow:
  3079. !No_r_DM= NR(i,k)*LAMr**(1.+alpha_r))*iGR31
  3080. No_r_DM= sngl(dble(NR(i,k))*dble(LAMr)**dble(1.+alpha_r))*iGR31
  3081. No_r = No_r_DM
  3082. else
  3083. iLAMr = sqrt(sqrt( (QR(i,k)*DE(i,k))/(GR34*cmr*No_r) ))
  3084. !note: No_r= No_r_SM is already done (in Part 1)
  3085. endif
  3086. !note: There is an error in MY05a_eq(8) for VENTx (corrected in code)
  3087. VENTr= Avx*GR32*iLAMr**cexr5 + Bvx*ScTHRD*sqrt(gam*afr*iMUkin)*GR17* &
  3088. iLAMr**cexr6
  3089. ABw = CHLC*CHLC/(Ka*RGASV*T(i,k)*T(i,k))+1./(DE(i,k)*(QSS(i,k))* &
  3090. Cdiff)
  3091. QREVP= -dt*(PI2*ssat*No_r*VENTr/ABw)
  3092. !! QREVP= 0. !to suppress evaporation of rain
  3093. if ((QR(i,k))>QREVP) then !Note: QREVP is [(dQ/dt)*dt]
  3094. DEL= -QREVP
  3095. else
  3096. DEL= -QR(i,k)
  3097. endif
  3098. D= max(X+QC(i,k), DEL)
  3099. endif !QM< QSM
  3100. endif !QR<eps & NR<eps
  3101. X= D - QC(i,k)
  3102. QR(i,k)= QR(i,k) + D
  3103. if (QR(i,k)>0. .and. dblMom_r) &
  3104. NR(i,k)= max(0.,NR(i,k)+D*NR(i,k)/QR(i,k)) !(dNr/dt)|evap
  3105. ! The above expression of (dNr/dt)|evap is from Ferrier, 1994.
  3106. ! In CP2000a, Nr is not affected by evap. (except if Qr goes to zero).
  3107. QC(i,k)= 0.; NC(i,k)= 0.
  3108. T(i,k) = T(i,k) + LCP*X
  3109. Q(i,k) = Q(i,k) - X
  3110. else ![if(X >= -QC)]
  3111. ! Nucleation of cloud droplets:
  3112. if (ssat>0. .and. WZ(i,k)>0. .and. dblMom_c) &
  3113. NC(i,k)= max(NC(i,k),NccnFNC(WZ(i,k),TM(i,k),HPS(i)*S(i,k),CCNtype))
  3114. ! All supersaturation is removed (condensed onto cloud field).
  3115. T(i,k) = T(i,k) + LCP*X
  3116. Q(i,k) = Q(i,k) - X
  3117. QC(i,k) = QC(i,k) + X
  3118. if (dblMom_c) then
  3119. if (X<0.) then
  3120. if (QC(i,k)>0.) then
  3121. NC(i,k)= max(0., NC(i,k) + X*NC(i,k)/QC(i,k) ) !(dNc/dt)|evap
  3122. else
  3123. NC(i,k)= 0.
  3124. endif
  3125. endif
  3126. if (QC(i,k)>0..and.NC(i,k)==0.) NC(i,k)= 1.e7 !prevents non-zero_Q & zero_N
  3127. endif
  3128. endif
  3129. ENDIF
  3130. !Protect against negative values due to overdepletion:
  3131. if (dblMom_r) then
  3132. if (QR(i,k)<epsQ.or.NR(i,k)<epsN) then
  3133. Q(i,k) = Q(i,k) + QR(i,k)
  3134. T(i,k) = T(i,k) - QR(i,k)*LCP
  3135. QR(i,k)= 0.; NR(i,k)= 0.
  3136. endif
  3137. else
  3138. if (QR(i,k)<epsQ) then
  3139. Q(i,k) = Q(i,k) + QR(i,k)
  3140. T(i,k) = T(i,k) - QR(i,k)*LCP
  3141. QR(i,k)= 0.
  3142. endif
  3143. endif
  3144. ENDDO
  3145. ENDDO !cond/evap [k-loop]
  3146. ENDIF !if warmphase_ON
  3147. !----------------------------------------------------------------------------------!
  3148. ! End of warm-phase microphysics (Part 3) !
  3149. !----------------------------------------------------------------------------------!
  3150. !----------------------------------------------------------------------------------!
  3151. ! PART 4: Sedimentation !
  3152. !----------------------------------------------------------------------------------!
  3153. !----------------------------------------------------------------------------------!
  3154. ! Sedimentation is computed using a modified version of the box-Lagrangian !
  3155. ! scheme. Sedimentation is only computed for columns containing non-zero !
  3156. ! hydrometeor quantities (at at least one level). !
  3157. !----------------------------------------------------------------------------------!
  3158. IF (sedi_ON) THEN
  3159. fluxM_r= 0.; fluxM_i= 0.; fluxM_s= 0.; fluxM_g= 0.; fluxM_h= 0.
  3160. RT_rn1 = 0.; RT_rn2 = 0.; RT_fr1 = 0.; RT_fr2 = 0.; RT_sn1 = 0.
  3161. RT_sn2 = 0.; RT_sn3 = 0.; RT_pe1 = 0.; RT_pe2 = 0.; RT_peL = 0.
  3162. !-- RAIN sedimentation:
  3163. if (DblMom_r) then
  3164. call SEDI_main_2(QR,NR,1,Q,T,DE,iDE,gamfact_r,epsQr_sedi,epsN,afr,bfr,cmr,dmr, &
  3165. ckQr1,ckQr2,icexr9,LCP,ni,nk,VrMax,DrMax,dt,DZ,fluxM_r,ktop_sedi, &
  3166. GRAV,massFlux3D=massFlux3D_r)
  3167. else !if DblMom_r
  3168. call SEDI_main_1b(QR,1,T,DE,iDE,gamfact_r,epsQr_sedi,afr,bfr,icmr,dmr,ckQr1, &
  3169. icexr9,ni,nk,VrMax,DrMax,dt,DZ,fluxM_r,No_r_SM,ktop_sedi,GRAV, &
  3170. massFlux3D=massFlux3D_r)
  3171. endif !if DblMom_r
  3172. !-- ICE sedimentation:
  3173. if (DblMom_i) then
  3174. call SEDI_main_2(QI,NY,2,Q,T,DE,iDE,gamfact,epsQi_sedi,epsN,afi,bfi,cmi,dmi,ckQi1, &
  3175. ckQi2,ckQi4,LSP,ni,nk,ViMax,DiMax,dt,DZ,fluxM_i,ktop_sedi,GRAV)
  3176. else
  3177. call SEDI_main_1b(QI,2,T,DE,iDE,gamfact,epsQi_sedi,afi,bfi,icmi,dmi,ckQi1,ckQi4, &
  3178. ni,nk,ViMax,DiMax,dt,DZ,fluxM_i,-99.,ktop_sedi,GRAV)
  3179. endif
  3180. !-- SNOW sedimentation:
  3181. if (DblMom_s) then
  3182. call SEDI_main_2(QN,NN,3,Q,T,DE,iDE,gamfact,epsQs_sedi,epsN,afs,bfs,cms,dms,ckQs1, &
  3183. ckQs2,iGS20,LSP,ni,nk,VsMax,DsMax,dt,DZ,fluxM_s,ktop_sedi,GRAV, &
  3184. massFlux3D=massFlux3D_s)
  3185. else
  3186. call SEDI_main_1b(QN,3,T,DE,iDE,gamfact,epsQs_sedi,afs,bfs,icms,dms,ckQs1,iGS20, &
  3187. ni,nk,VsMax,DsMax,dt,DZ,fluxM_s,-99.,ktop_sedi,GRAV,massFlux3D= &
  3188. massFlux3D_s)
  3189. endif
  3190. !-- GRAUPEL sedimentation:
  3191. if (DblMom_g) then
  3192. call SEDI_main_2(QG,NG,4,Q,T,DE,iDE,gamfact,epsQg_sedi,epsN,afg,bfg,cmg,dmg,ckQg1, &
  3193. ckQg2,ckQg4,LSP,ni,nk,VgMax,DgMax,dt,DZ,fluxM_g,ktop_sedi,GRAV)
  3194. else
  3195. call SEDI_main_1b(QG,4,T,DE,iDE,gamfact,epsQg_sedi,afg,bfg,icmg,dmg,ckQg1,ckQg4, &
  3196. ni,nk,VgMax,DgMax,dt,DZ,fluxM_g,No_g_SM,ktop_sedi,GRAV)
  3197. endif
  3198. !-- HAIL sedimentation:
  3199. if (DblMom_h) then
  3200. call SEDI_main_2(QH,NH,5,Q,T,DE,iDE,gamfact,epsQh_sedi,epsN,afh,bfh,cmh,dmh,ckQh1, &
  3201. ckQh2,ckQh4,LSP,ni,nk,VhMax,DhMax,dt,DZ,fluxM_h,ktop_sedi,GRAV)
  3202. else
  3203. call SEDI_main_1b(QH,5,T,DE,iDE,gamfact,epsQh_sedi,afh,bfh,icmh,dmh,ckQh1,ckQh4, &
  3204. ni,nk,VhMax,DhMax,dt,DZ,fluxM_h,No_h_SM,ktop_sedi,GRAV)
  3205. endif
  3206. !======= End of sedimentation for each category ========!
  3207. !--- Impose constraints on size distribution parameters ---!
  3208. do k= 1,nk
  3209. do i= 1,ni
  3210. !snow:
  3211. if (QN(i,k)>epsQ .and. NN(i,k)>epsN) then
  3212. !Impose No_s max for snow: (assumes alpha_s=0.)
  3213. iLAMs = max( iLAMmin2, iLAMDA_x(DE(i,k),QN(i,k), 1./NN(i,k),iGS20,idms) )
  3214. tmp1 = min(NN(i,k)/iLAMs,No_s_max) !min. No_s
  3215. NN(i,k)= tmp1**(dms/(1.+dms))*(iGS20*DE(i,k)*QN(i,k))**(1./(1.+dms)) !impose Nos_max
  3216. !Impose LAMDAs_min (by increasing LAMDAs if it is below LAMDAs_min2 [2xLAMDAs_min])
  3217. iLAMs = max( iLAMmin2, iLAMDA_x(DE(i,k),QN(i,k),1./NN(i,k),iGS20,idms) )
  3218. tmp2 = 1./iLAMs !LAMs before adjustment
  3219. !adjust value of lamdas_min to be applied:
  3220. ! This adjusts for multiple corrections (each time step). The factor 0.6 was obtained by
  3221. ! trial-and-error to ultimately give reasonable LAMs profiles, smooth and with min LAMs~lamdas_min
  3222. tmp4 = 0.6*lamdas_min
  3223. tmp5 = 2.*tmp4
  3224. tmp3 = tmp2 + tmp4*(max(0.,tmp5-tmp2)/tmp5)**2. !LAMs after adjustment
  3225. tmp3 = max(tmp3, lamdas_min) !final correction
  3226. NN(i,k)= NN(i,k)*(tmp3*iLAMs)**dms !re-compute NN after LAMs adjustment
  3227. endif
  3228. enddo !i-loop
  3229. enddo !k-loop
  3230. !===
  3231. !Compute melted (liquid-equivalent) volume fluxes [m3 (liquid) m-2 (sfc area) s-1]:
  3232. ! (note: For other precipitation schemes in RPN-CMC physics, this is computed in 'vkuocon6.ftn')
  3233. RT_rn1 = fluxM_r *idew
  3234. RT_sn1 = fluxM_i *idew
  3235. RT_sn2 = fluxM_s *idew
  3236. RT_sn3 = fluxM_g *idew
  3237. RT_pe1 = fluxM_h *idew
  3238. !----
  3239. !Compute sum of solid (unmelted) volume fluxes [m3 (bulk hydrometeor) m-2 (sfc area) s-1]:
  3240. !(this is the precipitation rate for UNmelted total snow [i+s+g])
  3241. ! Note: In 'calcdiagn.ftn', the total solid precipitation (excluding hail) SN is computed
  3242. ! from the sum of the liq-eq.vol fluxes, tss_sn1 + tss_sn2 + tss_sn3. With the
  3243. ! accumulation of SND (in 'calcdiag.ftn'), the solid-to-liquid ratio for the total
  3244. ! accumulated "snow" (i+s+g) can be compute as SND/SN. Likewise, the instantaneous
  3245. ! solid-to-liquid ratio of solid precipitation is computed (in 'calcdiag.ftn') as
  3246. ! RS2L = RSND/RSN.
  3247. do i= 1,ni
  3248. fluxV_i= fluxM_i(i)*idei
  3249. fluxV_g= fluxM_g(i)*ideg
  3250. !Compute unmelted volume flux for snow:
  3251. ! note: This is based on the strict calculation of the volume flux, where vol=(pi/6)D^3,
  3252. ! and remains in the integral calculation Fv = int[V(D)*vol(D)*N(D)*dD].
  3253. ! For a constant density (ice and graupel), vol(D) = m(D)/dex, dex comes out of
  3254. ! integral and Fv_x=Fm_x/dex
  3255. ! Optimized for alpha_s = 0.
  3256. if (QN(i,nk)>epsQ .and. NN(i,nk)>epsN .and. fluxM_s(i)>0.) then
  3257. tmp1= 1./iLAMDA_x(DE(i,nk),QN(i,nk),1./NN(i,nk),iGS20,idms) !LAMDA_s
  3258. fluxV_s= fluxM_s(i)*rfact_FvFm*tmp1**(dms-3.)
  3259. else
  3260. fluxV_s=0.
  3261. endif
  3262. !total solid unmelted volume flux, before accounting for partial melting:
  3263. tmp1= fluxV_i + fluxV_g + fluxV_s
  3264. !liquid-fraction of partially-melted solid precipitation:
  3265. ! The physical premise is that if QR>0, QN+QI+QG>0, and T>0, then QR
  3266. ! originates from melting and can be used to estimate the liquid portion
  3267. ! of the partially-melted solid hydrometeor.
  3268. tmp2= QR(i,nk) + QI(i,nk) + QN(i,nk) + QG(i,nk)
  3269. if (T(i,nk)>TRPL .and. tmp2>epsQ) then
  3270. fracLiq= QR(i,nk)/tmp2
  3271. else
  3272. fracLiq= 0.
  3273. endif
  3274. !Tend total volume flux towards the liquid-equivalent as the liquid-fraction increases to 1:
  3275. tmp3= RT_sn1(i) + RT_sn2(i) + RT_sn3(i) !total liquid-equivalent volume flux (RSN, Fv_sol)
  3276. RT_snd(i)= (1.-fracLiq)*tmp1 + fracLiq*tmp3 !total volume flux with partial melting (RSND, Fvsle_sol)
  3277. !Note: Calculation of instantaneous solid-to-liquid ratio [RS2L = RSND/RSN]
  3278. ! is based on the above quantities and is done on 'calcdiag.ftn'.
  3279. enddo !i-loop
  3280. !====
  3281. !++++
  3282. ! Diagnose surface precipitation types:
  3283. !
  3284. ! The following involves diagnostic conditions to determine surface precipitation rates
  3285. ! for various precipitation elements defined in Canadian Meteorological Operational Internship
  3286. ! Program module 3.1 (plus one for large hail) based on the sedimentation rates of the five
  3287. ! sedimenting hydrometeor categories.
  3288. !
  3289. ! With the diagnostics shut off (precipDiag_ON=.false.), 5 rates are just the 5 category
  3290. ! rates, with the other 6 rates just 0. The model output variables will have:
  3291. !
  3292. ! total liquid = RT_rn1 [RAIN]
  3293. ! total solid = RT_sn1 [ICE] + RT_sn2 [SNOW] + RT_sn3 [GRAUPEL] + RT_pe1 [HAIL]
  3294. !
  3295. ! With the diagnostics on, the 5 sedimentation rates are partitioned into 9 rates,
  3296. ! with the following model output variable:
  3297. !
  3298. ! total liquid = RT_rn1 [liquid rain] + RT_rn2 [liquid drizzle]
  3299. ! total solid = RT_fr1 [freezing rain] + RT_fr2 [freezing drizzle] + RT_sn1 [ice crystals] +
  3300. ! RT_sn2 [snow] + RT_sn3 [graupel] + RT_pe1 [ice pellets] + RT_pe2 [hail]
  3301. !
  3302. ! NOTE: - The above total liquid/solid rates are computed in 'calcdiag.ftn' (as R2/R4).
  3303. ! - RT_peL [large hail] is a sub-set of RT_pe2 [hail] and is thus not added to the total
  3304. ! solid precipitation.
  3305. ! call tmg_start0(98,'mmCalcDIAG')
  3306. IF (precipDiag_ON) THEN
  3307. DO i= 1,ni
  3308. DE(i,nk)= S(i,nk)*PS(i)/(RGASD*T(i,nk))
  3309. !rain vs. drizzle:
  3310. if (DblMom_r) then
  3311. N_r= NR(i,nk)
  3312. else
  3313. N_r= (No_r*GR31)**(3./(4.+alpha_r))*(GR31*iGR34*DE(i,nk)*QR(i,nk)*icmr)** &
  3314. ((1.+alpha_r)/(4.+alpha_r)) !i.e. NR = f(No_r,QR)
  3315. endif
  3316. if (QR(i,nk)>epsQ .and. N_r>epsN) then
  3317. Dm_r(i,nk)= (DE(i,nk)*icmr*QR(i,nk)/N_r)**thrd
  3318. if (Dm_r(i,nk)>Dr_large) then !Dr_large is rain/drizzle size threshold
  3319. RT_rn2(i)= RT_rn1(i); RT_rn1(i)= 0.
  3320. endif
  3321. endif
  3322. !liquid vs. freezing rain or drizzle:
  3323. if (T(i,nk)<TRPL) then
  3324. RT_fr1(i)= RT_rn1(i); RT_rn1(i)= 0.
  3325. RT_fr2(i)= RT_rn2(i); RT_rn2(i)= 0.
  3326. endif
  3327. !ice pellets vs. hail:
  3328. if (T(i,nk)>(TRPL+5.0)) then
  3329. !note: The condition (T_sfc<5C) for ice pellets is a simply proxy for the presence
  3330. ! of a warm layer aloft, though which falling snow or graupel will melt to rain,
  3331. ! over a sub-freezinglayer, where the rain will freeze into the 'hail' category
  3332. RT_pe2(i)= RT_pe1(i); RT_pe1(i)= 0.
  3333. endif
  3334. !large hail:
  3335. if (QH(i,nk)>epsQ) then
  3336. if (DblMom_h) then
  3337. N_h= NH(i,nk)
  3338. else
  3339. N_h= (No_h_SM*GH31)**(3./(4.+alpha_h))*(GH31*iGH34*DE(i,nk)*QH(i,nk)* &
  3340. icmh)**((1.+alpha_h)/(4.+alpha_h)) !i.e. Nh = f(No_h,Qh)
  3341. endif
  3342. Dm_h(i,nk)= Dm_x(DE(i,nk),QH(i,nk),1./N_h,icmh,thrd)
  3343. if (DM_h(i,nk)>Dh_large) RT_peL(i)= RT_pe2(i)
  3344. !note: large hail (RT_peL) is a subset of the total hail (RT_pe2)
  3345. endif
  3346. ENDDO
  3347. ENDIF !if (precipDiag_ON)
  3348. !
  3349. !++++
  3350. ELSE
  3351. massFlux3D_r= 0.
  3352. massFlux3D_s= 0.
  3353. ENDIF ! if (sedi_ON)
  3354. where (Q<0.) Q= 0.
  3355. !-----------------------------------------------------------------------------------!
  3356. ! End of sedimentation calculations (Part 4) !
  3357. !-----------------------------------------------------------------------------------!
  3358. !===================================================================================!
  3359. ! End of microphysics scheme !
  3360. !===================================================================================!
  3361. !-----------------------------------------------------------------------------------!
  3362. ! Calculation of diagnostic output variables: !
  3363. IF (calcDiag) THEN
  3364. !For reflectivity calculations:
  3365. ZEC= minZET
  3366. cxr= icmr*icmr !for rain
  3367. cxi= 1./fdielec*icmr*icmr !for all frozen categories
  3368. Gzr= (6.+alpha_r)*(5.+alpha_r)*(4.+alpha_r)/((3.+alpha_r)*(2.+alpha_r)*(1.+alpha_r))
  3369. Gzi= (6.+alpha_i)*(5.+alpha_i)*(4.+alpha_i)/((3.+alpha_i)*(2.+alpha_i)*(1.+alpha_i))
  3370. if (snowSpherical) then !dms=3
  3371. Gzs= (6.+alpha_s)*(5.+alpha_s)*(4.+alpha_s)/((3.+alpha_s)*(2.+alpha_s)* &
  3372. (1.+alpha_s))
  3373. else !dms=2
  3374. Gzs= (4.+alpha_s)*(3.+alpha_s)/((2.+alpha_s)*(1.+alpha_s))
  3375. endif
  3376. Gzg= (6.+alpha_g)*(5.+alpha_g)*(4.+alpha_g)/((3.+alpha_g)*(2.+alpha_g)*(1.+alpha_g))
  3377. Gzh= (6.+alpha_h)*(5.+alpha_h)*(4.+alpha_h)/((3.+alpha_h)*(2.+alpha_h)*(1.+alpha_h))
  3378. do k= 1,nk
  3379. do i= 1,ni
  3380. DE(i,k)= S(i,k)*PS(i)/(RGASD*T(i,k))
  3381. tmp9= DE(i,k)*DE(i,k)
  3382. !Compute N_x for single-moment categories:
  3383. if (DblMom_c) then
  3384. N_c= NC(i,k)
  3385. else
  3386. N_c= N_c_SM
  3387. endif
  3388. if (DblMom_r) then
  3389. N_r= NR(i,k)
  3390. else
  3391. N_r= (No_r_SM*GR31)**(3./(4.+alpha_r))*(GR31*iGR34*DE(i,k)*QR(i,k)*icmr)** &
  3392. ((1.+alpha_r)/(4.+alpha_r)) !i.e. NR = f(No_r,QR)
  3393. endif
  3394. if (DblMom_i) then
  3395. N_i= NY(i,k)
  3396. else
  3397. N_i= N_Cooper(TRPL,T(i,k))
  3398. endif
  3399. if (DblMom_s) then
  3400. N_s= NN(i,k)
  3401. else
  3402. No_s= Nos_Thompson(TRPL,T(i,k))
  3403. N_s = (No_s*GS31)**(dms/(1.+dms+alpha_s))*(GS31*iGS34*DE(i,k)*QN(i,k)* &
  3404. icms)**((1.+alpha_s)/(1.+dms+alpha_s))
  3405. endif
  3406. if (DblMom_g) then
  3407. N_g= NG(i,k)
  3408. else
  3409. N_g= (No_g_SM*GG31)**(3./(4.+alpha_g))*(GG31*GG34*DE(i,k)*QG(i,k)*icmg)** &
  3410. ((1.+alpha_g)/(4.+alpha_g)) !i.e. NX = f(No_x,QX)
  3411. endif
  3412. if (DblMom_h) then
  3413. N_h= NH(i,k)
  3414. else
  3415. N_h= (No_h_SM*GH31)**(3./(4.+alpha_h))*(GH31*iGH34*DE(i,k)*QH(i,k)*icmh)** &
  3416. ((1.+alpha_h)/(4.+alpha_h)) !i.e. NX = f(No_x,QX)
  3417. endif
  3418. !Total equivalent reflectivity: (units of [dBZ])
  3419. tmp1= 0.; tmp2= 0.; tmp3= 0.; tmp4= 0.; tmp5= 0.
  3420. if (QR(i,k)>epsQ .and. N_r>epsN) tmp1 = cxr*Gzr*tmp9*QR(i,k)*QR(i,k)/N_r
  3421. if (QI(i,k)>epsQ .and. N_i>epsN) tmp2 = cxi*Gzi*tmp9*QI(i,k)*QI(i,k)/N_i
  3422. if (QN(i,k)>epsQ .and. N_s>epsN) tmp3 = cxi*Gzs*tmp9*QN(i,k)*QN(i,k)/N_s
  3423. if (QG(i,k)>epsQ .and. N_g>epsN) tmp4 = cxi*Gzg*tmp9*QG(i,k)*QG(i,k)/N_g
  3424. if (QH(i,k)>epsQ .and. N_h>epsN) tmp5 = cxi*Gzh*tmp9*QH(i,k)*QH(i,k)/N_h
  3425. !Modifiy dielectric constant for melting ice-phase categories:
  3426. if ( T(i,k)>TRPL) then
  3427. tmp2= tmp2*fdielec
  3428. tmp3= tmp3*fdielec
  3429. tmp4= tmp4*fdielec
  3430. tmp5= tmp5*fdielec
  3431. endif
  3432. ZET(i,k) = tmp1 + tmp2 + tmp3 + tmp4 + tmp5 != Zr+Zi+Zs+Zg+Zh
  3433. if (ZET(i,k)>0.) then
  3434. ZET(i,k)= 10.*log10((ZET(i,k)*Zfact)) !convert to dBZ
  3435. else
  3436. ZET(i,k)= minZET
  3437. endif
  3438. ZET(i,k)= max(ZET(i,k),minZET)
  3439. ZEC(i)= max(ZEC(i),ZET(i,k)) !composite (max in column) of ZET
  3440. !Mean-mass diameters: (units of [m])
  3441. Dm_c(i,k)= 0.; Dm_r(i,k)= 0.; Dm_i(i,k)= 0.
  3442. Dm_s(i,k)= 0.; Dm_g(i,k)= 0.; Dm_h(i,k)= 0.
  3443. if(QC(i,k)>epsQ.and.N_c>epsN) Dm_c(i,k)=Dm_x(DE(i,k),QC(i,k),1./N_c,icmr,thrd)
  3444. if(QR(i,k)>epsQ.and.N_r>epsN) Dm_r(i,k)=Dm_x(DE(i,k),QR(i,k),1./N_r,icmr,thrd)
  3445. if(QI(i,k)>epsQ.and.N_i>epsN) Dm_i(i,k)=Dm_x(DE(i,k),QI(i,k),1./N_i,icmi,thrd)
  3446. if(QN(i,k)>epsQ.and.N_s>epsN) Dm_s(i,k)=Dm_x(DE(i,k),QN(i,k),1./N_s,icms,idms)
  3447. if(QG(i,k)>epsQ.and.N_g>epsN) Dm_g(i,k)=Dm_x(DE(i,k),QG(i,k),1./N_g,icmg,thrd)
  3448. if(QH(i,k)>epsQ.and.N_h>epsN) Dm_h(i,k)=Dm_x(DE(i,k),QH(i,k),1./N_h,icmh,thrd)
  3449. !Supercooled liquid water:
  3450. SLW(i,k)= 0.
  3451. if (T(i,k)<TRPL) SLW(i,k)= DE(i,k)*(QC(i,k)+QR(i,k)) !(units of [kg/m3])
  3452. !Visibility:
  3453. !VIS1: component through liquid cloud (fog) [m]
  3454. ! (following parameterization of Gultepe and Milbrandt, 2007)
  3455. tmp1= QC(i,k)*DE(i,k)*1.e+3 !LWC [g m-3]
  3456. tmp2= N_c*1.e-6 !Nc [cm-3]
  3457. if (tmp1>0.005 .and. tmp2>1.) then
  3458. VIS1(i,k)= max(epsVIS,1000.*(1.13*(tmp1*tmp2)**(-0.51))) !based on FRAM [GM2007, eqn (4)
  3459. !VIS1(i,k)= max(epsVIS,min(maxVIS, (tmp1*tmp2)**(-0.65))) !based on RACE [GM2007, eqn (3)
  3460. else
  3461. VIS1(i,k)= 3.*maxVIS !gets set to maxVIS after calc. of VIS
  3462. endif
  3463. !VIS2: component through rain !based on Gultepe and Milbrandt, 2008, Table 2 eqn (1)
  3464. tmp1= massFlux3D_r(i,k)*idew*3.6e+6 !rain rate [mm h-1]
  3465. if (tmp1>0.01) then
  3466. VIS2(i,k)= max(epsVIS,1000.*(-4.12*tmp1**0.176+9.01)) ![m]
  3467. else
  3468. VIS2(i,k)= 3.*maxVIS
  3469. endif
  3470. !VIS3: component through snow !based on Gultepe and Milbrandt, 2008, Table 2 eqn (6)
  3471. tmp1= massFlux3D_s(i,k)*idew*3.6e+6 !snow rate, liq-eq [mm h-1]
  3472. if (tmp1>0.01) then
  3473. VIS3(i,k)= max(epsVIS,1000.*(1.10*tmp1**(-0.701))) ![m]
  3474. else
  3475. VIS3(i,k)= 3.*maxVIS
  3476. endif
  3477. !VIS: visibility due to reduction from all components 1, 2, and 3
  3478. ! (based on sum of extinction coefficients and Koschmieders's Law)
  3479. VIS(i,k) = min(maxVIS, 1./(1./VIS1(i,k) + 1./VIS2(i,k) + 1./VIS3(i,k)))
  3480. VIS1(i,k)= min(maxVIS, VIS1(i,k))
  3481. VIS2(i,k)= min(maxVIS, VIS2(i,k))
  3482. VIS3(i,k)= min(maxVIS, VIS3(i,k))
  3483. enddo !i-loop
  3484. enddo !k-loop
  3485. !Diagnostic levels:
  3486. h_CB = noVal_h_XX !height (AGL) of cloud base
  3487. h_SN = noVal_h_XX !height (AGL) of snow level [conventional snow (not just QN>0.)]
  3488. h_ML1= noVal_h_XX !height (AGL) of melting level [first 0C isotherm from ground]
  3489. h_ML2= noVal_h_XX !height (AGL) of melting level [first 0C isotherm from top]
  3490. ! note: h_ML2 = h_ML1 implies only 1 melting level
  3491. tmp1= 1./GRAV
  3492. do i= 1,ni
  3493. CB_found= .false.; SN_found= .false.; ML_found= .false.
  3494. do k= nk,2,-1
  3495. !cloud base:
  3496. if ((QC(i,k)>epsQ2.or.QI(i,k)>epsQ2) .and. .not.CB_found) then
  3497. h_CB(i) = GZ(i,k)*tmp1
  3498. CB_found= .true.
  3499. endif
  3500. !snow level:
  3501. if ( ((QN(i,k)>epsQ2 .and. Dm_s(i,k)>minSnowSize) .or. &
  3502. (QG(i,k)>epsQ2 .and. Dm_g(i,k)>minSnowSize)) .and. .not.SN_found) then
  3503. h_SN(i) = GZ(i,k)*tmp1
  3504. SN_found= .true.
  3505. endif
  3506. !melting level: (height of lowest 0C isotherm)
  3507. if (T(i,k)>TRPL .and. T(i,k-1)<TRPL .and. .not.ML_found) then
  3508. h_ML1(i) = GZ(i,k)*tmp1
  3509. ML_found= .true.
  3510. endif
  3511. enddo
  3512. enddo
  3513. do i= 1,ni
  3514. ML_found= .false. !from top
  3515. do k= 2,nk
  3516. !melting level: (height of highest 0C isotherm)
  3517. if (T(i,k)>TRPL .and. T(i,k-1)<TRPL .and. .not.ML_found) then
  3518. h_ML2(i) = GZ(i,k)*tmp1
  3519. ML_found= .true.
  3520. endif
  3521. enddo
  3522. enddo
  3523. ENDIF
  3524. ! !
  3525. !-------------
  3526. !Convert N from #/m3 to #/kg:
  3527. ! note: - at this point, NX is updated NX (at t+1); NXTEND is NX before S/S (at t*)
  3528. ! - NXM is no longer used (it does not need a unit conversion)
  3529. do k= 1,nk
  3530. DE(:,k) = S(:,k)*PS(:)/(RGASD*T(:,k)) !air density at time (t)
  3531. iDE(:,k)= 1./DE(:,k)
  3532. enddo
  3533. NC= NC*iDE; NCTEND= NCTEND*iDE
  3534. NR= NR*iDE; NRTEND= NRTEND*iDE
  3535. NY= NY*iDE; NYTEND= NYTEND*iDE
  3536. NN= NN*iDE; NNTEND= NNTEND*iDE
  3537. NG= NG*iDE; NGTEND= NGTEND*iDE
  3538. NH= NH*iDE; NHTEND= NHTEND*iDE
  3539. !=============
  3540. !-----------------------------------------------------------------------------------!
  3541. ! Compute the tendencies of T, Q, QC, etc. (to be passed back to model dynamics) !
  3542. ! and reset the fields to their initial (saved) values at time {*}: !
  3543. do k= 1,nk
  3544. do i= 1,ni
  3545. tmp1=T_TEND(i,k); T_TEND(i,k)=(T(i,k) -T_TEND(i,k))*iDT; T(i,k) = tmp1
  3546. tmp1=Q_TEND(i,k); Q_TEND(i,k)=(Q(i,k) -Q_TEND(i,k))*iDT; Q(i,k) = tmp1
  3547. tmp1=QCTEND(i,k); QCTEND(i,k)=(QC(i,k)-QCTEND(i,k))*iDT; QC(i,k)= tmp1
  3548. tmp1=QRTEND(i,k); QRTEND(i,k)=(QR(i,k)-QRTEND(i,k))*iDT; QR(i,k)= tmp1
  3549. tmp1=QITEND(i,k); QITEND(i,k)=(QI(i,k)-QITEND(i,k))*iDT; QI(i,k)= tmp1
  3550. tmp1=QNTEND(i,k); QNTEND(i,k)=(QN(i,k)-QNTEND(i,k))*iDT; QN(i,k)= tmp1
  3551. tmp1=QGTEND(i,k); QGTEND(i,k)=(QG(i,k)-QGTEND(i,k))*iDT; QG(i,k)= tmp1
  3552. tmp1=QHTEND(i,k); QHTEND(i,k)=(QH(i,k)-QHTEND(i,k))*iDT; QH(i,k)= tmp1
  3553. if (DblMom_c) then
  3554. tmp1=NCTEND(i,k); NCTEND(i,k)=(NC(i,k)-NCTEND(i,k))*iDT; NC(i,k)= tmp1
  3555. endif
  3556. if (DblMom_r) then
  3557. tmp1=NRTEND(i,k); NRTEND(i,k)=(NR(i,k)-NRTEND(i,k))*iDT; NR(i,k)= tmp1
  3558. endif
  3559. if (DblMom_i) then
  3560. tmp1=NYTEND(i,k); NYTEND(i,k)=(NY(i,k)-NYTEND(i,k))*iDT; NY(i,k)= tmp1
  3561. endif
  3562. if (DblMom_s) then
  3563. tmp1=NNTEND(i,k); NNTEND(i,k)=(NN(i,k)-NNTEND(i,k))*iDT; NN(i,k)= tmp1
  3564. endif
  3565. if (DblMom_g) then
  3566. tmp1=NGTEND(i,k); NGTEND(i,k)=(NG(i,k)-NGTEND(i,k))*iDT; NG(i,k)= tmp1
  3567. endif
  3568. if (DblMom_h) then
  3569. tmp1=NHTEND(i,k); NHTEND(i,k)=(NH(i,k)-NHTEND(i,k))*iDT; NH(i,k)= tmp1
  3570. endif
  3571. enddo
  3572. enddo
  3573. ! !
  3574. !-----------------------------------------------------------------------------------!
  3575. END SUBROUTINE mp_milbrandt2mom_main
  3576. !___________________________________________________________________________________!
  3577. real function des_OF_Ds(Ds_local,desMax_local,eds_local,fds_local)
  3578. !Computes density of equivalent-volume snow particle based on (pi/6*des)*Ds^3 = cms*Ds^dms
  3579. real :: Ds_local,desMax_local,eds_local,fds_local
  3580. ! des_OF_Ds= min(desMax_local, eds_local*Ds_local**fds_local)
  3581. des_OF_Ds= min(desMax_local, eds_local*exp(fds_local*log(Ds_local))) !IBM optimization
  3582. end function des_OF_Ds
  3583. real function Dm_x(DE_local,QX_local,iNX_local,icmx_local,idmx_local)
  3584. !Computes mean-mass diameter
  3585. real :: DE_local,QX_local,iNX_local,icmx_local,idmx_local
  3586. !Dm_x = (DE_local*QX_local*iNX_local*icmx_local)**idmx_local
  3587. Dm_x = exp(idmx_local*log(DE_local*QX_local*iNX_local*icmx_local)) !IBM optimization
  3588. end function Dm_x
  3589. real function iLAMDA_x(DE_local,QX_local,iNX_local,icex_local,idmx_local)
  3590. !Computes 1/LAMDA ("slope" parameter):
  3591. real :: DE_local,QX_local,iNX_local,icex_local,idmx_local
  3592. !iLAMDA_x = (DE_local*QX_local*iNX_local*icex_local)**idmx_local
  3593. iLAMDA_x = exp(idmx_local*log(DE_local*QX_local*iNX_local*icex_local)) !IBM optimization
  3594. end function
  3595. real function N_Cooper(TRPL_local,T_local)
  3596. !Computes total number concentration of ice as a function of temperature
  3597. !according to parameterization of Cooper (1986):
  3598. real :: TRPL_local,T_local
  3599. N_Cooper= 5.*exp(0.304*(TRPL_local-max(233.,T_local)))
  3600. end function N_Cooper
  3601. real function Nos_Thompson(TRPL_local,T_local)
  3602. !Computes the snow intercept, No_s, as a function of temperature
  3603. !according to the parameterization of Thompson et al. (2004):
  3604. real :: TRPL_local,T_local
  3605. Nos_Thompson= min(2.e+8, 2.e+6*exp(-0.12*min(-0.001,T_local-TRPL_local)))
  3606. end function Nos_Thompson
  3607. !===================================================================================================!
  3608. END MODULE my_dmom_mod
  3609. !________________________________________________________________________________________!
  3610. MODULE module_mp_milbrandt2mom
  3611. use module_wrf_error
  3612. use my_dmom_mod
  3613. implicit none
  3614. ! To be done later. Currently, parameters are initialized in the main routine
  3615. ! (at every time step).
  3616. CONTAINS
  3617. !----------------------------------------------------------------------------------------!
  3618. SUBROUTINE milbrandt2mom_init
  3619. ! To be done later. Currently, parameters are initialized in the main routine (at every time step).
  3620. END SUBROUTINE milbrandt2mom_init
  3621. !----------------------------------------------------------------------------------------!
  3622. !+---------------------------------------------------------------------+
  3623. ! This is a wrapper routine designed to transfer values from 3D to 2D. !
  3624. !+---------------------------------------------------------------------+
  3625. SUBROUTINE mp_milbrandt2mom_driver(qv, qc, qr, qi, qs, qg, qh, nc, nr, ni, ns, ng, &
  3626. nh, th, pii, p, w, dz, dt_in, itimestep, &
  3627. RAINNC, RAINNCV, SNOWNC, SNOWNCV, GRPLNC, GRPLNCV, &
  3628. ! HAILNC, HAILNCV, SR, Zet, ccntype, &
  3629. HAILNC, HAILNCV, SR, Zet, &
  3630. ids,ide, jds,jde, kds,kde, & ! domain dims
  3631. ims,ime, jms,jme, kms,kme, & ! memory dims
  3632. its,ite, jts,jte, kts,kte) ! tile dims
  3633. implicit none
  3634. !Subroutine arguments:
  3635. integer, intent(in):: ids,ide, jds,jde, kds,kde, &
  3636. ims,ime, jms,jme, kms,kme, &
  3637. its,ite, jts,jte, kts,kte
  3638. real, dimension(ims:ime, kms:kme, jms:jme), intent(inout):: &
  3639. qv,qc,qr,qi,qs,qg,qh,nc,nr,ni,ns,ng,nh,th,Zet
  3640. real, dimension(ims:ime, kms:kme, jms:jme), intent(in):: &
  3641. pii,p,w,dz
  3642. real, dimension(ims:ime, jms:jme), intent(inout):: &
  3643. RAINNC,RAINNCV,SNOWNC,SNOWNCV,GRPLNC,GRPLNCV,HAILNC,HAILNCV, &
  3644. SR
  3645. real, intent(in):: dt_in
  3646. integer, intent(in):: itimestep !, ccntype
  3647. !Local variables:
  3648. real, dimension(1:ite-its+1,1:kte-kts+1) :: t2d,qv2d,qc2d,qr2d,qi2d,qs2d,qg2d,qh2d,&
  3649. nc2d,nr2d,ni2d,ns2d,ng2d,nh2d,p2d,dz2d,rho,irho,omega2d,t2d_m,qv2d_m,qc2d_m, &
  3650. qr2d_m,qi2d_m,qs2d_m,qg2d_m,qh2d_m,nc2d_m,nr2d_m,ni2d_m,ns2d_m,ng2d_m,nh2d_m,&
  3651. sigma2d,tmp01,tmp02,tmp03,tmp04,tmp05,tmp06,tmp07,tmp08,tmp09,tmp10,tmp11, &
  3652. tmp12,tmp13,tmp14,tmp15,tmp16,tmp17,tmp18,gz2d,zet2d
  3653. !tentatively local; to be passed out as output variables later
  3654. real, dimension(1:ite-its+1,1:kte-kts+1) :: Dm_c,Dm_r,Dm_i,Dm_s,Dm_g,Dm_h, &
  3655. SLW,VIS,VIS1,VIS2,VIS3,SS01,SS02,SS03,SS04,SS05,SS06,SS07,SS08,SS09,SS10, &
  3656. SS11,SS12,SS13,SS14,SS15,SS16,SS17,SS18,SS19,SS20,T_tend,Q_tend,QCtend, &
  3657. QRtend,QItend,QStend,QGtend,QHtend,NCtend,NRtend,NItend,NStend,NGtend,NHtend
  3658. real, dimension(1:ite-its+1) :: rt_rn1,rt_rn2,rt_fr1,rt_fr2,rt_sn1,rt_sn2,rt_sn3, &
  3659. rt_pe1,rt_pe2,rt_peL,rt_snd,ZEC,h_CB,h_ML1,h_ML2,h_SN,p_src
  3660. real :: dt,ms2mmstp
  3661. real :: qc_max,qr_max,qs_max,qi_max,qg_max,qh_max,nc_max,nr_max,ns_max,ni_max, &
  3662. ng_max,nh_max
  3663. integer :: i,j,k,i2d,j2d,k2d,i2d_max,k2d_max
  3664. integer :: imax_qc, imax_qr, imax_qi, imax_qs, imax_qg, imax_qh
  3665. integer :: imax_nc, imax_nr, imax_ni, imax_ns, imax_ng, imax_nh
  3666. integer :: jmax_qc, jmax_qr, jmax_qi, jmax_qs, jmax_qg, jmax_qh
  3667. integer :: jmax_nc, jmax_nr, jmax_ni, jmax_ns, jmax_ng, jmax_nh
  3668. integer :: kmax_qc, kmax_qr, kmax_qi, kmax_qs, kmax_qg, kmax_qh
  3669. integer :: kmax_nc, kmax_nr, kmax_ni, kmax_ns, kmax_ng, kmax_nh
  3670. integer :: i_start, j_start, i_end, j_end, CCNtype
  3671. logical :: precipDiag_ON,sedi_ON,warmphase_ON,autoconv_ON,icephase_ON,snow_ON, &
  3672. initN,dblMom_c,dblMom_r,dblMom_i,dblMom_s,dblMom_g,dblMom_h
  3673. real, parameter :: ms2mmh = 3.6e+6 !conversion factor for precipitation rates
  3674. real, parameter :: R_d = 287.04 !gas constant for dry air
  3675. character*512 :: mp_debug
  3676. !+---+
  3677. i2d_max = ite-its+1
  3678. k2d_max = kte-kts+1
  3679. dt = dt_in
  3680. ms2mmstp = 1.e+3*dt !conversion factor: m/2 to mm/step
  3681. !--- temporary initialization (until variables are put as namelist options:
  3682. ! CCNtype = 1. !maritime --> N_c = 80 cm-3 for dblMom_c = .F.
  3683. CCNtype = 2. !continental --> N_c = 200 cm-3 for dblMom_c = .F.
  3684. precipDiag_ON = .true.; dblMom_c = .true.
  3685. sedi_ON = .true.; dblMom_r = .true.
  3686. warmphase_ON = .true.; dblMom_i = .true.
  3687. autoconv_ON = .true.; dblMom_s = .true.
  3688. icephase_ON = .true.; dblMom_g = .true.
  3689. snow_ON = .true.; dblMom_h = .true.
  3690. initN = .true.
  3691. !---
  3692. qc_max = 0.; nc_max = 0.
  3693. qr_max = 0.; nr_max = 0.
  3694. qi_max = 0.; ni_max = 0.
  3695. qs_max = 0.; ns_max = 0.
  3696. qg_max = 0.; ng_max = 0.
  3697. qh_max = 0.; nh_max = 0.
  3698. imax_qc = 0; imax_nc = 0; jmax_qc = 0; jmax_nc = 0; kmax_qc = 0; kmax_nc = 0
  3699. imax_qr = 0; imax_nr = 0; jmax_qr = 0; jmax_nr = 0; kmax_qr = 0; kmax_nr = 0
  3700. imax_qi = 0; imax_ni = 0; jmax_qi = 0; jmax_ni = 0; kmax_qi = 0; kmax_ni = 0
  3701. imax_qs = 0; imax_ns = 0; jmax_qs = 0; jmax_ns = 0; kmax_qs = 0; kmax_ns = 0
  3702. imax_qg = 0; imax_ng = 0; jmax_qg = 0; jmax_ng = 0; kmax_qg = 0; kmax_ng = 0
  3703. imax_qh = 0; imax_nh = 0; jmax_qh = 0; jmax_nh = 0; kmax_qh = 0; kmax_nh = 0
  3704. RAINNCV = 0.
  3705. SNOWNCV = 0.
  3706. GRPLNCV = 0.
  3707. HAILNCV = 0.
  3708. SR = 0.
  3709. do i = 1, 512
  3710. mp_debug(i:i) = char(0)
  3711. enddo
  3712. j_loop1: do j = jts, jte
  3713. j2d = j-jts+1 !index value for 2D arrays, to be passed to main micro scheme
  3714. i_loop1: do i = its, ite
  3715. i2d = i-its+1 !index value for 2D arrays, to be passed to main micro scheme
  3716. !Approximate geopotential:
  3717. ! (assumes lowest model level is at sea-level; acceptable for purposes of scheme)
  3718. gz2d(i2d,kts)= 0.
  3719. do k = kts+1, kte
  3720. gz2d(i2d,k)= gz2d(i2d,k-1) + dz(i,k,j)*9.81
  3721. enddo
  3722. k_loop1: do k = kts, kte
  3723. k2d = k-kts+1 !index value for 2D arrays, to be passed to main micro scheme
  3724. !Note: The 3D number concentration variables (seen by WRF dynamics) are in units of 1/kg.
  3725. ! However, the 2D variables must be converted to units of 1/m3 (by multiplying by air
  3726. ! density) before being passed to the main subroutine mp_milbrandtsmom. They are then
  3727. ! converted back after the call, upon putting them back from 2D to 3D variables.
  3728. !Convert 3D to 2D arrays (etc.):
  3729. t2d(i2d,k2d) = th(i,k,j)*pii(i,k,j)
  3730. p2d(i2d,k2d) = p(i,k,j)
  3731. dz2d(i2d,k2d) = dz(i,k,j)
  3732. qv2d(i2d,k2d) = qv(i,k,j)
  3733. !chen rho(i2d,k2d) = p2d(i2d,k2d)/(R_d*t2d(i2d,k2d))
  3734. !chen omega2d(i2d,k2d)= -w(i,k,j)*p2d(i2d,k2d)*9.81
  3735. rho(i2d,k2d) = p2d(i2d,k)/(R_d*t2d(i2d,k))
  3736. omega2d(i2d,k2d)= -w(i,k,j)*rho(i2d,k2d)*9.81
  3737. qc2d(i2d,k2d) = qc(i,k,j); nc2d(i2d,k2d) = nc(i,k,j)
  3738. qi2d(i2d,k2d) = qi(i,k,j); ni2d(i2d,k2d) = ni(i,k,j)
  3739. qr2d(i2d,k2d) = qr(i,k,j); nr2d(i2d,k2d) = nr(i,k,j)
  3740. qs2d(i2d,k2d) = qs(i,k,j); ns2d(i2d,k2d) = ns(i,k,j)
  3741. qg2d(i2d,k2d) = qg(i,k,j); ng2d(i2d,k2d) = ng(i,k,j)
  3742. qh2d(i2d,k2d) = qh(i,k,j); nh2d(i2d,k2d) = nh(i,k,j)
  3743. sigma2d(i2d,k2d)= p2d(i2d,k2d)/p2d(i2d,kte-kts+1)
  3744. enddo k_loop1
  3745. K_loop9: do k= kts, kte
  3746. k2d = k-kts+1 !index value for 2D arrays, to be passed to main micro scheme
  3747. sigma2d(i2d,k2d)= p2d(i2d,k2d)/p2d(i2d,kte-kts+1)
  3748. enddo K_loop9
  3749. enddo i_loop1
  3750. p_src(:)= p2d(:,k2d_max)
  3751. !Flip arrays: (to conform to vertical leveling in GEM)
  3752. ! Note: This step (and the flipping back) could be avoided by changing the indexing
  3753. ! in the sedimentation subroutine. It is done this way to allow for directly
  3754. ! pasting the GEM code directly into this subdriver without having to change
  3755. ! the code.
  3756. tmp01= omega2d; tmp02= t2d; tmp03= qv2d; tmp04= qc2d; tmp05=qr2d; tmp06=qi2d
  3757. tmp07= qs2d; tmp08= qg2d; tmp09= qh2d; tmp10= nc2d; tmp11=nr2d; tmp12=ni2d
  3758. tmp13= ns2d; tmp14= ng2d; tmp15= nh2d; tmp16= sigma2d; tmp17=dz2d; tmp18=gz2d
  3759. do k = kts-1,kte-1
  3760. k2d = k-kts+1
  3761. omega2d(:,k2d+1)= tmp01(:,k2d_max-k2d)
  3762. t2d(:,k2d+1) = tmp02(:,k2d_max-k2d)
  3763. qv2d(:,k2d+1) = tmp03(:,k2d_max-k2d)
  3764. qc2d(:,k2d+1) = tmp04(:,k2d_max-k2d)
  3765. qr2d(:,k2d+1) = tmp05(:,k2d_max-k2d)
  3766. qi2d(:,k2d+1) = tmp06(:,k2d_max-k2d)
  3767. qs2d(:,k2d+1) = tmp07(:,k2d_max-k2d)
  3768. qg2d(:,k2d+1) = tmp08(:,k2d_max-k2d)
  3769. qh2d(:,k2d+1) = tmp09(:,k2d_max-k2d)
  3770. nc2d(:,k2d+1) = tmp10(:,k2d_max-k2d)
  3771. nr2d(:,k2d+1) = tmp11(:,k2d_max-k2d)
  3772. ni2d(:,k2d+1) = tmp12(:,k2d_max-k2d)
  3773. ns2d(:,k2d+1) = tmp13(:,k2d_max-k2d)
  3774. ng2d(:,k2d+1) = tmp14(:,k2d_max-k2d)
  3775. nh2d(:,k2d+1) = tmp15(:,k2d_max-k2d)
  3776. sigma2d(:,k2d+1)= tmp16(:,k2d_max-k2d)
  3777. dz2d(:,k2d+1) = tmp17(:,k2d_max-k2d)
  3778. gz2d(:,k2d+1) = tmp18(:,k2d_max-k2d)
  3779. enddo
  3780. !Copy 2d arrays xx2d to xx2d_m: (to facilitate inclusion of main milbrandt2mom
  3781. ! subroutine which uses arrays at two different time levels, for GEM model)
  3782. t2d_m = t2d; qv2d_m = qv2d
  3783. qc2d_m = qc2d; nc2d_m = nc2d
  3784. qr2d_m = qr2d; nr2d_m = nr2d
  3785. qi2d_m = qi2d; ni2d_m = ni2d
  3786. qs2d_m = qs2d; ns2d_m = ns2d
  3787. qg2d_m = qg2d; ng2d_m = ng2d
  3788. qh2d_m = qh2d; nh2d_m = nh2d
  3789. call mp_milbrandt2mom_main(omega2d,t2d,qv2d,qc2d,qr2d,qi2d,qs2d,qg2d,qh2d,nc2d, &
  3790. nr2d,ni2d,ns2d,ng2d,nh2d,p_src,t2d_m,qv2d_m,qc2d_m,qr2d_m,qi2d_m,qs2d_m, &
  3791. qg2d_m,qh2d_m,nc2d_m,nr2d_m,ni2d_m,ns2d_m,ng2d_m,nh2d_m,p_src,sigma2d, &
  3792. rt_rn1,rt_rn2,rt_fr1,rt_fr2,rt_sn1,rt_sn2,rt_sn3,rt_pe1,rt_pe2,rt_peL,rt_snd,&
  3793. gz2d,T_tend,Q_tend,QCtend,QRtend,QItend,QStend,QGtend,QHtend,NCtend,NRtend, &
  3794. NItend,NStend,NGtend,NHtend,dt,i2d_max,1,k2d_max,j,itimestep,CCNtype,precipDiag_ON,&
  3795. sedi_ON,warmphase_ON,autoconv_ON,icephase_ON,snow_ON,initN,dblMom_c,dblMom_r,&
  3796. dblMom_i,dblMom_s,dblMom_g,dblMom_h,Dm_c,Dm_r,Dm_i,Dm_s,Dm_g,Dm_h,Zet2d,ZEC, &
  3797. SLW,VIS,VIS1,VIS2,VIS3,h_CB,h_ML1,h_ML2,h_SN,SS01,SS02,SS03,SS04,SS05,SS06, &
  3798. SS07,SS08,SS09,SS10,SS11,SS12,SS13,SS14,SS15,SS16,SS17,SS18,SS19,SS20)
  3799. !Add tendencies:
  3800. t2d(:,:) = t2d(:,:) + T_tend(:,:)*dt
  3801. qv2d(:,:)= qv2d(:,:) + Q_tend(:,:)*dt
  3802. qc2d(:,:)= qc2d(:,:) + QCtend(:,:)*dt; nc2d(:,:)= nc2d(:,:) + NCtend(:,:)*dt
  3803. qr2d(:,:)= qr2d(:,:) + QRtend(:,:)*dt; nr2d(:,:)= nr2d(:,:) + NRtend(:,:)*dt
  3804. qi2d(:,:)= qi2d(:,:) + QItend(:,:)*dt; ni2d(:,:)= ni2d(:,:) + NItend(:,:)*dt
  3805. qs2d(:,:)= qs2d(:,:) + QStend(:,:)*dt; ns2d(:,:)= ns2d(:,:) + NStend(:,:)*dt
  3806. qg2d(:,:)= qg2d(:,:) + QGtend(:,:)*dt; ng2d(:,:)= ng2d(:,:) + NGtend(:,:)*dt
  3807. qh2d(:,:)= qh2d(:,:) + QHtend(:,:)*dt; nh2d(:,:)= nh2d(:,:) + NHtend(:,:)*dt
  3808. !Flip arrays back : (to conform to vertical leveling in WRF)
  3809. tmp02= t2d; tmp03= qv2d; tmp04= qc2d; tmp05=qr2d; tmp06=qi2d
  3810. tmp07= qs2d; tmp08= qg2d; tmp09= qh2d; tmp10= nc2d; tmp11=nr2d; tmp12=ni2d
  3811. tmp13= ns2d; tmp14= ng2d; tmp15= nh2d; tmp16= Zet2d; tmp17=ss01; tmp18=ss02
  3812. do k = kts-1,kte-1
  3813. k2d = k-kts+1
  3814. t2d(:,k2d+1) = tmp02(:,k2d_max-k2d)
  3815. qv2d(:,k2d+1) = tmp03(:,k2d_max-k2d)
  3816. qc2d(:,k2d+1) = tmp04(:,k2d_max-k2d)
  3817. qr2d(:,k2d+1) = tmp05(:,k2d_max-k2d)
  3818. qi2d(:,k2d+1) = tmp06(:,k2d_max-k2d)
  3819. qs2d(:,k2d+1) = tmp07(:,k2d_max-k2d)
  3820. qg2d(:,k2d+1) = tmp08(:,k2d_max-k2d)
  3821. qh2d(:,k2d+1) = tmp09(:,k2d_max-k2d)
  3822. nc2d(:,k2d+1) = tmp10(:,k2d_max-k2d)
  3823. nr2d(:,k2d+1) = tmp11(:,k2d_max-k2d)
  3824. ni2d(:,k2d+1) = tmp12(:,k2d_max-k2d)
  3825. ns2d(:,k2d+1) = tmp13(:,k2d_max-k2d)
  3826. ng2d(:,k2d+1) = tmp14(:,k2d_max-k2d)
  3827. nh2d(:,k2d+1) = tmp15(:,k2d_max-k2d)
  3828. Zet2d(:,k2d+1) = tmp16(:,k2d_max-k2d)
  3829. enddo
  3830. i_loop2: do i = its, ite
  3831. i2d = i-its+1
  3832. !Convert individual precipitation rates (in m/s) to WRF precipitation fields:
  3833. ! note: RAINNC is not actually "rain"; it is the total precipitation.
  3834. ! The liquid precipitation is the total multiplied by the liquid fraction,
  3835. ! --> rain = RAINNC*(1-SR) (done elsewhere in WRF)
  3836. RAINNCV(i,j) = (rt_rn1(i2d)+rt_rn2(i2d)+rt_fr1(i2d)+rt_fr2(i2d)+rt_sn1(i2d)+ &
  3837. rt_sn2(i2d)+rt_sn3(i2d)+rt_pe1(i2d)+rt_pe2(i2d))*ms2mmstp
  3838. SNOWNCV(i,j) = (rt_sn1(i2d) + rt_sn2(i2d))*ms2mmstp
  3839. HAILNCV(i,j) = (rt_pe1(i2d) + rt_pe2(i2d))*ms2mmstp
  3840. GRPLNCV(i,j) = rt_sn3(i2d) *ms2mmstp
  3841. RAINNC(i,j) = RAINNC(i,j) + RAINNCV(i,j)
  3842. SNOWNC(i,j) = SNOWNC(i,j) + SNOWNCV(i,j)
  3843. HAILNC(i,j) = HAILNC(i,j) + HAILNCV(i,j)
  3844. GRPLNC(i,j) = GRPLNC(i,j) + GRPLNCV(i,j)
  3845. SR(i,j) = (SNOWNCV(i,j)+HAILNCV(i,j)+GRPLNCV(i,j))/(RAINNCV(i,j)+1.e-12)
  3846. k_loop2: do k = kts, kte
  3847. k2d = k-kts+1
  3848. if(.not.(t2d(i2d,k2d)>=173.) .or. (t2d(i2d,k2d)>1000.)) then
  3849. write(6,*)
  3850. write(6,*) '*** Stopping in mp_milbrandt2mom_driver due to unrealistic temperature ***'
  3851. write(6,*) ' step: ',itimestep
  3852. write(6,'(a5,5i5,8e15.5)') 'i,k: ',i,j,k,i2d,k2d,t2d(i2d,k2d),qv2d(i2d,k2d),qc2d(i2d,k2d),qr2d(i2d,k2d), &
  3853. qi2d(i2d,k2d),qs2d(i2d,k2d),qg2d(i2d,k2d),qh2d(i2d,k2d)
  3854. write(6,*)
  3855. stop
  3856. endif
  3857. !Convert back to 3D arrays (and change units of number concentrations back to kg-1):
  3858. th(i,k,j) = t2d(i2d,k2d)/pii(i,k,j)
  3859. qv(i,k,j) = qv2d(i2d,k2d)
  3860. ! irho(i,k) = R_d*t2d(i2d,k2d)/p2d(i2d,k2d)
  3861. qc(i,k,j) = qc2d(i2d,k2d); nc(i,k,j) = nc2d(i2d,k2d)
  3862. qi(i,k,j) = qi2d(i2d,k2d); ni(i,k,j) = ni2d(i2d,k2d)
  3863. qr(i,k,j) = qr2d(i2d,k2d); nr(i,k,j) = nr2d(i2d,k2d)
  3864. qs(i,k,j) = qs2d(i2d,k2d); ns(i,k,j) = ns2d(i2d,k2d)
  3865. qg(i,k,j) = qg2d(i2d,k2d); ng(i,k,j) = ng2d(i2d,k2d)
  3866. qh(i,k,j) = qh2d(i2d,k2d); nh(i,k,j) = nh2d(i2d,k2d)
  3867. Zet(i,k,j)= Zet2d(i2d,k2d)
  3868. enddo k_loop2
  3869. enddo i_loop2
  3870. enddo j_loop1
  3871. do i = 1, 256
  3872. mp_debug(i:i) = char(0)
  3873. enddo
  3874. END SUBROUTINE mp_milbrandt2mom_driver
  3875. !+---+-----------------------------------------------------------------+
  3876. !________________________________________________________________________________________!
  3877. END MODULE module_mp_milbrandt2mom