phys_convec_ec2tm.F90 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. !###############################################################################
  2. !
  3. ! Convert ecmwf convective fields to TM convective fields.
  4. !
  5. ! Original code by Dirk Olivie, KNMI.
  6. !
  7. ! Research notes by DO :
  8. !
  9. ! sign:
  10. ! mfup : positive
  11. ! dtup : positive
  12. ! mfdo : negative
  13. ! dtdo : positive
  14. !
  15. ! input mass fluxes are contaminated by profiles :
  16. ! the same for every grid point, different for each time step
  17. ! mfup : not contaminated
  18. ! dtup : between 0. and -0.99e-19
  19. ! mfdo : between -0.99e-6 and 0.99e-6
  20. ! dtdo : betweeb 0. and -0.99e-20
  21. !
  22. ! minumum values:
  23. ! mfup : 1.e-6
  24. ! dtup : 1.e-10
  25. ! mfdo : 1.e-6
  26. ! dtdo : 1.e-10
  27. !
  28. ! remarks:
  29. !
  30. ! 1. start updraft is not always the lowest level : sometimes second or third
  31. !
  32. ! 2. end downdraft is not always lowest level : sometimes 6th level
  33. !
  34. ! 3. in the updraft cloud : delta_updraft = 1.e-4
  35. ! epsilon_updraft = 1.e-5
  36. ! this automatically/naturally decreases the mass flux : GOOD GOOD GOOD
  37. !
  38. ! 4. there is a part incloud where the mass flus is constant;
  39. ! later over many layer (order of 10) the mass flux decreases
  40. !
  41. ! 5. detrainment updraft 2 or 3 levels higher (sometimes 15 levels : i = 17565)
  42. ! then the updraft mass flux
  43. !
  44. ! 6. only detrainment downdraft lowest level different from zero
  45. !
  46. ! 7. the cloudbase of updraft and downdraft correspond sometimes quite well
  47. !
  48. !###############################################################################
  49. !
  50. #define IF_NOTOK_RETURN(action) if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; action; return; end if
  51. #define IF_ERROR_RETURN(action) if (status> 0) then; write (gol,'("in ",a)') rname; call goErr; action; return; end if
  52. !
  53. !###############################################################################
  54. module phys_convec_ec2tm
  55. use GO, only : gol, goPr, goErr
  56. implicit none
  57. ! --- in/out -----------------------------
  58. private
  59. public :: ECconv_to_TMconv
  60. public :: convec_mfldet_to_entdet
  61. ! --- const ---------------------------------------
  62. character(len=*), parameter :: mname = 'phys_convec_ec2tm'
  63. contains
  64. ! =============================================================
  65. !
  66. ! o Level order is always top->down (ecmwf order)
  67. !
  68. ! o ECMWF mass fluxes mflu_ec and mfld_ec are defined for half levels.
  69. ! According to the original code, the mass fluxes read from the grib
  70. ! files are valid for the upper half level of a cell.
  71. ! The bottom values mflu_ec(lm) and mfld_ec(lm) should have been
  72. ! set to zero.
  73. !
  74. subroutine ECconv_to_TMconv( lm, zh_ec, &
  75. mflu_ec, detu_ec, mfld_ec, detd_ec, &
  76. entu , detu , entd , detd , &
  77. status )
  78. ! --- in/out -------------------------------
  79. integer, intent(in) :: lm
  80. real, intent(in) :: zh_ec(0:lm) ! geopot. height m (half lev)
  81. real, intent(in) :: mflu_ec(0:lm) ! updr. mass flux kg/m2/s (half lev)
  82. real, intent(in) :: detu_ec(1:lm) ! updr. detr. rate kg/m3/s (full lev)
  83. real, intent(in) :: mfld_ec(0:lm) ! downdr. mass flux kg/m2/s (half lev)
  84. real, intent(in) :: detd_ec(1:lm) ! downdr. detr. rate kg/m3/s (full lev)
  85. real, intent(out) :: entu(1:lm) ! updr. entr. kg/m2/s (full lev)
  86. real, intent(out) :: detu(1:lm) ! downdr. detr. kg/m2/s (full lev)
  87. real, intent(out) :: entd(1:lm) ! updr. entr. kg/m2/s (full lev)
  88. real, intent(out) :: detd(1:lm) ! downdr. detr. kg/m2/s (full lev)
  89. integer, intent(out) :: status
  90. ! --- const -----------------------------------------
  91. character(len=*), parameter :: rname = mname//'/ECconv_to_TMconv'
  92. ! --- local ------------------------------
  93. integer :: l ! level number
  94. real :: mflu(0:lm) ! updr. mass flux kg/m2/s (half lev)
  95. real :: mfld(0:lm) ! downdr. mass flux kg/m2/s (half lev)
  96. ! layer thickness
  97. real :: dz ! m
  98. ! updraft top
  99. integer :: uptop ! layer
  100. logical :: uptop_found
  101. ! downdraft top
  102. integer :: dotop ! layer
  103. logical :: dotop_found
  104. ! --- begin --------------------------------
  105. ! copy ecmwf arrays into local arrays
  106. mflu = mflu_ec
  107. detu = detu_ec
  108. entu = 0.0
  109. mfld = mfld_ec
  110. detd = detd_ec
  111. entd = 0.0
  112. ! removing small values due to gribbing
  113. where ( mflu < 1.e-6 ) mflu = 0.0
  114. where ( detu < 1.e-10 ) detu = 0.0
  115. where ( mfld > -1.e-6 ) mfld = 0.0
  116. where ( detd < 1.e-10 ) detd = 0.0
  117. ! height integral of detrainment rates
  118. do l = 1, lm
  119. dz = zh_ec(l-1) - zh_ec(l)
  120. detu(l) = detu(l)*dz ! kg/m3/s -> kg/m2/s
  121. detd(l) = detd(l)*dz ! kg/m3/s -> kg/m2/s
  122. enddo
  123. ! find updraftop
  124. uptop = 0
  125. uptop_found = .false.
  126. do l = 1, lm
  127. if ( mflu(l) > 0.0 ) then
  128. uptop = l
  129. uptop_found = .true.
  130. exit
  131. end if
  132. end do
  133. ! find downdrafttop
  134. dotop = 0
  135. dotop_found = .false.
  136. do l = 1, lm
  137. if ( mfld(l) < 0.0 ) then
  138. dotop = l
  139. dotop_found = .true.
  140. exit
  141. end if
  142. end do
  143. ! updraft
  144. if ( uptop_found ) then
  145. ! set updr. entr/detr to zero above uptop
  146. do l = 1, uptop-1
  147. entu(l) = 0.0
  148. detu(l) = 0.0
  149. enddo
  150. ! loop from uptop to bot:
  151. do l = uptop, lm
  152. ! entr = out through top - in through bot + out by detr
  153. entu(l) = mflu(l-1) - mflu(l) + detu(l)
  154. enddo
  155. else
  156. ! no updr. at all
  157. mflu(:) = 0.0
  158. detu(:) = 0.0
  159. entu(:) = 0.0
  160. endif
  161. ! downdraft
  162. if ( dotop_found ) then
  163. ! set updr. entr/detr to zero above dotop
  164. !AJS: BUG ? do l = 1, dotop+1
  165. do l = 1, dotop-1
  166. detd(l) = 0.0
  167. entd(l) = 0.0
  168. enddo
  169. ! loop from dotop to bot:
  170. do l = dotop, lm
  171. ! entr = out through top - in through bot + out by detr
  172. entd(l) = mfld(l-1) - mfld(l) + detd(l)
  173. enddo
  174. else
  175. ! no downdr. at all
  176. mfld(:) = 0.0
  177. detd(:) = 0.0
  178. entd(:) = 0.0
  179. endif
  180. ! check on negative values:
  181. do l = 1, lm
  182. if ( entu(l) < 0.0 ) then
  183. detu(l) = detu(l) - entu(l)
  184. entu(l) = 0.0
  185. endif
  186. if ( detu(l) < 0.0 ) then
  187. entu(l) = entu(l) - detu(l)
  188. detu(l) = 0.0
  189. endif
  190. if ( entd(l) < 0.0 ) then
  191. detd(l) = detd(l) - entd(l)
  192. entd(l) = 0.0
  193. endif
  194. if ( detd(l) < 0.0 ) then
  195. entd(l) = entd(l) - detd(l)
  196. detd(l) = 0.0
  197. endif
  198. enddo
  199. ! ok
  200. status = 0
  201. end subroutine ECconv_to_TMconv
  202. ! =============================================================
  203. !
  204. ! Generalized version of ECconv_to_TMconv .
  205. !
  206. ! o Level order is either 'u' upwards (tm order) or 'd' downwards (ecmwf order)
  207. !
  208. ! o ECMWF mass fluxes mflu_ec and mfld_ec are defined for half levels.
  209. ! According to the original code, the mass fluxes read from the grib
  210. ! files are valid for the upper half level of a cell.
  211. ! The bottom values mflu_ec(lm) and mfld_ec(lm) should have been
  212. ! set to zero.
  213. !
  214. subroutine convec_mfldet_to_entdet( updo, lm, zh_ec, &
  215. mflu_ec, detu_ec, mfld_ec, detd_ec, &
  216. entu , detu , entd , detd , &
  217. status )
  218. ! --- in/out -------------------------------
  219. character(len=1) :: updo
  220. integer, intent(in) :: lm
  221. real, intent(in) :: zh_ec(0:lm) ! geopot. height m (half lev)
  222. real, intent(in) :: mflu_ec(0:lm) ! updr. mass flux kg/m2/s (half lev)
  223. real, intent(in) :: detu_ec(1:lm) ! updr. detr. rate kg/m3/s (full lev)
  224. real, intent(in) :: mfld_ec(0:lm) ! downdr. mass flux kg/m2/s (half lev)
  225. real, intent(in) :: detd_ec(1:lm) ! downdr. detr. rate kg/m3/s (full lev)
  226. real, intent(out) :: entu(1:lm) ! updr. entr. kg/m2/s (full lev)
  227. real, intent(out) :: detu(1:lm) ! downdr. detr. kg/m2/s (full lev)
  228. real, intent(out) :: entd(1:lm) ! updr. entr. kg/m2/s (full lev)
  229. real, intent(out) :: detd(1:lm) ! downdr. detr. kg/m2/s (full lev)
  230. integer, intent(out) :: status
  231. ! --- const -----------------------------------------
  232. character(len=*), parameter :: rname = mname//'/convec_mfldet_to_entdet'
  233. ! --- local ------------------------------
  234. integer :: l ! level number
  235. real :: mflu(0:lm) ! updr. mass flux kg/m2/s (half lev)
  236. real :: mfld(0:lm) ! downdr. mass flux kg/m2/s (half lev)
  237. ! layer thickness
  238. real :: dz ! m
  239. ! updraft top
  240. integer :: uptop ! layer
  241. logical :: uptop_found
  242. ! downdraft top
  243. integer :: dotop ! layer
  244. logical :: dotop_found
  245. ! --- begin --------------------------------
  246. ! copy ecmwf arrays into local arrays
  247. mflu = mflu_ec
  248. detu = detu_ec
  249. entu = 0.0
  250. mfld = mfld_ec
  251. detd = detd_ec
  252. entd = 0.0
  253. ! removing small values due to gribbing
  254. where ( mflu < 1.e-6 ) mflu = 0.0
  255. where ( detu < 1.e-10 ) detu = 0.0
  256. where ( mfld > -1.e-6 ) mfld = 0.0
  257. where ( detd < 1.e-10 ) detd = 0.0
  258. ! height integral of detrainment rates
  259. do l = 1, lm
  260. dz = abs( zh_ec(l) - zh_ec(l-1) ) ! m
  261. detu(l) = detu(l)*dz ! kg/m3/s -> kg/m2/s
  262. detd(l) = detd(l)*dz ! kg/m3/s -> kg/m2/s
  263. end do
  264. ! levels upwards (TM) or downwards (EC)
  265. select case ( updo )
  266. ! ***
  267. case ( 'u', 'U' )
  268. ! find updraftop
  269. uptop = 0
  270. uptop_found = .false.
  271. ! loop over layers from top to bot:
  272. do l = lm, 1, -1
  273. ! flux through bottom ? then this is the top level
  274. if ( mflu(l-1) > 0.0 ) then
  275. uptop = l
  276. uptop_found = .true.
  277. exit
  278. end if
  279. end do
  280. ! compute entrainments of updraught
  281. if ( uptop_found ) then
  282. ! loop from bot to uptop:
  283. do l = 1, uptop
  284. ! entr = out through top - in through bot + out by detr
  285. entu(l) = mflu(l) - mflu(l-1) + detu(l)
  286. enddo
  287. ! set updr. entr/detr to zero above uptop
  288. do l = uptop+1, lm
  289. entu(l) = 0.0
  290. detu(l) = 0.0
  291. enddo
  292. else
  293. ! no updr. at all
  294. detu(:) = 0.0
  295. entu(:) = 0.0
  296. endif
  297. ! find downdrafttop
  298. dotop = 0
  299. dotop_found = .false.
  300. ! loop over layers from top to bot:
  301. do l = lm, 1, -1
  302. ! flux through bottom ? then this is the top level
  303. if ( mfld(l-1) < 0.0 ) then
  304. dotop = l
  305. dotop_found = .true.
  306. exit
  307. end if
  308. end do
  309. ! compute entrainments of downdraught
  310. if ( dotop_found ) then
  311. ! loop from bot to dotop:
  312. do l = 1, dotop
  313. ! entr = out through top - in through bot + out by detr
  314. entd(l) = mfld(l) - mfld(l-1) + detd(l)
  315. enddo
  316. ! set updr. entr/detr to zero above dotop
  317. do l = dotop+1, lm
  318. detd(l) = 0.0
  319. entd(l) = 0.0
  320. enddo
  321. else
  322. ! no downdr. at all
  323. detd(:) = 0.0
  324. entd(:) = 0.0
  325. endif
  326. ! ***
  327. case ( 'd', 'D' )
  328. ! find updraftop
  329. uptop = 0
  330. uptop_found = .false.
  331. ! loop over layers from top to bot:
  332. do l = 1, lm
  333. ! flux through bottom ? then this is the top level
  334. if ( mflu(l) > 0.0 ) then
  335. uptop = l
  336. uptop_found = .true.
  337. exit
  338. end if
  339. end do
  340. ! compute entrainments of updraught
  341. if ( uptop_found ) then
  342. ! set updr. entr/detr to zero above uptop
  343. do l = 1, uptop-1
  344. entu(l) = 0.0
  345. detu(l) = 0.0
  346. enddo
  347. ! loop from uptop to bot:
  348. do l = uptop, lm
  349. ! entr = out through top - in through bot + out by detr
  350. entu(l) = mflu(l-1) - mflu(l) + detu(l)
  351. enddo
  352. else
  353. ! no updr. at all
  354. detu(:) = 0.0
  355. entu(:) = 0.0
  356. endif
  357. ! find downdrafttop
  358. dotop = 0
  359. dotop_found = .false.
  360. ! loop over layers from top to bot:
  361. do l = 1, lm
  362. ! flux through bottom ? then this is the top level
  363. if ( mfld(l) < 0.0 ) then
  364. dotop = l
  365. dotop_found = .true.
  366. exit
  367. end if
  368. end do
  369. ! compute entrainments of downdraught
  370. if ( dotop_found ) then
  371. ! set updr. entr/detr to zero above dotop
  372. do l = 1, dotop-1
  373. detd(l) = 0.0
  374. entd(l) = 0.0
  375. enddo
  376. ! loop from dotop to bot:
  377. do l = dotop, lm
  378. ! entr = out through top - in through bot + out by detr
  379. entd(l) = mfld(l-1) - mfld(l) + detd(l)
  380. enddo
  381. else
  382. ! no downdr. at all
  383. detd(:) = 0.0
  384. entd(:) = 0.0
  385. endif
  386. ! ***
  387. case default
  388. write (gol,'("unsupported updo : ",a)') updo; call goErr
  389. write (gol,'("in ",a)') rname; call goErr; status=1; return
  390. end select
  391. ! check on negative values:
  392. do l = 1, lm
  393. if ( entu(l) < 0.0 ) then
  394. detu(l) = detu(l) - entu(l)
  395. entu(l) = 0.0
  396. endif
  397. if ( detu(l) < 0.0 ) then
  398. entu(l) = entu(l) - detu(l)
  399. detu(l) = 0.0
  400. endif
  401. if ( entd(l) < 0.0 ) then
  402. detd(l) = detd(l) - entd(l)
  403. entd(l) = 0.0
  404. endif
  405. if ( detd(l) < 0.0 ) then
  406. entd(l) = entd(l) - detd(l)
  407. detd(l) = 0.0
  408. endif
  409. enddo
  410. ! ok
  411. status = 0
  412. end subroutine convec_mfldet_to_entdet
  413. end module phys_convec_ec2tm