PageRenderTime 67ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/wrfv2_fire/share/module_bc.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 3400 lines | 2558 code | 521 blank | 321 comment | 148 complexity | 29e913f4d91363971266041ed6c69a14 MD5 | raw file
Possible License(s): AGPL-1.0
  1. !WRF:MODEL_LAYER:BOUNDARY
  2. !
  3. MODULE module_bc
  4. USE module_configure
  5. USE module_wrf_error
  6. USE module_model_constants
  7. IMPLICIT NONE
  8. ! TYPE bcs
  9. !
  10. ! LOGICAL :: periodic_x
  11. ! LOGICAL :: symmetric_xs
  12. ! LOGICAL :: symmetric_xe
  13. ! LOGICAL :: open_xs
  14. ! LOGICAL :: open_xe
  15. ! LOGICAL :: periodic_y
  16. ! LOGICAL :: symmetric_ys
  17. ! LOGICAL :: symmetric_ye
  18. ! LOGICAL :: open_ys
  19. ! LOGICAL :: open_ye
  20. ! LOGICAL :: nested
  21. ! LOGICAL :: specified
  22. ! LOGICAL :: top_radiation
  23. !
  24. ! END TYPE bcs
  25. ! set the bdyzone. We are hardwiring this here and we'll
  26. ! decide later where it should be set and stored
  27. INTEGER, PARAMETER :: bdyzone = 4
  28. INTEGER, PARAMETER :: bdyzone_x = bdyzone
  29. INTEGER, PARAMETER :: bdyzone_y = bdyzone
  30. INTERFACE stuff_bdy
  31. MODULE PROCEDURE stuff_bdy_new , stuff_bdy_old
  32. END INTERFACE
  33. INTERFACE stuff_bdytend
  34. MODULE PROCEDURE stuff_bdytend_new , stuff_bdytend_old
  35. END INTERFACE
  36. CONTAINS
  37. SUBROUTINE boundary_condition_check ( config_flags, bzone, error, gn )
  38. ! this routine checks the boundary condition logicals
  39. ! to make sure that the boundary conditions are not over
  40. ! or under specified. The routine also checks that the
  41. ! boundary zone is sufficiently sized for the specified
  42. ! boundary conditions
  43. IMPLICIT NONE
  44. TYPE( grid_config_rec_type ) config_flags
  45. INTEGER, INTENT(IN ) :: bzone, gn
  46. INTEGER, INTENT(INOUT) :: error
  47. ! local variables
  48. INTEGER :: xs_bc, xe_bc, ys_bc, ye_bc, bzone_min
  49. INTEGER :: nprocx, nprocy
  50. CALL wrf_debug( 100 , ' checking boundary conditions for grid ' )
  51. error = 0
  52. xs_bc = 0
  53. xe_bc = 0
  54. ys_bc = 0
  55. ye_bc = 0
  56. ! sum the number of conditions specified for each lateral boundary.
  57. ! obviously, this number should be 1
  58. IF( config_flags%periodic_x ) THEN
  59. xs_bc = xs_bc+1
  60. xe_bc = xe_bc+1
  61. ENDIF
  62. IF( config_flags%periodic_y ) THEN
  63. ys_bc = ys_bc+1
  64. ye_bc = ye_bc+1
  65. ENDIF
  66. IF( config_flags%symmetric_xs ) xs_bc = xs_bc + 1
  67. IF( config_flags%symmetric_xe ) xe_bc = xe_bc + 1
  68. IF( config_flags%open_xs ) xs_bc = xs_bc + 1
  69. IF( config_flags%open_xe ) xe_bc = xe_bc + 1
  70. IF( config_flags%symmetric_ys ) ys_bc = ys_bc + 1
  71. IF( config_flags%symmetric_ye ) ye_bc = ye_bc + 1
  72. IF( config_flags%open_ys ) ys_bc = ys_bc + 1
  73. IF( config_flags%open_ye ) ye_bc = ye_bc + 1
  74. IF( config_flags%nested ) THEN
  75. xs_bc = xs_bc + 1
  76. xe_bc = xe_bc + 1
  77. ys_bc = ys_bc + 1
  78. ye_bc = ye_bc + 1
  79. ENDIF
  80. IF( config_flags%specified ) THEN
  81. IF( .NOT. config_flags%periodic_x)xs_bc = xs_bc + 1
  82. IF( .NOT. config_flags%periodic_x)xe_bc = xe_bc + 1
  83. ys_bc = ys_bc + 1
  84. ye_bc = ye_bc + 1
  85. ENDIF
  86. IF( config_flags%polar ) THEN
  87. ys_bc = ys_bc + 1
  88. ye_bc = ye_bc + 1
  89. ENDIF
  90. ! check the number of conditions for each boundary
  91. IF( (xs_bc /= 1) .or. &
  92. (xe_bc /= 1) .or. &
  93. (ys_bc /= 1) .or. &
  94. (ye_bc /= 1) ) THEN
  95. error = 1
  96. write( wrf_err_message ,*) ' *** Error in boundary condition specification '
  97. CALL wrf_message ( wrf_err_message )
  98. write( wrf_err_message ,*) ' boundary conditions at xs ', xs_bc
  99. CALL wrf_message ( wrf_err_message )
  100. write( wrf_err_message ,*) ' boundary conditions at xe ', xe_bc
  101. CALL wrf_message ( wrf_err_message )
  102. write( wrf_err_message ,*) ' boundary conditions at ys ', ys_bc
  103. CALL wrf_message ( wrf_err_message )
  104. write( wrf_err_message ,*) ' boundary conditions at ye ', ye_bc
  105. CALL wrf_message ( wrf_err_message )
  106. write( wrf_err_message ,*) ' boundary conditions logicals are '
  107. CALL wrf_message ( wrf_err_message )
  108. write( wrf_err_message ,*) ' periodic_x ',config_flags%periodic_x
  109. CALL wrf_message ( wrf_err_message )
  110. write( wrf_err_message ,*) ' periodic_y ',config_flags%periodic_y
  111. CALL wrf_message ( wrf_err_message )
  112. write( wrf_err_message ,*) ' symmetric_xs ',config_flags%symmetric_xs
  113. CALL wrf_message ( wrf_err_message )
  114. write( wrf_err_message ,*) ' symmetric_xe ',config_flags%symmetric_xe
  115. CALL wrf_message ( wrf_err_message )
  116. write( wrf_err_message ,*) ' symmetric_ys ',config_flags%symmetric_ys
  117. CALL wrf_message ( wrf_err_message )
  118. write( wrf_err_message ,*) ' symmetric_ye ',config_flags%symmetric_ye
  119. CALL wrf_message ( wrf_err_message )
  120. write( wrf_err_message ,*) ' open_xs ',config_flags%open_xs
  121. CALL wrf_message ( wrf_err_message )
  122. write( wrf_err_message ,*) ' open_xe ',config_flags%open_xe
  123. CALL wrf_message ( wrf_err_message )
  124. write( wrf_err_message ,*) ' open_ys ',config_flags%open_ys
  125. CALL wrf_message ( wrf_err_message )
  126. write( wrf_err_message ,*) ' open_ye ',config_flags%open_ye
  127. CALL wrf_message ( wrf_err_message )
  128. write( wrf_err_message ,*) ' polar ',config_flags%polar
  129. CALL wrf_message ( wrf_err_message )
  130. write( wrf_err_message ,*) ' nested ',config_flags%nested
  131. CALL wrf_message ( wrf_err_message )
  132. write( wrf_err_message ,*) ' specified ',config_flags%specified
  133. CALL wrf_message ( wrf_err_message )
  134. CALL wrf_error_fatal( ' *** Error in boundary condition specification ' )
  135. ENDIF
  136. ! now check to see if boundary zone size is sufficient.
  137. ! we could have the necessary boundary zone size be returned
  138. ! to the calling routine.
  139. IF( config_flags%periodic_x .or. &
  140. config_flags%periodic_y .or. &
  141. config_flags%symmetric_xs .or. &
  142. config_flags%symmetric_xe .or. &
  143. config_flags%symmetric_ys .or. &
  144. config_flags%symmetric_ye ) THEN
  145. bzone_min = MAX( 1, &
  146. (config_flags%h_mom_adv_order+1)/2, &
  147. (config_flags%h_sca_adv_order+1)/2 )
  148. IF( bzone < bzone_min) THEN
  149. error = 2
  150. WRITE ( wrf_err_message , * ) ' boundary zone not large enough '
  151. CALL wrf_message ( wrf_err_message )
  152. WRITE ( wrf_err_message , * ) ' boundary zone specified ',bzone
  153. CALL wrf_message ( wrf_err_message )
  154. WRITE ( wrf_err_message , * ) ' minimum boundary zone needed ',bzone_min
  155. CALL wrf_error_fatal ( wrf_err_message )
  156. ENDIF
  157. ENDIF
  158. CALL wrf_debug ( 100 , ' boundary conditions OK for grid ' )
  159. END subroutine boundary_condition_check
  160. !--------------------------------------------------------------------------
  161. SUBROUTINE set_physical_bc2d( dat, variable_in, &
  162. config_flags, &
  163. ids,ide, jds,jde, & ! domain dims
  164. ims,ime, jms,jme, & ! memory dims
  165. ips,ipe, jps,jpe, & ! patch dims
  166. its,ite, jts,jte )
  167. ! This subroutine sets the data in the boundary region, by direct
  168. ! assignment if possible, for periodic and symmetric (wall)
  169. ! boundary conditions. Currently, we are only doing 1 variable
  170. ! at a time - lots of overhead, so maybe this routine can be easily
  171. ! inlined later or we could pass multiple variables -
  172. ! would probably want a largestep and smallstep version.
  173. ! 15 Jan 99, Dave
  174. ! Modified the incoming its,ite,jts,jte to truly be the tile size.
  175. ! This required modifying the loop limits when the "istag" or "jstag"
  176. ! is used, as this is only required at the end of the domain.
  177. IMPLICIT NONE
  178. INTEGER, INTENT(IN ) :: ids,ide, jds,jde
  179. INTEGER, INTENT(IN ) :: ims,ime, jms,jme
  180. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe
  181. INTEGER, INTENT(IN ) :: its,ite, jts,jte
  182. CHARACTER, INTENT(IN ) :: variable_in
  183. CHARACTER :: variable
  184. REAL, DIMENSION( ims:ime , jms:jme ) :: dat
  185. TYPE( grid_config_rec_type ) config_flags
  186. INTEGER :: i, j, istag, jstag, itime
  187. LOGICAL :: debug, open_bc_copy
  188. !------------
  189. debug = .false.
  190. open_bc_copy = .false.
  191. variable = variable_in
  192. IF ( variable_in .ge. 'A' .and. variable_in .le. 'Z' ) THEN
  193. variable = CHAR( ICHAR(variable_in) - ICHAR('A') + ICHAR('a') )
  194. ENDIF
  195. IF ((variable == 'u') .or. (variable == 'v') .or. &
  196. (variable == 'w') .or. (variable == 't') .or. &
  197. (variable == 'x') .or. (variable == 'y') .or. &
  198. (variable == 'r') .or. (variable == 'p') ) open_bc_copy = .true.
  199. ! begin, first set a staggering variable
  200. istag = -1
  201. jstag = -1
  202. IF ((variable == 'u') .or. (variable == 'x')) istag = 0
  203. IF ((variable == 'v') .or. (variable == 'y')) jstag = 0
  204. if(debug) then
  205. write(6,*) ' in bc2d, var is ',variable, istag, jstag
  206. write(6,*) ' b.cs are ', &
  207. config_flags%periodic_x, &
  208. config_flags%periodic_y
  209. end if
  210. IF ( variable == 'd' ) then !JDM
  211. istag = 0
  212. jstag = 0
  213. ENDIF
  214. IF ( variable == 'e' ) then !JDM
  215. istag = 0
  216. ENDIF
  217. IF ( variable == 'f' ) then !JDM
  218. jstag = 0
  219. ENDIF
  220. ! periodic conditions.
  221. ! note, patch must cover full range in periodic dir, or else
  222. ! its intra-patch communication that is handled elsewheres.
  223. ! symmetry conditions can always be handled here, because no
  224. ! outside patch communication is needed
  225. periodicity_x: IF( ( config_flags%periodic_x ) ) THEN
  226. IF ( ( ids == ips ) .and. ( ide == ipe ) ) THEN ! test if east and west both on-processor
  227. IF ( its == ids ) THEN
  228. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  229. DO i = 0,-(bdyzone-1),-1
  230. dat(ids+i-1,j) = dat(ide+i-1,j)
  231. ENDDO
  232. ENDDO
  233. ENDIF
  234. IF ( ite == ide ) THEN
  235. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  236. !! DO i = 1 , bdyzone
  237. DO i = -istag , bdyzone
  238. dat(ide+i+istag,j) = dat(ids+i+istag,j)
  239. ENDDO
  240. ENDDO
  241. ENDIF
  242. ENDIF
  243. ELSE
  244. symmetry_xs: IF( ( config_flags%symmetric_xs ) .and. &
  245. ( its == ids ) ) THEN
  246. IF ( (variable /= 'u') .and. (variable /= 'x') ) THEN
  247. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  248. DO i = 1, bdyzone
  249. dat(ids-i,j) = dat(ids+i-1,j) ! here, dat(0) = dat(1), etc
  250. ENDDO ! symmetry about dat(0.5) (u=0 pt)
  251. ENDDO
  252. ELSE
  253. IF( variable == 'u' ) THEN
  254. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  255. DO i = 0, bdyzone-1
  256. dat(ids-i,j) = - dat(ids+i,j) ! here, u(0) = - u(2), etc
  257. ENDDO ! normal b.c symmetry at u(1)
  258. ENDDO
  259. ELSE
  260. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  261. DO i = 0, bdyzone-1
  262. dat(ids-i,j) = dat(ids+i,j) ! here, phi(0) = phi(2), etc
  263. ENDDO ! normal b.c symmetry at phi(1)
  264. ENDDO
  265. END IF
  266. ENDIF
  267. ENDIF symmetry_xs
  268. ! now the symmetry boundary at xe
  269. symmetry_xe: IF( ( config_flags%symmetric_xe ) .and. &
  270. ( ite == ide ) ) THEN
  271. IF ( (variable /= 'u') .and. (variable /= 'x') ) THEN
  272. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  273. DO i = 1, bdyzone
  274. dat(ide+i-1,j) = dat(ide-i,j) ! sym. about dat(ide-0.5)
  275. ENDDO
  276. ENDDO
  277. ELSE
  278. IF (variable == 'u' ) THEN
  279. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  280. DO i = 0, bdyzone-1
  281. dat(ide+i,j) = - dat(ide-i,j) ! u(ide+1) = - u(ide-1), etc.
  282. ENDDO
  283. ENDDO
  284. ELSE
  285. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  286. DO i = 0, bdyzone-1
  287. dat(ide+i,j) = dat(ide-i,j) ! phi(ide+1) = phi(ide-1), etc.
  288. ENDDO
  289. ENDDO
  290. END IF
  291. END IF
  292. END IF symmetry_xe
  293. ! set open b.c in X copy into boundary zone here. WCS, 19 March 2000
  294. open_xs: IF( ( config_flags%open_xs .or. &
  295. config_flags%specified .or. &
  296. config_flags%nested ) .and. &
  297. ( its == ids ) .and. open_bc_copy ) THEN
  298. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  299. dat(ids-1,j) = dat(ids,j) ! here, dat(0) = dat(1)
  300. dat(ids-2,j) = dat(ids,j)
  301. dat(ids-3,j) = dat(ids,j)
  302. ENDDO
  303. ENDIF open_xs
  304. ! now the open boundary copy at xe
  305. open_xe: IF( ( config_flags%open_xe .or. &
  306. config_flags%specified .or. &
  307. config_flags%nested ) .and. &
  308. ( ite == ide ) .and. open_bc_copy ) THEN
  309. IF ( variable /= 'u' .and. variable /= 'x') THEN
  310. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  311. dat(ide ,j) = dat(ide-1,j)
  312. dat(ide+1,j) = dat(ide-1,j)
  313. dat(ide+2,j) = dat(ide-1,j)
  314. ENDDO
  315. ELSE
  316. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  317. dat(ide+1,j) = dat(ide,j)
  318. dat(ide+2,j) = dat(ide,j)
  319. dat(ide+3,j) = dat(ide,j)
  320. ENDDO
  321. END IF
  322. END IF open_xe
  323. ! end open b.c in X copy into boundary zone addition. WCS, 19 March 2000
  324. END IF periodicity_x
  325. ! same procedure in y
  326. periodicity_y: IF( ( config_flags%periodic_y ) ) THEN
  327. IF ( ( jds == jps ) .and. ( jde == jpe ) ) THEN ! test of both north and south on processor
  328. IF( jts == jds ) then
  329. DO j = 0, -(bdyzone-1), -1
  330. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  331. dat(i,jds+j-1) = dat(i,jde+j-1)
  332. ENDDO
  333. ENDDO
  334. END IF
  335. IF( jte == jde ) then
  336. DO j = -jstag, bdyzone
  337. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  338. dat(i,jde+j+jstag) = dat(i,jds+j+jstag)
  339. ENDDO
  340. ENDDO
  341. END IF
  342. END IF
  343. ELSE
  344. symmetry_ys: IF( ( config_flags%symmetric_ys ) .and. &
  345. ( jts == jds) ) THEN
  346. IF ( (variable /= 'v') .and. (variable /= 'y') ) THEN
  347. DO j = 1, bdyzone
  348. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  349. dat(i,jds-j) = dat(i,jds+j-1)
  350. ENDDO
  351. ENDDO
  352. ELSE
  353. IF (variable == 'v') THEN
  354. DO j = 1, bdyzone
  355. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  356. dat(i,jds-j) = - dat(i,jds+j)
  357. ENDDO
  358. ENDDO
  359. ELSE
  360. DO j = 1, bdyzone
  361. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  362. dat(i,jds-j) = dat(i,jds+j)
  363. ENDDO
  364. ENDDO
  365. END IF
  366. ENDIF
  367. ENDIF symmetry_ys
  368. ! now the symmetry boundary at ye
  369. symmetry_ye: IF( ( config_flags%symmetric_ye ) .and. &
  370. ( jte == jde ) ) THEN
  371. IF ( (variable /= 'v') .and. (variable /= 'y') ) THEN
  372. DO j = 1, bdyzone
  373. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  374. dat(i,jde+j-1) = dat(i,jde-j)
  375. ENDDO
  376. ENDDO
  377. ELSE
  378. IF (variable == 'v' ) THEN
  379. DO j = 1, bdyzone
  380. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  381. dat(i,jde+j) = - dat(i,jde-j) ! bugfix: changed jds on rhs to jde , JM 20020410
  382. ENDDO
  383. ENDDO
  384. ELSE
  385. DO j = 1, bdyzone
  386. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  387. dat(i,jde+j) = dat(i,jde-j)
  388. ENDDO
  389. ENDDO
  390. END IF
  391. ENDIF
  392. END IF symmetry_ye
  393. ! set open b.c in Y copy into boundary zone here. WCS, 19 March 2000
  394. open_ys: IF( ( config_flags%open_ys .or. &
  395. config_flags%polar .or. &
  396. config_flags%specified .or. &
  397. config_flags%nested ) .and. &
  398. ( jts == jds) .and. open_bc_copy ) THEN
  399. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  400. dat(i,jds-1) = dat(i,jds)
  401. dat(i,jds-2) = dat(i,jds)
  402. dat(i,jds-3) = dat(i,jds)
  403. ENDDO
  404. ENDIF open_ys
  405. ! now the open boundary copy at ye
  406. open_ye: IF( ( config_flags%open_ye .or. &
  407. config_flags%polar .or. &
  408. config_flags%specified .or. &
  409. config_flags%nested ) .and. &
  410. ( jte == jde ) .and. open_bc_copy ) THEN
  411. IF (variable /= 'v' .and. variable /= 'y' ) THEN
  412. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  413. dat(i,jde ) = dat(i,jde-1)
  414. dat(i,jde+1) = dat(i,jde-1)
  415. dat(i,jde+2) = dat(i,jde-1)
  416. ENDDO
  417. ELSE
  418. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  419. dat(i,jde+1) = dat(i,jde)
  420. dat(i,jde+2) = dat(i,jde)
  421. dat(i,jde+3) = dat(i,jde)
  422. ENDDO
  423. ENDIF
  424. END IF open_ye
  425. ! end open b.c in Y copy into boundary zone addition. WCS, 19 March 2000
  426. END IF periodicity_y
  427. ! fix corners for doubly periodic domains
  428. IF ( config_flags%periodic_x .and. config_flags%periodic_y &
  429. .and. (ids == ips) .and. (ide == ipe) &
  430. .and. (jds == jps) .and. (jde == jpe) ) THEN
  431. IF ( (its == ids) .and. (jts == jds) ) THEN ! lower left corner fill
  432. DO j = 0, -(bdyzone-1), -1
  433. DO i = 0, -(bdyzone-1), -1
  434. dat(ids+i-1,jds+j-1) = dat(ide+i-1,jde+j-1)
  435. ENDDO
  436. ENDDO
  437. END IF
  438. IF ( (ite == ide) .and. (jts == jds) ) THEN ! lower right corner fill
  439. DO j = 0, -(bdyzone-1), -1
  440. DO i = 1, bdyzone
  441. dat(ide+i+istag,jds+j-1) = dat(ids+i+istag,jde+j-1)
  442. ENDDO
  443. ENDDO
  444. END IF
  445. IF ( (ite == ide) .and. (jte == jde) ) THEN ! upper right corner fill
  446. DO j = 1, bdyzone
  447. DO i = 1, bdyzone
  448. dat(ide+i+istag,jde+j+jstag) = dat(ids+i+istag,jds+j+jstag)
  449. ENDDO
  450. ENDDO
  451. END IF
  452. IF ( (its == ids) .and. (jte == jde) ) THEN ! upper left corner fill
  453. DO j = 1, bdyzone
  454. DO i = 0, -(bdyzone-1), -1
  455. dat(ids+i-1,jde+j+jstag) = dat(ide+i-1,jds+j+jstag)
  456. ENDDO
  457. ENDDO
  458. END IF
  459. END IF
  460. END SUBROUTINE set_physical_bc2d
  461. !-----------------------------------
  462. SUBROUTINE set_physical_bc3d( dat, variable_in, &
  463. config_flags, &
  464. ids,ide, jds,jde, kds,kde, & ! domain dims
  465. ims,ime, jms,jme, kms,kme, & ! memory dims
  466. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  467. its,ite, jts,jte, kts,kte )
  468. ! This subroutine sets the data in the boundary region, by direct
  469. ! assignment if possible, for periodic and symmetric (wall)
  470. ! boundary conditions. Currently, we are only doing 1 variable
  471. ! at a time - lots of overhead, so maybe this routine can be easily
  472. ! inlined later or we could pass multiple variables -
  473. ! would probably want a largestep and smallstep version.
  474. ! 15 Jan 99, Dave
  475. ! Modified the incoming its,ite,jts,jte to truly be the tile size.
  476. ! This required modifying the loop limits when the "istag" or "jstag"
  477. ! is used, as this is only required at the end of the domain.
  478. IMPLICIT NONE
  479. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  480. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  481. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  482. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  483. CHARACTER, INTENT(IN ) :: variable_in
  484. CHARACTER :: variable
  485. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ) :: dat
  486. TYPE( grid_config_rec_type ) config_flags
  487. INTEGER :: i, j, k, istag, jstag, itime, k_end
  488. LOGICAL :: debug, open_bc_copy
  489. !------------
  490. debug = .false.
  491. open_bc_copy = .false.
  492. variable = variable_in
  493. IF ( variable_in .ge. 'A' .and. variable_in .le. 'Z' ) THEN
  494. variable = CHAR( ICHAR(variable_in) - ICHAR('A') + ICHAR('a') )
  495. ENDIF
  496. IF ((variable == 'u') .or. (variable == 'v') .or. &
  497. (variable == 'w') .or. (variable == 't') .or. &
  498. (variable == 'd') .or. (variable == 'e') .or. &
  499. (variable == 'x') .or. (variable == 'y') .or. &
  500. (variable == 'f') .or. (variable == 'r') .or. &
  501. (variable == 'p') ) open_bc_copy = .true.
  502. ! begin, first set a staggering variable
  503. istag = -1
  504. jstag = -1
  505. k_end = max(1,min(kde-1,kte))
  506. IF ((variable == 'u') .or. (variable == 'x')) istag = 0
  507. IF ((variable == 'v') .or. (variable == 'y')) jstag = 0
  508. IF ((variable == 'd') .or. (variable == 'xy')) then
  509. istag = 0
  510. jstag = 0
  511. ENDIF
  512. IF ((variable == 'e') ) then
  513. istag = 0
  514. k_end = min(kde,kte)
  515. ENDIF
  516. IF ((variable == 'f') ) then
  517. jstag = 0
  518. k_end = min(kde,kte)
  519. ENDIF
  520. IF ( variable == 'w') k_end = min(kde,kte)
  521. ! k_end = kte
  522. if(debug) then
  523. write(6,*) ' in bc, var is ',variable, istag, jstag, kte, k_end
  524. write(6,*) ' b.cs are ', &
  525. config_flags%periodic_x, &
  526. config_flags%periodic_y
  527. end if
  528. ! periodic conditions.
  529. ! note, patch must cover full range in periodic dir, or else
  530. ! its intra-patch communication that is handled elsewheres.
  531. ! symmetry conditions can always be handled here, because no
  532. ! outside patch communication is needed
  533. periodicity_x: IF( ( config_flags%periodic_x ) ) THEN
  534. IF ( ( ids == ips ) .and. ( ide == ipe ) ) THEN ! test if both east and west on-processor
  535. IF ( its == ids ) THEN
  536. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  537. DO k = kts, k_end
  538. DO i = 0,-(bdyzone-1),-1
  539. dat(ids+i-1,k,j) = dat(ide+i-1,k,j)
  540. ENDDO
  541. ENDDO
  542. ENDDO
  543. ENDIF
  544. IF ( ite == ide ) THEN
  545. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  546. DO k = kts, k_end
  547. DO i = -istag , bdyzone
  548. dat(ide+i+istag,k,j) = dat(ids+i+istag,k,j)
  549. ENDDO
  550. ENDDO
  551. ENDDO
  552. ENDIF
  553. ENDIF
  554. ELSE
  555. symmetry_xs: IF( ( config_flags%symmetric_xs ) .and. &
  556. ( its == ids ) ) THEN
  557. IF ( (variable /= 'u') .and. (variable /= 'x') ) THEN
  558. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  559. DO k = kts, k_end
  560. DO i = 1, bdyzone
  561. dat(ids-i,k,j) = dat(ids+i-1,k,j) ! here, dat(0) = dat(1), etc
  562. ENDDO ! symmetry about dat(0.5) (u = 0 pt)
  563. ENDDO
  564. ENDDO
  565. ELSE
  566. IF ( variable == 'u' ) THEN
  567. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  568. DO k = kts, k_end
  569. DO i = 1, bdyzone
  570. dat(ids-i,k,j) = - dat(ids+i,k,j) ! here, u(0) = - u(2), etc
  571. ENDDO ! normal b.c symmetry at u(1)
  572. ENDDO
  573. ENDDO
  574. ELSE
  575. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  576. DO k = kts, k_end
  577. DO i = 1, bdyzone
  578. dat(ids-i,k,j) = dat(ids+i,k,j) ! here, phi(0) = phi(2), etc
  579. ENDDO ! normal b.c symmetry at phi(1)
  580. ENDDO
  581. ENDDO
  582. END IF
  583. ENDIF
  584. ENDIF symmetry_xs
  585. ! now the symmetry boundary at xe
  586. symmetry_xe: IF( ( config_flags%symmetric_xe ) .and. &
  587. ( ite == ide ) ) THEN
  588. IF ( (variable /= 'u') .and. (variable /= 'x') ) THEN
  589. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  590. DO k = kts, k_end
  591. DO i = 1, bdyzone
  592. dat(ide+i-1,k,j) = dat(ide-i,k,j) ! sym. about dat(ide-0.5)
  593. ENDDO
  594. ENDDO
  595. ENDDO
  596. ELSE
  597. IF (variable == 'u') THEN
  598. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  599. DO k = kts, k_end
  600. DO i = 1, bdyzone
  601. dat(ide+i,k,j) = - dat(ide-i,k,j) ! u(ide+1) = - u(ide-1), etc.
  602. ENDDO
  603. ENDDO
  604. ENDDO
  605. ELSE
  606. DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
  607. DO k = kts, k_end
  608. DO i = 1, bdyzone
  609. dat(ide+i,k,j) = dat(ide-i,k,j) ! phi(ide+1) = - phi(ide-1), etc.
  610. ENDDO
  611. ENDDO
  612. ENDDO
  613. END IF
  614. END IF
  615. END IF symmetry_xe
  616. ! set open b.c in X copy into boundary zone here. WCS, 19 March 2000
  617. open_xs: IF( ( config_flags%open_xs .or. &
  618. config_flags%specified .or. &
  619. config_flags%nested ) .and. &
  620. ( its == ids ) .and. open_bc_copy ) THEN
  621. DO j = jts-bdyzone, MIN(jte,jde+jstag)+bdyzone
  622. DO k = kts, k_end
  623. dat(ids-1,k,j) = dat(ids,k,j) ! here, dat(0) = dat(1), etc
  624. dat(ids-2,k,j) = dat(ids,k,j)
  625. dat(ids-3,k,j) = dat(ids,k,j)
  626. ENDDO
  627. ENDDO
  628. ENDIF open_xs
  629. ! now the open_xe boundary copy
  630. open_xe: IF( ( config_flags%open_xe .or. &
  631. config_flags%specified .or. &
  632. config_flags%nested ) .and. &
  633. ( ite == ide ) .and. open_bc_copy ) THEN
  634. IF (variable /= 'u' .and. variable /= 'x' ) THEN
  635. DO j = jts-bdyzone, MIN(jte,jde+jstag)+bdyzone
  636. DO k = kts, k_end
  637. dat(ide ,k,j) = dat(ide-1,k,j)
  638. dat(ide+1,k,j) = dat(ide-1,k,j)
  639. dat(ide+2,k,j) = dat(ide-1,k,j)
  640. ENDDO
  641. ENDDO
  642. ELSE
  643. !!!!!!! I am not sure about this one! JM 20020402
  644. DO j = MAX(jds,jts-1)-bdyzone, MIN(jte+1,jde+jstag)+bdyzone
  645. DO k = kts, k_end
  646. dat(ide+1,k,j) = dat(ide,k,j)
  647. dat(ide+2,k,j) = dat(ide,k,j)
  648. dat(ide+3,k,j) = dat(ide,k,j)
  649. ENDDO
  650. ENDDO
  651. END IF
  652. END IF open_xe
  653. ! end open b.c in X copy into boundary zone addition. WCS, 19 March 2000
  654. END IF periodicity_x
  655. ! same procedure in y
  656. periodicity_y: IF( ( config_flags%periodic_y ) ) THEN
  657. IF ( ( jds == jps ) .and. ( jde == jpe ) ) THEN ! test if both north and south on processor
  658. IF( jts == jds ) then
  659. DO j = 0, -(bdyzone-1), -1
  660. DO k = kts, k_end
  661. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  662. dat(i,k,jds+j-1) = dat(i,k,jde+j-1)
  663. ENDDO
  664. ENDDO
  665. ENDDO
  666. END IF
  667. IF( jte == jde ) then
  668. DO j = -jstag, bdyzone
  669. DO k = kts, k_end
  670. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  671. dat(i,k,jde+j+jstag) = dat(i,k,jds+j+jstag)
  672. ENDDO
  673. ENDDO
  674. ENDDO
  675. END IF
  676. END IF
  677. ELSE
  678. symmetry_ys: IF( ( config_flags%symmetric_ys ) .and. &
  679. ( jts == jds) ) THEN
  680. IF ( (variable /= 'v') .and. (variable /= 'y') ) THEN
  681. DO j = 1, bdyzone
  682. DO k = kts, k_end
  683. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  684. dat(i,k,jds-j) = dat(i,k,jds+j-1)
  685. ENDDO
  686. ENDDO
  687. ENDDO
  688. ELSE
  689. IF (variable == 'v') THEN
  690. DO j = 1, bdyzone
  691. DO k = kts, k_end
  692. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  693. dat(i,k,jds-j) = - dat(i,k,jds+j)
  694. ENDDO
  695. ENDDO
  696. ENDDO
  697. ELSE
  698. DO j = 1, bdyzone
  699. DO k = kts, k_end
  700. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  701. dat(i,k,jds-j) = dat(i,k,jds+j)
  702. ENDDO
  703. ENDDO
  704. ENDDO
  705. END IF
  706. ENDIF
  707. ENDIF symmetry_ys
  708. ! now the symmetry boundary at ye
  709. symmetry_ye: IF( ( config_flags%symmetric_ye ) .and. &
  710. ( jte == jde ) ) THEN
  711. IF ( (variable /= 'v') .and. (variable /= 'y') ) THEN
  712. DO j = 1, bdyzone
  713. DO k = kts, k_end
  714. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  715. dat(i,k,jde+j-1) = dat(i,k,jde-j)
  716. ENDDO
  717. ENDDO
  718. ENDDO
  719. ELSE
  720. IF ( variable == 'v' ) THEN
  721. DO j = 1, bdyzone
  722. DO k = kts, k_end
  723. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  724. dat(i,k,jde+j) = - dat(i,k,jde-j)
  725. ENDDO
  726. ENDDO
  727. ENDDO
  728. ELSE
  729. DO j = 1, bdyzone
  730. DO k = kts, k_end
  731. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  732. dat(i,k,jde+j) = dat(i,k,jde-j)
  733. ENDDO
  734. ENDDO
  735. ENDDO
  736. END IF
  737. ENDIF
  738. END IF symmetry_ye
  739. ! set open b.c in Y copy into boundary zone here. WCS, 19 March 2000
  740. open_ys: IF( ( config_flags%open_ys .or. &
  741. config_flags%polar .or. &
  742. config_flags%specified .or. &
  743. config_flags%nested ) .and. &
  744. ( jts == jds) .and. open_bc_copy ) THEN
  745. DO k = kts, k_end
  746. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  747. dat(i,k,jds-1) = dat(i,k,jds)
  748. dat(i,k,jds-2) = dat(i,k,jds)
  749. dat(i,k,jds-3) = dat(i,k,jds)
  750. ENDDO
  751. ENDDO
  752. ENDIF open_ys
  753. ! now the open boundary copy at ye
  754. open_ye: IF( ( config_flags%open_ye .or. &
  755. config_flags%polar .or. &
  756. config_flags%specified .or. &
  757. config_flags%nested ) .and. &
  758. ( jte == jde ) .and. open_bc_copy ) THEN
  759. IF (variable /= 'v' .and. variable /= 'y' ) THEN
  760. DO k = kts, k_end
  761. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  762. dat(i,k,jde ) = dat(i,k,jde-1)
  763. dat(i,k,jde+1) = dat(i,k,jde-1)
  764. dat(i,k,jde+2) = dat(i,k,jde-1)
  765. ENDDO
  766. ENDDO
  767. ELSE
  768. DO k = kts, k_end
  769. DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
  770. dat(i,k,jde+1) = dat(i,k,jde)
  771. dat(i,k,jde+2) = dat(i,k,jde)
  772. dat(i,k,jde+3) = dat(i,k,jde)
  773. ENDDO
  774. ENDDO
  775. ENDIF
  776. END IF open_ye
  777. ! end open b.c in Y copy into boundary zone addition. WCS, 19 March 2000
  778. END IF periodicity_y
  779. ! fix corners for doubly periodic domains
  780. IF ( config_flags%periodic_x .and. config_flags%periodic_y &
  781. .and. (ids == ips) .and. (ide == ipe) &
  782. .and. (jds == jps) .and. (jde == jpe) ) THEN
  783. IF ( (its == ids) .and. (jts == jds) ) THEN ! lower left corner fill
  784. DO j = 0, -(bdyzone-1), -1
  785. DO k = kts, k_end
  786. DO i = 0, -(bdyzone-1), -1
  787. dat(ids+i-1,k,jds+j-1) = dat(ide+i-1,k,jde+j-1)
  788. ENDDO
  789. ENDDO
  790. ENDDO
  791. END IF
  792. IF ( (ite == ide) .and. (jts == jds) ) THEN ! lower right corner fill
  793. DO j = 0, -(bdyzone-1), -1
  794. DO k = kts, k_end
  795. DO i = 1, bdyzone
  796. dat(ide+i+istag,k,jds+j-1) = dat(ids+i+istag,k,jde+j-1)
  797. ENDDO
  798. ENDDO
  799. ENDDO
  800. END IF
  801. IF ( (ite == ide) .and. (jte == jde) ) THEN ! upper right corner fill
  802. DO j = 1, bdyzone
  803. DO k = kts, k_end
  804. DO i = 1, bdyzone
  805. dat(ide+i+istag,k,jde+j+jstag) = dat(ids+i+istag,k,jds+j+jstag)
  806. ENDDO
  807. ENDDO
  808. ENDDO
  809. END IF
  810. IF ( (its == ids) .and. (jte == jde) ) THEN ! upper left corner fill
  811. DO j = 1, bdyzone
  812. DO k = kts, k_end
  813. DO i = 0, -(bdyzone-1), -1
  814. dat(ids+i-1,k,jde+j+jstag) = dat(ide+i-1,k,jds+j+jstag)
  815. ENDDO
  816. ENDDO
  817. ENDDO
  818. END IF
  819. END IF
  820. END SUBROUTINE set_physical_bc3d
  821. SUBROUTINE init_module_bc
  822. END SUBROUTINE init_module_bc
  823. !------------------------------------------------------------------------
  824. ! a couple versions of this call to allow a smaller-than-memory dimensioned field (e.g. tile sized)
  825. ! to be passed in as the first argument. Both of these call the _core version defined below.
  826. SUBROUTINE relax_bdytend ( field, field_tend, &
  827. field_bdy_xs, field_bdy_xe, &
  828. field_bdy_ys, field_bdy_ye, &
  829. field_bdy_tend_xs, field_bdy_tend_xe, &
  830. field_bdy_tend_ys, field_bdy_tend_ye, &
  831. variable_in, config_flags, &
  832. spec_bdy_width, spec_zone, relax_zone, &
  833. dtbc, fcx, gcx, &
  834. ids,ide, jds,jde, kds,kde, & ! domain dims
  835. ims,ime, jms,jme, kms,kme, & ! memory dims
  836. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  837. its,ite, jts,jte, kts,kte &
  838. )
  839. IMPLICIT NONE
  840. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  841. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  842. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  843. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  844. INTEGER, INTENT(IN ) :: spec_bdy_width, spec_zone, relax_zone
  845. REAL, INTENT(IN ) :: dtbc
  846. CHARACTER, INTENT(IN ) :: variable_in
  847. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: field
  848. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field_tend
  849. REAL, DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_xs, field_bdy_xe
  850. REAL, DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_ys, field_bdy_ye
  851. REAL, DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_tend_xs, field_bdy_tend_xe
  852. REAL, DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_tend_ys, field_bdy_tend_ye
  853. REAL, DIMENSION( spec_bdy_width ), INTENT(IN ) :: fcx, gcx
  854. TYPE( grid_config_rec_type ) config_flags
  855. CALL relax_bdytend_core ( field, field_tend, &
  856. field_bdy_xs, field_bdy_xe, &
  857. field_bdy_ys, field_bdy_ye, &
  858. field_bdy_tend_xs, field_bdy_tend_xe, &
  859. field_bdy_tend_ys, field_bdy_tend_ye, &
  860. variable_in, config_flags, &
  861. spec_bdy_width, spec_zone, relax_zone, &
  862. dtbc, fcx, gcx, &
  863. ids,ide, jds,jde, kds,kde, & ! domain dims
  864. ims,ime, jms,jme, kms,kme, & ! memory dims
  865. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  866. its,ite, jts,jte, kts,kte, & ! patch dims
  867. ims,ime, jms,jme, kms,kme ) ! dimension of the field argument
  868. END SUBROUTINE relax_bdytend
  869. ! version that allows tile-sized version of field. Note, caller should define the
  870. ! field to be -+1 of tile size in each dimension because routine is going off onto halo
  871. ! for example, see relax_bdytend in dyn_em/module_bc_em.F
  872. SUBROUTINE relax_bdytend_tile ( field, field_tend, &
  873. field_bdy_xs, field_bdy_xe, &
  874. field_bdy_ys, field_bdy_ye, &
  875. field_bdy_tend_xs, field_bdy_tend_xe, &
  876. field_bdy_tend_ys, field_bdy_tend_ye, &
  877. variable_in, config_flags, &
  878. spec_bdy_width, spec_zone, relax_zone, &
  879. dtbc, fcx, gcx, &
  880. ids,ide, jds,jde, kds,kde, & ! domain dims
  881. ims,ime, jms,jme, kms,kme, & ! memory dims
  882. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  883. its,ite, jts,jte, kts,kte, &
  884. iXs,iXe, jXs,jXe, kXs,kXe & ! dims of first argument
  885. )
  886. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  887. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  888. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  889. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  890. INTEGER, INTENT(IN ) :: iXs,iXe, jXs,jXe, kXs,kXe
  891. INTEGER, INTENT(IN ) :: spec_bdy_width, spec_zone, relax_zone
  892. REAL, INTENT(IN ) :: dtbc
  893. CHARACTER, INTENT(IN ) :: variable_in
  894. REAL, DIMENSION( iXs:iXe , kXs:kXe , jXs:jXe ), INTENT(IN ) :: field
  895. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field_tend
  896. REAL, DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_xs, field_bdy_xe
  897. REAL, DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_ys, field_bdy_ye
  898. REAL, DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_tend_xs, field_bdy_tend_xe
  899. REAL, DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_tend_ys, field_bdy_tend_ye
  900. REAL, DIMENSION( spec_bdy_width ), INTENT(IN ) :: fcx, gcx
  901. TYPE( grid_config_rec_type ) config_flags
  902. CALL relax_bdytend_core ( field, field_tend, &
  903. field_bdy_xs, field_bdy_xe, &
  904. field_bdy_ys, field_bdy_ye, &
  905. field_bdy_tend_xs, field_bdy_tend_xe, &
  906. field_bdy_tend_ys, field_bdy_tend_ye, &
  907. variable_in, config_flags, &
  908. spec_bdy_width, spec_zone, relax_zone, &
  909. dtbc, fcx, gcx, &
  910. ids,ide, jds,jde, kds,kde, & ! domain dims
  911. ims,ime, jms,jme, kms,kme, & ! memory dims
  912. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  913. its,ite, jts,jte, kts,kte, &
  914. iXs,iXe, jXs,jXe, kXs,kXe ) ! dimension of the field argument
  915. END SUBROUTINE relax_bdytend_tile
  916. SUBROUTINE relax_bdytend_core ( field, field_tend, &
  917. field_bdy_xs, field_bdy_xe, &
  918. field_bdy_ys, field_bdy_ye, &
  919. field_bdy_tend_xs, field_bdy_tend_xe, &
  920. field_bdy_tend_ys, field_bdy_tend_ye, &
  921. variable_in, config_flags, &
  922. spec_bdy_width, spec_zone, relax_zone, &
  923. dtbc, fcx, gcx, &
  924. ids,ide, jds,jde, kds,kde, & ! domain dims
  925. ims,ime, jms,jme, kms,kme, & ! memory dims
  926. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  927. its,ite, jts,jte, kts,kte, & ! patch dims
  928. iXs,iXe, jXs,jXe, kXs,kXe & ! field (1st arg) dims; might be tile or patch
  929. )
  930. ! This subroutine adds the tendencies in the boundary relaxation region, for specified
  931. ! boundary conditions.
  932. ! spec_bdy_width is only used to dimension the boundary arrays.
  933. ! relax_zone is the inner edge of the boundary relaxation zone treated here.
  934. ! spec_zone is the width of the outer specified b.c.s that are not changed here.
  935. ! (JD July 2000)
  936. IMPLICIT NONE
  937. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  938. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  939. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  940. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  941. INTEGER, INTENT(IN ) :: iXs,iXe, jXs,jXe, kXs,kXe
  942. INTEGER, INTENT(IN ) :: spec_bdy_width, spec_zone, relax_zone
  943. REAL, INTENT(IN ) :: dtbc
  944. CHARACTER, INTENT(IN ) :: variable_in
  945. REAL, DIMENSION( iXs:iXe , kXs:kXe , jXs:jXe ), INTENT(IN ) :: field
  946. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field_tend
  947. REAL, DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_xs, field_bdy_xe
  948. REAL, DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_ys, field_bdy_ye
  949. REAL, DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_tend_xs, field_bdy_tend_xe
  950. REAL, DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_tend_ys, field_bdy_tend_ye
  951. REAL, DIMENSION( spec_bdy_width ), INTENT(IN ) :: fcx, gcx
  952. TYPE( grid_config_rec_type ) config_flags
  953. CHARACTER :: variable
  954. INTEGER :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf, im1, ip1
  955. INTEGER :: b_dist, b_limit
  956. REAL :: fls0, fls1, fls2, fls3, fls4
  957. LOGICAL :: periodic_x
  958. periodic_x = config_flags%periodic_x
  959. variable = variable_in
  960. IF (variable == 'U') variable = 'u'
  961. IF (variable == 'V') variable = 'v'
  962. IF (variable == 'M') variable = 'm'
  963. IF (variable == 'H') variable = 'h'
  964. ibs = ids
  965. ibe = ide-1
  966. itf = min(ite,ide-1)
  967. jbs = jds
  968. jbe = jde-1
  969. jtf = min(jte,jde-1)
  970. ktf = kde-1
  971. IF (variable == 'u') ibe = ide
  972. IF (variable == 'u') itf = min(ite,ide)
  973. IF (variable == 'v') jbe = jde
  974. IF (variable == 'v') jtf = min(jte,jde)
  975. IF (variable == 'm') ktf = kte
  976. IF (variable == 'h') ktf = kte
  977. IF (jts - jbs .lt. relax_zone) THEN
  978. ! Y-start boundary
  979. DO j = max(jts,jbs+spec_zone), min(jtf,jbs+relax_zone-1)
  980. b_dist = j - jbs
  981. b_limit = b_dist
  982. IF(periodic_x)b_limit = 0
  983. DO k = kts, ktf
  984. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  985. im1 = max(i-1,ibs)
  986. ip1 = min(i+1,ibe)
  987. fls0 = field_bdy_ys(i, k, b_dist+1) &
  988. + dtbc * field_bdy_tend_ys(i, k, b_dist+1) &
  989. - field(i,k,j)
  990. fls1 = field_bdy_ys(im1, k, b_dist+1) &
  991. + dtbc * field_bdy_tend_ys(im1, k, b_dist+1) &
  992. - field(im1,k,j)
  993. fls2 = field_bdy_ys(ip1, k, b_dist+1) &
  994. + dtbc * field_bdy_tend_ys(ip1, k, b_dist+1) &
  995. - field(ip1,k,j)
  996. fls3 = field_bdy_ys(i, k, b_dist) &
  997. + dtbc * field_bdy_tend_ys(i, k, b_dist) &
  998. - field(i,k,j-1)
  999. fls4 = field_bdy_ys(i, k, b_dist+2) &
  1000. + dtbc * field_bdy_tend_ys(i, k, b_dist+2) &
  1001. - field(i,k,j+1)
  1002. field_tend(i,k,j) = field_tend(i,k,j) &
  1003. + fcx(b_dist+1)*fls0 &
  1004. - gcx(b_dist+1)*(fls1+fls2+fls3+fls4-4.*fls0)
  1005. ENDDO
  1006. ENDDO
  1007. ENDDO
  1008. ENDIF
  1009. IF (jbe - jtf .lt. relax_zone) THEN
  1010. ! Y-end boundary
  1011. DO j = max(jts,jbe-relax_zone+1), min(jtf,jbe-spec_zone)
  1012. b_dist = jbe - j
  1013. b_limit = b_dist
  1014. IF(periodic_x)b_limit = 0
  1015. DO k = kts, ktf
  1016. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1017. im1 = max(i-1,ibs)
  1018. ip1 = min(i+1,ibe)
  1019. fls0 = field_bdy_ye(i, k, b_dist+1) &
  1020. + dtbc * field_bdy_tend_ye(i, k, b_dist+1) &
  1021. - field(i,k,j)
  1022. fls1 = field_bdy_ye(im1, k, b_dist+1) &
  1023. + dtbc * field_bdy_tend_ye(im1, k, b_dist+1) &
  1024. - field(im1,k,j)
  1025. fls2 = field_bdy_ye(ip1, k, b_dist+1) &
  1026. + dtbc * field_bdy_tend_ye(ip1, k, b_dist+1) &
  1027. - field(ip1,k,j)
  1028. fls3 = field_bdy_ye(i, k, b_dist) &
  1029. + dtbc * field_bdy_tend_ye(i, k, b_dist) &
  1030. - field(i,k,j+1)
  1031. fls4 = field_bdy_ye(i, k, b_dist+2) &
  1032. + dtbc * field_bdy_tend_ye(i, k, b_dist+2) &
  1033. - field(i,k,j-1)
  1034. field_tend(i,k,j) = field_tend(i,k,j) &
  1035. + fcx(b_dist+1)*fls0 &
  1036. - gcx(b_dist+1)*(fls1+fls2+fls3+fls4-4.*fls0)
  1037. ENDDO
  1038. ENDDO
  1039. ENDDO
  1040. ENDIF
  1041. IF(.NOT.periodic_x)THEN
  1042. IF (its - ibs .lt. relax_zone) THEN
  1043. ! X-start boundary
  1044. DO i = max(its,ibs+spec_zone), min(itf,ibs+relax_zone-1)
  1045. b_dist = i - ibs
  1046. DO k = kts, ktf
  1047. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1048. fls0 = field_bdy_xs(j, k, b_dist+1) &
  1049. + dtbc * field_bdy_tend_xs(j, k, b_dist+1) &
  1050. - field(i,k,j)
  1051. fls1 = field_bdy_xs(j-1, k, b_dist+1) &
  1052. + dtbc * field_bdy_tend_xs(j-1, k, b_dist+1) &
  1053. - field(i,k,j-1)
  1054. fls2 = field_bdy_xs(j+1, k, b_dist+1) &
  1055. + dtbc * field_bdy_tend_xs(j+1, k, b_dist+1) &
  1056. - field(i,k,j+1)
  1057. fls3 = field_bdy_xs(j, k, b_dist) &
  1058. + dtbc * field_bdy_tend_xs(j, k, b_dist) &
  1059. - field(i-1,k,j)
  1060. fls4 = field_bdy_xs(j, k, b_dist+2) &
  1061. + dtbc * field_bdy_tend_xs(j, k, b_dist+2) &
  1062. - field(i+1,k,j)
  1063. field_tend(i,k,j) = field_tend(i,k,j) &
  1064. + fcx(b_dist+1)*fls0 &
  1065. - gcx(b_dist+1)*(fls1+fls2+fls3+fls4-4.*fls0)
  1066. ENDDO
  1067. ENDDO
  1068. ENDDO
  1069. ENDIF
  1070. IF (ibe - itf .lt. relax_zone) THEN
  1071. ! X-end boundary
  1072. DO i = max(its,ibe-relax_zone+1), min(itf,ibe-spec_zone)
  1073. b_dist = ibe - i
  1074. DO k = kts, ktf
  1075. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1076. fls0 = field_bdy_xe(j, k, b_dist+1) &
  1077. + dtbc * field_bdy_tend_xe(j, k, b_dist+1) &
  1078. - field(i,k,j)
  1079. fls1 = field_bdy_xe(j-1, k, b_dist+1) &
  1080. + dtbc * field_bdy_tend_xe(j-1, k, b_dist+1) &
  1081. - field(i,k,j-1)
  1082. fls2 = field_bdy_xe(j+1, k, b_dist+1) &
  1083. + dtbc * field_bdy_tend_xe(j+1, k, b_dist+1) &
  1084. - field(i,k,j+1)
  1085. fls3 = field_bdy_xe(j, k, b_dist) &
  1086. + dtbc * field_bdy_tend_xe(j, k, b_dist) &
  1087. - field(i+1,k,j)
  1088. fls4 = field_bdy_xe(j, k, b_dist+2) &
  1089. + dtbc * field_bdy_tend_xe(j, k, b_dist+2) &
  1090. - field(i-1,k,j)
  1091. field_tend(i,k,j) = field_tend(i,k,j) &
  1092. + fcx(b_dist+1)*fls0 &
  1093. - gcx(b_dist+1)*(fls1+fls2+fls3+fls4-4.*fls0)
  1094. ENDDO
  1095. ENDDO
  1096. ENDDO
  1097. ENDIF
  1098. ENDIF
  1099. END SUBROUTINE relax_bdytend_core
  1100. !------------------------------------------------------------------------
  1101. SUBROUTINE spec_bdytend ( field_tend, &
  1102. field_bdy_xs, field_bdy_xe, &
  1103. field_bdy_ys, field_bdy_ye, &
  1104. field_bdy_tend_xs, field_bdy_tend_xe, &
  1105. field_bdy_tend_ys, field_bdy_tend_ye, &
  1106. variable_in, config_flags, &
  1107. spec_bdy_width, spec_zone, &
  1108. ids,ide, jds,jde, kds,kde, & ! domain dims
  1109. ims,ime, jms,jme, kms,kme, & ! memory dims
  1110. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  1111. its,ite, jts,jte, kts,kte )
  1112. ! This subroutine sets the tendencies in the boundary specified region.
  1113. ! spec_bdy_width is only used to dimension the boundary arrays.
  1114. ! spec_zone is the width of the outer specified b.c.s that are set here.
  1115. ! (JD July 2000)
  1116. IMPLICIT NONE
  1117. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  1118. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  1119. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  1120. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  1121. INTEGER, INTENT(IN ) :: spec_bdy_width, spec_zone
  1122. CHARACTER, INTENT(IN ) :: variable_in
  1123. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(OUT ) :: field_tend
  1124. REAL, DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_xs, field_bdy_xe
  1125. REAL, DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_ys, field_bdy_ye
  1126. REAL, DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_tend_xs, field_bdy_tend_xe
  1127. REAL, DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_tend_ys, field_bdy_tend_ye
  1128. TYPE( grid_config_rec_type ) config_flags
  1129. CHARACTER :: variable
  1130. INTEGER :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf
  1131. INTEGER :: b_dist, b_limit
  1132. LOGICAL :: periodic_x
  1133. periodic_x = config_flags%periodic_x
  1134. variable = variable_in
  1135. IF (variable == 'U') variable = 'u'
  1136. IF (variable == 'V') variable = 'v'
  1137. IF (variable == 'M') variable = 'm'
  1138. IF (variable == 'H') variable = 'h'
  1139. ibs = ids
  1140. ibe = ide-1
  1141. itf = min(ite,ide-1)
  1142. jbs = jds
  1143. jbe = jde-1
  1144. jtf = min(jte,jde-1)
  1145. ktf = kde-1
  1146. IF (variable == 'u') ibe = ide
  1147. IF (variable == 'u') itf = min(ite,ide)
  1148. IF (variable == 'v') jbe = jde
  1149. IF (variable == 'v') jtf = min(jte,jde)
  1150. IF (variable == 'm') ktf = kte
  1151. IF (variable == 'h') ktf = kte
  1152. IF (jts - jbs .lt. spec_zone) THEN
  1153. ! Y-start boundary
  1154. DO j = jts, min(jtf,jbs+spec_zone-1)
  1155. b_dist = j - jbs
  1156. b_limit = b_dist
  1157. IF(periodic_x)b_limit = 0
  1158. DO k = kts, ktf
  1159. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1160. field_tend(i,k,j) = field_bdy_tend_ys(i, k, b_dist+1)
  1161. ENDDO
  1162. ENDDO
  1163. ENDDO
  1164. ENDIF
  1165. IF (jbe - jtf .lt. spec_zone) THEN
  1166. ! Y-end boundary
  1167. DO j = max(jts,jbe-spec_zone+1), jtf
  1168. b_dist = jbe - j
  1169. b_limit = b_dist
  1170. IF(periodic_x)b_limit = 0
  1171. DO k = kts, ktf
  1172. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1173. field_tend(i,k,j) = field_bdy_tend_ye(i, k, b_dist+1)
  1174. ENDDO
  1175. ENDDO
  1176. ENDDO
  1177. ENDIF
  1178. IF(.NOT.periodic_x)THEN
  1179. IF (its - ibs .lt. spec_zone) THEN
  1180. ! X-start boundary
  1181. DO i = its, min(itf,ibs+spec_zone-1)
  1182. b_dist = i - ibs
  1183. DO k = kts, ktf
  1184. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1185. field_tend(i,k,j) = field_bdy_tend_xs(j, k, b_dist+1)
  1186. ENDDO
  1187. ENDDO
  1188. ENDDO
  1189. ENDIF
  1190. IF (ibe - itf .lt. spec_zone) THEN
  1191. ! X-end boundary
  1192. DO i = max(its,ibe-spec_zone+1), itf
  1193. b_dist = ibe - i
  1194. DO k = kts, ktf
  1195. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1196. field_tend(i,k,j) = field_bdy_tend_xe(j, k, b_dist+1)
  1197. ENDDO
  1198. ENDDO
  1199. ENDDO
  1200. ENDIF
  1201. ENDIF
  1202. END SUBROUTINE spec_bdytend
  1203. !------------------------------------------------------------------------
  1204. SUBROUTINE spec_bdyfield ( field, &
  1205. field_bdy_xs, field_bdy_xe, &
  1206. field_bdy_ys, field_bdy_ye, &
  1207. variable_in, config_flags, &
  1208. spec_bdy_width, spec_zone, &
  1209. ids,ide, jds,jde, kds,kde, & ! domain dims
  1210. ims,ime, jms,jme, kms,kme, & ! memory dims
  1211. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  1212. its,ite, jts,jte, kts,kte )
  1213. ! This subroutine sets the tendencies in the boundary specified region.
  1214. ! spec_bdy_width is only used to dimension the boundary arrays.
  1215. ! spec_zone is the width of the outer specified b.c.s that are set here.
  1216. ! (JD July 2000)
  1217. IMPLICIT NONE
  1218. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  1219. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  1220. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  1221. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  1222. INTEGER, INTENT(IN ) :: spec_bdy_width, spec_zone
  1223. CHARACTER, INTENT(IN ) :: variable_in
  1224. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(OUT ) :: field
  1225. REAL, DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_xs, field_bdy_xe
  1226. REAL, DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN ) :: field_bdy_ys, field_bdy_ye
  1227. TYPE( grid_config_rec_type ) config_flags
  1228. CHARACTER :: variable
  1229. INTEGER :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf
  1230. INTEGER :: b_dist, b_limit
  1231. LOGICAL :: periodic_x
  1232. periodic_x = config_flags%periodic_x
  1233. variable = variable_in
  1234. IF (variable == 'U') variable = 'u'
  1235. IF (variable == 'V') variable = 'v'
  1236. IF (variable == 'M') variable = 'm'
  1237. IF (variable == 'H') variable = 'h'
  1238. ibs = ids
  1239. ibe = ide-1
  1240. itf = min(ite,ide-1)
  1241. jbs = jds
  1242. jbe = jde-1
  1243. jtf = min(jte,jde-1)
  1244. ktf = kde-1
  1245. IF (variable == 'u') ibe = ide
  1246. IF (variable == 'u') itf = min(ite,ide)
  1247. IF (variable == 'v') jbe = jde
  1248. IF (variable == 'v') jtf = min(jte,jde)
  1249. IF (variable == 'm') ktf = kte
  1250. IF (variable == 'h') ktf = kte
  1251. IF (jts - jbs .lt. spec_zone) THEN
  1252. ! Y-start boundary
  1253. DO j = jts, min(jtf,jbs+spec_zone-1)
  1254. b_dist = j - jbs
  1255. b_limit = b_dist
  1256. IF(periodic_x)b_limit = 0
  1257. DO k = kts, ktf
  1258. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1259. field(i,k,j) = field_bdy_ys(i, k, b_dist+1)
  1260. ENDDO
  1261. ENDDO
  1262. ENDDO
  1263. ENDIF
  1264. IF (jbe - jtf .lt. spec_zone) THEN
  1265. ! Y-end boundary
  1266. DO j = max(jts,jbe-spec_zone+1), jtf
  1267. b_dist = jbe - j
  1268. b_limit = b_dist
  1269. IF(periodic_x)b_limit = 0
  1270. DO k = kts, ktf
  1271. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1272. field(i,k,j) = field_bdy_ye(i, k, b_dist+1)
  1273. ENDDO
  1274. ENDDO
  1275. ENDDO
  1276. ENDIF
  1277. IF(.NOT.periodic_x)THEN
  1278. IF (its - ibs .lt. spec_zone) THEN
  1279. ! X-start boundary
  1280. DO i = its, min(itf,ibs+spec_zone-1)
  1281. b_dist = i - ibs
  1282. DO k = kts, ktf
  1283. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1284. field(i,k,j) = field_bdy_xs(j, k, b_dist+1)
  1285. ENDDO
  1286. ENDDO
  1287. ENDDO
  1288. ENDIF
  1289. IF (ibe - itf .lt. spec_zone) THEN
  1290. ! X-end boundary
  1291. DO i = max(its,ibe-spec_zone+1), itf
  1292. b_dist = ibe - i
  1293. DO k = kts, ktf
  1294. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1295. field(i,k,j) = field_bdy_xe(j, k, b_dist+1)
  1296. ENDDO
  1297. ENDDO
  1298. ENDDO
  1299. ENDIF
  1300. ENDIF
  1301. END SUBROUTINE spec_bdyfield
  1302. !------------------------------------------------------------------------
  1303. SUBROUTINE spec_bdyupdate( field, &
  1304. field_tend, dt, &
  1305. variable_in, config_flags, &
  1306. spec_zone, &
  1307. ids,ide, jds,jde, kds,kde, & ! domain dims
  1308. ims,ime, jms,jme, kms,kme, & ! memory dims
  1309. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  1310. its,ite, jts,jte, kts,kte )
  1311. ! This subroutine adds the tendencies in the boundary specified region.
  1312. ! spec_zone is the width of the outer specified b.c.s that are set here.
  1313. ! (JD August 2000)
  1314. IMPLICIT NONE
  1315. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  1316. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  1317. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  1318. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  1319. INTEGER, INTENT(IN ) :: spec_zone
  1320. CHARACTER, INTENT(IN ) :: variable_in
  1321. REAL, INTENT(IN ) :: dt
  1322. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field
  1323. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: field_tend
  1324. TYPE( grid_config_rec_type ) config_flags
  1325. CHARACTER :: variable
  1326. INTEGER :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf
  1327. INTEGER :: b_dist, b_limit
  1328. LOGICAL :: periodic_x
  1329. periodic_x = config_flags%periodic_x
  1330. variable = variable_in
  1331. IF (variable == 'U') variable = 'u'
  1332. IF (variable == 'V') variable = 'v'
  1333. IF (variable == 'M') variable = 'm'
  1334. IF (variable == 'H') variable = 'h'
  1335. ibs = ids
  1336. ibe = ide-1
  1337. itf = min(ite,ide-1)
  1338. jbs = jds
  1339. jbe = jde-1
  1340. jtf = min(jte,jde-1)
  1341. ktf = kde-1
  1342. IF (variable == 'u') ibe = ide
  1343. IF (variable == 'u') itf = min(ite,ide)
  1344. IF (variable == 'v') jbe = jde
  1345. IF (variable == 'v') jtf = min(jte,jde)
  1346. IF (variable == 'm') ktf = kte
  1347. IF (variable == 'h') ktf = kte
  1348. IF (jts - jbs .lt. spec_zone) THEN
  1349. ! Y-start boundary
  1350. DO j = jts, min(jtf,jbs+spec_zone-1)
  1351. b_dist = j - jbs
  1352. b_limit = b_dist
  1353. IF(periodic_x)b_limit = 0
  1354. DO k = kts, ktf
  1355. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1356. field(i,k,j) = field(i,k,j) + dt*field_tend(i,k,j)
  1357. ENDDO
  1358. ENDDO
  1359. ENDDO
  1360. ENDIF
  1361. IF (jbe - jtf .lt. spec_zone) THEN
  1362. ! Y-end boundary
  1363. DO j = max(jts,jbe-spec_zone+1), jtf
  1364. b_dist = jbe - j
  1365. b_limit = b_dist
  1366. IF(periodic_x)b_limit = 0
  1367. DO k = kts, ktf
  1368. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1369. field(i,k,j) = field(i,k,j) + dt*field_tend(i,k,j)
  1370. ENDDO
  1371. ENDDO
  1372. ENDDO
  1373. ENDIF
  1374. IF(.NOT.periodic_x)THEN
  1375. IF (its - ibs .lt. spec_zone) THEN
  1376. ! X-start boundary
  1377. DO i = its, min(itf,ibs+spec_zone-1)
  1378. b_dist = i - ibs
  1379. DO k = kts, ktf
  1380. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1381. field(i,k,j) = field(i,k,j) + dt*field_tend(i,k,j)
  1382. ENDDO
  1383. ENDDO
  1384. ENDDO
  1385. ENDIF
  1386. IF (ibe - itf .lt. spec_zone) THEN
  1387. ! X-end boundary
  1388. DO i = max(its,ibe-spec_zone+1), itf
  1389. b_dist = ibe - i
  1390. DO k = kts, ktf
  1391. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1392. field(i,k,j) = field(i,k,j) + dt*field_tend(i,k,j)
  1393. ENDDO
  1394. ENDDO
  1395. ENDDO
  1396. ENDIF
  1397. ENDIF
  1398. END SUBROUTINE spec_bdyupdate
  1399. !------------------------------------------------------------------------
  1400. SUBROUTINE zero_grad_bdy ( field, &
  1401. variable_in, config_flags, &
  1402. spec_zone, &
  1403. ids,ide, jds,jde, kds,kde, & ! domain dims
  1404. ims,ime, jms,jme, kms,kme, & ! memory dims
  1405. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  1406. its,ite, jts,jte, kts,kte )
  1407. ! This subroutine sets zero gradient conditions in the boundary specified region.
  1408. ! spec_zone is the width of the outer specified b.c.s that are set here.
  1409. ! (JD August 2000)
  1410. IMPLICIT NONE
  1411. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  1412. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  1413. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  1414. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  1415. INTEGER, INTENT(IN ) :: spec_zone
  1416. CHARACTER, INTENT(IN ) :: variable_in
  1417. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field
  1418. TYPE( grid_config_rec_type ) config_flags
  1419. CHARACTER :: variable
  1420. INTEGER :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf, i_inner, j_inner
  1421. INTEGER :: b_dist, b_limit
  1422. LOGICAL :: periodic_x
  1423. periodic_x = config_flags%periodic_x
  1424. variable = variable_in
  1425. IF (variable == 'U') variable = 'u'
  1426. IF (variable == 'V') variable = 'v'
  1427. ibs = ids
  1428. ibe = ide-1
  1429. itf = min(ite,ide-1)
  1430. jbs = jds
  1431. jbe = jde-1
  1432. jtf = min(jte,jde-1)
  1433. ktf = kde-1
  1434. IF (variable == 'u') ibe = ide
  1435. IF (variable == 'u') itf = min(ite,ide)
  1436. IF (variable == 'v') jbe = jde
  1437. IF (variable == 'v') jtf = min(jte,jde)
  1438. IF (variable == 'w') ktf = kde
  1439. IF (jts - jbs .lt. spec_zone) THEN
  1440. ! Y-start boundary
  1441. DO j = jts, min(jtf,jbs+spec_zone-1)
  1442. b_dist = j - jbs
  1443. b_limit = b_dist
  1444. IF(periodic_x)b_limit = 0
  1445. DO k = kts, ktf
  1446. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1447. i_inner = max(i,ibs+spec_zone)
  1448. i_inner = min(i_inner,ibe-spec_zone)
  1449. IF(periodic_x)i_inner = i
  1450. field(i,k,j) = field(i_inner,k,jbs+spec_zone)
  1451. ENDDO
  1452. ENDDO
  1453. ENDDO
  1454. ENDIF
  1455. IF (jbe - jtf .lt. spec_zone) THEN
  1456. ! Y-end boundary
  1457. DO j = max(jts,jbe-spec_zone+1), jtf
  1458. b_dist = jbe - j
  1459. b_limit = b_dist
  1460. IF(periodic_x)b_limit = 0
  1461. DO k = kts, ktf
  1462. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1463. i_inner = max(i,ibs+spec_zone)
  1464. i_inner = min(i_inner,ibe-spec_zone)
  1465. IF(periodic_x)i_inner = i
  1466. field(i,k,j) = field(i_inner,k,jbe-spec_zone)
  1467. ENDDO
  1468. ENDDO
  1469. ENDDO
  1470. ENDIF
  1471. IF(.NOT.periodic_x)THEN
  1472. IF (its - ibs .lt. spec_zone) THEN
  1473. ! X-start boundary
  1474. DO i = its, min(itf,ibs+spec_zone-1)
  1475. b_dist = i - ibs
  1476. DO k = kts, ktf
  1477. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1478. j_inner = max(j,jbs+spec_zone)
  1479. j_inner = min(j_inner,jbe-spec_zone)
  1480. field(i,k,j) = field(ibs+spec_zone,k,j_inner)
  1481. ENDDO
  1482. ENDDO
  1483. ENDDO
  1484. ENDIF
  1485. IF (ibe - itf .lt. spec_zone) THEN
  1486. ! X-end boundary
  1487. DO i = max(its,ibe-spec_zone+1), itf
  1488. b_dist = ibe - i
  1489. DO k = kts, ktf
  1490. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1491. j_inner = max(j,jbs+spec_zone)
  1492. j_inner = min(j_inner,jbe-spec_zone)
  1493. field(i,k,j) = field(ibe-spec_zone,k,j_inner)
  1494. ENDDO
  1495. ENDDO
  1496. ENDDO
  1497. ENDIF
  1498. ENDIF
  1499. END SUBROUTINE zero_grad_bdy
  1500. !------------------------------------------------------------------------
  1501. SUBROUTINE flow_dep_bdy ( field, &
  1502. u, v, config_flags, &
  1503. spec_zone, &
  1504. ids,ide, jds,jde, kds,kde, & ! domain dims
  1505. ims,ime, jms,jme, kms,kme, & ! memory dims
  1506. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  1507. its,ite, jts,jte, kts,kte )
  1508. ! This subroutine sets zero gradient conditions for outflow and zero value
  1509. ! for inflow in the boundary specified region. Note that field must be unstaggered.
  1510. ! The velocities, u and v, will only be used to check their sign (coupled vels OK)
  1511. ! spec_zone is the width of the outer specified b.c.s that are set here.
  1512. ! (JD August 2000)
  1513. IMPLICIT NONE
  1514. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  1515. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  1516. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  1517. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  1518. INTEGER, INTENT(IN ) :: spec_zone
  1519. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field
  1520. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: u
  1521. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: v
  1522. TYPE( grid_config_rec_type ) config_flags
  1523. INTEGER :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf, i_inner, j_inner
  1524. INTEGER :: b_dist, b_limit
  1525. LOGICAL :: periodic_x
  1526. periodic_x = config_flags%periodic_x
  1527. ibs = ids
  1528. ibe = ide-1
  1529. itf = min(ite,ide-1)
  1530. jbs = jds
  1531. jbe = jde-1
  1532. jtf = min(jte,jde-1)
  1533. ktf = kde-1
  1534. IF (jts - jbs .lt. spec_zone) THEN
  1535. ! Y-start boundary
  1536. DO j = jts, min(jtf,jbs+spec_zone-1)
  1537. b_dist = j - jbs
  1538. b_limit = b_dist
  1539. IF(periodic_x)b_limit = 0
  1540. DO k = kts, ktf
  1541. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1542. i_inner = max(i,ibs+spec_zone)
  1543. i_inner = min(i_inner,ibe-spec_zone)
  1544. IF(periodic_x)i_inner = i
  1545. IF(v(i,k,j) .lt. 0.)THEN
  1546. field(i,k,j) = field(i_inner,k,jbs+spec_zone)
  1547. ELSE
  1548. field(i,k,j) = 0.
  1549. ENDIF
  1550. ENDDO
  1551. ENDDO
  1552. ENDDO
  1553. ENDIF
  1554. IF (jbe - jtf .lt. spec_zone) THEN
  1555. ! Y-end boundary
  1556. DO j = max(jts,jbe-spec_zone+1), jtf
  1557. b_dist = jbe - j
  1558. b_limit = b_dist
  1559. IF(periodic_x)b_limit = 0
  1560. DO k = kts, ktf
  1561. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1562. i_inner = max(i,ibs+spec_zone)
  1563. i_inner = min(i_inner,ibe-spec_zone)
  1564. IF(periodic_x)i_inner = i
  1565. IF(v(i,k,j+1) .gt. 0.)THEN
  1566. field(i,k,j) = field(i_inner,k,jbe-spec_zone)
  1567. ELSE
  1568. field(i,k,j) = 0.
  1569. ENDIF
  1570. ENDDO
  1571. ENDDO
  1572. ENDDO
  1573. ENDIF
  1574. IF(.NOT.periodic_x)THEN
  1575. IF (its - ibs .lt. spec_zone) THEN
  1576. ! X-start boundary
  1577. DO i = its, min(itf,ibs+spec_zone-1)
  1578. b_dist = i - ibs
  1579. DO k = kts, ktf
  1580. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1581. j_inner = max(j,jbs+spec_zone)
  1582. j_inner = min(j_inner,jbe-spec_zone)
  1583. IF(u(i,k,j) .lt. 0.)THEN
  1584. field(i,k,j) = field(ibs+spec_zone,k,j_inner)
  1585. ELSE
  1586. field(i,k,j) = 0.
  1587. ENDIF
  1588. ENDDO
  1589. ENDDO
  1590. ENDDO
  1591. ENDIF
  1592. IF (ibe - itf .lt. spec_zone) THEN
  1593. ! X-end boundary
  1594. DO i = max(its,ibe-spec_zone+1), itf
  1595. b_dist = ibe - i
  1596. DO k = kts, ktf
  1597. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1598. j_inner = max(j,jbs+spec_zone)
  1599. j_inner = min(j_inner,jbe-spec_zone)
  1600. IF(u(i+1,k,j) .gt. 0.)THEN
  1601. field(i,k,j) = field(ibe-spec_zone,k,j_inner)
  1602. ELSE
  1603. field(i,k,j) = 0.
  1604. ENDIF
  1605. ENDDO
  1606. ENDDO
  1607. ENDDO
  1608. ENDIF
  1609. ENDIF
  1610. END SUBROUTINE flow_dep_bdy
  1611. !------------------------------------------------------------------------------
  1612. SUBROUTINE flow_dep_bdy_qnn ( field, &
  1613. u, v, config_flags, &
  1614. spec_zone, &
  1615. ids,ide, jds,jde, kds,kde, & ! domain dims
  1616. ims,ime, jms,jme, kms,kme, & ! memory dims
  1617. ips,ipe, jps,jpe, kps,kpe, & ! patch dims
  1618. its,ite, jts,jte, kts,kte )
  1619. ! This subroutine sets zero gradient conditions for outflow and zero value
  1620. ! for inflow in the boundary specified region. Note that field must be unstaggered.
  1621. ! The velocities, u and v, will only be used to check their sign (coupled vels OK)
  1622. ! spec_zone is the width of the outer specified b.c.s that are set here.
  1623. ! (JD August 2000)
  1624. IMPLICIT NONE
  1625. INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
  1626. INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
  1627. INTEGER, INTENT(IN ) :: ips,ipe, jps,jpe, kps,kpe
  1628. INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
  1629. INTEGER, INTENT(IN ) :: spec_zone
  1630. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field
  1631. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: u
  1632. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: v
  1633. TYPE( grid_config_rec_type ) config_flags
  1634. INTEGER :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf, i_inner, j_inner
  1635. INTEGER :: b_dist, b_limit
  1636. LOGICAL :: periodic_x
  1637. periodic_x = config_flags%periodic_x
  1638. ibs = ids
  1639. ibe = ide-1
  1640. itf = min(ite,ide-1)
  1641. jbs = jds
  1642. jbe = jde-1
  1643. jtf = min(jte,jde-1)
  1644. ktf = kde-1
  1645. IF (jts - jbs .lt. spec_zone) THEN
  1646. ! Y-start boundary
  1647. DO j = jts, min(jtf,jbs+spec_zone-1)
  1648. b_dist = j - jbs
  1649. b_limit = b_dist
  1650. IF(periodic_x)b_limit = 0
  1651. DO k = kts, ktf
  1652. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1653. i_inner = max(i,ibs+spec_zone)
  1654. i_inner = min(i_inner,ibe-spec_zone)
  1655. IF(periodic_x)i_inner = i
  1656. IF(v(i,k,j) .lt. 0.)THEN
  1657. field(i,k,j) = field(i_inner,k,jbs+spec_zone)
  1658. ELSE
  1659. field(i,k,j) = n_ccn0
  1660. ENDIF
  1661. ENDDO
  1662. ENDDO
  1663. ENDDO
  1664. ENDIF
  1665. IF (jbe - jtf .lt. spec_zone) THEN
  1666. ! Y-end boundary
  1667. DO j = max(jts,jbe-spec_zone+1), jtf
  1668. b_dist = jbe - j
  1669. b_limit = b_dist
  1670. IF(periodic_x)b_limit = 0
  1671. DO k = kts, ktf
  1672. DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
  1673. i_inner = max(i,ibs+spec_zone)
  1674. i_inner = min(i_inner,ibe-spec_zone)
  1675. IF(periodic_x)i_inner = i
  1676. IF(v(i,k,j+1) .gt. 0.)THEN
  1677. field(i,k,j) = field(i_inner,k,jbe-spec_zone)
  1678. ELSE
  1679. field(i,k,j) = n_ccn0
  1680. ENDIF
  1681. ENDDO
  1682. ENDDO
  1683. ENDDO
  1684. ENDIF
  1685. IF(.NOT.periodic_x)THEN
  1686. IF (its - ibs .lt. spec_zone) THEN
  1687. ! X-start boundary
  1688. DO i = its, min(itf,ibs+spec_zone-1)
  1689. b_dist = i - ibs
  1690. DO k = kts, ktf
  1691. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1692. j_inner = max(j,jbs+spec_zone)
  1693. j_inner = min(j_inner,jbe-spec_zone)
  1694. IF(u(i,k,j) .lt. 0.)THEN
  1695. field(i,k,j) = field(ibs+spec_zone,k,j_inner)
  1696. ELSE
  1697. field(i,k,j) = n_ccn0
  1698. ENDIF
  1699. ENDDO
  1700. ENDDO
  1701. ENDDO
  1702. ENDIF
  1703. IF (ibe - itf .lt. spec_zone) THEN
  1704. ! X-end boundary
  1705. DO i = max(its,ibe-spec_zone+1), itf
  1706. b_dist = ibe - i
  1707. DO k = kts, ktf
  1708. DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
  1709. j_inner = max(j,jbs+spec_zone)
  1710. j_inner = min(j_inner,jbe-spec_zone)
  1711. IF(u(i+1,k,j) .gt. 0.)THEN
  1712. field(i,k,j) = field(ibe-spec_zone,k,j_inner)
  1713. ELSE
  1714. field(i,k,j) = n_ccn0
  1715. ENDIF
  1716. ENDDO
  1717. ENDDO
  1718. ENDDO
  1719. ENDIF
  1720. ENDIF
  1721. END SUBROUTINE flow_dep_bdy_qnn
  1722. !------------------------------------------------------------------------------
  1723. SUBROUTINE stuff_bdy_new ( data3d , space_bdy_xs, space_bdy_xe, space_bdy_ys, space_bdy_ye, &
  1724. char_stagger , &
  1725. spec_bdy_width , &
  1726. ids, ide, jds, jde, kds, kde , &
  1727. ims, ime, jms, jme, kms, kme , &
  1728. its, ite, jts, jte, kts, kte )
  1729. ! This routine puts the data in the 3d arrays into the proper locations
  1730. ! for the lateral boundary arrays.
  1731. USE module_state_description
  1732. IMPLICIT NONE
  1733. INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
  1734. INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
  1735. INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
  1736. INTEGER , INTENT(IN) :: spec_bdy_width
  1737. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3d
  1738. REAL , DIMENSION(jms:jme,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_xs, space_bdy_xe
  1739. REAL , DIMENSION(ims:ime,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_ys, space_bdy_ye
  1740. CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
  1741. INTEGER :: i , ii , j , jj , k
  1742. ! There are four lateral boundary locations that are stored.
  1743. ! X start boundary
  1744. IF ( char_stagger .EQ. 'W' ) THEN
  1745. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1746. DO k = kds , kde
  1747. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  1748. space_bdy_xs(j,k,i) = data3d(i,k,j)
  1749. END DO
  1750. END DO
  1751. END DO
  1752. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  1753. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1754. DO k = kds , kde
  1755. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  1756. space_bdy_xs(j,k,i) = data3d(i,k,j)
  1757. END DO
  1758. END DO
  1759. END DO
  1760. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  1761. DO j = MAX(jds,jts) , MIN(jde,jte)
  1762. DO k = kds , kde - 1
  1763. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  1764. space_bdy_xs(j,k,i) = data3d(i,k,j)
  1765. END DO
  1766. END DO
  1767. END DO
  1768. ELSE
  1769. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1770. DO k = kds , kde - 1
  1771. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  1772. space_bdy_xs(j,k,i) = data3d(i,k,j)
  1773. END DO
  1774. END DO
  1775. END DO
  1776. END IF
  1777. ! X end boundary
  1778. IF ( char_stagger .EQ. 'U' ) THEN
  1779. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1780. DO k = kds , kde - 1
  1781. DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
  1782. ii = ide - i + 1
  1783. space_bdy_xe(j,k,ii) = data3d(i,k,j)
  1784. END DO
  1785. END DO
  1786. END DO
  1787. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  1788. DO j = MAX(jds,jts) , MIN(jde,jte)
  1789. DO k = kds , kde - 1
  1790. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  1791. ii = ide - i
  1792. space_bdy_xe(j,k,ii) = data3d(i,k,j)
  1793. END DO
  1794. END DO
  1795. END DO
  1796. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  1797. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1798. DO k = kds , kde
  1799. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  1800. ii = ide - i
  1801. space_bdy_xe(j,k,ii) = data3d(i,k,j)
  1802. END DO
  1803. END DO
  1804. END DO
  1805. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  1806. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1807. DO k = kds , kde
  1808. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  1809. ii = ide - i
  1810. space_bdy_xe(j,k,ii) = data3d(i,k,j)
  1811. END DO
  1812. END DO
  1813. END DO
  1814. ELSE
  1815. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1816. DO k = kds , kde - 1
  1817. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  1818. ii = ide - i
  1819. space_bdy_xe(j,k,ii) = data3d(i,k,j)
  1820. END DO
  1821. END DO
  1822. END DO
  1823. END IF
  1824. ! Y start boundary
  1825. IF ( char_stagger .EQ. 'W' ) THEN
  1826. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  1827. DO k = kds , kde
  1828. DO i = MAX(ids,its) , MIN(ide-1,ite)
  1829. space_bdy_ys(i,k,j) = data3d(i,k,j)
  1830. END DO
  1831. END DO
  1832. END DO
  1833. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  1834. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  1835. DO k = kds , kde
  1836. DO i = MAX(ids,its) , MIN(ide-1,ite)
  1837. space_bdy_ys(i,k,j) = data3d(i,k,j)
  1838. END DO
  1839. END DO
  1840. END DO
  1841. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  1842. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  1843. DO k = kds , kde - 1
  1844. DO i = MAX(ids,its) , MIN(ide,ite)
  1845. space_bdy_ys(i,k,j) = data3d(i,k,j)
  1846. END DO
  1847. END DO
  1848. END DO
  1849. ELSE
  1850. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  1851. DO k = kds , kde - 1
  1852. DO i = MAX(ids,its) , MIN(ide-1,ite)
  1853. space_bdy_ys(i,k,j) = data3d(i,k,j)
  1854. END DO
  1855. END DO
  1856. END DO
  1857. END IF
  1858. ! Y end boundary
  1859. IF ( char_stagger .EQ. 'V' ) THEN
  1860. DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
  1861. DO k = kds , kde - 1
  1862. DO i = MAX(ids,its) , MIN(ide-1,ite)
  1863. jj = jde - j + 1
  1864. space_bdy_ye(i,k,jj) = data3d(i,k,j)
  1865. END DO
  1866. END DO
  1867. END DO
  1868. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  1869. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  1870. DO k = kds , kde - 1
  1871. DO i = MAX(ids,its) , MIN(ide,ite)
  1872. jj = jde - j
  1873. space_bdy_ye(i,k,jj) = data3d(i,k,j)
  1874. END DO
  1875. END DO
  1876. END DO
  1877. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  1878. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  1879. DO k = kds , kde
  1880. DO i = MAX(ids,its) , MIN(ide-1,ite)
  1881. jj = jde - j
  1882. space_bdy_ye(i,k,jj) = data3d(i,k,j)
  1883. END DO
  1884. END DO
  1885. END DO
  1886. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  1887. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  1888. DO k = kds , kde
  1889. DO i = MAX(ids,its) , MIN(ide-1,ite)
  1890. jj = jde - j
  1891. space_bdy_ye(i,k,jj) = data3d(i,k,j)
  1892. END DO
  1893. END DO
  1894. END DO
  1895. ELSE
  1896. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  1897. DO k = kds , kde - 1
  1898. DO i = MAX(ids,its) , MIN(ide-1,ite)
  1899. jj = jde - j
  1900. space_bdy_ye(i,k,jj) = data3d(i,k,j)
  1901. END DO
  1902. END DO
  1903. END DO
  1904. END IF
  1905. END SUBROUTINE stuff_bdy_new
  1906. SUBROUTINE stuff_bdytend_new ( data3dnew , data3dold , time_diff , &
  1907. space_bdy_xs, space_bdy_xe, space_bdy_ys, space_bdy_ye, &
  1908. char_stagger , &
  1909. spec_bdy_width , &
  1910. ids, ide, jds, jde, kds, kde , &
  1911. ims, ime, jms, jme, kms, kme , &
  1912. its, ite, jts, jte, kts, kte )
  1913. ! This routine puts the tendency data into the proper locations
  1914. ! for the lateral boundary arrays.
  1915. USE module_state_description
  1916. IMPLICIT NONE
  1917. INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
  1918. INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
  1919. INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
  1920. INTEGER , INTENT(IN) :: spec_bdy_width
  1921. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3dnew , data3dold
  1922. REAL , DIMENSION(jms:jme,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_xs, space_bdy_xe
  1923. REAL , DIMENSION(ims:ime,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_ys, space_bdy_ye
  1924. CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
  1925. REAL , INTENT(IN) :: time_diff ! seconds
  1926. INTEGER :: i , ii , j , jj , k
  1927. #if 0
  1928. ! Here is the easy way to zero out the boundary tendencies for
  1929. ! time-dependent boundaries.
  1930. space_bdy_xs = 0.
  1931. space_bdy_xe = 0.
  1932. space_bdy_ys = 0.
  1933. space_bdy_ye = 0.
  1934. return
  1935. #else
  1936. ! There are four lateral boundary locations that are stored.
  1937. ! X start boundary
  1938. IF ( char_stagger .EQ. 'W' ) THEN
  1939. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1940. DO k = kds , kde
  1941. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  1942. space_bdy_xs(j,k,i) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  1943. END DO
  1944. END DO
  1945. END DO
  1946. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  1947. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1948. DO k = kds , kde
  1949. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  1950. space_bdy_xs(j,k,i) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  1951. END DO
  1952. END DO
  1953. END DO
  1954. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  1955. DO j = MAX(jds,jts) , MIN(jde,jte)
  1956. DO k = kds , kde - 1
  1957. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  1958. space_bdy_xs(j,k,i) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  1959. END DO
  1960. END DO
  1961. END DO
  1962. ELSE
  1963. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1964. DO k = kds , kde - 1
  1965. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  1966. space_bdy_xs(j,k,i) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  1967. END DO
  1968. END DO
  1969. END DO
  1970. END IF
  1971. ! X end boundary
  1972. IF ( char_stagger .EQ. 'U' ) THEN
  1973. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1974. DO k = kds , kde - 1
  1975. DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
  1976. ii = ide - i + 1
  1977. space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  1978. END DO
  1979. END DO
  1980. END DO
  1981. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  1982. DO j = MAX(jds,jts) , MIN(jde,jte)
  1983. DO k = kds , kde - 1
  1984. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  1985. ii = ide - i
  1986. space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  1987. END DO
  1988. END DO
  1989. END DO
  1990. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  1991. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  1992. DO k = kds , kde
  1993. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  1994. ii = ide - i
  1995. space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  1996. END DO
  1997. END DO
  1998. END DO
  1999. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2000. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2001. DO k = kds , kde
  2002. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2003. ii = ide - i
  2004. space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2005. END DO
  2006. END DO
  2007. END DO
  2008. ELSE
  2009. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2010. DO k = kds , kde - 1
  2011. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2012. ii = ide - i
  2013. space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2014. END DO
  2015. END DO
  2016. END DO
  2017. END IF
  2018. ! Y start boundary
  2019. IF ( char_stagger .EQ. 'W' ) THEN
  2020. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2021. DO k = kds , kde
  2022. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2023. space_bdy_ys(i,k,j) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2024. END DO
  2025. END DO
  2026. END DO
  2027. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2028. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2029. DO k = kds , kde
  2030. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2031. space_bdy_ys(i,k,j) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2032. END DO
  2033. END DO
  2034. END DO
  2035. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2036. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2037. DO k = kds , kde - 1
  2038. DO i = MAX(ids,its) , MIN(ide,ite)
  2039. space_bdy_ys(i,k,j) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2040. END DO
  2041. END DO
  2042. END DO
  2043. ELSE
  2044. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2045. DO k = kds , kde - 1
  2046. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2047. space_bdy_ys(i,k,j) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2048. END DO
  2049. END DO
  2050. END DO
  2051. END IF
  2052. ! Y end boundary
  2053. IF ( char_stagger .EQ. 'V' ) THEN
  2054. DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
  2055. DO k = kds , kde - 1
  2056. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2057. jj = jde - j + 1
  2058. space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2059. END DO
  2060. END DO
  2061. END DO
  2062. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2063. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2064. DO k = kds , kde - 1
  2065. DO i = MAX(ids,its) , MIN(ide,ite)
  2066. jj = jde - j
  2067. space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2068. END DO
  2069. END DO
  2070. END DO
  2071. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  2072. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2073. DO k = kds , kde
  2074. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2075. jj = jde - j
  2076. space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2077. END DO
  2078. END DO
  2079. END DO
  2080. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2081. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2082. DO k = kds , kde
  2083. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2084. jj = jde - j
  2085. space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2086. END DO
  2087. END DO
  2088. END DO
  2089. ELSE
  2090. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2091. DO k = kds , kde - 1
  2092. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2093. jj = jde - j
  2094. space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2095. END DO
  2096. END DO
  2097. END DO
  2098. END IF
  2099. #endif
  2100. END SUBROUTINE stuff_bdytend_new
  2101. !--- old versions for use with modules that use the old bdy data structures ---
  2102. SUBROUTINE stuff_bdy_old ( data3d , space_bdy , char_stagger , &
  2103. ijds , ijde , spec_bdy_width , &
  2104. ids, ide, jds, jde, kds, kde , &
  2105. ims, ime, jms, jme, kms, kme , &
  2106. its, ite, jts, jte, kts, kte )
  2107. ! This routine puts the data in the 3d arrays into the proper locations
  2108. ! for the lateral boundary arrays.
  2109. USE module_state_description
  2110. IMPLICIT NONE
  2111. INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
  2112. INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
  2113. INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
  2114. INTEGER , INTENT(IN) :: ijds , ijde , spec_bdy_width
  2115. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3d
  2116. REAL , DIMENSION(ijds:ijde,kds:kde,spec_bdy_width,4) , INTENT(OUT) :: space_bdy
  2117. CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
  2118. INTEGER :: i , ii , j , jj , k
  2119. ! There are four lateral boundary locations that are stored.
  2120. ! X start boundary
  2121. IF ( char_stagger .EQ. 'W' ) THEN
  2122. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2123. DO k = kds , kde
  2124. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2125. space_bdy(j,k,i,P_XSB) = data3d(i,k,j)
  2126. END DO
  2127. END DO
  2128. END DO
  2129. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2130. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2131. DO k = kds , kde
  2132. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2133. space_bdy(j,k,i,P_XSB) = data3d(i,k,j)
  2134. END DO
  2135. END DO
  2136. END DO
  2137. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  2138. DO j = MAX(jds,jts) , MIN(jde,jte)
  2139. DO k = kds , kde - 1
  2140. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2141. space_bdy(j,k,i,P_XSB) = data3d(i,k,j)
  2142. END DO
  2143. END DO
  2144. END DO
  2145. ELSE
  2146. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2147. DO k = kds , kde - 1
  2148. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2149. space_bdy(j,k,i,P_XSB) = data3d(i,k,j)
  2150. END DO
  2151. END DO
  2152. END DO
  2153. END IF
  2154. ! X end boundary
  2155. IF ( char_stagger .EQ. 'U' ) THEN
  2156. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2157. DO k = kds , kde - 1
  2158. DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
  2159. ii = ide - i + 1
  2160. space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
  2161. END DO
  2162. END DO
  2163. END DO
  2164. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  2165. DO j = MAX(jds,jts) , MIN(jde,jte)
  2166. DO k = kds , kde - 1
  2167. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2168. ii = ide - i
  2169. space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
  2170. END DO
  2171. END DO
  2172. END DO
  2173. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  2174. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2175. DO k = kds , kde
  2176. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2177. ii = ide - i
  2178. space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
  2179. END DO
  2180. END DO
  2181. END DO
  2182. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2183. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2184. DO k = kds , kde
  2185. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2186. ii = ide - i
  2187. space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
  2188. END DO
  2189. END DO
  2190. END DO
  2191. ELSE
  2192. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2193. DO k = kds , kde - 1
  2194. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2195. ii = ide - i
  2196. space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
  2197. END DO
  2198. END DO
  2199. END DO
  2200. END IF
  2201. ! Y start boundary
  2202. IF ( char_stagger .EQ. 'W' ) THEN
  2203. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2204. DO k = kds , kde
  2205. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2206. space_bdy(i,k,j,P_YSB) = data3d(i,k,j)
  2207. END DO
  2208. END DO
  2209. END DO
  2210. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2211. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2212. DO k = kds , kde
  2213. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2214. space_bdy(i,k,j,P_YSB) = data3d(i,k,j)
  2215. END DO
  2216. END DO
  2217. END DO
  2218. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2219. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2220. DO k = kds , kde - 1
  2221. DO i = MAX(ids,its) , MIN(ide,ite)
  2222. space_bdy(i,k,j,P_YSB) = data3d(i,k,j)
  2223. END DO
  2224. END DO
  2225. END DO
  2226. ELSE
  2227. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2228. DO k = kds , kde - 1
  2229. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2230. space_bdy(i,k,j,P_YSB) = data3d(i,k,j)
  2231. END DO
  2232. END DO
  2233. END DO
  2234. END IF
  2235. ! Y end boundary
  2236. IF ( char_stagger .EQ. 'V' ) THEN
  2237. DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
  2238. DO k = kds , kde - 1
  2239. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2240. jj = jde - j + 1
  2241. space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
  2242. END DO
  2243. END DO
  2244. END DO
  2245. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2246. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2247. DO k = kds , kde - 1
  2248. DO i = MAX(ids,its) , MIN(ide,ite)
  2249. jj = jde - j
  2250. space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
  2251. END DO
  2252. END DO
  2253. END DO
  2254. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  2255. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2256. DO k = kds , kde
  2257. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2258. jj = jde - j
  2259. space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
  2260. END DO
  2261. END DO
  2262. END DO
  2263. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2264. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2265. DO k = kds , kde
  2266. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2267. jj = jde - j
  2268. space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
  2269. END DO
  2270. END DO
  2271. END DO
  2272. ELSE
  2273. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2274. DO k = kds , kde - 1
  2275. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2276. jj = jde - j
  2277. space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
  2278. END DO
  2279. END DO
  2280. END DO
  2281. END IF
  2282. END SUBROUTINE stuff_bdy_old
  2283. SUBROUTINE stuff_bdytend_old ( data3dnew , data3dold , time_diff , space_bdy , char_stagger , &
  2284. ijds , ijde , spec_bdy_width , &
  2285. ids, ide, jds, jde, kds, kde , &
  2286. ims, ime, jms, jme, kms, kme , &
  2287. its, ite, jts, jte, kts, kte )
  2288. ! This routine puts the tendency data into the proper locations
  2289. ! for the lateral boundary arrays.
  2290. USE module_state_description
  2291. IMPLICIT NONE
  2292. INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
  2293. INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
  2294. INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
  2295. INTEGER , INTENT(IN) :: ijds , ijde , spec_bdy_width
  2296. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3dnew , data3dold
  2297. ! REAL , DIMENSION(:,:,:,:) , INTENT(OUT) :: space_bdy
  2298. REAL , DIMENSION(ijds:ijde,kds:kde,spec_bdy_width,4) , INTENT(OUT) :: space_bdy
  2299. CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
  2300. REAL , INTENT(IN) :: time_diff ! seconds
  2301. INTEGER :: i , ii , j , jj , k
  2302. ! There are four lateral boundary locations that are stored.
  2303. ! X start boundary
  2304. IF ( char_stagger .EQ. 'W' ) THEN
  2305. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2306. DO k = kds , kde
  2307. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2308. space_bdy(j,k,i,P_XSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2309. ! space_bdy(j,k,i,P_XSB) = 0. ! zeroout
  2310. END DO
  2311. END DO
  2312. END DO
  2313. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2314. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2315. DO k = kds , kde
  2316. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2317. space_bdy(j,k,i,P_XSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2318. ! space_bdy(j,k,i,P_XSB) = 0. ! zeroout
  2319. END DO
  2320. END DO
  2321. END DO
  2322. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  2323. DO j = MAX(jds,jts) , MIN(jde,jte)
  2324. DO k = kds , kde - 1
  2325. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2326. space_bdy(j,k,i,P_XSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2327. ! space_bdy(j,k,i,P_XSB) = 0. ! zeroout
  2328. END DO
  2329. END DO
  2330. END DO
  2331. ELSE
  2332. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2333. DO k = kds , kde - 1
  2334. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2335. space_bdy(j,k,i,P_XSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2336. ! space_bdy(j,k,i,P_XSB) = 0. ! zeroout
  2337. END DO
  2338. END DO
  2339. END DO
  2340. END IF
  2341. ! X end boundary
  2342. IF ( char_stagger .EQ. 'U' ) THEN
  2343. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2344. DO k = kds , kde - 1
  2345. DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
  2346. ii = ide - i + 1
  2347. space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2348. ! space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
  2349. END DO
  2350. END DO
  2351. END DO
  2352. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  2353. DO j = MAX(jds,jts) , MIN(jde,jte)
  2354. DO k = kds , kde - 1
  2355. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2356. ii = ide - i
  2357. space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2358. ! space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
  2359. END DO
  2360. END DO
  2361. END DO
  2362. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  2363. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2364. DO k = kds , kde
  2365. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2366. ii = ide - i
  2367. space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2368. ! space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
  2369. END DO
  2370. END DO
  2371. END DO
  2372. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2373. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2374. DO k = kds , kde
  2375. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2376. ii = ide - i
  2377. space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2378. ! space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
  2379. END DO
  2380. END DO
  2381. END DO
  2382. ELSE
  2383. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2384. DO k = kds , kde - 1
  2385. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2386. ii = ide - i
  2387. space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2388. ! space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
  2389. END DO
  2390. END DO
  2391. END DO
  2392. END IF
  2393. ! Y start boundary
  2394. IF ( char_stagger .EQ. 'W' ) THEN
  2395. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2396. DO k = kds , kde
  2397. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2398. space_bdy(i,k,j,P_YSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2399. ! space_bdy(i,k,j,P_YSB) = 0. ! zeroout
  2400. END DO
  2401. END DO
  2402. END DO
  2403. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2404. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2405. DO k = kds , kde
  2406. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2407. space_bdy(i,k,j,P_YSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2408. ! space_bdy(i,k,j,P_YSB) = 0. ! zeroout
  2409. END DO
  2410. END DO
  2411. END DO
  2412. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2413. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2414. DO k = kds , kde - 1
  2415. DO i = MAX(ids,its) , MIN(ide,ite)
  2416. space_bdy(i,k,j,P_YSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2417. ! space_bdy(i,k,j,P_YSB) = 0. ! zeroout
  2418. END DO
  2419. END DO
  2420. END DO
  2421. ELSE
  2422. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2423. DO k = kds , kde - 1
  2424. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2425. space_bdy(i,k,j,P_YSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2426. ! space_bdy(i,k,j,P_YSB) = 0. ! zeroout
  2427. END DO
  2428. END DO
  2429. END DO
  2430. END IF
  2431. ! Y end boundary
  2432. IF ( char_stagger .EQ. 'V' ) THEN
  2433. DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
  2434. DO k = kds , kde - 1
  2435. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2436. jj = jde - j + 1
  2437. space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2438. ! space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
  2439. END DO
  2440. END DO
  2441. END DO
  2442. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2443. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2444. DO k = kds , kde - 1
  2445. DO i = MAX(ids,its) , MIN(ide,ite)
  2446. jj = jde - j
  2447. space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2448. ! space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
  2449. END DO
  2450. END DO
  2451. END DO
  2452. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  2453. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2454. DO k = kds , kde
  2455. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2456. jj = jde - j
  2457. space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2458. ! space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
  2459. END DO
  2460. END DO
  2461. END DO
  2462. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2463. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2464. DO k = kds , kde
  2465. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2466. jj = jde - j
  2467. space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2468. ! space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
  2469. END DO
  2470. END DO
  2471. END DO
  2472. ELSE
  2473. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2474. DO k = kds , kde - 1
  2475. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2476. jj = jde - j
  2477. space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
  2478. ! space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
  2479. END DO
  2480. END DO
  2481. END DO
  2482. END IF
  2483. END SUBROUTINE stuff_bdytend_old
  2484. SUBROUTINE stuff_bdy_ijk ( data3d , space_bdy_xs, space_bdy_xe, &
  2485. space_bdy_ys, space_bdy_ye, &
  2486. char_stagger , spec_bdy_width, &
  2487. ids, ide, jds, jde, kds, kde , &
  2488. ims, ime, jms, jme, kms, kme , &
  2489. its, ite, jts, jte, kts, kte )
  2490. ! This routine puts the data in the 3d arrays into the proper locations
  2491. ! for the lateral boundary arrays.
  2492. USE module_state_description
  2493. IMPLICIT NONE
  2494. INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
  2495. INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
  2496. INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
  2497. INTEGER , INTENT(IN) :: spec_bdy_width
  2498. REAL , DIMENSION(ims:ime,jms:jme,kms:kme) , INTENT(IN) :: data3d
  2499. ! REAL , DIMENSION(:,:,:,:) , INTENT(OUT) :: space_bdy
  2500. ! REAL , DIMENSION(ijds:ijde,kds:kde,spec_bdy_width,4,1) , INTENT(OUT) :: space_bdy
  2501. REAL , DIMENSION(jms:jme,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_xs, space_bdy_xe
  2502. REAL , DIMENSION(ims:ime,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_ys, space_bdy_ye
  2503. CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
  2504. INTEGER :: i , ii , j , jj , k
  2505. ! There are four lateral boundary locations that are stored.
  2506. ! X start boundary
  2507. IF ( char_stagger .EQ. 'W' ) THEN
  2508. DO k = kds , kde
  2509. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2510. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2511. space_bdy_xs(j,k,i) = data3d(i,j,k)
  2512. END DO
  2513. END DO
  2514. END DO
  2515. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2516. DO k = kds , kde
  2517. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2518. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2519. space_bdy_xs(j,k,i) = data3d(i,j,k)
  2520. END DO
  2521. END DO
  2522. END DO
  2523. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  2524. DO k = kds , kde - 1
  2525. DO j = MAX(jds,jts) , MIN(jde,jte)
  2526. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2527. space_bdy_xs(j,k,i) = data3d(i,j,k)
  2528. END DO
  2529. END DO
  2530. END DO
  2531. ELSE
  2532. DO k = kds , kde - 1
  2533. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2534. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2535. space_bdy_xs(j,k,i) = data3d(i,j,k)
  2536. END DO
  2537. END DO
  2538. END DO
  2539. END IF
  2540. ! X end boundary
  2541. IF ( char_stagger .EQ. 'U' ) THEN
  2542. DO k = kds , kde - 1
  2543. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2544. DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
  2545. ii = ide - i + 1
  2546. space_bdy_xe(j,k,ii) = data3d(i,j,k)
  2547. END DO
  2548. END DO
  2549. END DO
  2550. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  2551. DO k = kds , kde - 1
  2552. DO j = MAX(jds,jts) , MIN(jde,jte)
  2553. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2554. ii = ide - i
  2555. space_bdy_xe(j,k,ii) = data3d(i,j,k)
  2556. END DO
  2557. END DO
  2558. END DO
  2559. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  2560. DO k = kds , kde
  2561. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2562. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2563. ii = ide - i
  2564. space_bdy_xe(j,k,ii) = data3d(i,j,k)
  2565. END DO
  2566. END DO
  2567. END DO
  2568. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2569. DO k = kds , kde
  2570. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2571. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2572. ii = ide - i
  2573. space_bdy_xe(j,k,ii) = data3d(i,j,k)
  2574. END DO
  2575. END DO
  2576. END DO
  2577. ELSE
  2578. DO k = kds , kde - 1
  2579. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2580. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2581. ii = ide - i
  2582. space_bdy_xe(j,k,ii) = data3d(i,j,k)
  2583. END DO
  2584. END DO
  2585. END DO
  2586. END IF
  2587. ! Y start boundary
  2588. IF ( char_stagger .EQ. 'W' ) THEN
  2589. DO k = kds , kde
  2590. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2591. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2592. space_bdy_ys(i,k,j) = data3d(i,j,k)
  2593. END DO
  2594. END DO
  2595. END DO
  2596. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2597. DO k = kds , kde
  2598. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2599. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2600. space_bdy_ys(i,k,j) = data3d(i,j,k)
  2601. END DO
  2602. END DO
  2603. END DO
  2604. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2605. DO k = kds , kde - 1
  2606. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2607. DO i = MAX(ids,its) , MIN(ide,ite)
  2608. space_bdy_ys(i,k,j) = data3d(i,j,k)
  2609. END DO
  2610. END DO
  2611. END DO
  2612. ELSE
  2613. DO k = kds , kde - 1
  2614. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2615. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2616. space_bdy_ys(i,k,j) = data3d(i,j,k)
  2617. END DO
  2618. END DO
  2619. END DO
  2620. END IF
  2621. ! Y end boundary
  2622. IF ( char_stagger .EQ. 'V' ) THEN
  2623. DO k = kds , kde - 1
  2624. DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
  2625. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2626. jj = jde - j + 1
  2627. space_bdy_ye(i,k,jj) = data3d(i,j,k)
  2628. END DO
  2629. END DO
  2630. END DO
  2631. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2632. DO k = kds , kde - 1
  2633. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2634. DO i = MAX(ids,its) , MIN(ide,ite)
  2635. jj = jde - j
  2636. space_bdy_ye(i,k,jj) = data3d(i,j,k)
  2637. END DO
  2638. END DO
  2639. END DO
  2640. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  2641. DO k = kds , kde
  2642. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2643. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2644. jj = jde - j
  2645. space_bdy_ye(i,k,jj) = data3d(i,j,k)
  2646. END DO
  2647. END DO
  2648. END DO
  2649. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2650. DO k = kds , kde
  2651. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2652. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2653. jj = jde - j
  2654. space_bdy_ye(i,k,jj) = data3d(i,j,k)
  2655. END DO
  2656. END DO
  2657. END DO
  2658. ELSE
  2659. DO k = kds , kde - 1
  2660. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2661. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2662. jj = jde - j
  2663. space_bdy_ye(i,k,jj) = data3d(i,j,k)
  2664. ! if (K .eq. 54 .and. I .eq. 369) then
  2665. ! write(0,*) 'N bound i,k,jj,P_YEB,data3d,space_bdy: ', i,k,jj,P_YEB,data3d(I,j,k),space_bdy(i,k,jj,P_YEB,1)
  2666. ! endif
  2667. END DO
  2668. END DO
  2669. END DO
  2670. END IF
  2671. END SUBROUTINE stuff_bdy_ijk
  2672. SUBROUTINE stuff_bdytend_ijk ( data3dnew , data3dold , time_diff , &
  2673. space_bdy_xs, space_bdy_xe, space_bdy_ys, space_bdy_ye, &
  2674. char_stagger , &
  2675. spec_bdy_width , &
  2676. ids, ide, jds, jde, kds, kde , &
  2677. ims, ime, jms, jme, kms, kme , &
  2678. its, ite, jts, jte, kts, kte )
  2679. ! This routine puts the tendency data into the proper locations
  2680. ! for the lateral boundary arrays.
  2681. USE module_state_description
  2682. IMPLICIT NONE
  2683. INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
  2684. INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
  2685. INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
  2686. INTEGER , INTENT(IN) :: spec_bdy_width
  2687. ! REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3dnew , data3dold
  2688. REAL , DIMENSION(ims:ime,jms:jme,kms:kme) , INTENT(IN) :: data3dnew , data3dold
  2689. REAL , DIMENSION(jms:jme,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_xs, space_bdy_xe
  2690. REAL , DIMENSION(ims:ime,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_ys, space_bdy_ye
  2691. CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
  2692. REAL , INTENT(IN) :: time_diff ! seconds
  2693. INTEGER :: i , ii , j , jj , k
  2694. ! There are four lateral boundary locations that are stored.
  2695. ! X start boundary
  2696. IF ( char_stagger .EQ. 'W' ) THEN
  2697. DO k = kds , kde
  2698. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2699. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2700. space_bdy_xs(j,k,i) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2701. END DO
  2702. END DO
  2703. END DO
  2704. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2705. DO k = kds , kde
  2706. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2707. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2708. space_bdy_xs(j,k,i) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2709. END DO
  2710. END DO
  2711. END DO
  2712. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  2713. DO k = kds , kde - 1
  2714. DO j = MAX(jds,jts) , MIN(jde,jte)
  2715. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2716. space_bdy_xs(j,k,i) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2717. END DO
  2718. END DO
  2719. END DO
  2720. ELSE
  2721. DO k = kds , kde - 1
  2722. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2723. DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
  2724. space_bdy_xs(j,k,i) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2725. END DO
  2726. END DO
  2727. END DO
  2728. END IF
  2729. ! X end boundary
  2730. IF ( char_stagger .EQ. 'U' ) THEN
  2731. DO k = kds , kde - 1
  2732. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2733. DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
  2734. ii = ide - i + 1
  2735. space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2736. END DO
  2737. END DO
  2738. END DO
  2739. ELSE IF ( char_stagger .EQ. 'V' ) THEN
  2740. DO k = kds , kde - 1
  2741. DO j = MAX(jds,jts) , MIN(jde,jte)
  2742. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2743. ii = ide - i
  2744. space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2745. END DO
  2746. END DO
  2747. END DO
  2748. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  2749. DO k = kds , kde
  2750. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2751. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2752. ii = ide - i
  2753. space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2754. END DO
  2755. END DO
  2756. END DO
  2757. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2758. DO k = kds , kde
  2759. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2760. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2761. ii = ide - i
  2762. space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2763. END DO
  2764. END DO
  2765. END DO
  2766. ELSE
  2767. DO k = kds , kde - 1
  2768. DO j = MAX(jds,jts) , MIN(jde-1,jte)
  2769. DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
  2770. ii = ide - i
  2771. space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2772. END DO
  2773. END DO
  2774. END DO
  2775. END IF
  2776. ! Y start boundary
  2777. IF ( char_stagger .EQ. 'W' ) THEN
  2778. DO k = kds , kde
  2779. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2780. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2781. space_bdy_ys(i,k,j) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2782. END DO
  2783. END DO
  2784. END DO
  2785. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2786. DO k = kds , kde
  2787. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2788. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2789. space_bdy_ys(i,k,j) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2790. END DO
  2791. END DO
  2792. END DO
  2793. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2794. DO k = kds , kde - 1
  2795. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2796. DO i = MAX(ids,its) , MIN(ide,ite)
  2797. space_bdy_ys(i,k,j) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2798. END DO
  2799. END DO
  2800. END DO
  2801. ELSE
  2802. DO k = kds , kde - 1
  2803. DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
  2804. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2805. space_bdy_ys(i,k,j) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2806. END DO
  2807. END DO
  2808. END DO
  2809. END IF
  2810. ! Y end boundary
  2811. IF ( char_stagger .EQ. 'V' ) THEN
  2812. DO k = kds , kde - 1
  2813. DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
  2814. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2815. jj = jde - j + 1
  2816. space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2817. END DO
  2818. END DO
  2819. END DO
  2820. ELSE IF ( char_stagger .EQ. 'U' ) THEN
  2821. DO k = kds , kde - 1
  2822. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2823. DO i = MAX(ids,its) , MIN(ide,ite)
  2824. jj = jde - j
  2825. space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2826. END DO
  2827. END DO
  2828. END DO
  2829. ELSE IF ( char_stagger .EQ. 'W' ) THEN
  2830. DO k = kds , kde
  2831. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2832. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2833. jj = jde - j
  2834. space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2835. END DO
  2836. END DO
  2837. END DO
  2838. ELSE IF ( char_stagger .EQ. 'M' ) THEN
  2839. DO k = kds , kde
  2840. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2841. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2842. jj = jde - j
  2843. space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2844. END DO
  2845. END DO
  2846. END DO
  2847. ELSE
  2848. DO k = kds , kde - 1
  2849. DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
  2850. DO i = MAX(ids,its) , MIN(ide-1,ite)
  2851. jj = jde - j
  2852. space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
  2853. ! if (K .eq. 54 .and. I .eq. 369) then
  2854. ! write(0,*) 'N bound i,k,jj,data3dnew,data3dold: ', i,k,jj,data3dnew(I,j,k),data3dold(i,j,k)
  2855. ! endif
  2856. END DO
  2857. END DO
  2858. END DO
  2859. END IF
  2860. END SUBROUTINE stuff_bdytend_ijk
  2861. END MODULE module_bc
  2862. SUBROUTINE get_bdyzone_x ( bzx )
  2863. USE module_bc
  2864. IMPLICIT NONE
  2865. INTEGER bzx
  2866. bzx = bdyzone_x
  2867. END SUBROUTINE get_bdyzone_x
  2868. SUBROUTINE get_bdyzone_y ( bzy)
  2869. USE module_bc
  2870. IMPLICIT NONE
  2871. INTEGER bzy
  2872. bzy = bdyzone_y
  2873. END SUBROUTINE get_bdyzone_y
  2874. SUBROUTINE get_bdyzone ( bz)
  2875. USE module_bc
  2876. IMPLICIT NONE
  2877. INTEGER bz
  2878. bz = bdyzone
  2879. END SUBROUTINE get_bdyzone