PageRenderTime 67ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 1ms

/wrfv2_fire/dyn_em/module_big_step_utilities_em.F

https://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 6155 lines | 3822 code | 1351 blank | 982 comment | 56 complexity | 28eae140e72dd9b7b229817c61222a96 MD5 | raw file
Possible License(s): AGPL-1.0

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

  1. !wrf:MODEL_LAYER:DYNAMICS
  2. !
  3. #if (RWORDSIZE == 4)
  4. # define VPOWX vspowx
  5. # define VPOW vspow
  6. #else
  7. # define VPOWX vpowx
  8. # define VPOW vpow
  9. #endif
  10. MODULE module_big_step_utilities_em
  11. USE module_model_constants
  12. USE module_state_description, only: p_qg, p_qs, p_qi, gdscheme, tiedtkescheme, kfetascheme, g3scheme, &
  13. p_qv, param_first_scalar, p_qr, p_qc
  14. USE module_configure, ONLY : grid_config_rec_type
  15. CONTAINS
  16. !-------------------------------------------------------------------------------
  17. SUBROUTINE calc_mu_uv ( config_flags, &
  18. mu, mub, muu, muv, &
  19. ids, ide, jds, jde, kds, kde, &
  20. ims, ime, jms, jme, kms, kme, &
  21. its, ite, jts, jte, kts, kte )
  22. IMPLICIT NONE
  23. ! Input data
  24. TYPE(grid_config_rec_type ) , INTENT(IN ) :: config_flags
  25. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  26. ims, ime, jms, jme, kms, kme, &
  27. its, ite, jts, jte, kts, kte
  28. REAL, DIMENSION( ims:ime , jms:jme ) , INTENT( OUT) :: muu, muv
  29. REAL, DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mu, mub
  30. ! local stuff
  31. INTEGER :: i, j, itf, jtf, im, jm
  32. !<DESCRIPTION>
  33. !
  34. ! calc_mu_uv calculates the full column dry-air mass at the staggered
  35. ! horizontal velocity points (u,v) and places the results in muu and muv.
  36. ! This routine uses the reference state (mub) and perturbation state (mu)
  37. !
  38. !</DESCRIPTION>
  39. itf=ite
  40. jtf=MIN(jte,jde-1)
  41. IF ( ( its .NE. ids ) .AND. ( ite .NE. ide ) ) THEN
  42. DO j=jts,jtf
  43. DO i=its,itf
  44. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
  45. ENDDO
  46. ENDDO
  47. ELSE IF ( ( its .EQ. ids ) .AND. ( ite .NE. ide ) ) THEN
  48. DO j=jts,jtf
  49. DO i=its+1,itf
  50. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
  51. ENDDO
  52. ENDDO
  53. i=its
  54. im = its
  55. if(config_flags%periodic_x) im = its-1
  56. DO j=jts,jtf
  57. ! muu(i,j) = mu(i,j) +mub(i,j)
  58. ! fix for periodic b.c., 13 march 2004, wcs
  59. muu(i,j) = 0.5*(mu(i,j)+mu(im,j)+mub(i,j)+mub(im,j))
  60. ENDDO
  61. ELSE IF ( ( its .NE. ids ) .AND. ( ite .EQ. ide ) ) THEN
  62. DO j=jts,jtf
  63. DO i=its,itf-1
  64. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
  65. ENDDO
  66. ENDDO
  67. i=ite
  68. im = ite-1
  69. if(config_flags%periodic_x) im = ite
  70. DO j=jts,jtf
  71. ! muu(i,j) = mu(i-1,j) +mub(i-1,j)
  72. ! fix for periodic b.c., 13 march 2004, wcs
  73. muu(i,j) = 0.5*(mu(i-1,j)+mu(im,j)+mub(i-1,j)+mub(im,j))
  74. ENDDO
  75. ELSE IF ( ( its .EQ. ids ) .AND. ( ite .EQ. ide ) ) THEN
  76. DO j=jts,jtf
  77. DO i=its+1,itf-1
  78. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
  79. ENDDO
  80. ENDDO
  81. i=its
  82. im = its
  83. if(config_flags%periodic_x) im = its-1
  84. DO j=jts,jtf
  85. ! muu(i,j) = mu(i,j) +mub(i,j)
  86. ! fix for periodic b.c., 13 march 2004, wcs
  87. muu(i,j) = 0.5*(mu(i,j)+mu(im,j)+mub(i,j)+mub(im,j))
  88. ENDDO
  89. i=ite
  90. im = ite-1
  91. if(config_flags%periodic_x) im = ite
  92. DO j=jts,jtf
  93. ! muu(i,j) = mu(i-1,j) +mub(i-1,j)
  94. ! fix for periodic b.c., 13 march 2004, wcs
  95. muu(i,j) = 0.5*(mu(i-1,j)+mu(im,j)+mub(i-1,j)+mub(im,j))
  96. ENDDO
  97. END IF
  98. itf=MIN(ite,ide-1)
  99. jtf=jte
  100. IF ( ( jts .NE. jds ) .AND. ( jte .NE. jde ) ) THEN
  101. DO j=jts,jtf
  102. DO i=its,itf
  103. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
  104. ENDDO
  105. ENDDO
  106. ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .NE. jde ) ) THEN
  107. DO j=jts+1,jtf
  108. DO i=its,itf
  109. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
  110. ENDDO
  111. ENDDO
  112. j=jts
  113. jm = jts
  114. if(config_flags%periodic_y) jm = jts-1
  115. DO i=its,itf
  116. ! muv(i,j) = mu(i,j) +mub(i,j)
  117. ! fix for periodic b.c., 13 march 2004, wcs
  118. muv(i,j) = 0.5*(mu(i,j)+mu(i,jm)+mub(i,j)+mub(i,jm))
  119. ENDDO
  120. ELSE IF ( ( jts .NE. jds ) .AND. ( jte .EQ. jde ) ) THEN
  121. DO j=jts,jtf-1
  122. DO i=its,itf
  123. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
  124. ENDDO
  125. ENDDO
  126. j=jte
  127. jm = jte-1
  128. if(config_flags%periodic_y) jm = jte
  129. DO i=its,itf
  130. muv(i,j) = mu(i,j-1) +mub(i,j-1)
  131. ! fix for periodic b.c., 13 march 2004, wcs
  132. muv(i,j) = 0.5*(mu(i,j-1)+mu(i,jm)+mub(i,j-1)+mub(i,jm))
  133. ENDDO
  134. ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .EQ. jde ) ) THEN
  135. DO j=jts+1,jtf-1
  136. DO i=its,itf
  137. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
  138. ENDDO
  139. ENDDO
  140. j=jts
  141. jm = jts
  142. if(config_flags%periodic_y) jm = jts-1
  143. DO i=its,itf
  144. ! muv(i,j) = mu(i,j) +mub(i,j)
  145. ! fix for periodic b.c., 13 march 2004, wcs
  146. muv(i,j) = 0.5*(mu(i,j)+mu(i,jm)+mub(i,j)+mub(i,jm))
  147. ENDDO
  148. j=jte
  149. jm = jte-1
  150. if(config_flags%periodic_y) jm = jte
  151. DO i=its,itf
  152. ! muv(i,j) = mu(i,j-1) +mub(i,j-1)
  153. ! fix for periodic b.c., 13 march 2004, wcs
  154. muv(i,j) = 0.5*(mu(i,j-1)+mu(i,jm)+mub(i,j-1)+mub(i,jm))
  155. ENDDO
  156. END IF
  157. END SUBROUTINE calc_mu_uv
  158. !-------------------------------------------------------------------------------
  159. SUBROUTINE calc_mu_uv_1 ( config_flags, &
  160. mu, muu, muv, &
  161. ids, ide, jds, jde, kds, kde, &
  162. ims, ime, jms, jme, kms, kme, &
  163. its, ite, jts, jte, kts, kte )
  164. IMPLICIT NONE
  165. ! Input data
  166. TYPE(grid_config_rec_type ) , INTENT(IN ) :: config_flags
  167. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  168. ims, ime, jms, jme, kms, kme, &
  169. its, ite, jts, jte, kts, kte
  170. REAL, DIMENSION( ims:ime , jms:jme ) , INTENT( OUT) :: muu, muv
  171. REAL, DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mu
  172. ! local stuff
  173. INTEGER :: i, j, itf, jtf, im, jm
  174. !<DESCRIPTION>
  175. !
  176. ! calc_mu_uv calculates the full column dry-air mass at the staggered
  177. ! horizontal velocity points (u,v) and places the results in muu and muv.
  178. ! This routine uses the full state (mu)
  179. !
  180. !</DESCRIPTION>
  181. itf=ite
  182. jtf=MIN(jte,jde-1)
  183. IF ( ( its .NE. ids ) .AND. ( ite .NE. ide ) ) THEN
  184. DO j=jts,jtf
  185. DO i=its,itf
  186. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j))
  187. ENDDO
  188. ENDDO
  189. ELSE IF ( ( its .EQ. ids ) .AND. ( ite .NE. ide ) ) THEN
  190. DO j=jts,jtf
  191. DO i=its+1,itf
  192. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j))
  193. ENDDO
  194. ENDDO
  195. i=its
  196. im = its
  197. if(config_flags%periodic_x) im = its-1
  198. DO j=jts,jtf
  199. muu(i,j) = 0.5*(mu(i,j)+mu(im,j))
  200. ENDDO
  201. ELSE IF ( ( its .NE. ids ) .AND. ( ite .EQ. ide ) ) THEN
  202. DO j=jts,jtf
  203. DO i=its,itf-1
  204. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j))
  205. ENDDO
  206. ENDDO
  207. i=ite
  208. im = ite-1
  209. if(config_flags%periodic_x) im = ite
  210. DO j=jts,jtf
  211. muu(i,j) = 0.5*(mu(i-1,j)+mu(im,j))
  212. ENDDO
  213. ELSE IF ( ( its .EQ. ids ) .AND. ( ite .EQ. ide ) ) THEN
  214. DO j=jts,jtf
  215. DO i=its+1,itf-1
  216. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j))
  217. ENDDO
  218. ENDDO
  219. i=its
  220. im = its
  221. if(config_flags%periodic_x) im = its-1
  222. DO j=jts,jtf
  223. muu(i,j) = 0.5*(mu(i,j)+mu(im,j))
  224. ENDDO
  225. i=ite
  226. im = ite-1
  227. if(config_flags%periodic_x) im = ite
  228. DO j=jts,jtf
  229. muu(i,j) = 0.5*(mu(i-1,j)+mu(im,j))
  230. ENDDO
  231. END IF
  232. itf=MIN(ite,ide-1)
  233. jtf=jte
  234. IF ( ( jts .NE. jds ) .AND. ( jte .NE. jde ) ) THEN
  235. DO j=jts,jtf
  236. DO i=its,itf
  237. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1))
  238. ENDDO
  239. ENDDO
  240. ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .NE. jde ) ) THEN
  241. DO j=jts+1,jtf
  242. DO i=its,itf
  243. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1))
  244. ENDDO
  245. ENDDO
  246. j=jts
  247. jm = jts
  248. if(config_flags%periodic_y) jm = jts-1
  249. DO i=its,itf
  250. muv(i,j) = 0.5*(mu(i,j)+mu(i,jm))
  251. ENDDO
  252. ELSE IF ( ( jts .NE. jds ) .AND. ( jte .EQ. jde ) ) THEN
  253. DO j=jts,jtf-1
  254. DO i=its,itf
  255. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1))
  256. ENDDO
  257. ENDDO
  258. j=jte
  259. jm = jte-1
  260. if(config_flags%periodic_y) jm = jte
  261. DO i=its,itf
  262. muv(i,j) = 0.5*(mu(i,j-1)+mu(i,jm))
  263. ENDDO
  264. ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .EQ. jde ) ) THEN
  265. DO j=jts+1,jtf-1
  266. DO i=its,itf
  267. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1))
  268. ENDDO
  269. ENDDO
  270. j=jts
  271. jm = jts
  272. if(config_flags%periodic_y) jm = jts-1
  273. DO i=its,itf
  274. muv(i,j) = 0.5*(mu(i,j)+mu(i,jm))
  275. ENDDO
  276. j=jte
  277. jm = jte-1
  278. if(config_flags%periodic_y) jm = jte
  279. DO i=its,itf
  280. muv(i,j) = 0.5*(mu(i,j-1)+mu(i,jm))
  281. ENDDO
  282. END IF
  283. END SUBROUTINE calc_mu_uv_1
  284. !-------------------------------------------------------------------------------
  285. ! Map scale factor comments for this routine:
  286. ! Locally not changed, but sent the correct map scale factors
  287. ! from module_em (msfuy, msfvx, msfty)
  288. SUBROUTINE couple_momentum ( muu, ru, u, msfu, &
  289. muv, rv, v, msfv, msfv_inv, &
  290. mut, rw, w, msft, &
  291. ids, ide, jds, jde, kds, kde, &
  292. ims, ime, jms, jme, kms, kme, &
  293. its, ite, jts, jte, kts, kte )
  294. IMPLICIT NONE
  295. ! Input data
  296. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  297. ims, ime, jms, jme, kms, kme, &
  298. its, ite, jts, jte, kts, kte
  299. REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT( OUT) :: ru, rv, rw
  300. REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: muu, muv, mut
  301. REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfu, msfv, msft, msfv_inv
  302. REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: u, v, w
  303. ! Local data
  304. INTEGER :: i, j, k, itf, jtf, ktf
  305. !<DESCRIPTION>
  306. !
  307. ! couple_momentum couples the velocities to the full column mass and
  308. ! the map factors.
  309. !
  310. !</DESCRIPTION>
  311. ktf=MIN(kte,kde-1)
  312. itf=ite
  313. jtf=MIN(jte,jde-1)
  314. DO j=jts,jtf
  315. DO k=kts,ktf
  316. DO i=its,itf
  317. ru(i,k,j)=u(i,k,j)*muu(i,j)/msfu(i,j)
  318. ENDDO
  319. ENDDO
  320. ENDDO
  321. itf=MIN(ite,ide-1)
  322. jtf=jte
  323. DO j=jts,jtf
  324. DO k=kts,ktf
  325. DO i=its,itf
  326. rv(i,k,j)=v(i,k,j)*muv(i,j)*msfv_inv(i,j)
  327. ! rv(i,k,j)=v(i,k,j)*muv(i,j)/msfv(i,j)
  328. ENDDO
  329. ENDDO
  330. ENDDO
  331. itf=MIN(ite,ide-1)
  332. jtf=MIN(jte,jde-1)
  333. DO j=jts,jtf
  334. DO k=kts,kte
  335. DO i=its,itf
  336. rw(i,k,j)=w(i,k,j)*mut(i,j)/msft(i,j)
  337. ENDDO
  338. ENDDO
  339. ENDDO
  340. END SUBROUTINE couple_momentum
  341. !-------------------------------------------------------------------
  342. SUBROUTINE calc_mu_staggered ( mu, mub, muu, muv, &
  343. ids, ide, jds, jde, kds, kde, &
  344. ims, ime, jms, jme, kms, kme, &
  345. its, ite, jts, jte, kts, kte )
  346. IMPLICIT NONE
  347. ! Input data
  348. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  349. ims, ime, jms, jme, kms, kme, &
  350. its, ite, jts, jte, kts, kte
  351. REAL, DIMENSION( ims:ime , jms:jme ) , INTENT( OUT) :: muu, muv
  352. REAL, DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mu, mub
  353. ! local stuff
  354. INTEGER :: i, j, itf, jtf
  355. !<DESCRIPTION>
  356. !
  357. ! calc_mu_staggered calculates the full dry air mass at the staggered
  358. ! velocity points (u,v).
  359. !
  360. !</DESCRIPTION>
  361. itf=ite
  362. jtf=MIN(jte,jde-1)
  363. IF ( ( its .NE. ids ) .AND. ( ite .NE. ide ) ) THEN
  364. DO j=jts,jtf
  365. DO i=its,itf
  366. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
  367. ENDDO
  368. ENDDO
  369. ELSE IF ( ( its .EQ. ids ) .AND. ( ite .NE. ide ) ) THEN
  370. DO j=jts,jtf
  371. DO i=its+1,itf
  372. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
  373. ENDDO
  374. ENDDO
  375. i=its
  376. DO j=jts,jtf
  377. muu(i,j) = mu(i,j) +mub(i,j)
  378. ENDDO
  379. ELSE IF ( ( its .NE. ids ) .AND. ( ite .EQ. ide ) ) THEN
  380. DO j=jts,jtf
  381. DO i=its,itf-1
  382. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
  383. ENDDO
  384. ENDDO
  385. i=ite
  386. DO j=jts,jtf
  387. muu(i,j) = mu(i-1,j) +mub(i-1,j)
  388. ENDDO
  389. ELSE IF ( ( its .EQ. ids ) .AND. ( ite .EQ. ide ) ) THEN
  390. DO j=jts,jtf
  391. DO i=its+1,itf-1
  392. muu(i,j) = 0.5*(mu(i,j)+mu(i-1,j)+mub(i,j)+mub(i-1,j))
  393. ENDDO
  394. ENDDO
  395. i=its
  396. DO j=jts,jtf
  397. muu(i,j) = mu(i,j) +mub(i,j)
  398. ENDDO
  399. i=ite
  400. DO j=jts,jtf
  401. muu(i,j) = mu(i-1,j) +mub(i-1,j)
  402. ENDDO
  403. END IF
  404. itf=MIN(ite,ide-1)
  405. jtf=jte
  406. IF ( ( jts .NE. jds ) .AND. ( jte .NE. jde ) ) THEN
  407. DO j=jts,jtf
  408. DO i=its,itf
  409. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
  410. ENDDO
  411. ENDDO
  412. ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .NE. jde ) ) THEN
  413. DO j=jts+1,jtf
  414. DO i=its,itf
  415. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
  416. ENDDO
  417. ENDDO
  418. j=jts
  419. DO i=its,itf
  420. muv(i,j) = mu(i,j) +mub(i,j)
  421. ENDDO
  422. ELSE IF ( ( jts .NE. jds ) .AND. ( jte .EQ. jde ) ) THEN
  423. DO j=jts,jtf-1
  424. DO i=its,itf
  425. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
  426. ENDDO
  427. ENDDO
  428. j=jte
  429. DO i=its,itf
  430. muv(i,j) = mu(i,j-1) +mub(i,j-1)
  431. ENDDO
  432. ELSE IF ( ( jts .EQ. jds ) .AND. ( jte .EQ. jde ) ) THEN
  433. DO j=jts+1,jtf-1
  434. DO i=its,itf
  435. muv(i,j) = 0.5*(mu(i,j)+mu(i,j-1)+mub(i,j)+mub(i,j-1))
  436. ENDDO
  437. ENDDO
  438. j=jts
  439. DO i=its,itf
  440. muv(i,j) = mu(i,j) +mub(i,j)
  441. ENDDO
  442. j=jte
  443. DO i=its,itf
  444. muv(i,j) = mu(i,j-1) +mub(i,j-1)
  445. ENDDO
  446. END IF
  447. END SUBROUTINE calc_mu_staggered
  448. !-------------------------------------------------------------------------------
  449. SUBROUTINE couple ( mu, mub, rfield, field, name, &
  450. msf, &
  451. ids, ide, jds, jde, kds, kde, &
  452. ims, ime, jms, jme, kms, kme, &
  453. its, ite, jts, jte, kts, kte )
  454. IMPLICIT NONE
  455. ! Input data
  456. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  457. ims, ime, jms, jme, kms, kme, &
  458. its, ite, jts, jte, kts, kte
  459. CHARACTER(LEN=1) , INTENT(IN ) :: name
  460. REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT( OUT) :: rfield
  461. REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mu, mub, msf
  462. REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: field
  463. ! Local data
  464. INTEGER :: i, j, k, itf, jtf, ktf
  465. REAL , DIMENSION(ims:ime,jms:jme) :: muu , muv
  466. !<DESCRIPTION>
  467. !
  468. ! subroutine couple couples the input variable with the dry-air
  469. ! column mass (mu).
  470. !
  471. !</DESCRIPTION>
  472. ktf=MIN(kte,kde-1)
  473. IF (name .EQ. 'u')THEN
  474. CALL calc_mu_staggered ( mu, mub, muu, muv, &
  475. ids, ide, jds, jde, kds, kde, &
  476. ims, ime, jms, jme, kms, kme, &
  477. its, ite, jts, jte, kts, kte )
  478. itf=ite
  479. jtf=MIN(jte,jde-1)
  480. DO j=jts,jtf
  481. DO k=kts,ktf
  482. DO i=its,itf
  483. rfield(i,k,j)=field(i,k,j)*muu(i,j)/msf(i,j)
  484. ENDDO
  485. ENDDO
  486. ENDDO
  487. ELSE IF (name .EQ. 'v')THEN
  488. CALL calc_mu_staggered ( mu, mub, muu, muv, &
  489. ids, ide, jds, jde, kds, kde, &
  490. ims, ime, jms, jme, kms, kme, &
  491. its, ite, jts, jte, kts, kte )
  492. itf=ite
  493. itf=MIN(ite,ide-1)
  494. jtf=jte
  495. DO j=jts,jtf
  496. DO k=kts,ktf
  497. DO i=its,itf
  498. rfield(i,k,j)=field(i,k,j)*muv(i,j)/msf(i,j)
  499. ENDDO
  500. ENDDO
  501. ENDDO
  502. ELSE IF (name .EQ. 'w')THEN
  503. itf=MIN(ite,ide-1)
  504. jtf=MIN(jte,jde-1)
  505. DO j=jts,jtf
  506. DO k=kts,kte
  507. DO i=its,itf
  508. rfield(i,k,j)=field(i,k,j)*(mu(i,j)+mub(i,j))/msf(i,j)
  509. ENDDO
  510. ENDDO
  511. ENDDO
  512. ELSE IF (name .EQ. 'h')THEN
  513. itf=MIN(ite,ide-1)
  514. jtf=MIN(jte,jde-1)
  515. DO j=jts,jtf
  516. DO k=kts,kte
  517. DO i=its,itf
  518. rfield(i,k,j)=field(i,k,j)*(mu(i,j)+mub(i,j))
  519. ENDDO
  520. ENDDO
  521. ENDDO
  522. ELSE
  523. itf=MIN(ite,ide-1)
  524. jtf=MIN(jte,jde-1)
  525. DO j=jts,jtf
  526. DO k=kts,ktf
  527. DO i=its,itf
  528. rfield(i,k,j)=field(i,k,j)*(mu(i,j)+mub(i,j))
  529. ENDDO
  530. ENDDO
  531. ENDDO
  532. ENDIF
  533. END SUBROUTINE couple
  534. !-------------------------------------------------------------------------------
  535. SUBROUTINE calc_ww_cp ( u, v, mup, mub, ww, &
  536. rdx, rdy, msftx, msfty, &
  537. msfux, msfuy, msfvx, msfvx_inv, &
  538. msfvy, dnw, &
  539. ids, ide, jds, jde, kds, kde, &
  540. ims, ime, jms, jme, kms, kme, &
  541. its, ite, jts, jte, kts, kte )
  542. IMPLICIT NONE
  543. ! Input data
  544. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  545. ims, ime, jms, jme, kms, kme, &
  546. its, ite, jts, jte, kts, kte
  547. REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(IN ) :: u, v
  548. REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: mup, mub, &
  549. msftx, msfty, &
  550. msfux, msfuy, &
  551. msfvx, msfvy, &
  552. msfvx_inv
  553. REAL , DIMENSION( kms:kme ) , INTENT(IN ) :: dnw
  554. REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(OUT ) :: ww
  555. REAL , INTENT(IN ) :: rdx, rdy
  556. ! Local data
  557. INTEGER :: i, j, k, itf, jtf, ktf
  558. REAL , DIMENSION( its:ite ) :: dmdt
  559. REAL , DIMENSION( its:ite, kts:kte ) :: divv
  560. REAL , DIMENSION( its:ite+1, jts:jte+1 ) :: muu, muv
  561. !<DESCRIPTION>
  562. !
  563. ! calc_ww calculates omega using the velocities (u,v) and the dry-air
  564. ! column mass (mup+mub).
  565. ! The algorithm integrates the continuity equation through the column
  566. ! followed by a diagnosis of omega.
  567. !
  568. !</DESCRIPTION>
  569. !<DESCRIPTION>
  570. !
  571. ! calc_ww_cp calculates omega using the velocities (u,v) and the
  572. ! column mass mu.
  573. !
  574. !</DESCRIPTION>
  575. jtf=MIN(jte,jde-1)
  576. ktf=MIN(kte,kde-1)
  577. itf=MIN(ite,ide-1)
  578. ! mu coupled with the appropriate map factor
  579. DO j=jts,jtf
  580. DO i=its,min(ite+1,ide)
  581. ! u is always coupled with my
  582. muu(i,j) = 0.5*(mup(i,j)+mub(i,j)+mup(i-1,j)+mub(i-1,j))/msfuy(i,j)
  583. ENDDO
  584. ENDDO
  585. DO j=jts,min(jte+1,jde)
  586. DO i=its,itf
  587. ! v is always coupled with mx
  588. ! muv(i,j) = 0.5*(mup(i,j)+mub(i,j)+mup(i,j-1)+mub(i,j-1))/msfvx(i,j)
  589. muv(i,j) = 0.5*(mup(i,j)+mub(i,j)+mup(i,j-1)+mub(i,j-1))*msfvx_inv(i,j)
  590. ENDDO
  591. ENDDO
  592. DO j=jts,jtf
  593. DO i=its,ite
  594. dmdt(i) = 0.
  595. ww(i,1,j) = 0.
  596. ww(i,kte,j) = 0.
  597. ENDDO
  598. ! Comments on the modifications for map scale factors
  599. ! ADT eqn 47 / my (putting rho -> 'mu') is:
  600. ! (1/my) partial d mu/dt = -mx partial d/dx(mu u/my)
  601. ! -mx partial d/dy(mu v/mx)
  602. ! -partial d/dz(mu w/my)
  603. !
  604. ! Using nu instead of z the last term becomes:
  605. ! -partial d/dnu(mu (dnu/dt)/my)
  606. !
  607. ! Integrating with respect to nu over ALL levels, with dnu/dt=0 at top
  608. ! and bottom, the last term becomes = 0
  609. !
  610. ! Integral|bot->top[(1/my) partial d mu/dt]dnu =
  611. ! Integral|bot->top[-mx partial d/dx(mu u/my)
  612. ! -mx partial d/dy(mu v/mx)]dnu
  613. !
  614. ! muu='mu'[on u]/my, muv='mu'[on v]/mx
  615. ! (1/my) partial d mu/dt is independent of nu
  616. ! => LHS = Integral|bot->top[con]dnu = conservation*(-1) = -dmdt
  617. !
  618. ! => dmdt = mx*Integral|bot->top[partial d/dx(mu u/my) +
  619. ! partial d/dy(mu v/mx)]dnu
  620. ! => dmdt = sum_bot->top[divv]
  621. ! where
  622. ! divv=mx*[partial d/dx(mu u/my) + partial d/dy(mu v/mx)]*delta nu
  623. DO k=kts,ktf
  624. DO i=its,itf
  625. divv(i,k) = msftx(i,j)*dnw(k)*( rdx*(muu(i+1,j)*u(i+1,k,j)-muu(i,j)*u(i,k,j)) &
  626. +rdy*(muv(i,j+1)*v(i,k,j+1)-muv(i,j)*v(i,k,j)) )
  627. ! dmdt(i) = dmdt(i) + dnw(k)* ( rdx*(ru(i+1,k,j)-ru(i,k,j)) &
  628. ! +rdy*(rv(i,k,j+1)-rv(i,k,j)) )
  629. dmdt(i) = dmdt(i) + divv(i,k)
  630. ENDDO
  631. ENDDO
  632. ! Further map scale factor notes:
  633. ! Now integrate from bottom to top, level by level:
  634. ! mu dnu/dt/my [k+1] = mu dnu/dt/my [k] + [-(1/my) partial d mu/dt
  635. ! -mx partial d/dx(mu u/my)
  636. ! -mx partial d/dy(mu v/mx)]*dnu[k->k+1]
  637. ! ww [k+1] = ww [k] -(1/my) partial d mu/dt * dnu[k->k+1] - divv[k]
  638. ! = ww [k] -dmdt * dnw[k] - divv[k]
  639. DO k=2,ktf
  640. DO i=its,itf
  641. ! ww(i,k,j)=ww(i,k-1,j) &
  642. ! - dnw(k-1)* ( dmdt(i) &
  643. ! +rdx*(ru(i+1,k-1,j)-ru(i,k-1,j)) &
  644. ! +rdy*(rv(i,k-1,j+1)-rv(i,k-1,j)) )
  645. ww(i,k,j)=ww(i,k-1,j) - dnw(k-1)*dmdt(i) - divv(i,k-1)
  646. ENDDO
  647. ENDDO
  648. ENDDO
  649. END SUBROUTINE calc_ww_cp
  650. !-------------------------------------------------------------------------------
  651. SUBROUTINE calc_cq ( moist, cqu, cqv, cqw, n_moist, &
  652. ids, ide, jds, jde, kds, kde, &
  653. ims, ime, jms, jme, kms, kme, &
  654. its, ite, jts, jte, kts, kte )
  655. IMPLICIT NONE
  656. ! Input data
  657. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  658. ims, ime, jms, jme, kms, kme, &
  659. its, ite, jts, jte, kts, kte
  660. INTEGER , INTENT(IN ) :: n_moist
  661. REAL, DIMENSION( ims:ime, kms:kme , jms:jme , n_moist ), INTENT(IN ) :: moist
  662. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT( OUT) :: cqu, cqv, cqw
  663. ! Local stuff
  664. REAL :: qtot
  665. INTEGER :: i, j, k, itf, jtf, ktf, ispe
  666. !<DESCRIPTION>
  667. !
  668. ! calc_cq calculates moist coefficients for the momentum equations.
  669. !
  670. !</DESCRIPTION>
  671. itf=ite
  672. jtf=MIN(jte,jde-1)
  673. ktf=MIN(kte,kde-1)
  674. IF( n_moist >= PARAM_FIRST_SCALAR ) THEN
  675. DO j=jts,jtf
  676. DO k=kts,ktf
  677. DO i=its,itf
  678. qtot = 0.
  679. !DEC$ loop count(3)
  680. DO ispe=PARAM_FIRST_SCALAR,n_moist
  681. qtot = qtot + moist(i,k,j,ispe) + moist(i-1,k,j,ispe)
  682. ENDDO
  683. ! qtot = 0.5*( moist(i ,k,j,1)+moist(i ,k,j,2)+moist(i ,k,j,3)+ &
  684. ! & moist(i-1,k,j,1)+moist(i-1,k,j,2)+moist(i-1,k,j,3) )
  685. ! cqu(i,k,j) = 1./(1.+qtot)
  686. cqu(i,k,j) = 1./(1.+0.5*qtot)
  687. ENDDO
  688. ENDDO
  689. ENDDO
  690. itf=MIN(ite,ide-1)
  691. jtf=jte
  692. DO j=jts,jtf
  693. DO k=kts,ktf
  694. DO i=its,itf
  695. qtot = 0.
  696. !DEC$ loop count(3)
  697. DO ispe=PARAM_FIRST_SCALAR,n_moist
  698. qtot = qtot + moist(i,k,j,ispe) + moist(i,k,j-1,ispe)
  699. ENDDO
  700. ! qtot = 0.5*( moist(i,k,j ,1)+moist(i,k,j ,2)+moist(i,k,j ,3)+ &
  701. ! & moist(i,k,j-1,1)+moist(i,k,j-1,2)+moist(i,k,j-1,3) )
  702. ! cqv(i,k,j) = 1./(1.+qtot)
  703. cqv(i,k,j) = 1./(1.+0.5*qtot)
  704. ENDDO
  705. ENDDO
  706. ENDDO
  707. itf=MIN(ite,ide-1)
  708. jtf=MIN(jte,jde-1)
  709. DO j=jts,jtf
  710. DO k=kts+1,ktf
  711. DO i=its,itf
  712. qtot = 0.
  713. !DEC$ loop count(3)
  714. DO ispe=PARAM_FIRST_SCALAR,n_moist
  715. qtot = qtot + moist(i,k,j,ispe) + moist(i,k-1,j,ispe)
  716. ENDDO
  717. ! qtot = 0.5*( moist(i,k ,j,1)+moist(i,k ,j,2)+moist(i,k-1,j,3)+ &
  718. ! & moist(i,k-1,j,1)+moist(i,k-1,j,2)+moist(i,k ,j,3) )
  719. ! cqw(i,k,j) = qtot
  720. cqw(i,k,j) = 0.5*qtot
  721. ENDDO
  722. ENDDO
  723. ENDDO
  724. ELSE
  725. DO j=jts,jtf
  726. DO k=kts,ktf
  727. DO i=its,itf
  728. cqu(i,k,j) = 1.
  729. ENDDO
  730. ENDDO
  731. ENDDO
  732. itf=MIN(ite,ide-1)
  733. jtf=jte
  734. DO j=jts,jtf
  735. DO k=kts,ktf
  736. DO i=its,itf
  737. cqv(i,k,j) = 1.
  738. ENDDO
  739. ENDDO
  740. ENDDO
  741. itf=MIN(ite,ide-1)
  742. jtf=MIN(jte,jde-1)
  743. DO j=jts,jtf
  744. DO k=kts+1,ktf
  745. DO i=its,itf
  746. cqw(i,k,j) = 0.
  747. ENDDO
  748. ENDDO
  749. ENDDO
  750. END IF
  751. END SUBROUTINE calc_cq
  752. !----------------------------------------------------------------------
  753. SUBROUTINE calc_alt ( alt, al, alb, &
  754. ids, ide, jds, jde, kds, kde, &
  755. ims, ime, jms, jme, kms, kme, &
  756. its, ite, jts, jte, kts, kte )
  757. IMPLICIT NONE
  758. ! Input data
  759. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  760. ims, ime, jms, jme, kms, kme, &
  761. its, ite, jts, jte, kts, kte
  762. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: alb, al
  763. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT( OUT) :: alt
  764. ! Local stuff
  765. INTEGER :: i, j, k, itf, jtf, ktf
  766. !<DESCRIPTION>
  767. !
  768. ! calc_alt computes the full inverse density
  769. !
  770. !</DESCRIPTION>
  771. itf=MIN(ite,ide-1)
  772. jtf=MIN(jte,jde-1)
  773. ktf=MIN(kte,kde-1)
  774. DO j=jts,jtf
  775. DO k=kts,ktf
  776. DO i=its,itf
  777. alt(i,k,j) = al(i,k,j)+alb(i,k,j)
  778. ENDDO
  779. ENDDO
  780. ENDDO
  781. END SUBROUTINE calc_alt
  782. !----------------------------------------------------------------------
  783. SUBROUTINE calc_p_rho_phi ( moist, n_moist, hypsometric_opt, &
  784. al, alb, mu, muts, ph, phb, p, pb, &
  785. t, p0, t0, ptop, znu, znw, dnw, rdnw, &
  786. rdn, non_hydrostatic, &
  787. ids, ide, jds, jde, kds, kde, &
  788. ims, ime, jms, jme, kms, kme, &
  789. its, ite, jts, jte, kts, kte )
  790. IMPLICIT NONE
  791. ! Input data
  792. LOGICAL , INTENT(IN ) :: non_hydrostatic
  793. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  794. ims, ime, jms, jme, kms, kme, &
  795. its, ite, jts, jte, kts, kte
  796. INTEGER , INTENT(IN ) :: n_moist
  797. INTEGER , INTENT(IN ) :: hypsometric_opt
  798. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: alb, &
  799. pb, &
  800. t
  801. REAL, DIMENSION( ims:ime , kms:kme , jms:jme, n_moist ), INTENT(IN ) :: moist
  802. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT( OUT) :: al, p
  803. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: ph, phb
  804. REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: mu, muts
  805. REAL, DIMENSION( kms:kme ), INTENT(IN ) :: znu, znw, dnw, rdnw, rdn
  806. REAL, INTENT(IN ) :: t0, p0, ptop
  807. ! Local stuff
  808. INTEGER :: i, j, k, itf, jtf, ktf, ispe
  809. REAL :: qvf, qtot, qf1, qf2
  810. REAL, DIMENSION( its:ite) :: temp,cpovcv_v
  811. REAL :: pfu, phm, pfd
  812. !<DESCRIPTION>
  813. !
  814. ! For the nonhydrostatic option, calc_p_rho_phi calculates the
  815. ! diagnostic quantities pressure and (inverse) density from the
  816. ! prognostic variables using the equation of state.
  817. !
  818. ! For the hydrostatic option, calc_p_rho_phi calculates the
  819. ! diagnostic quantities (inverse) density and geopotential from the
  820. ! prognostic variables using the equation of state and the hydrostatic
  821. ! equation.
  822. !
  823. !</DESCRIPTION>
  824. itf=MIN(ite,ide-1)
  825. jtf=MIN(jte,jde-1)
  826. ktf=MIN(kte,kde-1)
  827. #ifndef INTELMKL
  828. cpovcv_v = cpovcv
  829. #endif
  830. IF (non_hydrostatic) THEN
  831. IF (hypsometric_opt == 1) THEN
  832. DO j=jts,jtf
  833. DO k=kts,ktf
  834. DO i=its,itf
  835. al(i,k,j)=-1./muts(i,j)*(alb(i,k,j)*mu(i,j) + rdnw(k)*(ph(i,k+1,j)-ph(i,k,j)))
  836. END DO
  837. END DO
  838. END DO
  839. ELSE IF (hypsometric_opt == 2) THEN
  840. ! The relation used to get specific volume, al, is: al = -dZ/dp,
  841. ! where dp = mut * d(eta). The pressure depth, dp, is replaced with
  842. ! p*(dp/p) ~ p*LOG((p+0.5dp)/(p-0.5dp)). Difference between dp and p*dLOG(p)
  843. ! is as follows: p*dLOG(p) - dp = 1/12*(dp/p)**3 + 1/90*(dp/p)**5 + ...
  844. ! Therefore, p*dLOG(p) is always larger than dp and the difference is
  845. ! in proportion to dp/p. TKW, 02/16/2010
  846. DO j=jts,jtf
  847. DO k=kts,ktf
  848. DO i=its,itf
  849. pfu = muts(i,j)*znw(k+1)+ptop
  850. pfd = muts(i,j)*znw(k) +ptop
  851. phm = muts(i,j)*znu(k) +ptop
  852. al(i,k,j) = (ph(i,k+1,j)-ph(i,k,j)+phb(i,k+1,j)-phb(i,k,j))/phm/LOG(pfd/pfu)-alb(i,k,j)
  853. END DO
  854. END DO
  855. END DO
  856. ELSE
  857. CALL wrf_error_fatal ( 'calc_p_rho_phi: hypsometric_opt should be 1 or 2' )
  858. END IF
  859. IF (n_moist >= PARAM_FIRST_SCALAR ) THEN
  860. DO j=jts,jtf
  861. DO k=kts,ktf
  862. DO i=its,itf
  863. qvf = 1.+rvovrd*moist(i,k,j,P_QV)
  864. temp(i)=(r_d*(t0+t(i,k,j))*qvf)/(p0*(al(i,k,j)+alb(i,k,j)))
  865. ENDDO
  866. #ifdef INTELMKL
  867. CALL VPOWX ( itf-its+1, temp(its), cpovcv, p(its,k,j) )
  868. #else
  869. ! use vector version from libmassv or from compat lib in frame/libmassv.F
  870. CALL VPOW ( p(its,k,j), temp(its), cpovcv_v(its), itf-its+1 )
  871. #endif
  872. DO i=its,itf
  873. p(i,k,j)= p(i,k,j)*p0-pb(i,k,j)
  874. ENDDO
  875. ENDDO
  876. ENDDO
  877. ELSE
  878. DO j=jts,jtf
  879. DO k=kts,ktf
  880. DO i=its,itf
  881. p(i,k,j)=p0*( (r_d*(t0+t(i,k,j)))/ &
  882. (p0*(al(i,k,j)+alb(i,k,j))) )**cpovcv &
  883. -pb(i,k,j)
  884. ENDDO
  885. ENDDO
  886. ENDDO
  887. END IF
  888. ELSE
  889. ! hydrostatic pressure, al, and ph1 calc; WCS, 5 sept 2001
  890. IF (n_moist >= PARAM_FIRST_SCALAR ) THEN
  891. DO j=jts,jtf
  892. k=ktf ! top layer
  893. DO i=its,itf
  894. qtot = 0.
  895. DO ispe=PARAM_FIRST_SCALAR,n_moist
  896. qtot = qtot + moist(i,k,j,ispe)
  897. ENDDO
  898. qf2 = 1.
  899. qf1 = qtot*qf2
  900. p(i,k,j) = - 0.5*(mu(i,j)+qf1*muts(i,j))/rdnw(k)/qf2
  901. qvf = 1.+rvovrd*moist(i,k,j,P_QV)
  902. al(i,k,j) = (r_d/p1000mb)*(t(i,k,j)+t0)*qvf* &
  903. (((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm) - alb(i,k,j)
  904. ENDDO
  905. DO k=ktf-1,kts,-1 ! remaining layers, integrate down
  906. DO i=its,itf
  907. qtot = 0.
  908. DO ispe=PARAM_FIRST_SCALAR,n_moist
  909. qtot = qtot + 0.5*( moist(i,k ,j,ispe) + moist(i,k+1,j,ispe) )
  910. ENDDO
  911. qf2 = 1.
  912. qf1 = qtot*qf2
  913. p(i,k,j) = p(i,k+1,j) - (mu(i,j) + qf1*muts(i,j))/qf2/rdn(k+1)
  914. qvf = 1.+rvovrd*moist(i,k,j,P_QV)
  915. al(i,k,j) = (r_d/p1000mb)*(t(i,k,j)+t0)*qvf* &
  916. (((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm) - alb(i,k,j)
  917. ENDDO
  918. ENDDO
  919. ENDDO
  920. ELSE
  921. DO j=jts,jtf
  922. k=ktf ! top layer
  923. DO i=its,itf
  924. qtot = 0.
  925. qf2 = 1.
  926. qf1 = qtot*qf2
  927. p(i,k,j) = - 0.5*(mu(i,j)+qf1*muts(i,j))/rdnw(k)/qf2
  928. qvf = 1.
  929. al(i,k,j) = (r_d/p1000mb)*(t(i,k,j)+t0)*qvf* &
  930. (((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm) - alb(i,k,j)
  931. ENDDO
  932. DO k=ktf-1,kts,-1 ! remaining layers, integrate down
  933. DO i=its,itf
  934. qtot = 0.
  935. qf2 = 1.
  936. qf1 = qtot*qf2
  937. p(i,k,j) = p(i,k+1,j) - (mu(i,j) + qf1*muts(i,j))/qf2/rdn(k+1)
  938. qvf = 1.
  939. al(i,k,j) = (r_d/p1000mb)*(t(i,k,j)+t0)*qvf* &
  940. (((p(i,k,j)+pb(i,k,j))/p1000mb)**cvpm) - alb(i,k,j)
  941. ENDDO
  942. ENDDO
  943. ENDDO
  944. END IF
  945. IF (hypsometric_opt == 1) THEN
  946. DO j=jts,jtf
  947. DO k=2,ktf+1 ! integrate hydrostatic equation for geopotential
  948. DO i=its,itf
  949. ph(i,k,j) = ph(i,k-1,j) - (dnw(k-1))*( &
  950. (muts(i,j))*al(i,k-1,j)+ &
  951. mu(i,j)*alb(i,k-1,j) )
  952. ENDDO
  953. ENDDO
  954. ENDDO
  955. ELSE
  956. ! Revised hypsometric eq.: dZ=-al*p*dLOG(p), where p is dry pressure
  957. DO j=jts,jtf
  958. DO i=its,itf
  959. ph(i,kts,j) = phb(i,kts,j)
  960. END DO
  961. DO k=kts+1,ktf+1
  962. DO i=its,itf
  963. pfu = muts(i,j)*znw(k) +ptop
  964. pfd = muts(i,j)*znw(k-1)+ptop
  965. phm = muts(i,j)*znu(k-1)+ptop
  966. ph(i,k,j) = ph(i,k-1,j) + (al(i,k-1,j)+alb(i,k-1,j))*phm*LOG(pfd/pfu)
  967. ENDDO
  968. ENDDO
  969. DO k=kts,ktf+1
  970. DO i=its,itf
  971. ph(i,k,j) = ph(i,k,j) - phb(i,k,j)
  972. END DO
  973. END DO
  974. END DO
  975. END IF
  976. END IF
  977. END SUBROUTINE calc_p_rho_phi
  978. !----------------------------------------------------------------------
  979. SUBROUTINE calc_php ( php, ph, phb, &
  980. ids, ide, jds, jde, kds, kde, &
  981. ims, ime, jms, jme, kms, kme, &
  982. its, ite, jts, jte, kts, kte )
  983. IMPLICIT NONE
  984. ! Input data
  985. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  986. ims, ime, jms, jme, kms, kme, &
  987. its, ite, jts, jte, kts, kte
  988. REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT(IN ) :: phb, ph
  989. REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT( OUT) :: php
  990. ! Local stuff
  991. INTEGER :: i, j, k, itf, jtf, ktf
  992. !<DESCRIPTION>
  993. !
  994. ! calc_php calculates the full geopotential from the reference state
  995. ! geopotential and the perturbation geopotential (phb_ph).
  996. !
  997. !</DESCRIPTION>
  998. itf=MIN(ite,ide-1)
  999. jtf=MIN(jte,jde-1)
  1000. ktf=MIN(kte,kde-1)
  1001. DO j=jts,jtf
  1002. DO k=kts,ktf
  1003. DO i=its,itf
  1004. php(i,k,j) = 0.5*(phb(i,k,j)+phb(i,k+1,j)+ph(i,k,j)+ph(i,k+1,j))
  1005. ENDDO
  1006. ENDDO
  1007. ENDDO
  1008. END SUBROUTINE calc_php
  1009. !-------------------------------------------------------------------------------
  1010. SUBROUTINE diagnose_w( ph_tend, ph_new, ph_old, w, mu, dt, &
  1011. u, v, ht, &
  1012. cf1, cf2, cf3, rdx, rdy, &
  1013. msftx, msfty, &
  1014. ids, ide, jds, jde, kds, kde, &
  1015. ims, ime, jms, jme, kms, kme, &
  1016. its, ite, jts, jte, kts, kte )
  1017. IMPLICIT NONE
  1018. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  1019. ims, ime, jms, jme, kms, kme, &
  1020. its, ite, jts, jte, kts, kte
  1021. REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT(IN ) :: ph_tend, &
  1022. ph_new, &
  1023. ph_old, &
  1024. u, &
  1025. v
  1026. REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT( OUT) :: w
  1027. REAL, DIMENSION( ims:ime, jms:jme ), INTENT(IN ) :: mu, ht, msftx, msfty
  1028. REAL, INTENT(IN ) :: dt, cf1, cf2, cf3, rdx, rdy
  1029. INTEGER :: i, j, k, itf, jtf
  1030. itf=MIN(ite,ide-1)
  1031. jtf=MIN(jte,jde-1)
  1032. !<DESCRIPTION>
  1033. !
  1034. ! diagnose_w diagnoses the vertical velocity from the geopoential equation.
  1035. ! Used with the hydrostatic option.
  1036. !
  1037. !</DESCRIPTION>
  1038. DO j = jts, jtf
  1039. ! lower b.c. on w
  1040. ! Notes on map scale factors:
  1041. ! Chain rule: if Z=Z(X,Y) [true at the surface] then
  1042. ! dZ/dt = dZ/dX * dX/dt + dZ/dY * dY/dt, U=dX/dt, V=dY/dt
  1043. ! Using capitals to denote actual values
  1044. ! In mapped values, u=U, v=V, z=Z, 1/dX=mx/dx, 1/dY=my/dy
  1045. ! => w = dz/dt = mx u dz/dx + my v dz/dy
  1046. ! [where dz/dx is just the surface height change between x
  1047. ! gridpoints, and dz/dy is the change between y gridpoints]
  1048. ! [NB: cf1, cf2 and cf3 do vertical weighting of u or v values
  1049. ! nearest the surface]
  1050. ! Previously msft multiplied by rdy and rdx terms.
  1051. ! Now msfty multiplies rdy term, and msftx multiplies msftx term
  1052. DO i = its, itf
  1053. w(i,1,j)= msfty(i,j)*.5*rdy*( &
  1054. (ht(i,j+1)-ht(i,j )) &
  1055. *(cf1*v(i,1,j+1)+cf2*v(i,2,j+1)+cf3*v(i,3,j+1)) &
  1056. +(ht(i,j )-ht(i,j-1)) &
  1057. *(cf1*v(i,1,j )+cf2*v(i,2,j )+cf3*v(i,3,j )) ) &
  1058. +msftx(i,j)*.5*rdx*( &
  1059. (ht(i+1,j)-ht(i,j )) &
  1060. *(cf1*u(i+1,1,j)+cf2*u(i+1,2,j)+cf3*u(i+1,3,j)) &
  1061. +(ht(i,j )-ht(i-1,j)) &
  1062. *(cf1*u(i ,1,j)+cf2*u(i ,2,j)+cf3*u(i ,3,j)) )
  1063. ENDDO
  1064. ! use geopotential equation to diagnose w
  1065. ! Further notes on map scale factors
  1066. ! If ph_tend contains: -mx partial d/dx(mu rho u/my)
  1067. ! -mx partial d/dy(phi mu v/mx)
  1068. ! -partial d/dz(phi mu w/my)
  1069. ! then phi eqn is: partial d/dt(mu phi/my) = ph_tend + mu g w/my
  1070. ! => w = [my/(mu*g)]*[partial d/dt(mu phi/my) - ph_tend]
  1071. DO k = 2, kte
  1072. DO i = its, itf
  1073. w(i,k,j) = msfty(i,j)*( (ph_new(i,k,j)-ph_old(i,k,j))/dt &
  1074. - ph_tend(i,k,j)/mu(i,j) )/g
  1075. ENDDO
  1076. ENDDO
  1077. ENDDO
  1078. END SUBROUTINE diagnose_w
  1079. !-------------------------------------------------------------------------------
  1080. SUBROUTINE rhs_ph( ph_tend, u, v, ww, &
  1081. ph, ph_old, phb, w, &
  1082. mut, muu, muv, &
  1083. fnm, fnp, &
  1084. rdnw, cfn, cfn1, rdx, rdy, &
  1085. msfux, msfuy, msfvx, &
  1086. msfvx_inv, msfvy, &
  1087. msftx, msfty, &
  1088. non_hydrostatic, &
  1089. config_flags, &
  1090. ids, ide, jds, jde, kds, kde, &
  1091. ims, ime, jms, jme, kms, kme, &
  1092. its, ite, jts, jte, kts, kte )
  1093. IMPLICIT NONE
  1094. TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
  1095. INTEGER , INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
  1096. ims, ime, jms, jme, kms, kme, &
  1097. its, ite, jts, jte, kts, kte
  1098. REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT(IN ) :: &
  1099. u, &
  1100. v, &
  1101. ww, &
  1102. ph, &
  1103. ph_old, &
  1104. phb, &
  1105. w
  1106. REAL, DIMENSION( ims:ime, kms:kme , jms:jme ), INTENT(INOUT) :: ph_tend
  1107. REAL, DIMENSION( ims:ime, jms:jme ), INTENT(IN ) :: muu, muv, mut, &
  1108. msfux, msfuy, &
  1109. msfvx, msfvy, &
  1110. msftx, msfty, &
  1111. msfvx_inv
  1112. REAL, DIMENSION( kms:kme ), INTENT(IN ) :: rdnw, fnm, fnp
  1113. REAL, INTENT(IN ) :: cfn, cfn1, rdx, rdy
  1114. LOGICAL, INTENT(IN ) :: non_hydrostatic
  1115. ! Local stuff
  1116. INTEGER :: i, j, k, itf, jtf, ktf, kz, i_start, j_start
  1117. REAL :: ur, ul, ub, vr, vl, vb
  1118. REAL, DIMENSION(its:ite,kts:kte) :: wdwn
  1119. INTEGER :: advective_order
  1120. LOGICAL :: specified
  1121. !<DESCRIPTION>
  1122. !
  1123. ! rhs_ph calculates the large-timestep tendency terms for the geopotential
  1124. ! equation. These terms include the advection and "gw". The geopotential
  1125. ! equation is cast in advective form, so we don't use the flux form advection
  1126. ! algorithms here.
  1127. !
  1128. !</DESCRIPTION>
  1129. specified = .false.
  1130. if(config_flags%specified .or. config_flags%nested) specified = .true.
  1131. advective_order = config_flags%h_sca_adv_order
  1132. itf=MIN(ite,ide-1)
  1133. jtf=MIN(jte,jde-1)
  1134. ktf=MIN(kte,kde-1)
  1135. ! Notes on map scale factors (WCS, 2 march 2008)
  1136. ! phi equation is: mu/my d/dt(phi) = -(1/my) mx mu u d/dx(phi)
  1137. ! -(1/my) my mu v d/dy(phi)
  1138. ! - omega d/d_eta(phi)
  1139. ! +mu g w/my
  1140. !
  1141. ! A little further explanation...
  1142. ! The tendency term we are computing here is for mu/my d/dt(phi). It is advective form
  1143. ! but it is multiplied be mu/my. It will be decoupled from (mu/my) when the implicit w-phi
  1144. ! solution is computed in subourine advance_w. The formulation dates from the early
  1145. ! days of the mass coordinate model when we were testing both a flux and an advective formulation
  1146. ! for the geopotential equation and different forms of the vertical momentum equation and the
  1147. ! vertically implicit solver.
  1148. ! advective form for the geopotential equation
  1149. DO j = jts, jtf
  1150. DO k = 2, kte
  1151. DO i = its, itf
  1152. wdwn(i,k) = .5*(ww(i,k,j)+ww(i,k-1,j))*rdnw(k-1) &
  1153. *(ph(i,k,j)-ph(i,k-1,j)+phb(i,k,j)-phb(i,k-1,j))
  1154. ENDDO
  1155. ENDDO
  1156. ! RHS term 3 is: - omega partial d/dnu(phi)
  1157. DO k = 2, kte-1
  1158. DO i = its, itf
  1159. ph_tend(i,k,j) = ph_tend(i,k,j) &
  1160. - (fnm(k)*wdwn(i,k+1)+fnp(k)*wdwn(i,k))
  1161. ENDDO
  1162. ENDDO
  1163. ENDDO
  1164. IF (non_hydrostatic) THEN ! add in "gw" term.
  1165. DO j = jts, jtf ! in hydrostatic mode, "gw" will be diagnosed
  1166. ! after the timestep to give us "w"
  1167. DO i = its, itf
  1168. ph_tend(i,kde,j) = 0.
  1169. ENDDO
  1170. DO k = 2, kte
  1171. DO i = its, itf
  1172. ! phi equation RHS term 4
  1173. ph_tend(i,k,j) = ph_tend(i,k,j) + mut(i,j)*g*w(i,k,j)/msfty(i,j)
  1174. ENDDO
  1175. ENDDO
  1176. ENDDO
  1177. END IF
  1178. ! Notes on map scale factors:
  1179. ! RHS terms 1 and 2 are: -(1/my) mx u mu partial d/dx(phi)
  1180. ! -(1/my) my v mu partial d/dy(phi)
  1181. IF (advective_order <= 2) THEN
  1182. ! y (v) advection
  1183. i_start = its
  1184. j_start = jts
  1185. itf=MIN(ite,ide-1)
  1186. jtf=MIN(jte,jde-1)
  1187. IF ( (config_flags%open_ys .or. specified) .and. jts == jds ) j_start = jts+1
  1188. IF ( (config_flags%open_ye .or. specified) .and. jte == jde ) jtf = jtf-2
  1189. DO j = j_start, jtf
  1190. DO k = 2, kte-1
  1191. DO i = i_start, itf
  1192. ph_tend(i,k,j)=ph_tend(i,k,j) - (0.25*rdy/msfty(i,j))* &
  1193. ( muv(i,j+1)*(v(i,k,j+1)+v(i,k-1,j+1))*msfvy(i,j+1)* &
  1194. (phb(i,k,j+1)-phb(i,k,j )+ph(i,k,j+1)-ph(i,k,j )) &
  1195. +muv(i,j )*(v(i,k,j )+v(i,k-1,j ))*msfvy(i,j )* &
  1196. (phb(i,k,j )-phb(i,k,j-1)+ph(i,k,j )-ph(i,k,j-1)) )
  1197. ENDDO
  1198. ENDDO
  1199. k = kte
  1200. DO i = i_start, itf
  1201. ph_tend(i,k,j)=ph_tend(i,k,j) - (0.5*rdy/msfty(i,j))* &
  1202. ( muv(i,j+1)*(cfn*v(i,k-1,j+1)+cfn1*v(i,k-2,j+1))*msfvy(i,j+1)* &
  1203. (phb(i,k,j+1)-phb(i,k,j )+ph(i,k,j+1)-ph(i,k,j )) &
  1204. +muv(i,j )*(cfn*v(i,k-1,j )+cfn1*v(i,k-2,j ))*msfvy(i,j )* &
  1205. (phb(i,k,j )-phb(i,k,j-1)+ph(i,k,j )-ph(i,k,j-1)) )
  1206. ENDDO
  1207. ENDDO
  1208. ! x (u) advection
  1209. i_start = its
  1210. j_start = jts
  1211. itf=MIN(ite,ide-1)
  1212. jtf=MIN(jte,jde-1)
  1213. IF ( (config_flags%open_xs .or. specified) .and. its == ids ) i_start = its+1
  1214. IF ( (config_flags%open_xe .or. specified) .and. ite == ide ) itf = itf-2
  1215. DO j = j_start, jtf
  1216. DO k = 2, kte-1
  1217. DO i = i_start, itf
  1218. ph_tend(i,k,j)=ph_tend(i,k,j) - (0.25*rdx/msfty(i,j))* &
  1219. ( muu(i+1,j)*(u(i+1,k,j)+u(i+1,k-1,j))*msfux(i+1,j)* &
  1220. (phb(i+1,k,j)-phb(i ,k,j)+ph(i+1,k,j)-ph(i ,k,j)) &
  1221. +muu(i ,j)*(u(i ,k,j)+u(i ,k-1,j))*msfux(i ,j)* &
  1222. (phb(i ,k,j)-phb(i-1,k,j)+ph(i ,k,j)-ph(i-1,k,j)) )
  1223. ENDDO
  1224. ENDDO
  1225. k = kte
  1226. DO i = i_start, itf
  1227. ph_tend(i,k,j)=ph_tend(i,k,j) - (0.5*rdx/msfty(i,j))* &
  1228. ( muu(i+1,j)*(cfn*u(i+1,k-1,j)+cfn1*u(i+1,k-2,j))*msfux(i+1,j)* &
  1229. (phb(i+1,k,j)-phb(i ,k,j)+ph(i+1,k,j)-ph(i ,k,j)) &
  1230. +muu(i ,j)*(cfn*u(i ,k-1,j)+cfn1*u(i ,k-2,j))*msfux( i,j)* &
  1231. (phb(i ,k,j)-phb(i-1,k,j)+ph(i ,k,j)-ph(i-1,k,j)) )
  1232. ENDDO
  1233. ENDDO
  1234. ELSE IF (advective_order <= 4) THEN
  1235. ! y (v) advection
  1236. i_start = its
  1237. j_start = jts
  1238. itf=MIN(ite,ide-1)
  1239. jtf=MIN(jte,jde-1)
  1240. IF ( (config_flags%open_ys .or. specified) .and. jts == jds ) j_start = jts+2
  1241. IF ( (config_flags%open_ye .or. specified) .and. jte == jde ) jtf = jtf-3
  1242. DO j = j_start, jtf
  1243. DO k = 2, kte-1
  1244. DO i = i_start, itf
  1245. ph_tend(i,k,j)=ph_tend(i,k,j) - (0.25*rdy/msfty(i,j))*( &
  1246. ( muv(i,j+1)*(v(i,k,j+1)+v(i,k-1,j+1))*msfvy(i,j+1) &
  1247. +muv(i,j )*(v(i,k,j )+v(i,k-1,j ))*msfvy(i,j ))* (1./12.)*( &
  1248. 8.*(ph(i,k,j+1)-ph(i,k,j-1)) &
  1249. -(ph(i,k,j+2)-ph(i,k,j-2)) &
  1250. +8.*(phb(i,k,j+1)-phb(i,k,j-1)) &
  1251. -(phb(i,k,j+2)-phb(i,k,j-2)) ) )
  1252. ENDDO
  1253. ENDDO
  1254. k = kte
  1255. DO i = i_start, itf
  1256. ph_tend(i,k,j)=ph_tend(i,k,j) - (0.5*rdy/msfty(i,j))*( &
  1257. ( muv(i,j+1)*(cfn*v(i,k-1,j+1)+cfn1*v(i,k-2,j+1))*msfvy(i,j+1) &
  1258. +muv(i,j )*(cfn*v(i,k-1,j )+cfn1*v(i,k-2,j ))*msfvy(i,j ))* (1./12.)*( &
  1259. 8.*(ph(i,k,j+1)-ph(i,k,j-1)) &
  1260. -(ph(i,k,j+2)-ph(i,k,j-2)) &
  1261. +8.*(phb(i,k,j+1)-phb(i,k,j-1)) &
  1262. -(phb(i,k,j+2)-phb(i,k,j-2)) ) )
  1263. ENDDO
  1264. ENDDO
  1265. ! pick up near boundary rows using 2nd order stencil for open and specified conditions
  1266. IF ( (config_flags%open_ys .or. specified) .and. jts <= jds+1 ) THEN
  1267. j = jds+1
  1268. DO k = 2, kte-1
  1269. DO i = i_start, itf
  1270. ph_tend(i,k,j)=ph_tend(i,k,j) - (0.25*rdy/msfty(i,j))* &
  1271. ( muv(i,j+1)*(v(i,k,j+1)+v(i,k-1,j+1))*msfvy(i,j+1)* &
  1272. (phb(i,k,j+1)-phb(i,k,j )+ph(i,k,j+1)-ph(i,k,j )) &
  1273. +muv(i,j )*(v(i,k,j )+v(i,k-1,j ))*msfvy(i,j )* &
  1274. (phb(i,k,j )-phb(i,k,j-1)+ph(i,k,j )-ph(i,k,j-1)) )
  1275. ENDDO
  1276. ENDDO
  1277. k = kte
  1278. DO i = i_start, itf
  1279. ph_tend(i,k,j)=ph_tend(i,k,j) - (0.5*rdy/msfty(i,j))* &
  1280. ( muv(i,j+1)*(cfn*v(i,k-1,j+1)+cfn1*v(i,k-2,j+1))*msfvy(i,j+1)* &
  1281. (phb(i,k,j+1)-phb(i,k,j )+ph(i,k,j+1)-ph(i,k,j )) &
  1282. +muv(i,j )*(cfn*v(i,k-1,j )+cfn1*v(i,k-2,j ))*msfvy(i,j )* &
  1283. (phb(i,k,j )-phb(i,k,j-1)+ph(i,k,j )-ph(i,k,j-1)) )
  1284. ENDDO
  1285. END IF
  1286. IF ( (config_fla

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