PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/wrfv2_fire/dyn_em/module_small_step_em.F

https://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 1772 lines | 1148 code | 325 blank | 299 comment | 13 complexity | d599c6f45b76074d79b180a438c884fd 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. ! SMALL_STEP code for the geometric height coordinate model
  4. !
  5. !---------------------------------------------------------------------------
  6. MODULE module_small_step_em
  7. USE module_configure
  8. USE module_model_constants
  9. CONTAINS
  10. !----------------------------------------------------------------------
  11. SUBROUTINE small_step_prep( u_1, u_2, v_1, v_2, w_1, w_2, &
  12. t_1, t_2, ph_1, ph_2, &
  13. mub, mu_1, mu_2, &
  14. muu, muus, muv, muvs, &
  15. mut, muts, mudf, &
  16. u_save, v_save, w_save, &
  17. t_save, ph_save, mu_save, &
  18. ww, ww_save, &
  19. dnw, c2a, pb, p, alt, &
  20. msfux, msfuy, msfvx, &
  21. msfvx_inv, &
  22. msfvy, msftx, msfty, &
  23. rdx, rdy, &
  24. rk_step, &
  25. ids,ide, jds,jde, kds,kde, &
  26. ims,ime, jms,jme, kms,kme, &
  27. its,ite, jts,jte, kts,kte )
  28. IMPLICIT NONE ! religion first
  29. ! declarations for the stuff coming in
  30. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  31. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  32. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  33. INTEGER, INTENT(IN ) :: rk_step
  34. REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: u_1, &
  35. v_1, &
  36. w_1, &
  37. t_1, &
  38. ph_1
  39. REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT( OUT) :: u_save, &
  40. v_save, &
  41. w_save, &
  42. t_save, &
  43. ph_save
  44. REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: u_2, &
  45. v_2, &
  46. w_2, &
  47. t_2, &
  48. ph_2
  49. REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT( OUT) :: c2a, &
  50. ww_save
  51. REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: pb, &
  52. p, &
  53. alt, &
  54. ww
  55. REAL, DIMENSION(ims:ime, jms:jme) , INTENT(INOUT) :: mu_1,mu_2
  56. REAL, DIMENSION(ims:ime, jms:jme) , INTENT(IN ) :: mub, &
  57. muu, &
  58. muv, &
  59. mut, &
  60. msfux,&
  61. msfuy,&
  62. msfvx,&
  63. msfvx_inv,&
  64. msfvy,&
  65. msftx,&
  66. msfty
  67. REAL, DIMENSION(ims:ime, jms:jme) , INTENT( OUT) :: muus, &
  68. muvs, &
  69. muts, &
  70. mudf
  71. REAL, DIMENSION(ims:ime, jms:jme) , INTENT( OUT) :: mu_save
  72. REAL, DIMENSION(kms:kme, jms:jme) , INTENT(IN ) :: dnw
  73. REAL, INTENT(IN) :: rdx,rdy
  74. ! local variables
  75. INTEGER :: i, j, k
  76. INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end
  77. INTEGER :: i_endu, j_endv
  78. !<DESCRIPTION>
  79. !
  80. ! small_step_prep prepares the prognostic variables for the small timestep.
  81. ! This includes switching time-levels in the arrays and computing coupled
  82. ! perturbation variables for the small timestep
  83. ! (i.e. mu*u" = mu(t)*u(t)-mu(*)*u(*); mu*u" is advanced during the small
  84. ! timesteps
  85. !
  86. !</DESCRIPTION>
  87. i_start = its
  88. i_end = min(ite,ide-1)
  89. j_start = jts
  90. j_end = min(jte,jde-1)
  91. k_start = kts
  92. k_end = min(kte,kde-1)
  93. i_endu = ite
  94. j_endv = jte
  95. ! if this is the first RK step, reset *_1 to *_2
  96. ! (we are replacing the t-dt fields with the time t fields)
  97. IF ((rk_step == 1) ) THEN
  98. DO j=j_start, j_end
  99. DO i=i_start, i_end
  100. mu_1(i,j)=mu_2(i,j)
  101. ww_save(i,kde,j) = 0.
  102. ww_save(i,1,j) = 0.
  103. mudf(i,j) = 0. ! initialize external mode div damp to zero
  104. ENDDO
  105. ENDDO
  106. DO j=j_start, j_end
  107. DO k=k_start, k_end
  108. DO i=i_start, i_endu
  109. u_1(i,k,j) = u_2(i,k,j)
  110. ENDDO
  111. ENDDO
  112. ENDDO
  113. DO j=j_start, j_endv
  114. DO k=k_start, k_end
  115. DO i=i_start, i_end
  116. v_1(i,k,j) = v_2(i,k,j)
  117. ENDDO
  118. ENDDO
  119. ENDDO
  120. DO j=j_start, j_end
  121. DO k=k_start, k_end
  122. DO i=i_start, i_end
  123. t_1(i,k,j) = t_2(i,k,j)
  124. ENDDO
  125. ENDDO
  126. ENDDO
  127. DO j=j_start, j_end
  128. DO k=k_start, min(kde,kte)
  129. DO i=i_start, i_end
  130. w_1(i,k,j) = w_2(i,k,j)
  131. ph_1(i,k,j) = ph_2(i,k,j)
  132. ENDDO
  133. ENDDO
  134. ENDDO
  135. DO j=j_start, j_end
  136. DO i=i_start, i_end
  137. muts(i,j)=mub(i,j)+mu_2(i,j)
  138. ENDDO
  139. DO i=i_start, i_endu
  140. ! rk_step==1, WCS fix for tiling
  141. ! muus(i,j)=0.5*(mub(i,j)+mu_2(i,j)+mub(i-1,j)+mu_2(i-1,j))
  142. muus(i,j) = muu(i,j)
  143. ENDDO
  144. ENDDO
  145. DO j=j_start, j_endv
  146. DO i=i_start, i_end
  147. ! rk_step==1, WCS fix for tiling
  148. ! muvs(i,j)=0.5*(mub(i,j)+mu_2(i,j)+mub(i,j-1)+mu_2(i,j-1))
  149. muvs(i,j) = muv(i,j)
  150. ENDDO
  151. ENDDO
  152. DO j=j_start, j_end
  153. DO i=i_start, i_end
  154. mu_save(i,j)=mu_2(i,j)
  155. mu_2(i,j)=0.
  156. ! mu_2(i,j)=mu_2(i,j)-mu_2(i,j)
  157. ENDDO
  158. ENDDO
  159. ELSE
  160. DO j=j_start, j_end
  161. DO i=i_start, i_end
  162. muts(i,j)=mub(i,j)+mu_1(i,j)
  163. ENDDO
  164. DO i=i_start, i_endu
  165. muus(i,j)=0.5*(mub(i,j)+mu_1(i,j)+mub(i-1,j)+mu_1(i-1,j))
  166. ENDDO
  167. ENDDO
  168. DO j=j_start, j_endv
  169. DO i=i_start, i_end
  170. muvs(i,j)=0.5*(mub(i,j)+mu_1(i,j)+mub(i,j-1)+mu_1(i,j-1))
  171. ENDDO
  172. ENDDO
  173. DO j=j_start, j_end
  174. DO i=i_start, i_end
  175. mu_save(i,j)=mu_2(i,j)
  176. mu_2(i,j)=mu_1(i,j)-mu_2(i,j)
  177. ENDDO
  178. ENDDO
  179. END IF
  180. ! set up the small timestep variables
  181. DO j=j_start, j_end
  182. DO i=i_start, i_end
  183. ww_save(i,kde,j) = 0.
  184. ww_save(i,1,j) = 0.
  185. ENDDO
  186. ENDDO
  187. DO j=j_start, j_end
  188. DO k=k_start, k_end
  189. DO i=i_start, i_end
  190. c2a(i,k,j) = cpovcv*(pb(i,k,j)+p(i,k,j))/alt(i,k,j)
  191. ENDDO
  192. ENDDO
  193. ENDDO
  194. DO j=j_start, j_end
  195. DO k=k_start, k_end
  196. DO i=i_start, i_endu
  197. u_save(i,k,j) = u_2(i,k,j)
  198. ! u coupled with my
  199. u_2(i,k,j) = (muus(i,j)*u_1(i,k,j)-muu(i,j)*u_2(i,k,j))/msfuy(i,j)
  200. ENDDO
  201. ENDDO
  202. ENDDO
  203. DO j=j_start, j_endv
  204. DO k=k_start, k_end
  205. DO i=i_start, i_end
  206. v_save(i,k,j) = v_2(i,k,j)
  207. ! v coupled with mx
  208. ! v_2(i,k,j) = (muvs(i,j)*v_1(i,k,j)-muv(i,j)*v_2(i,k,j))/msfvx(i,j)
  209. v_2(i,k,j) = (muvs(i,j)*v_1(i,k,j)-muv(i,j)*v_2(i,k,j))*msfvx_inv(i,j)
  210. ENDDO
  211. ENDDO
  212. ENDDO
  213. DO j=j_start, j_end
  214. DO k=k_start, k_end
  215. DO i=i_start, i_end
  216. t_save(i,k,j) = t_2(i,k,j)
  217. t_2(i,k,j) = muts(i,j)*t_1(i,k,j)-mut(i,j)*t_2(i,k,j)
  218. ENDDO
  219. ENDDO
  220. ENDDO
  221. DO j=j_start, j_end
  222. ! DO k=k_start, min(kde,kte)
  223. DO k=k_start, kde
  224. DO i=i_start, i_end
  225. w_save(i,k,j) = w_2(i,k,j)
  226. ! w coupled with my
  227. w_2(i,k,j) = (muts(i,j)* w_1(i,k,j)-mut(i,j)* w_2(i,k,j))/msfty(i,j)
  228. ph_save(i,k,j) = ph_2(i,k,j)
  229. ph_2(i,k,j) = ph_1(i,k,j)-ph_2(i,k,j)
  230. ENDDO
  231. ENDDO
  232. ENDDO
  233. DO j=j_start, j_end
  234. ! DO k=k_start, min(kde,kte)
  235. DO k=k_start, kde
  236. DO i=i_start, i_end
  237. ww_save(i,k,j) = ww(i,k,j)
  238. ENDDO
  239. ENDDO
  240. ENDDO
  241. END SUBROUTINE small_step_prep
  242. !-------------------------------------------------------------------------
  243. SUBROUTINE small_step_finish( u_2, u_1, v_2, v_1, w_2, w_1, &
  244. t_2, t_1, ph_2, ph_1, ww, ww1, &
  245. mu_2, mu_1, &
  246. mut, muts, muu, muus, muv, muvs, &
  247. u_save, v_save, w_save, &
  248. t_save, ph_save, mu_save, &
  249. msfux, msfuy, msfvx, msfvy, &
  250. msftx, msfty, &
  251. h_diabatic, &
  252. number_of_small_timesteps,dts, &
  253. rk_step, rk_order, &
  254. ids,ide, jds,jde, kds,kde, &
  255. ims,ime, jms,jme, kms,kme, &
  256. its,ite, jts,jte, kts,kte )
  257. IMPLICIT NONE ! religion first
  258. ! stuff passed in
  259. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  260. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  261. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  262. INTEGER, INTENT(IN ) :: number_of_small_timesteps
  263. INTEGER, INTENT(IN ) :: rk_step, rk_order
  264. REAL, INTENT(IN ) :: dts
  265. REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: u_1, &
  266. v_1, &
  267. w_1, &
  268. t_1, &
  269. ww1, &
  270. ph_1
  271. REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(INOUT) :: u_2, &
  272. v_2, &
  273. w_2, &
  274. t_2, &
  275. ww, &
  276. ph_2
  277. REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(IN ) :: u_save, &
  278. v_save, &
  279. w_save, &
  280. t_save, &
  281. ph_save, &
  282. h_diabatic
  283. REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: muus, muvs
  284. REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: mu_2, mu_1
  285. REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: mut, muts, &
  286. muu, muv, mu_save
  287. REAL, DIMENSION(ims:ime, jms:jme), INTENT(IN ) :: msfux, msfuy, &
  288. msfvx, msfvy, &
  289. msftx, msfty
  290. ! local stuff
  291. INTEGER :: i,j,k
  292. INTEGER :: i_start, i_end, j_start, j_end, i_endu, j_endv
  293. !<DESCRIPTION>
  294. !
  295. ! small_step_finish reconstructs the full uncoupled prognostic variables
  296. ! from the coupled perturbation variables used in the small timesteps.
  297. !
  298. !</DESCRIPTION>
  299. i_start = its
  300. i_end = min(ite,ide-1)
  301. j_start = jts
  302. j_end = min(jte,jde-1)
  303. i_endu = ite
  304. j_endv = jte
  305. ! addition of time level t back into variables
  306. DO j = j_start, j_endv
  307. DO k = kds, kde-1
  308. DO i = i_start, i_end
  309. ! v coupled with mx
  310. v_2(i,k,j) = (msfvx(i,j)*v_2(i,k,j) + v_save(i,k,j)*muv(i,j))/muvs(i,j)
  311. ENDDO
  312. ENDDO
  313. ENDDO
  314. DO j = j_start, j_end
  315. DO k = kds, kde-1
  316. DO i = i_start, i_endu
  317. ! u coupled with my
  318. u_2(i,k,j) = (msfuy(i,j)*u_2(i,k,j) + u_save(i,k,j)*muu(i,j))/muus(i,j)
  319. ENDDO
  320. ENDDO
  321. ENDDO
  322. DO j = j_start, j_end
  323. DO k = kds, kde
  324. DO i = i_start, i_end
  325. ! w coupled with my
  326. w_2(i,k,j) = (msfty(i,j)*w_2(i,k,j) + w_save(i,k,j)*mut(i,j))/muts(i,j)
  327. ph_2(i,k,j) = ph_2(i,k,j) + ph_save(i,k,j)
  328. ww(i,k,j) = ww(i,k,j) + ww1(i,k,j)
  329. ENDDO
  330. ENDDO
  331. ENDDO
  332. #ifdef REVERT
  333. DO j = j_start, j_end
  334. DO k = kds, kde-1
  335. DO i = i_start, i_end
  336. t_2(i,k,j) = (t_2(i,k,j) + t_save(i,k,j)*mut(i,j))/muts(i,j)
  337. ENDDO
  338. ENDDO
  339. ENDDO
  340. #else
  341. IF ( rk_step < rk_order ) THEN
  342. DO j = j_start, j_end
  343. DO k = kds, kde-1
  344. DO i = i_start, i_end
  345. t_2(i,k,j) = (t_2(i,k,j) + t_save(i,k,j)*mut(i,j))/muts(i,j)
  346. ENDDO
  347. ENDDO
  348. ENDDO
  349. ELSE
  350. DO j = j_start, j_end
  351. DO k = kds, kde-1
  352. DO i = i_start, i_end
  353. t_2(i,k,j) = (t_2(i,k,j) - dts*number_of_small_timesteps*mut(i,j)*h_diabatic(i,k,j) &
  354. + t_save(i,k,j)*mut(i,j))/muts(i,j)
  355. ENDDO
  356. ENDDO
  357. ENDDO
  358. ENDIF
  359. #endif
  360. DO j = j_start, j_end
  361. DO i = i_start, i_end
  362. mu_2(i,j) = mu_2(i,j) + mu_save(i,j)
  363. ENDDO
  364. ENDDO
  365. END SUBROUTINE small_step_finish
  366. !-----------------------------------------------------------------------
  367. SUBROUTINE calc_p_rho( al, p, ph, &
  368. alt, t_2, t_1, c2a, pm1, &
  369. mu, muts, znu, t0, &
  370. rdnw, dnw, smdiv, &
  371. non_hydrostatic, step, &
  372. ids, ide, jds, jde, kds, kde, &
  373. ims, ime, jms, jme, kms, kme, &
  374. its,ite, jts,jte, kts,kte )
  375. IMPLICIT NONE ! religion first
  376. ! declarations for the stuff coming in
  377. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  378. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  379. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  380. INTEGER, INTENT(IN ) :: step
  381. REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT( OUT) :: al, &
  382. p
  383. REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(IN ) :: alt, &
  384. t_2, &
  385. t_1, &
  386. c2a
  387. REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: ph, pm1
  388. REAL, DIMENSION(ims:ime, jms:jme) , INTENT(IN ) :: mu, &
  389. muts
  390. REAL, DIMENSION(kms:kme) , INTENT(IN ) :: dnw, &
  391. rdnw, &
  392. znu
  393. REAL, INTENT(IN ) :: t0, smdiv
  394. LOGICAL, INTENT(IN ) :: non_hydrostatic
  395. ! local variables
  396. INTEGER :: i, j, k
  397. INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end
  398. REAL :: ptmp
  399. !<DESCRIPTION>
  400. !
  401. ! For the nonhydrostatic option,
  402. ! calc_p_rho computes the perturbation inverse density and
  403. ! perturbation pressure from the hydrostatic relation and the
  404. ! linearized equation of state, respectively.
  405. !
  406. ! For the hydrostatic option,
  407. ! calc_p_rho computes the perturbation pressure, perturbation density,
  408. ! and perturbation geopotential
  409. ! from the vertical coordinate definition, linearized equation of state
  410. ! and the hydrostatic relation, respectively.
  411. !
  412. ! forward weighting of the pressure (divergence damping) is also
  413. ! computed here.
  414. !
  415. !</DESCRIPTION>
  416. i_start = its
  417. i_end = min(ite,ide-1)
  418. j_start = jts
  419. j_end = min(jte,jde-1)
  420. k_start = kts
  421. k_end = min(kte,kde-1)
  422. IF (non_hydrostatic) THEN
  423. DO j=j_start, j_end
  424. DO k=k_start, k_end
  425. DO i=i_start, i_end
  426. ! al computation is all dry, so ok with moisture
  427. al(i,k,j)=-1./muts(i,j)*(alt(i,k,j)*mu(i,j) &
  428. +rdnw(k)*(ph(i,k+1,j)-ph(i,k,j)))
  429. ! this is temporally linearized p, no moisture correction needed
  430. p(i,k,j)=c2a(i,k,j)*(alt(i,k,j)*(t_2(i,k,j)-mu(i,j)*t_1(i,k,j)) &
  431. /(muts(i,j)*(t0+t_1(i,k,j)))-al (i,k,j))
  432. ENDDO
  433. ENDDO
  434. ENDDO
  435. ELSE ! hydrostatic calculation
  436. DO j=j_start, j_end
  437. DO k=k_start, k_end
  438. DO i=i_start, i_end
  439. p(i,k,j)=mu(i,j)*znu(k)
  440. al(i,k,j)=alt(i,k,j)*(t_2(i,k,j)-mu(i,j)*t_1(i,k,j)) &
  441. /(muts(i,j)*(t0+t_1(i,k,j)))-p(i,k,j)/c2a(i,k,j)
  442. ph(i,k+1,j)=ph(i,k,j)-dnw(k)*(muts(i,j)*al (i,k,j) &
  443. +mu(i,j)*alt(i,k,j))
  444. ENDDO
  445. ENDDO
  446. ENDDO
  447. END IF
  448. ! divergence damping setup
  449. IF (step == 0) then ! we're initializing small timesteps
  450. DO j=j_start, j_end
  451. DO k=k_start, k_end
  452. DO i=i_start, i_end
  453. pm1(i,k,j)=p(i,k,j)
  454. ENDDO
  455. ENDDO
  456. ENDDO
  457. ELSE ! we're in the small timesteps
  458. DO j=j_start, j_end ! and adding div damping component
  459. DO k=k_start, k_end
  460. DO i=i_start, i_end
  461. ptmp = p(i,k,j)
  462. p(i,k,j) = p(i,k,j) + smdiv*(p(i,k,j)-pm1(i,k,j))
  463. pm1(i,k,j) = ptmp
  464. ENDDO
  465. ENDDO
  466. ENDDO
  467. END IF
  468. END SUBROUTINE calc_p_rho
  469. !----------------------------------------------------------------------
  470. SUBROUTINE calc_coef_w( a,alpha,gamma, &
  471. mut, cqw, &
  472. rdn, rdnw, c2a, &
  473. dts, g, epssm, top_lid, &
  474. ids,ide, jds,jde, kds,kde, & ! domain dims
  475. ims,ime, jms,jme, kms,kme, & ! memory dims
  476. its,ite, jts,jte, kts,kte ) ! tile dims
  477. IMPLICIT NONE ! religion first
  478. ! passed in through the call
  479. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  480. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  481. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  482. LOGICAL, INTENT(IN ) :: top_lid
  483. REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: c2a, &
  484. cqw
  485. REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(INOUT) :: alpha, &
  486. gamma, &
  487. a
  488. REAL, DIMENSION(ims:ime, jms:jme), INTENT(IN ) :: mut
  489. REAL, DIMENSION(kms:kme), INTENT(IN ) :: rdn, &
  490. rdnw
  491. REAL, INTENT(IN ) :: epssm, &
  492. dts, &
  493. g
  494. ! Local stack data.
  495. REAL, DIMENSION(ims:ime) :: cof
  496. REAL :: b, c
  497. INTEGER :: i, j, k, i_start, i_end, j_start, j_end, k_start, k_end
  498. INTEGER :: ij, ijp, ijm, lid_flag
  499. !<DESCRIPTION>
  500. !
  501. ! calc_coef_w calculates the coefficients needed for the
  502. ! implicit solution of the vertical momentum and geopotential equations.
  503. ! This requires solution of a tri-diagonal equation.
  504. !
  505. !</DESCRIPTION>
  506. i_start = its
  507. i_end = min(ite,ide-1)
  508. j_start = jts
  509. j_end = min(jte,jde-1)
  510. k_start = kts
  511. k_end = kte-1
  512. lid_flag=1
  513. IF(top_lid)lid_flag=0
  514. outer_j_loop: DO j = j_start, j_end
  515. DO i = i_start, i_end
  516. cof(i) = (.5*dts*g*(1.+epssm)/mut(i,j))**2
  517. a(i, 2 ,j) = 0.
  518. a(i,kde,j) =-2.*cof(i)*rdnw(kde-1)**2*c2a(i,kde-1,j)*lid_flag
  519. gamma(i,1 ,j) = 0.
  520. ENDDO
  521. DO k=3,kde-1
  522. DO i=i_start, i_end
  523. a(i,k,j) = -cqw(i,k,j)*cof(i)*rdn(k)* rdnw(k-1)*c2a(i,k-1,j)
  524. ENDDO
  525. ENDDO
  526. DO k=2,kde-1
  527. DO i=i_start, i_end
  528. b = 1.+cqw(i,k,j)*cof(i)*rdn(k)*(rdnw(k )*c2a(i,k,j ) &
  529. +rdnw(k-1)*c2a(i,k-1,j))
  530. c = -cqw(i,k,j)*cof(i)*rdn(k)*rdnw(k )*c2a(i,k,j )
  531. alpha(i,k,j) = 1./(b-a(i,k,j)*gamma(i,k-1,j))
  532. gamma(i,k,j) = c*alpha(i,k,j)
  533. ENDDO
  534. ENDDO
  535. DO i=i_start, i_end
  536. b = 1.+2.*cof(i)*rdnw(kde-1)**2*c2a(i,kde-1,j)
  537. c = 0.
  538. alpha(i,kde,j) = 1./(b-a(i,kde,j)*gamma(i,kde-1,j))
  539. gamma(i,kde,j) = c*alpha(i,kde,j)
  540. ENDDO
  541. ENDDO outer_j_loop
  542. END SUBROUTINE calc_coef_w
  543. !----------------------------------------------------------------------
  544. SUBROUTINE advance_uv ( u, ru_tend, v, rv_tend, &
  545. p, pb, &
  546. ph, php, alt, al, mu, &
  547. muu, cqu, muv, cqv, mudf, &
  548. msfux, msfuy, msfvx, &
  549. msfvx_inv, msfvy, &
  550. rdx, rdy, dts, &
  551. cf1, cf2, cf3, fnm, fnp, &
  552. emdiv, &
  553. rdnw, config_flags, spec_zone, &
  554. non_hydrostatic, top_lid, &
  555. ids, ide, jds, jde, kds, kde, &
  556. ims, ime, jms, jme, kms, kme, &
  557. its, ite, jts, jte, kts, kte )
  558. IMPLICIT NONE ! religion first
  559. ! stuff coming in
  560. TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
  561. LOGICAL, INTENT(IN ) :: non_hydrostatic, top_lid
  562. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  563. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  564. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  565. INTEGER, INTENT(IN ) :: spec_zone
  566. REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
  567. INTENT(INOUT) :: &
  568. u, &
  569. v
  570. REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
  571. INTENT(IN ) :: &
  572. ru_tend, &
  573. rv_tend, &
  574. ph, &
  575. php, &
  576. p, &
  577. pb, &
  578. alt, &
  579. al, &
  580. cqu, &
  581. cqv
  582. REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: muu, &
  583. muv, &
  584. mu, &
  585. mudf
  586. REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnm, &
  587. fnp , &
  588. rdnw
  589. REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: msfux, &
  590. msfuy, &
  591. msfvx, &
  592. msfvy, &
  593. msfvx_inv
  594. REAL, INTENT(IN ) :: rdx, &
  595. rdy, &
  596. dts, &
  597. cf1, &
  598. cf2, &
  599. cf3, &
  600. emdiv
  601. ! Local 3d array from the stack (note tile size)
  602. REAL, DIMENSION (its:ite, kts:kte) :: dpn, dpxy
  603. REAL, DIMENSION (its:ite) :: mudf_xy
  604. REAL :: dx, dy
  605. INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end
  606. INTEGER :: i_endu, j_endv, k_endw
  607. INTEGER :: i_start_up, i_end_up, j_start_up, j_end_up
  608. INTEGER :: i_start_vp, i_end_vp, j_start_vp, j_end_vp
  609. INTEGER :: i_start_u_tend, i_end_u_tend, j_start_v_tend, j_end_v_tend
  610. !<DESCRIPTION>
  611. !
  612. ! advance_uv advances the explicit perturbation horizontal momentum
  613. ! equations (u,v) by adding in the large-timestep tendency along with
  614. ! the small timestep pressure gradient tendency.
  615. !
  616. !</DESCRIPTION>
  617. ! now, the real work.
  618. ! set the loop bounds taking into account boundary conditions.
  619. IF( config_flags%nested .or. config_flags%specified ) THEN
  620. i_start = max( its,ids+spec_zone )
  621. i_end = min( ite,ide-spec_zone-1 )
  622. j_start = max( jts,jds+spec_zone )
  623. j_end = min( jte,jde-spec_zone-1 )
  624. k_start = kts
  625. k_end = min( kte, kde-1 )
  626. i_endu = min( ite,ide-spec_zone )
  627. j_endv = min( jte,jde-spec_zone )
  628. k_endw = k_end
  629. IF( config_flags%periodic_x) THEN
  630. i_start = its
  631. i_end = min(ite,ide-1)
  632. i_endu = ite
  633. ENDIF
  634. ELSE
  635. i_start = its
  636. i_end = min(ite,ide-1)
  637. j_start = jts
  638. j_end = min(jte,jde-1)
  639. k_start = kts
  640. k_end = kte-1
  641. i_endu = ite
  642. j_endv = jte
  643. k_endw = k_end
  644. ENDIF
  645. i_start_up = i_start
  646. i_end_up = i_endu
  647. j_start_up = j_start
  648. j_end_up = j_end
  649. i_start_vp = i_start
  650. i_end_vp = i_end
  651. j_start_vp = j_start
  652. j_end_vp = j_endv
  653. IF ( (config_flags%open_xs .or. &
  654. config_flags%symmetric_xs ) &
  655. .and. (its == ids) ) &
  656. i_start_up = i_start_up + 1
  657. IF ( (config_flags%open_xe .or. &
  658. config_flags%symmetric_xe ) &
  659. .and. (ite == ide) ) &
  660. i_end_up = i_end_up - 1
  661. IF ( (config_flags%open_ys .or. &
  662. config_flags%symmetric_ys .or. &
  663. config_flags%polar ) &
  664. .and. (jts == jds) ) &
  665. j_start_vp = j_start_vp + 1
  666. IF ( (config_flags%open_ye .or. &
  667. config_flags%symmetric_ye .or. &
  668. config_flags%polar ) &
  669. .and. (jte == jde) ) &
  670. j_end_vp = j_end_vp - 1
  671. i_start_u_tend = i_start
  672. i_end_u_tend = i_endu
  673. j_start_v_tend = j_start
  674. j_end_v_tend = j_endv
  675. IF ( config_flags%symmetric_xs .and. (its == ids) ) &
  676. i_start_u_tend = i_start_u_tend+1
  677. IF ( config_flags%symmetric_xe .and. (ite == ide) ) &
  678. i_end_u_tend = i_end_u_tend-1
  679. IF ( config_flags%symmetric_ys .and. (jts == jds) ) &
  680. j_start_v_tend = j_start_v_tend+1
  681. IF ( config_flags%symmetric_ye .and. (jte == jde) ) &
  682. j_end_v_tend = j_end_v_tend-1
  683. dx = 1./rdx
  684. dy = 1./rdy
  685. ! start real calculations.
  686. ! first, u
  687. u_outer_j_loop: DO j = j_start, j_end
  688. DO k = k_start, k_end
  689. DO i = i_start_u_tend, i_end_u_tend
  690. u(i,k,j) = u(i,k,j) + dts*ru_tend(i,k,j)
  691. ENDDO
  692. ENDDO
  693. DO i = i_start_up, i_end_up
  694. mudf_xy(i)= -emdiv*dx*(mudf(i,j)-mudf(i-1,j))/msfuy(i,j)
  695. ENDDO
  696. DO k = k_start, k_end
  697. DO i = i_start_up, i_end_up
  698. ! Comments on map scale factors:
  699. ! x pressure gradient: ADT eqn 44, penultimate term on RHS
  700. ! = -(mx/my)*(mu/rho)*partial dp/dx
  701. ! [i.e., first rho->mu; 2nd still rho; alpha=1/rho]
  702. ! Klemp et al. splits into 2 terms:
  703. ! mu alpha partial dp/dx + partial dp/dnu * partial dphi/dx
  704. ! then into 4 terms:
  705. ! mu alpha partial dp'/dx + nu mu alpha' partial dmubar/dx +
  706. ! + mu partial dphi/dx + partial dphi'/dx * (partial dp'/dnu - mu')
  707. !
  708. ! first 3 terms:
  709. ! ph, alt, p, al, pb not coupled
  710. ! since we want tendency to fit ADT eqn 44 (coupled) we need to
  711. ! multiply by (mx/my):
  712. !
  713. dpxy(i,k)= (msfux(i,j)/msfuy(i,j))*.5*rdx*muu(i,j)*( &
  714. ((ph (i,k+1,j)-ph (i-1,k+1,j))+(ph (i,k,j)-ph (i-1,k,j))) &
  715. +(alt(i,k ,j)+alt(i-1,k ,j))*(p (i,k,j)-p (i-1,k,j)) &
  716. +(al (i,k ,j)+al (i-1,k ,j))*(pb (i,k,j)-pb (i-1,k,j)) )
  717. ENDDO
  718. ENDDO
  719. IF (non_hydrostatic) THEN
  720. DO i = i_start_up, i_end_up
  721. dpn(i,1) = .5*( cf1*(p(i,1,j)+p(i-1,1,j)) &
  722. +cf2*(p(i,2,j)+p(i-1,2,j)) &
  723. +cf3*(p(i,3,j)+p(i-1,3,j)) )
  724. dpn(i,kde) = 0.
  725. ENDDO
  726. IF (top_lid) THEN
  727. DO i = i_start_up, i_end_up
  728. dpn(i,kde) =.5*( cf1*(p(i-1,kde-1,j)+p(i,kde-1,j)) &
  729. +cf2*(p(i-1,kde-2,j)+p(i,kde-2,j)) &
  730. +cf3*(p(i-1,kde-3,j)+p(i,kde-3,j)) )
  731. ENDDO
  732. ENDIF
  733. DO k = k_start+1, k_end
  734. DO i = i_start_up, i_end_up
  735. dpn(i,k) = .5*( fnm(k)*(p(i,k ,j)+p(i-1,k ,j)) &
  736. +fnp(k)*(p(i,k-1,j)+p(i-1,k-1,j)) )
  737. ENDDO
  738. ENDDO
  739. ! Comments on map scale factors:
  740. ! 4th term:
  741. ! php, dpn, mu not coupled
  742. ! since we want tendency to fit ADT eqn 44 (coupled) we need to
  743. ! multiply by (mx/my):
  744. DO k = k_start, k_end
  745. DO i = i_start_up, i_end_up
  746. dpxy(i,k)=dpxy(i,k) + (msfux(i,j)/msfuy(i,j))*rdx*(php(i,k,j)-php(i-1,k,j))* &
  747. (rdnw(k)*(dpn(i,k+1)-dpn(i,k))-.5*(mu(i-1,j)+mu(i,j)))
  748. ENDDO
  749. ENDDO
  750. END IF
  751. DO k = k_start, k_end
  752. DO i = i_start_up, i_end_up
  753. u(i,k,j)=u(i,k,j)-dts*cqu(i,k,j)*dpxy(i,k)+mudf_xy(i)
  754. ENDDO
  755. ENDDO
  756. ENDDO u_outer_j_loop
  757. ! now v
  758. v_outer_j_loop: DO j = j_start_v_tend, j_end_v_tend
  759. DO k = k_start, k_end
  760. DO i = i_start, i_end
  761. v(i,k,j) = v(i,k,j) + dts*rv_tend(i,k,j)
  762. ENDDO
  763. ENDDO
  764. DO i = i_start, i_end
  765. mudf_xy(i)= -emdiv*dy*(mudf(i,j)-mudf(i,j-1))*msfvx_inv(i,j)
  766. ENDDO
  767. IF ( ( j >= j_start_vp) &
  768. .and.( j <= j_end_vp ) ) THEN
  769. DO k = k_start, k_end
  770. DO i = i_start, i_end
  771. ! Comments on map scale factors:
  772. ! y pressure gradient: ADT eqn 45, penultimate term on RHS
  773. ! = -(my/mx)*(mu/rho)*partial dp/dy
  774. ! [i.e., first rho->mu; 2nd still rho; alpha=1/rho]
  775. ! Klemp et al. splits into 2 terms:
  776. ! mu alpha partial dp/dy + partial dp/dnu * partial dphi/dy
  777. ! then into 4 terms:
  778. ! mu alpha partial dp'/dy + nu mu alpha' partial dmubar/dy +
  779. ! + mu partial dphi/dy + partial dphi'/dy * (partial dp'/dnu - mu')
  780. !
  781. ! first 3 terms:
  782. ! ph, alt, p, al, pb not coupled
  783. ! since we want tendency to fit ADT eqn 45 (coupled) we need to
  784. ! multiply by (my/mx):
  785. ! mudf_xy is NOT a map scale factor coupling
  786. ! it is some sort of divergence damping
  787. dpxy(i,k)= (msfvy(i,j)/msfvx(i,j))*.5*rdy*muv(i,j)*( &
  788. ((ph(i,k+1,j)-ph(i,k+1,j-1))+(ph (i,k,j)-ph (i,k,j-1))) &
  789. +(alt(i,k ,j)+alt(i,k ,j-1))*(p (i,k,j)-p (i,k,j-1)) &
  790. +(al (i,k ,j)+al (i,k ,j-1))*(pb (i,k,j)-pb (i,k,j-1)) )
  791. ENDDO
  792. ENDDO
  793. IF (non_hydrostatic) THEN
  794. DO i = i_start, i_end
  795. dpn(i,1) = .5*( cf1*(p(i,1,j)+p(i,1,j-1)) &
  796. +cf2*(p(i,2,j)+p(i,2,j-1)) &
  797. +cf3*(p(i,3,j)+p(i,3,j-1)) )
  798. dpn(i,kde) = 0.
  799. ENDDO
  800. IF (top_lid) THEN
  801. DO i = i_start, i_end
  802. dpn(i,kde) =.5*( cf1*(p(i,kde-1,j-1)+p(i,kde-1,j)) &
  803. +cf2*(p(i,kde-2,j-1)+p(i,kde-2,j)) &
  804. +cf3*(p(i,kde-3,j-1)+p(i,kde-3,j)) )
  805. ENDDO
  806. ENDIF
  807. DO k = k_start+1, k_end
  808. DO i = i_start, i_end
  809. dpn(i,k) = .5*( fnm(k)*(p(i,k ,j)+p(i,k ,j-1)) &
  810. +fnp(k)*(p(i,k-1,j)+p(i,k-1,j-1)) )
  811. ENDDO
  812. ENDDO
  813. ! Comments on map scale factors:
  814. ! 4th term:
  815. ! php, dpn, mu not coupled
  816. ! since we want tendency to fit ADT eqn 45 (coupled) we need to
  817. ! multiply by (my/mx):
  818. DO k = k_start, k_end
  819. DO i = i_start, i_end
  820. dpxy(i,k)=dpxy(i,k) + (msfvy(i,j)/msfvx(i,j))*rdy*(php(i,k,j)-php(i,k,j-1))* &
  821. (rdnw(k)*(dpn(i,k+1)-dpn(i,k))-.5*(mu(i,j-1)+mu(i,j)))
  822. ENDDO
  823. ENDDO
  824. END IF
  825. DO k = k_start, k_end
  826. DO i = i_start, i_end
  827. v(i,k,j)=v(i,k,j)-dts*cqv(i,k,j)*dpxy(i,k)+mudf_xy(i)
  828. ENDDO
  829. ENDDO
  830. END IF
  831. ENDDO v_outer_j_loop
  832. ! The check for j_start_vp and j_end_vp makes sure that the edges in v
  833. ! are not updated. Let's add a polar boundary condition check here for
  834. ! safety to ensure that v at the poles never gets to be non-zero in the
  835. ! small time steps.
  836. IF (config_flags%polar) THEN
  837. IF (jts == jds) THEN
  838. DO k = k_start, k_end
  839. DO i = i_start, i_end
  840. v(i,k,jds) = 0.
  841. ENDDO
  842. ENDDO
  843. END IF
  844. IF (jte == jde) THEN
  845. DO k = k_start, k_end
  846. DO i = i_start, i_end
  847. v(i,k,jde) = 0.
  848. ENDDO
  849. ENDDO
  850. END IF
  851. END IF
  852. END SUBROUTINE advance_uv
  853. !---------------------------------------------------------------------
  854. SUBROUTINE advance_mu_t( ww, ww_1, u, u_1, v, v_1, &
  855. mu, mut, muave, muts, muu, muv, &
  856. mudf, uam, vam, wwam, t, t_1, &
  857. t_ave, ft, mu_tend, &
  858. rdx, rdy, dts, epssm, &
  859. dnw, fnm, fnp, rdnw, &
  860. msfux, msfuy, msfvx, msfvx_inv, &
  861. msfvy, msftx, msfty, &
  862. step, config_flags, &
  863. ids, ide, jds, jde, kds, kde, &
  864. ims, ime, jms, jme, kms, kme, &
  865. its, ite, jts, jte, kts, kte )
  866. IMPLICIT NONE ! religion first
  867. ! stuff coming in
  868. TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
  869. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  870. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  871. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  872. INTEGER, INTENT(IN ) :: step
  873. REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
  874. INTENT(IN ) :: &
  875. u, &
  876. v, &
  877. u_1, &
  878. v_1, &
  879. t_1, &
  880. ft
  881. REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
  882. INTENT(INOUT) :: &
  883. ww, &
  884. ww_1, &
  885. t, &
  886. t_ave, &
  887. uam, &
  888. vam, &
  889. wwam
  890. REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: muu, &
  891. muv, &
  892. mut, &
  893. msfux,&
  894. msfuy,&
  895. msfvx,&
  896. msfvx_inv,&
  897. msfvy,&
  898. msftx,&
  899. msfty,&
  900. mu_tend
  901. REAL, DIMENSION( ims:ime , jms:jme ), INTENT( OUT) :: muave, &
  902. muts, &
  903. mudf
  904. REAL, DIMENSION( ims:ime , jms:jme ), INTENT(INOUT) :: mu
  905. REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnm, &
  906. fnp, &
  907. dnw, &
  908. rdnw
  909. REAL, INTENT(IN ) :: rdx, &
  910. rdy, &
  911. dts, &
  912. epssm
  913. ! Local arrays from the stack (note tile size)
  914. REAL, DIMENSION (its:ite, kts:kte) :: wdtn, dvdxi
  915. REAL, DIMENSION (its:ite) :: dmdt
  916. INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end
  917. INTEGER :: i_endu, j_endv
  918. REAL :: acc
  919. !<DESCRIPTION>
  920. !
  921. ! advance_mu_t advances the explicit perturbation theta equation and the mass
  922. ! conservation equation. In addition, the small timestep omega is updated,
  923. ! and some quantities needed in other places are squirrelled away.
  924. !
  925. !</DESCRIPTION>
  926. ! now, the real work.
  927. ! set the loop bounds taking into account boundary conditions.
  928. i_start = its
  929. i_end = min(ite,ide-1)
  930. j_start = jts
  931. j_end = min(jte,jde-1)
  932. k_start = kts
  933. k_end = kte-1
  934. IF ( .NOT. config_flags%periodic_x )THEN
  935. IF ( config_flags%specified .or. config_flags%nested ) then
  936. i_start = max(its,ids+1)
  937. i_end = min(ite,ide-2)
  938. ENDIF
  939. ENDIF
  940. IF ( config_flags%specified .or. config_flags%nested ) then
  941. j_start = max(jts,jds+1)
  942. j_end = min(jte,jde-2)
  943. ENDIF
  944. i_endu = ite
  945. j_endv = jte
  946. ! CALCULATION OF WW (dETA/dt)
  947. DO j = j_start, j_end
  948. DO i=i_start, i_end
  949. dmdt(i) = 0.
  950. ENDDO
  951. ! NOTE: mu is not coupled with the map scale factor.
  952. ! ww (omega) IS coupled with the map scale factor.
  953. ! Being coupled with the map scale factor means
  954. ! multiplication by (1/msft) in this case.
  955. ! Comments on map scale factors
  956. ! ADT eqn 47:
  957. ! partial drho/dt = -mx*my[partial d/dx(rho u/my) + partial d/dy(rho v/mx)]
  958. ! -partial d/dz(rho w)
  959. ! with rho -> mu, dividing by my, and with partial d/dnu(rho nu/my [=ww])
  960. ! as the final term (because we're looking for d_nu_/dt)
  961. !
  962. ! begin by integrating with respect to nu from bottom to top
  963. ! BCs are ww=0 at both
  964. ! final term gives 0
  965. ! first term gives Integral([1/my]partial d mu/dt) over total column = dm/dt
  966. ! RHS remaining is Integral(-mx[partial d/dx(mu u/my) +
  967. ! partial d/dy(mu v/mx)]) over column
  968. ! lines below find RHS terms at each level then set dmdt = sum over all levels
  969. !
  970. ! [don't divide the below by msfty until find ww, since dmdt is used in
  971. ! the meantime]
  972. DO k=k_start, k_end
  973. DO i=i_start, i_end
  974. dvdxi(i,k) = msftx(i,j)*msfty(i,j)*( &
  975. rdy*( (v(i,k,j+1)+muv(i,j+1)*v_1(i,k,j+1)*msfvx_inv(i,j+1)) &
  976. -(v(i,k,j )+muv(i,j )*v_1(i,k,j )*msfvx_inv(i,j )) ) &
  977. +rdx*( (u(i+1,k,j)+muu(i+1,j)*u_1(i+1,k,j)/msfuy(i+1,j)) &
  978. -(u(i,k,j )+muu(i ,j)*u_1(i,k,j )/msfuy(i ,j)) ))
  979. dmdt(i) = dmdt(i) + dnw(k)*dvdxi(i,k)
  980. ENDDO
  981. ENDDO
  982. DO i=i_start, i_end
  983. muave(i,j) = mu(i,j)
  984. mu(i,j) = mu(i,j)+dts*(dmdt(i)+mu_tend(i,j))
  985. mudf(i,j) = (dmdt(i)+mu_tend(i,j)) ! save tendency for div damp filter
  986. muts(i,j) = mut(i,j)+mu(i,j)
  987. muave(i,j) =.5*((1.+epssm)*mu(i,j)+(1.-epssm)*muave(i,j))
  988. ENDDO
  989. DO k=2,k_end
  990. DO i=i_start, i_end
  991. ww(i,k,j)=ww(i,k-1,j)-dnw(k-1)*(dmdt(i)+dvdxi(i,k-1)+mu_tend(i,j))/msfty(i,j)
  992. ENDDO
  993. END DO
  994. ! NOTE: ww_1 (large timestep ww) is already coupled with the
  995. ! map scale factor
  996. DO k=1,k_end
  997. DO i=i_start, i_end
  998. ww(i,k,j)=ww(i,k,j)-ww_1(i,k,j)
  999. END DO
  1000. END DO
  1001. ENDDO
  1002. ! CALCULATION OF THETA
  1003. ! NOTE: theta'' is not coupled with the map-scale factor,
  1004. ! while the theta'' tendency is coupled (i.e., mult by 1/msft)
  1005. ! Comments on map scale factors
  1006. ! BUT NOTE THAT both are mass coupled
  1007. ! in flux form equations (Klemp et al.) Theta = mu*theta
  1008. !
  1009. ! scalar eqn: partial d/dt(rho q/my) = -mx[partial d/dx(q rho u/my) +
  1010. ! partial d/dy(q rho v/mx)]
  1011. ! - partial d/dz(q rho w/my)
  1012. ! with rho -> mu, and with partial d/dnu(q rho nu/my) as the final term
  1013. !
  1014. ! adding previous tendency contribution which was map scale factor coupled
  1015. ! (had been divided by msfty)
  1016. ! need to uncouple before updating uncoupled Theta (by adding)
  1017. DO j=j_start, j_end
  1018. DO k=1,k_end
  1019. DO i=i_start, i_end
  1020. t_ave(i,k,j) = t(i,k,j)
  1021. t (i,k,j) = t(i,k,j) + msfty(i,j)*dts*ft(i,k,j)
  1022. END DO
  1023. END DO
  1024. ENDDO
  1025. DO j=j_start, j_end
  1026. DO i=i_start, i_end
  1027. wdtn(i,1 )=0.
  1028. wdtn(i,kde)=0.
  1029. ENDDO
  1030. DO k=2,k_end
  1031. DO i=i_start, i_end
  1032. ! for scalar eqn RHS term 3
  1033. wdtn(i,k)= ww(i,k,j)*(fnm(k)*t_1(i,k ,j)+fnp(k)*t_1(i,k-1,j))
  1034. ENDDO
  1035. ENDDO
  1036. ! scalar eqn, RHS terms 1, 2 and 3
  1037. ! multiply by msfty to uncouple result for Theta from map scale factor
  1038. DO k=1,k_end
  1039. DO i=i_start, i_end
  1040. ! multiplication by msfty uncouples result for Theta
  1041. t(i,k,j) = t(i,k,j) - dts*msfty(i,j)*( &
  1042. ! multiplication by mx needed for RHS terms 1 & 2
  1043. msftx(i,j)*( &
  1044. .5*rdy* &
  1045. ( v(i,k,j+1)*(t_1(i,k,j+1)+t_1(i,k, j )) &
  1046. -v(i,k,j )*(t_1(i,k, j )+t_1(i,k,j-1)) ) &
  1047. + .5*rdx* &
  1048. ( u(i+1,k,j)*(t_1(i+1,k,j)+t_1(i ,k,j)) &
  1049. -u(i ,k,j)*(t_1(i ,k,j)+t_1(i-1,k,j)) ) ) &
  1050. + rdnw(k)*( wdtn(i,k+1)-wdtn(i,k) ) )
  1051. ENDDO
  1052. ENDDO
  1053. ENDDO
  1054. END SUBROUTINE advance_mu_t
  1055. !------------------------------------------------------------
  1056. SUBROUTINE advance_w( w, rw_tend, ww, w_save, u, v, &
  1057. mu1, mut, muave, muts, &
  1058. t_2ave, t_2, t_1, &
  1059. ph, ph_1, phb, ph_tend, &
  1060. ht, c2a, cqw, alt, alb, &
  1061. a, alpha, gamma, &
  1062. rdx, rdy, dts, t0, epssm, &
  1063. dnw, fnm, fnp, rdnw, rdn, &
  1064. cf1, cf2, cf3, msftx, msfty,&
  1065. config_flags, top_lid, &
  1066. ids,ide, jds,jde, kds,kde, & ! domain dims
  1067. ims,ime, jms,jme, kms,kme, & ! memory dims
  1068. its,ite, jts,jte, kts,kte ) ! tile dims
  1069. ! We have used msfty for msft_inv but have not thought through w equation
  1070. ! pieces properly yet, so we will have to hope that it is okay
  1071. ! We think we have found a slight error in surface w calculation
  1072. IMPLICIT NONE ! religion first
  1073. ! stuff coming in
  1074. TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
  1075. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  1076. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  1077. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  1078. LOGICAL, INTENT(IN ) :: top_lid
  1079. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), &
  1080. INTENT(INOUT) :: &
  1081. t_2ave, &
  1082. w, &
  1083. ph
  1084. REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
  1085. INTENT(IN ) :: &
  1086. rw_tend, &
  1087. ww, &
  1088. w_save, &
  1089. u, &
  1090. v, &
  1091. t_2, &
  1092. t_1, &
  1093. ph_1, &
  1094. phb, &
  1095. ph_tend, &
  1096. alpha, &
  1097. gamma, &
  1098. a, &
  1099. c2a, &
  1100. cqw, &
  1101. alb, &
  1102. alt
  1103. REAL, DIMENSION( ims:ime , jms:jme ), &
  1104. INTENT(IN ) :: &
  1105. mu1, &
  1106. mut, &
  1107. muave, &
  1108. muts, &
  1109. ht, &
  1110. msftx, &
  1111. msfty
  1112. REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnp, &
  1113. fnm, &
  1114. rdnw, &
  1115. rdn, &
  1116. dnw
  1117. REAL, INTENT(IN ) :: rdx, &
  1118. rdy, &
  1119. dts, &
  1120. cf1, &
  1121. cf2, &
  1122. cf3, &
  1123. t0, &
  1124. epssm
  1125. ! Stack based 3d data, tile size.
  1126. REAL, DIMENSION( its:ite ) :: mut_inv, msft_inv
  1127. REAL, DIMENSION( its:ite, kts:kte ) :: rhs, wdwn
  1128. INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end
  1129. REAL, DIMENSION (kts:kte) :: dampwt
  1130. real :: htop,hbot,hdepth,hk
  1131. real :: pi,dampmag
  1132. !<DESCRIPTION>
  1133. !
  1134. ! advance_w advances the implicit w and geopotential equations.
  1135. !
  1136. !</DESCRIPTION>
  1137. ! set loop limits.
  1138. ! Currently set for periodic boundary conditions
  1139. i_start = its
  1140. i_end = min(ite,ide-1)
  1141. j_start = jts
  1142. j_end = min(jte,jde-1)
  1143. k_start = kts
  1144. k_end = kte-1
  1145. IF ( .NOT. config_flags%periodic_x )THEN
  1146. IF ( config_flags%specified .or. config_flags%nested ) then
  1147. i_start = max(its,ids+1)
  1148. i_end = min(ite,ide-2)
  1149. ENDIF
  1150. ENDIF
  1151. IF ( config_flags%specified .or. config_flags%nested ) then
  1152. j_start = max(jts,jds+1)
  1153. j_end = min(jte,jde-2)
  1154. ENDIF
  1155. pi = 4.*atan(1.)
  1156. dampmag = dts*config_flags%dampcoef
  1157. hdepth=config_flags%zdamp
  1158. ! calculation of phi and w equations
  1159. ! Comments on map scale factors:
  1160. ! phi equation is:
  1161. ! partial d/dt(rho phi/my) = -mx partial d/dx(phi rho u/my)
  1162. ! -mx partial d/dy(phi rho v/mx)
  1163. ! - partial d/dz(phi rho w/my) + rho g w/my
  1164. ! as with scalar equation, use uncoupled value (here phi) to find the
  1165. ! coupled tendency (rho phi/my)
  1166. ! here as usual rho -> ~'mu'
  1167. !
  1168. ! w eqn [divided by my] is:
  1169. ! partial d/dt(rho w/my) = -mx partial d/dx(w rho u/my)
  1170. ! -mx partial d/dy(v rho v/mx)
  1171. ! - partial d/dz(w rho w/my)
  1172. ! +rho[(u*u+v*v)/a + 2 u omega cos(lat) -
  1173. ! (1/rho) partial dp/dz - g + Fz]/my
  1174. ! here as usual rho -> ~'mu'
  1175. !
  1176. ! 'u,v,w' sent here must be coupled variables (= rho w/my etc.) by their usage
  1177. DO i=i_start, i_end
  1178. rhs(i,1) = 0.
  1179. ENDDO
  1180. j_loop_w: DO j = j_start, j_end
  1181. DO i=i_start, i_end
  1182. mut_inv(i) = 1./mut(i,j)
  1183. msft_inv(i) = 1./msfty(i,j)
  1184. ENDDO
  1185. DO k=1, k_end
  1186. DO i=i_start, i_end
  1187. t_2ave(i,k,j)=.5*((1.+epssm)*t_2(i,k,j) &
  1188. +(1.-epssm)*t_2ave(i,k,j))
  1189. t_2ave(i,k,j)=(t_2ave(i,k,j) + muave(i,j)*t0) &
  1190. /(muts(i,j)*(t0+t_1(i,k,j)))
  1191. wdwn(i,k+1)=.5*(ww(i,k+1,j)+ww(i,k,j))*rdnw(k) &
  1192. *(ph_1(i,k+1,j)-ph_1(i,k,j)+phb(i,k+1,j)-phb(i,k,j))
  1193. rhs(i,k+1) = dts*(ph_tend(i,k+1,j) + .5*g*(1.-epssm)*w(i,k+1,j))
  1194. ENDDO
  1195. ENDDO
  1196. !

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