merge standard release WRF/WPS V3.0.1.1 into wrffire
[wrffire.git] / wrfv2_fire / share / module_bc.F
blob29349f895d63c70717c74e5c4dae0f8acaad5a56
1 !WRF:MODEL_LAYER:BOUNDARY
4 MODULE module_bc
6    USE module_configure
7    USE module_wrf_error
8    IMPLICIT NONE
10 !   TYPE bcs
12 !     LOGICAL                     :: periodic_x
13 !     LOGICAL                     :: symmetric_xs
14 !     LOGICAL                     :: symmetric_xe
15 !     LOGICAL                     :: open_xs
16 !     LOGICAL                     :: open_xe
17 !     LOGICAL                     :: periodic_y
18 !     LOGICAL                     :: symmetric_ys
19 !     LOGICAL                     :: symmetric_ye
20 !     LOGICAL                     :: open_ys
21 !     LOGICAL                     :: open_ye
22 !     LOGICAL                     :: nested
23 !     LOGICAL                     :: specified
24 !     LOGICAL                     :: top_radiation
26 !   END TYPE bcs
28 !  set the bdyzone.  We are hardwiring this here and we'll
29 !  decide later where it should be set and stored
31    INTEGER, PARAMETER            :: bdyzone = 4
32    INTEGER, PARAMETER            :: bdyzone_x = bdyzone
33    INTEGER, PARAMETER            :: bdyzone_y = bdyzone
35    INTERFACE stuff_bdy
36      MODULE PROCEDURE stuff_bdy_new , stuff_bdy_old
37    END INTERFACE
39    INTERFACE stuff_bdytend
40      MODULE PROCEDURE stuff_bdytend_new , stuff_bdytend_old
41    END INTERFACE
43 CONTAINS
45   SUBROUTINE boundary_condition_check ( config_flags, bzone, error, gn )
47 !  this routine checks the boundary condition logicals 
48 !  to make sure that the boundary conditions are not over
49 !  or under specified.  The routine also checks that the
50 !  boundary zone is sufficiently sized for the specified
51 !  boundary conditions
53   IMPLICIT NONE
55   TYPE( grid_config_rec_type ) config_flags
57   INTEGER, INTENT(IN   ) :: bzone, gn
58   INTEGER, INTENT(INOUT) :: error
60 ! local variables
62   INTEGER :: xs_bc, xe_bc, ys_bc, ye_bc, bzone_min
63   INTEGER :: nprocx, nprocy
65   CALL wrf_debug( 100 , ' checking boundary conditions for grid ' )
67   error = 0
68   xs_bc = 0
69   xe_bc = 0
70   ys_bc = 0
71   ye_bc = 0
73 !  sum the number of conditions specified for each lateral boundary.
74 !  obviously, this number should be 1
76   IF( config_flags%periodic_x ) THEN
77     xs_bc = xs_bc+1
78     xe_bc = xe_bc+1
79   ENDIF
81   IF( config_flags%periodic_y ) THEN
82     ys_bc = ys_bc+1
83     ye_bc = ye_bc+1
84   ENDIF
86   IF( config_flags%symmetric_xs ) xs_bc = xs_bc + 1
87   IF( config_flags%symmetric_xe ) xe_bc = xe_bc + 1
88   IF( config_flags%open_xs )      xs_bc = xs_bc + 1
89   IF( config_flags%open_xe )      xe_bc = xe_bc + 1
92   IF( config_flags%symmetric_ys ) ys_bc = ys_bc + 1
93   IF( config_flags%symmetric_ye ) ye_bc = ye_bc + 1
94   IF( config_flags%open_ys )      ys_bc = ys_bc + 1
95   IF( config_flags%open_ye )      ye_bc = ye_bc + 1
97   IF( config_flags%nested ) THEN
98      xs_bc = xs_bc + 1
99      xe_bc = xe_bc + 1
100      ys_bc = ys_bc + 1
101      ye_bc = ye_bc + 1
102    ENDIF
104   IF( config_flags%specified ) THEN
105      IF( .NOT. config_flags%periodic_x)xs_bc = xs_bc + 1
106      IF( .NOT. config_flags%periodic_x)xe_bc = xe_bc + 1
107      ys_bc = ys_bc + 1
108      ye_bc = ye_bc + 1
109    ENDIF
111   IF( config_flags%polar ) THEN
112      ys_bc = ys_bc + 1
113      ye_bc = ye_bc + 1
114    ENDIF
116 !  check the number of conditions for each boundary
118    IF( (xs_bc /= 1) .or. &
119        (xe_bc /= 1) .or. &
120        (ys_bc /= 1) .or. &
121        (ye_bc /= 1)         ) THEN
123      error = 1
125      write( wrf_err_message ,*) ' *** Error in boundary condition specification '
126      CALL wrf_message ( wrf_err_message )
127      write( wrf_err_message ,*) ' boundary conditions at xs ', xs_bc
128      CALL wrf_message ( wrf_err_message )
129      write( wrf_err_message ,*) ' boundary conditions at xe ', xe_bc
130      CALL wrf_message ( wrf_err_message )
131      write( wrf_err_message ,*) ' boundary conditions at ys ', ys_bc
132      CALL wrf_message ( wrf_err_message )
133      write( wrf_err_message ,*) ' boundary conditions at ye ', ye_bc
134      CALL wrf_message ( wrf_err_message )
135      write( wrf_err_message ,*) ' boundary conditions logicals are '
136      CALL wrf_message ( wrf_err_message )
137      write( wrf_err_message ,*) ' periodic_x   ',config_flags%periodic_x
138      CALL wrf_message ( wrf_err_message )
139      write( wrf_err_message ,*) ' periodic_y   ',config_flags%periodic_y
140      CALL wrf_message ( wrf_err_message )
141      write( wrf_err_message ,*) ' symmetric_xs ',config_flags%symmetric_xs
142      CALL wrf_message ( wrf_err_message )
143      write( wrf_err_message ,*) ' symmetric_xe ',config_flags%symmetric_xe
144      CALL wrf_message ( wrf_err_message )
145      write( wrf_err_message ,*) ' symmetric_ys ',config_flags%symmetric_ys
146      CALL wrf_message ( wrf_err_message )
147      write( wrf_err_message ,*) ' symmetric_ye ',config_flags%symmetric_ye
148      CALL wrf_message ( wrf_err_message )
149      write( wrf_err_message ,*) ' open_xs      ',config_flags%open_xs
150      CALL wrf_message ( wrf_err_message )
151      write( wrf_err_message ,*) ' open_xe      ',config_flags%open_xe
152      CALL wrf_message ( wrf_err_message )
153      write( wrf_err_message ,*) ' open_ys      ',config_flags%open_ys
154      CALL wrf_message ( wrf_err_message )
155      write( wrf_err_message ,*) ' open_ye      ',config_flags%open_ye
156      CALL wrf_message ( wrf_err_message )
157      write( wrf_err_message ,*) ' polar        ',config_flags%polar
158      CALL wrf_message ( wrf_err_message )
159      write( wrf_err_message ,*) ' nested       ',config_flags%nested
160      CALL wrf_message ( wrf_err_message )
161      write( wrf_err_message ,*) ' specified    ',config_flags%specified
162      CALL wrf_message ( wrf_err_message )
163      CALL wrf_error_fatal( ' *** Error in boundary condition specification ' )
165    ENDIF
167 !  now check to see if boundary zone size is sufficient.
168 !  we could have the necessary boundary zone size be returned
169 !  to the calling routine.
171    IF( config_flags%periodic_x   .or. &
172        config_flags%periodic_y   .or. &
173        config_flags%symmetric_xs .or. &
174        config_flags%symmetric_xe .or. &
175        config_flags%symmetric_ys .or. &
176        config_flags%symmetric_ye        )  THEN
178        bzone_min = MAX( 1,                                  &
179                         (config_flags%h_mom_adv_order+1)/2, &
180                         (config_flags%h_sca_adv_order+1)/2 )
182        IF( bzone < bzone_min) THEN  
184          error = 2
185          WRITE ( wrf_err_message , * ) ' boundary zone not large enough '
186          CALL wrf_message ( wrf_err_message )
187          WRITE ( wrf_err_message , * ) ' boundary zone specified      ',bzone
188          CALL wrf_message ( wrf_err_message )
189          WRITE ( wrf_err_message , * ) ' minimum boundary zone needed ',bzone_min
190          CALL wrf_error_fatal ( wrf_err_message )
192        ENDIF
193    ENDIF
195    CALL wrf_debug ( 100 , ' boundary conditions OK for grid ' )
197    END subroutine boundary_condition_check
199 !--------------------------------------------------------------------------
200    SUBROUTINE set_physical_bc2d( dat, variable_in,  &
201                                  config_flags,           & 
202                                  ids,ide, jds,jde,   & ! domain dims
203                                  ims,ime, jms,jme,   & ! memory dims
204                                  ips,ipe, jps,jpe,   & ! patch  dims
205                                  its,ite, jts,jte   )      
207 !  This subroutine sets the data in the boundary region, by direct
208 !  assignment if possible, for periodic and symmetric (wall)
209 !  boundary conditions.  Currently, we are only doing 1 variable
210 !  at a time - lots of overhead, so maybe this routine can be easily 
211 !  inlined later or we could pass multiple variables -
212 !  would probably want a largestep and smallstep version.
214 !  15 Jan 99, Dave
215 !  Modified the incoming its,ite,jts,jte to truly be the tile size.
216 !  This required modifying the loop limits when the "istag" or "jstag"
217 !  is used, as this is only required at the end of the domain.
219       IMPLICIT NONE
221       INTEGER,      INTENT(IN   )    :: ids,ide, jds,jde
222       INTEGER,      INTENT(IN   )    :: ims,ime, jms,jme
223       INTEGER,      INTENT(IN   )    :: ips,ipe, jps,jpe
224       INTEGER,      INTENT(IN   )    :: its,ite, jts,jte
225       CHARACTER,    INTENT(IN   )    :: variable_in
227       CHARACTER                      :: variable
229       REAL,  DIMENSION( ims:ime , jms:jme ) :: dat
230       TYPE( grid_config_rec_type ) config_flags
232       INTEGER  :: i, j, istag, jstag, itime
234       LOGICAL  :: debug, open_bc_copy
236 !------------
238       debug = .false.
240       open_bc_copy = .false.
242       variable = variable_in
243       IF ( variable_in .ge. 'A' .and. variable_in .le. 'Z' ) THEN
244         variable = CHAR( ICHAR(variable_in) - ICHAR('A') + ICHAR('a') )
245       ENDIF
246       IF ((variable == 'u') .or. (variable == 'v') .or.  &
247           (variable == 'w') .or. (variable == 't') .or.  &
248           (variable == 'x') .or. (variable == 'y') .or.  &
249           (variable == 'r') .or. (variable == 'p') ) open_bc_copy = .true.
251 !  begin, first set a staggering variable
253       istag = -1
254       jstag = -1
256       IF ((variable == 'u') .or. (variable == 'x')) istag = 0
257       IF ((variable == 'v') .or. (variable == 'y')) jstag = 0
259       if(debug) then
260         write(6,*) ' in bc2d, var is ',variable, istag, jstag
261         write(6,*) ' b.cs are ',  &
262       config_flags%periodic_x,  &
263       config_flags%periodic_y
264       end if
265       
268 !  periodic conditions.
269 !  note, patch must cover full range in periodic dir, or else
270 !  its intra-patch communication that is handled elsewheres.
271 !  symmetry conditions can always be handled here, because no
272 !  outside patch communication is needed
274       periodicity_x:  IF( ( config_flags%periodic_x ) ) THEN 
275         IF ( ( ids == ips ) .and.  ( ide == ipe ) ) THEN  ! test if east and west both on-processor 
276           IF ( its == ids ) THEN
278             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
279             DO i = 0,-(bdyzone-1),-1
280               dat(ids+i-1,j) = dat(ide+i-1,j)
281             ENDDO
282             ENDDO
284           ENDIF
286           IF ( ite == ide ) THEN
288             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
289 !!          DO i = 1 , bdyzone
290             DO i = -istag , bdyzone
291               dat(ide+i+istag,j) = dat(ids+i+istag,j)
292             ENDDO
293             ENDDO
295           ENDIF
296         ENDIF
298       ELSE 
300         symmetry_xs: IF( ( config_flags%symmetric_xs ) .and.  &
301                          ( its == ids )                  )  THEN
303           IF ( (variable /= 'u') .and. (variable /= 'x') ) THEN
305             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
306             DO i = 1, bdyzone
307               dat(ids-i,j) = dat(ids+i-1,j) !  here, dat(0) = dat(1), etc
308             ENDDO                             !  symmetry about dat(0.5) (u=0 pt)
309             ENDDO
311           ELSE
313             IF( variable == 'u' ) THEN
315               DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
316               DO i = 0, bdyzone-1
317                 dat(ids-i,j) = - dat(ids+i,j) ! here, u(0) = - u(2), etc
318               ENDDO                             !  normal b.c symmetry at u(1)
319               ENDDO
321             ELSE
323               DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
324               DO i = 0, bdyzone-1
325                 dat(ids-i,j) =   dat(ids+i,j) ! here, phi(0) = phi(2), etc
326               ENDDO                             !  normal b.c symmetry at phi(1)
327               ENDDO
329             END IF
331           ENDIF
333         ENDIF symmetry_xs
336 !  now the symmetry boundary at xe
338         symmetry_xe: IF( ( config_flags%symmetric_xe ) .and.  &
339                          ( ite == ide )                  )  THEN
341           IF ( (variable /= 'u') .and. (variable /= 'x') ) THEN
343             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
344             DO i = 1, bdyzone
345               dat(ide+i-1,j) = dat(ide-i,j)  !  sym. about dat(ide-0.5)
346             ENDDO
347             ENDDO
349           ELSE
351             IF (variable == 'u' ) THEN
353               DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
354               DO i = 0, bdyzone-1
355                 dat(ide+i,j) = - dat(ide-i,j)  ! u(ide+1) = - u(ide-1), etc.
356               ENDDO
357               ENDDO
360             ELSE
362               DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
363               DO i = 0, bdyzone-1
364                 dat(ide+i,j) = dat(ide-i,j)  !  phi(ide+1) = phi(ide-1), etc.
365               ENDDO
366               ENDDO
368             END IF
370           END IF 
372         END IF symmetry_xe
375 !  set open b.c in X copy into boundary zone here.  WCS, 19 March 2000
377         open_xs: IF( ( config_flags%open_xs   .or. &
378                        config_flags%specified .or. &
379                        config_flags%nested            ) .and.  &
380                          ( its == ids ) .and. open_bc_copy  )  THEN
382             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
383               dat(ids-1,j) = dat(ids,j) !  here, dat(0) = dat(1)
384               dat(ids-2,j) = dat(ids,j)
385               dat(ids-3,j) = dat(ids,j)
386             ENDDO
388         ENDIF open_xs
391 !  now the open boundary copy at xe
393         open_xe: IF( ( config_flags%open_xe   .or. &
394                        config_flags%specified .or. &
395                        config_flags%nested            ) .and.  &
396                           ( ite == ide ) .and. open_bc_copy  )  THEN
398           IF ( variable /= 'u' .and. variable /= 'x') THEN
400             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
401               dat(ide  ,j) = dat(ide-1,j) 
402               dat(ide+1,j) = dat(ide-1,j) 
403               dat(ide+2,j) = dat(ide-1,j) 
404             ENDDO
406           ELSE
408             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
409               dat(ide+1,j) = dat(ide,j)
410               dat(ide+2,j) = dat(ide,j)
411               dat(ide+3,j) = dat(ide,j)
412             ENDDO
414           END IF 
416         END IF open_xe
418 !  end open b.c in X copy into boundary zone addition.  WCS, 19 March 2000
420       END IF periodicity_x
422 !  same procedure in y
424       periodicity_y:  IF( ( config_flags%periodic_y ) ) THEN
425         IF ( ( jds == jps ) .and. ( jde == jpe ) )  THEN    ! test of both north and south on processor
427           IF( jts == jds ) then
429             DO j = 0, -(bdyzone-1), -1
430             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
431               dat(i,jds+j-1) = dat(i,jde+j-1)
432             ENDDO
433             ENDDO
435           END IF
437           IF( jte == jde ) then
439             DO j = -jstag, bdyzone
440             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
441               dat(i,jde+j+jstag) = dat(i,jds+j+jstag)
442             ENDDO
443             ENDDO
445           END IF
447         END IF
449       ELSE
451         symmetry_ys: IF( ( config_flags%symmetric_ys ) .and.  &
452                          ( jts == jds)                   )  THEN
454           IF ( (variable /= 'v') .and. (variable /= 'y') ) THEN
456             DO j = 1, bdyzone
457             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
458               dat(i,jds-j) = dat(i,jds+j-1) 
459             ENDDO
460             ENDDO
462           ELSE
464             IF (variable == 'v') THEN
466               DO j = 1, bdyzone
467               DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
468                 dat(i,jds-j) = - dat(i,jds+j) 
469               ENDDO              
470               ENDDO
472             ELSE
474               DO j = 1, bdyzone
475               DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
476                 dat(i,jds-j) = dat(i,jds+j) 
477               ENDDO              
478               ENDDO
480             END IF
482           ENDIF
484         ENDIF symmetry_ys
486 !  now the symmetry boundary at ye
488         symmetry_ye: IF( ( config_flags%symmetric_ye ) .and.  &
489                          ( jte == jde )                  )  THEN
491           IF ( (variable /= 'v') .and. (variable /= 'y') ) THEN
493             DO j = 1, bdyzone
494             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
495               dat(i,jde+j-1) = dat(i,jde-j) 
496             ENDDO                               
497             ENDDO
499           ELSE
501             IF (variable == 'v' ) THEN
503               DO j = 1, bdyzone
504               DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
505                 dat(i,jde+j) = - dat(i,jde-j)    ! bugfix: changed jds on rhs to jde , JM 20020410
506               ENDDO                               
507               ENDDO
509             ELSE
511               DO j = 1, bdyzone
512               DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
513                 dat(i,jde+j) = dat(i,jde-j)
514               ENDDO                               
515               ENDDO
517             END IF
519           ENDIF
521         END IF symmetry_ye
523 !  set open b.c in Y copy into boundary zone here.  WCS, 19 March 2000
525         open_ys: IF( ( config_flags%open_ys   .or. &
526                        config_flags%polar     .or. &
527                        config_flags%specified .or. &
528                        config_flags%nested            ) .and.  &
529                          ( jts == jds) .and. open_bc_copy )  THEN
531             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
532               dat(i,jds-1) = dat(i,jds) 
533               dat(i,jds-2) = dat(i,jds) 
534               dat(i,jds-3) = dat(i,jds) 
535             ENDDO
537         ENDIF open_ys
539 !  now the open boundary copy at ye
541         open_ye: IF( ( config_flags%open_ye   .or. &
542                        config_flags%polar     .or. &
543                        config_flags%specified .or. &
544                        config_flags%nested            ) .and.  &
545                          ( jte == jde ) .and. open_bc_copy )  THEN
547           IF  (variable /= 'v' .and. variable /= 'y' ) THEN
549             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
550               dat(i,jde  ) = dat(i,jde-1) 
551               dat(i,jde+1) = dat(i,jde-1) 
552               dat(i,jde+2) = dat(i,jde-1) 
553             ENDDO                               
555           ELSE
557             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
558               dat(i,jde+1) = dat(i,jde) 
559               dat(i,jde+2) = dat(i,jde) 
560               dat(i,jde+3) = dat(i,jde) 
561             ENDDO                               
563           ENDIF
565         END IF open_ye
566       
567 !  end open b.c in Y copy into boundary zone addition.  WCS, 19 March 2000
569       END IF periodicity_y
571 !  fix corners for doubly periodic domains
573       IF ( config_flags%periodic_x .and. config_flags%periodic_y &
574            .and. (ids == ips) .and. (ide == ipe)                 &
575            .and. (jds == jps) .and. (jde == jpe)                   ) THEN
577          IF ( (its == ids) .and. (jts == jds) ) THEN  ! lower left corner fill
578            DO j = 0, -(bdyzone-1), -1
579            DO i = 0, -(bdyzone-1), -1
580              dat(ids+i-1,jds+j-1) = dat(ide+i-1,jde+j-1)
581            ENDDO
582            ENDDO
583          END IF
585          IF ( (ite == ide) .and. (jts == jds) ) THEN  ! lower right corner fill
586            DO j = 0, -(bdyzone-1), -1
587            DO i = 1, bdyzone
588              dat(ide+i+istag,jds+j-1) = dat(ids+i+istag,jde+j-1)
589            ENDDO
590            ENDDO
591          END IF
593          IF ( (ite == ide) .and. (jte == jde) ) THEN  ! upper right corner fill
594            DO j = 1, bdyzone
595            DO i = 1, bdyzone
596              dat(ide+i+istag,jde+j+jstag) = dat(ids+i+istag,jds+j+jstag)
597            ENDDO
598            ENDDO
599          END IF
601          IF ( (its == ids) .and. (jte == jde) ) THEN  ! upper left corner fill
602            DO j = 1, bdyzone
603            DO i = 0, -(bdyzone-1), -1
604              dat(ids+i-1,jde+j+jstag) = dat(ide+i-1,jds+j+jstag)
605            ENDDO
606            ENDDO
607          END IF
609        END IF
611    END SUBROUTINE set_physical_bc2d
613 !-----------------------------------
615    SUBROUTINE set_physical_bc3d( dat, variable_in,        &
616                                config_flags,                   & 
617                                ids,ide, jds,jde, kds,kde,  & ! domain dims
618                                ims,ime, jms,jme, kms,kme,  & ! memory dims
619                                ips,ipe, jps,jpe, kps,kpe,  & ! patch  dims
620                                its,ite, jts,jte, kts,kte )
622 !  This subroutine sets the data in the boundary region, by direct
623 !  assignment if possible, for periodic and symmetric (wall)
624 !  boundary conditions.  Currently, we are only doing 1 variable
625 !  at a time - lots of overhead, so maybe this routine can be easily 
626 !  inlined later or we could pass multiple variables -
627 !  would probably want a largestep and smallstep version.
629 !  15 Jan 99, Dave
630 !  Modified the incoming its,ite,jts,jte to truly be the tile size.
631 !  This required modifying the loop limits when the "istag" or "jstag"
632 !  is used, as this is only required at the end of the domain.
634       IMPLICIT NONE
636       INTEGER,      INTENT(IN   )    :: ids,ide, jds,jde, kds,kde
637       INTEGER,      INTENT(IN   )    :: ims,ime, jms,jme, kms,kme
638       INTEGER,      INTENT(IN   )    :: ips,ipe, jps,jpe, kps,kpe
639       INTEGER,      INTENT(IN   )    :: its,ite, jts,jte, kts,kte
640       CHARACTER,    INTENT(IN   )    :: variable_in
642       CHARACTER                      :: variable
644       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ) :: dat
645       TYPE( grid_config_rec_type ) config_flags
647       INTEGER  :: i, j, k, istag, jstag, itime, k_end
649       LOGICAL  :: debug, open_bc_copy
651 !------------
653       debug = .false.
655       open_bc_copy = .false.
657       variable = variable_in
658       IF ( variable_in .ge. 'A' .and. variable_in .le. 'Z' ) THEN
659         variable = CHAR( ICHAR(variable_in) - ICHAR('A') + ICHAR('a') )
660       ENDIF
662       IF ((variable == 'u') .or. (variable == 'v') .or.     &
663           (variable == 'w') .or. (variable == 't') .or.     &
664           (variable == 'd') .or. (variable == 'e') .or. &
665           (variable == 'x') .or. (variable == 'y') .or. &
666           (variable == 'f') .or. (variable == 'r') .or. &
667           (variable == 'p')                        ) open_bc_copy = .true.
669 !  begin, first set a staggering variable
671       istag = -1
672       jstag = -1
673       k_end = max(1,min(kde-1,kte))
676       IF ((variable == 'u') .or. (variable == 'x')) istag = 0
677       IF ((variable == 'v') .or. (variable == 'y')) jstag = 0
678       IF ((variable == 'd') .or. (variable == 'xy')) then
679          istag = 0
680          jstag = 0
681       ENDIF
682       IF ((variable == 'e') ) then
683          istag = 0
684          k_end = min(kde,kte)
685       ENDIF
687       IF ((variable == 'f') ) then
688          jstag = 0
689          k_end = min(kde,kte)
690       ENDIF
692       IF ( variable == 'w')  k_end = min(kde,kte)
694 !      k_end = kte
696       if(debug) then
697         write(6,*) ' in bc, var is ',variable, istag, jstag, kte, k_end
698         write(6,*) ' b.cs are ',  &
699       config_flags%periodic_x,  &
700       config_flags%periodic_y
701       end if
702       
705 !  periodic conditions.
706 !  note, patch must cover full range in periodic dir, or else
707 !  its intra-patch communication that is handled elsewheres.
708 !  symmetry conditions can always be handled here, because no
709 !  outside patch communication is needed
711       periodicity_x:  IF( ( config_flags%periodic_x ) ) THEN
713         IF ( ( ids == ips ) .and. ( ide == ipe ) ) THEN  ! test if both east and west on-processor
714           IF ( its == ids ) THEN
716             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
717             DO k = kts, k_end
718             DO i = 0,-(bdyzone-1),-1
719               dat(ids+i-1,k,j) = dat(ide+i-1,k,j)
720             ENDDO
721             ENDDO
722             ENDDO
724           ENDIF
727           IF ( ite == ide ) THEN
729             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
730             DO k = kts, k_end
731             DO i = -istag , bdyzone
732               dat(ide+i+istag,k,j) = dat(ids+i+istag,k,j)
733             ENDDO
734             ENDDO
735             ENDDO
737           ENDIF
739         ENDIF
741       ELSE 
743         symmetry_xs: IF( ( config_flags%symmetric_xs ) .and.  &
744                          ( its == ids )                  )  THEN
746           IF ( (variable /= 'u') .and. (variable /= 'x') ) THEN
748             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
749             DO k = kts, k_end
750             DO i = 1, bdyzone
751               dat(ids-i,k,j) = dat(ids+i-1,k,j) !  here, dat(0) = dat(1), etc
752             ENDDO                                 !  symmetry about dat(0.5) (u = 0 pt)
753             ENDDO
754             ENDDO
756           ELSE
758             IF ( variable == 'u' ) THEN
760               DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
761               DO k = kts, k_end
762               DO i = 1, bdyzone
763                 dat(ids-i,k,j) = - dat(ids+i,k,j) ! here, u(0) = - u(2), etc
764               ENDDO                                 !  normal b.c symmetry at u(1)
765               ENDDO
766               ENDDO
768             ELSE
770               DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
771               DO k = kts, k_end
772               DO i = 1, bdyzone
773                 dat(ids-i,k,j) = dat(ids+i,k,j) ! here, phi(0) = phi(2), etc
774               ENDDO                               !  normal b.c symmetry at phi(1)
775               ENDDO
776               ENDDO
778             END IF
780           ENDIF
782         ENDIF symmetry_xs
785 !  now the symmetry boundary at xe
787         symmetry_xe: IF( ( config_flags%symmetric_xe ) .and.  &
788                          ( ite == ide )                  )  THEN
790           IF ( (variable /= 'u') .and. (variable /= 'x') ) THEN
792             DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
793             DO k = kts, k_end
794             DO i = 1, bdyzone
795               dat(ide+i-1,k,j) = dat(ide-i,k,j)  !  sym. about dat(ide-0.5)
796             ENDDO
797             ENDDO
798             ENDDO
800           ELSE
802             IF (variable == 'u') THEN
804               DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
805               DO k = kts, k_end
806               DO i = 1, bdyzone
807                 dat(ide+i,k,j) = - dat(ide-i,k,j)  ! u(ide+1) = - u(ide-1), etc.
808               ENDDO
809               ENDDO
810               ENDDO
812             ELSE
814               DO j = MAX(jds,jts-1), MIN(jte+1,jde+jstag)
815               DO k = kts, k_end
816               DO i = 1, bdyzone
817                 dat(ide+i,k,j) = dat(ide-i,k,j)  ! phi(ide+1) = - phi(ide-1), etc.
818               ENDDO
819               ENDDO
820               ENDDO
822              END IF
824           END IF 
826         END IF symmetry_xe
828 !  set open b.c in X copy into boundary zone here.  WCS, 19 March 2000
830         open_xs: IF( ( config_flags%open_xs   .or. &
831                        config_flags%specified .or. &
832                        config_flags%nested            ) .and.  &
833                          ( its == ids ) .and. open_bc_copy  )  THEN
835             DO j = jts-bdyzone, MIN(jte,jde+jstag)+bdyzone
836             DO k = kts, k_end
837               dat(ids-1,k,j) = dat(ids,k,j) !  here, dat(0) = dat(1), etc
838               dat(ids-2,k,j) = dat(ids,k,j)
839               dat(ids-3,k,j) = dat(ids,k,j)
840             ENDDO
841             ENDDO
843         ENDIF open_xs
846 !  now the open_xe boundary copy 
848         open_xe: IF( ( config_flags%open_xe   .or. &
849                        config_flags%specified .or. &
850                        config_flags%nested            ) .and.  &
851                          ( ite == ide ) .and. open_bc_copy )  THEN
853           IF (variable /= 'u' .and. variable /= 'x' ) THEN
855             DO j = jts-bdyzone, MIN(jte,jde+jstag)+bdyzone
856             DO k = kts, k_end
857               dat(ide  ,k,j) = dat(ide-1,k,j)
858               dat(ide+1,k,j) = dat(ide-1,k,j)
859               dat(ide+2,k,j) = dat(ide-1,k,j)
860             ENDDO
861             ENDDO
863           ELSE
865 !!!!!!! I am not sure about this one!  JM 20020402
866             DO j = MAX(jds,jts-1)-bdyzone, MIN(jte+1,jde+jstag)+bdyzone
867             DO k = kts, k_end
868               dat(ide+1,k,j) = dat(ide,k,j)
869               dat(ide+2,k,j) = dat(ide,k,j)
870               dat(ide+3,k,j) = dat(ide,k,j)
871             ENDDO
872             ENDDO
874           END IF 
876         END IF open_xe
878 !  end open b.c in X copy into boundary zone addition.  WCS, 19 March 2000
880       END IF periodicity_x
882 !  same procedure in y
884       periodicity_y:  IF( ( config_flags%periodic_y ) ) THEN
885         IF ( ( jds == jps ) .and. ( jde == jpe ) )  THEN      ! test if both north and south on processor
886           IF( jts == jds ) then
888             DO j = 0, -(bdyzone-1), -1
889             DO k = kts, k_end
890             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
891               dat(i,k,jds+j-1) = dat(i,k,jde+j-1)
892             ENDDO
893             ENDDO
894             ENDDO
896           END IF
898           IF( jte == jde ) then
900             DO j = -jstag, bdyzone
901             DO k = kts, k_end
902             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
903               dat(i,k,jde+j+jstag) = dat(i,k,jds+j+jstag)
904             ENDDO
905             ENDDO
906             ENDDO
908           END IF
910         END IF
912       ELSE
914         symmetry_ys: IF( ( config_flags%symmetric_ys ) .and.  &
915                          ( jts == jds)                   )  THEN
917           IF ( (variable /= 'v') .and. (variable /= 'y') ) THEN
919             DO j = 1, bdyzone
920             DO k = kts, k_end
921             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
922               dat(i,k,jds-j) = dat(i,k,jds+j-1) 
923             ENDDO                               
924             ENDDO
925             ENDDO
927           ELSE
929             IF (variable == 'v') THEN
931               DO j = 1, bdyzone
932               DO k = kts, k_end
933               DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
934                 dat(i,k,jds-j) = - dat(i,k,jds+j) 
935               ENDDO              
936               ENDDO
937               ENDDO
939             ELSE
941               DO j = 1, bdyzone
942               DO k = kts, k_end
943               DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
944                 dat(i,k,jds-j) = dat(i,k,jds+j) 
945               ENDDO              
946               ENDDO
947               ENDDO
949             END IF
951           ENDIF
953         ENDIF symmetry_ys
955 !  now the symmetry boundary at ye
957         symmetry_ye: IF( ( config_flags%symmetric_ye ) .and.  &
958                          ( jte == jde )                  )  THEN
960           IF ( (variable /= 'v') .and. (variable /= 'y') ) THEN
962             DO j = 1, bdyzone
963             DO k = kts, k_end
964             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
965               dat(i,k,jde+j-1) = dat(i,k,jde-j) 
966             ENDDO                               
967             ENDDO
968             ENDDO
970           ELSE
972             IF ( variable == 'v' ) THEN
974               DO j = 1, bdyzone
975               DO k = kts, k_end
976               DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
977                 dat(i,k,jde+j) = - dat(i,k,jde-j) 
978               ENDDO                               
979               ENDDO
980               ENDDO
982             ELSE
984               DO j = 1, bdyzone
985               DO k = kts, k_end
986               DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
987                 dat(i,k,jde+j) = dat(i,k,jde-j) 
988               ENDDO                               
989               ENDDO
990               ENDDO
992             END IF
994           ENDIF
996         END IF symmetry_ye
997       
998 !  set open b.c in Y copy into boundary zone here.  WCS, 19 March 2000
1000         open_ys: IF( ( config_flags%open_ys   .or. &
1001                        config_flags%polar     .or. &
1002                        config_flags%specified .or. &
1003                        config_flags%nested            ) .and.  &
1004                          ( jts == jds) .and. open_bc_copy )  THEN
1006             DO k = kts, k_end
1007             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
1008               dat(i,k,jds-1) = dat(i,k,jds) 
1009               dat(i,k,jds-2) = dat(i,k,jds) 
1010               dat(i,k,jds-3) = dat(i,k,jds) 
1011             ENDDO
1012             ENDDO
1014         ENDIF open_ys
1016 !  now the open boundary copy at ye
1018         open_ye: IF( ( config_flags%open_ye   .or. &
1019                        config_flags%polar     .or. &
1020                        config_flags%specified .or. &
1021                        config_flags%nested            ) .and.  &
1022                          ( jte == jde ) .and. open_bc_copy )  THEN
1024           IF (variable /= 'v' .and. variable /= 'y' ) THEN
1026             DO k = kts, k_end
1027             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
1028               dat(i,k,jde  ) = dat(i,k,jde-1) 
1029               dat(i,k,jde+1) = dat(i,k,jde-1) 
1030               dat(i,k,jde+2) = dat(i,k,jde-1) 
1031             ENDDO                               
1032             ENDDO
1034           ELSE
1036             DO k = kts, k_end
1037             DO i = MAX(ids,its-1), MIN(ite+1,ide+istag)
1038               dat(i,k,jde+1) = dat(i,k,jde) 
1039               dat(i,k,jde+2) = dat(i,k,jde) 
1040               dat(i,k,jde+3) = dat(i,k,jde) 
1041             ENDDO                               
1042             ENDDO
1044           ENDIF
1046       END IF open_ye
1048 !  end open b.c in Y copy into boundary zone addition.  WCS, 19 March 2000
1050       END IF periodicity_y
1052 !  fix corners for doubly periodic domains
1054       IF ( config_flags%periodic_x .and. config_flags%periodic_y &
1055            .and. (ids == ips) .and. (ide == ipe)                 &
1056            .and. (jds == jps) .and. (jde == jpe)                   ) THEN
1058          IF ( (its == ids) .and. (jts == jds) ) THEN  ! lower left corner fill
1059            DO j = 0, -(bdyzone-1), -1
1060            DO k = kts, k_end
1061            DO i = 0, -(bdyzone-1), -1
1062              dat(ids+i-1,k,jds+j-1) = dat(ide+i-1,k,jde+j-1)
1063            ENDDO
1064            ENDDO
1065            ENDDO
1066          END IF
1068          IF ( (ite == ide) .and. (jts == jds) ) THEN  ! lower right corner fill
1069            DO j = 0, -(bdyzone-1), -1
1070            DO k = kts, k_end
1071            DO i = 1, bdyzone
1072              dat(ide+i+istag,k,jds+j-1) = dat(ids+i+istag,k,jde+j-1)
1073            ENDDO
1074            ENDDO
1075            ENDDO
1076          END IF
1078          IF ( (ite == ide) .and. (jte == jde) ) THEN  ! upper right corner fill
1079            DO j = 1, bdyzone
1080            DO k = kts, k_end
1081            DO i = 1, bdyzone
1082              dat(ide+i+istag,k,jde+j+jstag) = dat(ids+i+istag,k,jds+j+jstag)
1083            ENDDO
1084            ENDDO
1085            ENDDO
1086          END IF
1088          IF ( (its == ids) .and. (jte == jde) ) THEN  ! upper left corner fill
1089            DO j = 1, bdyzone
1090            DO k = kts, k_end
1091            DO i = 0, -(bdyzone-1), -1
1092              dat(ids+i-1,k,jde+j+jstag) = dat(ide+i-1,k,jds+j+jstag)
1093            ENDDO
1094            ENDDO
1095            ENDDO
1096          END IF
1098        END IF
1100    END SUBROUTINE set_physical_bc3d
1102    SUBROUTINE init_module_bc
1103    END SUBROUTINE init_module_bc
1105 !------------------------------------------------------------------------
1106    SUBROUTINE relax_bdytend   ( field, field_tend,                     &
1107                                 field_bdy_xs, field_bdy_xe,            &
1108                                 field_bdy_ys, field_bdy_ye,            &
1109                                 field_bdy_tend_xs, field_bdy_tend_xe,  &
1110                                 field_bdy_tend_ys, field_bdy_tend_ye,  &
1111                                 variable_in, config_flags,             &
1112                                 spec_bdy_width, spec_zone, relax_zone, &
1113                                 dtbc, fcx, gcx,             &
1114                                 ids,ide, jds,jde, kds,kde,  & ! domain dims
1115                                 ims,ime, jms,jme, kms,kme,  & ! memory dims
1116                                 ips,ipe, jps,jpe, kps,kpe,  & ! patch  dims
1117                                 its,ite, jts,jte, kts,kte )
1119 !  This subroutine adds the tendencies in the boundary relaxation region, for specified
1120 !  boundary conditions.  
1121 !  spec_bdy_width is only used to dimension the boundary arrays.
1122 !  relax_zone is the inner edge of the boundary relaxation zone treated here.
1123 !  spec_zone is the width of the outer specified b.c.s that are not changed here.
1124 !  (JD July 2000)
1126       IMPLICIT NONE
1128       INTEGER,      INTENT(IN   )    :: ids,ide, jds,jde, kds,kde
1129       INTEGER,      INTENT(IN   )    :: ims,ime, jms,jme, kms,kme
1130       INTEGER,      INTENT(IN   )    :: ips,ipe, jps,jpe, kps,kpe
1131       INTEGER,      INTENT(IN   )    :: its,ite, jts,jte, kts,kte
1132       INTEGER,      INTENT(IN   )    :: spec_bdy_width, spec_zone, relax_zone
1133       REAL,         INTENT(IN   )    :: dtbc
1134       CHARACTER,    INTENT(IN   )    :: variable_in
1137       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN   ) :: field
1138       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field_tend
1139       REAL,  DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_xs, field_bdy_xe
1140       REAL,  DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_ys, field_bdy_ye
1141       REAL,  DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_tend_xs, field_bdy_tend_xe
1142       REAL,  DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_tend_ys, field_bdy_tend_ye
1143       REAL,  DIMENSION( spec_bdy_width ), INTENT(IN   ) :: fcx, gcx
1144       TYPE( grid_config_rec_type ) config_flags
1146       CHARACTER  :: variable
1147       INTEGER    :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf, im1, ip1
1148       INTEGER    :: b_dist, b_limit
1149       REAL       :: fls0, fls1, fls2, fls3, fls4
1150       LOGICAL    :: periodic_x
1152       periodic_x = config_flags%periodic_x
1153       variable = variable_in
1155       IF (variable == 'U') variable = 'u'
1156       IF (variable == 'V') variable = 'v'
1157       IF (variable == 'M') variable = 'm'
1158       IF (variable == 'H') variable = 'h'
1160       ibs = ids
1161       ibe = ide-1
1162       itf = min(ite,ide-1)
1163       jbs = jds
1164       jbe = jde-1
1165       jtf = min(jte,jde-1)
1166       ktf = kde-1
1167       IF (variable == 'u') ibe = ide
1168       IF (variable == 'u') itf = min(ite,ide)
1169       IF (variable == 'v') jbe = jde
1170       IF (variable == 'v') jtf = min(jte,jde)
1171       IF (variable == 'm') ktf = kte
1172       IF (variable == 'h') ktf = kte
1174       IF (jts - jbs .lt. relax_zone) THEN
1175 ! Y-start boundary
1176         DO j = max(jts,jbs+spec_zone), min(jtf,jbs+relax_zone-1)
1177           b_dist = j - jbs
1178           b_limit = b_dist
1179           IF(periodic_x)b_limit = 0
1180           DO k = kts, ktf
1181             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1182               im1 = max(i-1,ibs)
1183               ip1 = min(i+1,ibe)
1184               fls0 = field_bdy_ys(i, k, b_dist+1) &
1185                    + dtbc * field_bdy_tend_ys(i, k, b_dist+1) &
1186                    - field(i,k,j)
1187               fls1 = field_bdy_ys(im1, k, b_dist+1) &
1188                    + dtbc * field_bdy_tend_ys(im1, k, b_dist+1) &
1189                    - field(im1,k,j)
1190               fls2 = field_bdy_ys(ip1, k, b_dist+1) &
1191                    + dtbc * field_bdy_tend_ys(ip1, k, b_dist+1) &
1192                    - field(ip1,k,j)
1193               fls3 = field_bdy_ys(i, k, b_dist) &
1194                    + dtbc * field_bdy_tend_ys(i, k, b_dist) &
1195                    - field(i,k,j-1)
1196               fls4 = field_bdy_ys(i, k, b_dist+2) &
1197                    + dtbc * field_bdy_tend_ys(i, k, b_dist+2) &
1198                    - field(i,k,j+1)
1199               field_tend(i,k,j) = field_tend(i,k,j) &
1200                                 + fcx(b_dist+1)*fls0 &
1201                                 - gcx(b_dist+1)*(fls1+fls2+fls3+fls4-4.*fls0)
1202             ENDDO
1203           ENDDO
1204         ENDDO
1205       ENDIF
1207       IF (jbe - jtf .lt. relax_zone) THEN
1208 ! Y-end boundary
1209         DO j = max(jts,jbe-relax_zone+1), min(jtf,jbe-spec_zone)
1210           b_dist = jbe - j
1211           b_limit = b_dist
1212           IF(periodic_x)b_limit = 0
1213           DO k = kts, ktf
1214             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1215               im1 = max(i-1,ibs)
1216               ip1 = min(i+1,ibe)
1217               fls0 = field_bdy_ye(i, k, b_dist+1) &
1218                    + dtbc * field_bdy_tend_ye(i, k, b_dist+1) &
1219                    - field(i,k,j)
1220               fls1 = field_bdy_ye(im1, k, b_dist+1) &
1221                    + dtbc * field_bdy_tend_ye(im1, k, b_dist+1) &
1222                    - field(im1,k,j)
1223               fls2 = field_bdy_ye(ip1, k, b_dist+1) &
1224                    + dtbc * field_bdy_tend_ye(ip1, k, b_dist+1) &
1225                    - field(ip1,k,j)
1226               fls3 = field_bdy_ye(i, k, b_dist) &
1227                    + dtbc * field_bdy_tend_ye(i, k, b_dist) &
1228                    - field(i,k,j+1)
1229               fls4 = field_bdy_ye(i, k, b_dist+2) &
1230                    + dtbc * field_bdy_tend_ye(i, k, b_dist+2) &
1231                    - field(i,k,j-1)
1232               field_tend(i,k,j) = field_tend(i,k,j) &
1233                                 + fcx(b_dist+1)*fls0 &
1234                                 - gcx(b_dist+1)*(fls1+fls2+fls3+fls4-4.*fls0)
1236             ENDDO
1237           ENDDO
1238         ENDDO
1239       ENDIF
1241     IF(.NOT.periodic_x)THEN
1242       IF (its - ibs .lt. relax_zone) THEN
1243 ! X-start boundary
1244         DO i = max(its,ibs+spec_zone), min(itf,ibs+relax_zone-1)
1245           b_dist = i - ibs
1246           DO k = kts, ktf
1247             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1248               fls0 = field_bdy_xs(j, k, b_dist+1) &
1249                    + dtbc * field_bdy_tend_xs(j, k, b_dist+1) &
1250                    - field(i,k,j)
1251               fls1 = field_bdy_xs(j-1, k, b_dist+1) &
1252                    + dtbc * field_bdy_tend_xs(j-1, k, b_dist+1) &
1253                    - field(i,k,j-1)
1254               fls2 = field_bdy_xs(j+1, k, b_dist+1) &
1255                    + dtbc * field_bdy_tend_xs(j+1, k, b_dist+1) &
1256                    - field(i,k,j+1)
1257               fls3 = field_bdy_xs(j, k, b_dist) &
1258                    + dtbc * field_bdy_tend_xs(j, k, b_dist) &
1259                    - field(i-1,k,j)
1260               fls4 = field_bdy_xs(j, k, b_dist+2) &
1261                    + dtbc * field_bdy_tend_xs(j, k, b_dist+2) &
1262                    - field(i+1,k,j)
1263               field_tend(i,k,j) = field_tend(i,k,j) &
1264                                 + fcx(b_dist+1)*fls0 &
1265                                 - gcx(b_dist+1)*(fls1+fls2+fls3+fls4-4.*fls0)
1267             ENDDO
1268           ENDDO
1269         ENDDO
1270       ENDIF
1272       IF (ibe - itf .lt. relax_zone) THEN
1273 ! X-end boundary
1274         DO i = max(its,ibe-relax_zone+1), min(itf,ibe-spec_zone)
1275           b_dist = ibe - i
1276           DO k = kts, ktf
1277             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1278               fls0 = field_bdy_xe(j, k, b_dist+1) &
1279                    + dtbc * field_bdy_tend_xe(j, k, b_dist+1) &
1280                    - field(i,k,j)
1281               fls1 = field_bdy_xe(j-1, k, b_dist+1) &
1282                    + dtbc * field_bdy_tend_xe(j-1, k, b_dist+1) &
1283                    - field(i,k,j-1)
1284               fls2 = field_bdy_xe(j+1, k, b_dist+1) &
1285                    + dtbc * field_bdy_tend_xe(j+1, k, b_dist+1) &
1286                    - field(i,k,j+1)
1287               fls3 = field_bdy_xe(j, k, b_dist) &
1288                    + dtbc * field_bdy_tend_xe(j, k, b_dist) &
1289                    - field(i+1,k,j)
1290               fls4 = field_bdy_xe(j, k, b_dist+2) &
1291                    + dtbc * field_bdy_tend_xe(j, k, b_dist+2) &
1292                    - field(i-1,k,j)
1293               field_tend(i,k,j) = field_tend(i,k,j) &
1294                                 + fcx(b_dist+1)*fls0 &
1295                                 - gcx(b_dist+1)*(fls1+fls2+fls3+fls4-4.*fls0)
1296             ENDDO
1297           ENDDO
1298         ENDDO
1299       ENDIF
1300     ENDIF
1303    END SUBROUTINE relax_bdytend
1304 !------------------------------------------------------------------------
1306    SUBROUTINE spec_bdytend   ( field_tend,                           &
1307                                field_bdy_xs, field_bdy_xe,           &
1308                                field_bdy_ys, field_bdy_ye,           &
1309                                field_bdy_tend_xs, field_bdy_tend_xe, &
1310                                field_bdy_tend_ys, field_bdy_tend_ye, &
1311                                variable_in, config_flags, & 
1312                                spec_bdy_width, spec_zone, &
1313                                ids,ide, jds,jde, kds,kde,  & ! domain dims
1314                                ims,ime, jms,jme, kms,kme,  & ! memory dims
1315                                ips,ipe, jps,jpe, kps,kpe,  & ! patch  dims
1316                                its,ite, jts,jte, kts,kte )
1318 !  This subroutine sets the tendencies in the boundary specified region.
1319 !  spec_bdy_width is only used to dimension the boundary arrays.
1320 !  spec_zone is the width of the outer specified b.c.s that are set here.
1321 !  (JD July 2000)
1323       IMPLICIT NONE
1325       INTEGER,      INTENT(IN   )    :: ids,ide, jds,jde, kds,kde
1326       INTEGER,      INTENT(IN   )    :: ims,ime, jms,jme, kms,kme
1327       INTEGER,      INTENT(IN   )    :: ips,ipe, jps,jpe, kps,kpe
1328       INTEGER,      INTENT(IN   )    :: its,ite, jts,jte, kts,kte
1329       INTEGER,      INTENT(IN   )    :: spec_bdy_width, spec_zone
1330       CHARACTER,    INTENT(IN   )    :: variable_in
1333       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(OUT  ) :: field_tend
1334       REAL,  DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_xs, field_bdy_xe
1335       REAL,  DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_ys, field_bdy_ye 
1336       REAL,  DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_tend_xs, field_bdy_tend_xe
1337       REAL,  DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_tend_ys, field_bdy_tend_ye 
1338       TYPE( grid_config_rec_type ) config_flags
1340       CHARACTER  :: variable
1341       INTEGER    :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf
1342       INTEGER    :: b_dist, b_limit
1343       LOGICAL    :: periodic_x
1345       periodic_x = config_flags%periodic_x
1347       variable = variable_in
1349       IF (variable == 'U') variable = 'u'
1350       IF (variable == 'V') variable = 'v'
1351       IF (variable == 'M') variable = 'm'
1352       IF (variable == 'H') variable = 'h'
1354       ibs = ids
1355       ibe = ide-1
1356       itf = min(ite,ide-1)
1357       jbs = jds
1358       jbe = jde-1
1359       jtf = min(jte,jde-1)
1360       ktf = kde-1
1361       IF (variable == 'u') ibe = ide
1362       IF (variable == 'u') itf = min(ite,ide)
1363       IF (variable == 'v') jbe = jde
1364       IF (variable == 'v') jtf = min(jte,jde)
1365       IF (variable == 'm') ktf = kte
1366       IF (variable == 'h') ktf = kte
1368       IF (jts - jbs .lt. spec_zone) THEN
1369 ! Y-start boundary
1370         DO j = jts, min(jtf,jbs+spec_zone-1)
1371           b_dist = j - jbs
1372           b_limit = b_dist
1373           IF(periodic_x)b_limit = 0
1374           DO k = kts, ktf
1375             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1376               field_tend(i,k,j) = field_bdy_tend_ys(i, k, b_dist+1)
1377             ENDDO
1378           ENDDO
1379         ENDDO
1380       ENDIF 
1381       IF (jbe - jtf .lt. spec_zone) THEN 
1382 ! Y-end boundary 
1383         DO j = max(jts,jbe-spec_zone+1), jtf 
1384           b_dist = jbe - j 
1385           b_limit = b_dist
1386           IF(periodic_x)b_limit = 0
1387           DO k = kts, ktf 
1388             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1389               field_tend(i,k,j) = field_bdy_tend_ye(i, k, b_dist+1)
1390             ENDDO
1391           ENDDO
1392         ENDDO
1393       ENDIF 
1395     IF(.NOT.periodic_x)THEN
1396       IF (its - ibs .lt. spec_zone) THEN
1397 ! X-start boundary
1398         DO i = its, min(itf,ibs+spec_zone-1)
1399           b_dist = i - ibs
1400           DO k = kts, ktf
1401             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1402               field_tend(i,k,j) = field_bdy_tend_xs(j, k, b_dist+1)
1403             ENDDO
1404           ENDDO
1405         ENDDO
1406       ENDIF 
1408       IF (ibe - itf .lt. spec_zone) THEN
1409 ! X-end boundary
1410         DO i = max(its,ibe-spec_zone+1), itf
1411           b_dist = ibe - i
1412           DO k = kts, ktf
1413             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1414               field_tend(i,k,j) = field_bdy_tend_xe(j, k, b_dist+1)
1415             ENDDO
1416           ENDDO
1417         ENDDO
1418       ENDIF 
1419     ENDIF
1421    END SUBROUTINE spec_bdytend
1422 !------------------------------------------------------------------------
1424    SUBROUTINE spec_bdyfield   ( field,                     &
1425                                field_bdy_xs, field_bdy_xe,           &
1426                                field_bdy_ys, field_bdy_ye,           &
1427                                variable_in, config_flags,  & 
1428                                spec_bdy_width, spec_zone, &
1429                                ids,ide, jds,jde, kds,kde,  & ! domain dims
1430                                ims,ime, jms,jme, kms,kme,  & ! memory dims
1431                                ips,ipe, jps,jpe, kps,kpe,  & ! patch  dims
1432                                its,ite, jts,jte, kts,kte )
1434 !  This subroutine sets the tendencies in the boundary specified region.
1435 !  spec_bdy_width is only used to dimension the boundary arrays.
1436 !  spec_zone is the width of the outer specified b.c.s that are set here.
1437 !  (JD July 2000)
1439       IMPLICIT NONE
1441       INTEGER,      INTENT(IN   )    :: ids,ide, jds,jde, kds,kde
1442       INTEGER,      INTENT(IN   )    :: ims,ime, jms,jme, kms,kme
1443       INTEGER,      INTENT(IN   )    :: ips,ipe, jps,jpe, kps,kpe
1444       INTEGER,      INTENT(IN   )    :: its,ite, jts,jte, kts,kte
1445       INTEGER,      INTENT(IN   )    :: spec_bdy_width, spec_zone
1446       CHARACTER,    INTENT(IN   )    :: variable_in
1449       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(OUT  ) :: field
1450       REAL,  DIMENSION( jms:jme , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_xs, field_bdy_xe
1451       REAL,  DIMENSION( ims:ime , kds:kde , spec_bdy_width ), INTENT(IN   ) :: field_bdy_ys, field_bdy_ye
1452       TYPE( grid_config_rec_type ) config_flags
1454       CHARACTER  :: variable
1455       INTEGER    :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf
1456       INTEGER    :: b_dist, b_limit
1457       LOGICAL    :: periodic_x
1459       periodic_x = config_flags%periodic_x
1461       variable = variable_in
1463       IF (variable == 'U') variable = 'u'
1464       IF (variable == 'V') variable = 'v'
1465       IF (variable == 'M') variable = 'm'
1466       IF (variable == 'H') variable = 'h'
1468       ibs = ids
1469       ibe = ide-1
1470       itf = min(ite,ide-1)
1471       jbs = jds
1472       jbe = jde-1
1473       jtf = min(jte,jde-1)
1474       ktf = kde-1
1475       IF (variable == 'u') ibe = ide
1476       IF (variable == 'u') itf = min(ite,ide)
1477       IF (variable == 'v') jbe = jde
1478       IF (variable == 'v') jtf = min(jte,jde)
1479       IF (variable == 'm') ktf = kte
1480       IF (variable == 'h') ktf = kte
1482       IF (jts - jbs .lt. spec_zone) THEN
1483 ! Y-start boundary
1484         DO j = jts, min(jtf,jbs+spec_zone-1)
1485           b_dist = j - jbs
1486           b_limit = b_dist
1487           IF(periodic_x)b_limit = 0
1488           DO k = kts, ktf
1489             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1490               field(i,k,j) = field_bdy_ys(i, k, b_dist+1)
1491             ENDDO
1492           ENDDO
1493         ENDDO
1494       ENDIF
1495       IF (jbe - jtf .lt. spec_zone) THEN
1496 ! Y-end boundary
1497         DO j = max(jts,jbe-spec_zone+1), jtf
1498           b_dist = jbe - j
1499           b_limit = b_dist
1500           IF(periodic_x)b_limit = 0
1501           DO k = kts, ktf
1502             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1503               field(i,k,j) = field_bdy_ye(i, k, b_dist+1)
1504             ENDDO
1505           ENDDO
1506         ENDDO
1507       ENDIF
1509     IF(.NOT.periodic_x)THEN
1510       IF (its - ibs .lt. spec_zone) THEN
1511 ! X-start boundary
1512         DO i = its, min(itf,ibs+spec_zone-1)
1513           b_dist = i - ibs
1514           DO k = kts, ktf
1515             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1516               field(i,k,j) = field_bdy_xs(j, k, b_dist+1)
1517             ENDDO
1518           ENDDO
1519         ENDDO
1520       ENDIF
1522       IF (ibe - itf .lt. spec_zone) THEN
1523 ! X-end boundary
1524         DO i = max(its,ibe-spec_zone+1), itf
1525           b_dist = ibe - i
1526           DO k = kts, ktf
1527             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1528               field(i,k,j) = field_bdy_xe(j, k, b_dist+1)
1529             ENDDO
1530           ENDDO
1531         ENDDO
1532       ENDIF
1533     ENDIF
1535    END SUBROUTINE spec_bdyfield
1536 !------------------------------------------------------------------------
1538    SUBROUTINE spec_bdyupdate(  field,      &
1539                                field_tend, dt,            &
1540                                variable_in, config_flags, & 
1541                                spec_zone,                  &
1542                                ids,ide, jds,jde, kds,kde,  & ! domain dims
1543                                ims,ime, jms,jme, kms,kme,  & ! memory dims
1544                                ips,ipe, jps,jpe, kps,kpe,  & ! patch  dims
1545                                its,ite, jts,jte, kts,kte )
1547 !  This subroutine adds the tendencies in the boundary specified region.
1548 !  spec_zone is the width of the outer specified b.c.s that are set here.
1549 !  (JD August 2000)
1551       IMPLICIT NONE
1553       INTEGER,      INTENT(IN   )    :: ids,ide, jds,jde, kds,kde
1554       INTEGER,      INTENT(IN   )    :: ims,ime, jms,jme, kms,kme
1555       INTEGER,      INTENT(IN   )    :: ips,ipe, jps,jpe, kps,kpe
1556       INTEGER,      INTENT(IN   )    :: its,ite, jts,jte, kts,kte
1557       INTEGER,      INTENT(IN   )    :: spec_zone
1558       CHARACTER,    INTENT(IN   )    :: variable_in
1559       REAL,         INTENT(IN   )    :: dt
1562       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field
1563       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN   ) :: field_tend
1564       TYPE( grid_config_rec_type ) config_flags
1566       CHARACTER  :: variable
1567       INTEGER    :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf
1568       INTEGER    :: b_dist, b_limit
1569       LOGICAL    :: periodic_x
1571       periodic_x = config_flags%periodic_x
1573       variable = variable_in
1575       IF (variable == 'U') variable = 'u'
1576       IF (variable == 'V') variable = 'v'
1577       IF (variable == 'M') variable = 'm'
1578       IF (variable == 'H') variable = 'h'
1580       ibs = ids
1581       ibe = ide-1
1582       itf = min(ite,ide-1)
1583       jbs = jds
1584       jbe = jde-1
1585       jtf = min(jte,jde-1)
1586       ktf = kde-1
1587       IF (variable == 'u') ibe = ide
1588       IF (variable == 'u') itf = min(ite,ide)
1589       IF (variable == 'v') jbe = jde
1590       IF (variable == 'v') jtf = min(jte,jde)
1591       IF (variable == 'm') ktf = kte
1592       IF (variable == 'h') ktf = kte
1594       IF (jts - jbs .lt. spec_zone) THEN
1595 ! Y-start boundary
1596         DO j = jts, min(jtf,jbs+spec_zone-1)
1597           b_dist = j - jbs
1598           b_limit = b_dist
1599           IF(periodic_x)b_limit = 0
1600           DO k = kts, ktf
1601             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1602               field(i,k,j) = field(i,k,j) + dt*field_tend(i,k,j) 
1603             ENDDO
1604           ENDDO
1605         ENDDO
1606       ENDIF 
1607       IF (jbe - jtf .lt. spec_zone) THEN 
1608 ! Y-end boundary 
1609         DO j = max(jts,jbe-spec_zone+1), jtf 
1610           b_dist = jbe - j 
1611           b_limit = b_dist
1612           IF(periodic_x)b_limit = 0
1613           DO k = kts, ktf 
1614             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1615               field(i,k,j) = field(i,k,j) + dt*field_tend(i,k,j) 
1616             ENDDO
1617           ENDDO
1618         ENDDO
1619       ENDIF 
1621     IF(.NOT.periodic_x)THEN
1622       IF (its - ibs .lt. spec_zone) THEN
1623 ! X-start boundary
1624         DO i = its, min(itf,ibs+spec_zone-1)
1625           b_dist = i - ibs
1626           DO k = kts, ktf
1627             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1628               field(i,k,j) = field(i,k,j) + dt*field_tend(i,k,j) 
1629             ENDDO
1630           ENDDO
1631         ENDDO
1632       ENDIF 
1634       IF (ibe - itf .lt. spec_zone) THEN
1635 ! X-end boundary
1636         DO i = max(its,ibe-spec_zone+1), itf
1637           b_dist = ibe - i
1638           DO k = kts, ktf
1639             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1640               field(i,k,j) = field(i,k,j) + dt*field_tend(i,k,j) 
1641             ENDDO
1642           ENDDO
1643         ENDDO
1644       ENDIF 
1645     ENDIF
1647    END SUBROUTINE spec_bdyupdate
1648 !------------------------------------------------------------------------
1650    SUBROUTINE zero_grad_bdy (  field,                     &
1651                                variable_in, config_flags, & 
1652                                spec_zone,                  &
1653                                ids,ide, jds,jde, kds,kde,  & ! domain dims
1654                                ims,ime, jms,jme, kms,kme,  & ! memory dims
1655                                ips,ipe, jps,jpe, kps,kpe,  & ! patch  dims
1656                                its,ite, jts,jte, kts,kte )
1658 !  This subroutine sets zero gradient conditions in the boundary specified region.
1659 !  spec_zone is the width of the outer specified b.c.s that are set here.
1660 !  (JD August 2000)
1662       IMPLICIT NONE
1664       INTEGER,      INTENT(IN   )    :: ids,ide, jds,jde, kds,kde
1665       INTEGER,      INTENT(IN   )    :: ims,ime, jms,jme, kms,kme
1666       INTEGER,      INTENT(IN   )    :: ips,ipe, jps,jpe, kps,kpe
1667       INTEGER,      INTENT(IN   )    :: its,ite, jts,jte, kts,kte
1668       INTEGER,      INTENT(IN   )    :: spec_zone
1669       CHARACTER,    INTENT(IN   )    :: variable_in
1672       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field
1673       TYPE( grid_config_rec_type ) config_flags
1675       CHARACTER  :: variable
1676       INTEGER    :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf, i_inner, j_inner
1677       INTEGER    :: b_dist, b_limit
1678       LOGICAL    :: periodic_x
1680       periodic_x = config_flags%periodic_x
1682       variable = variable_in
1684       IF (variable == 'U') variable = 'u'
1685       IF (variable == 'V') variable = 'v'
1687       ibs = ids
1688       ibe = ide-1
1689       itf = min(ite,ide-1)
1690       jbs = jds
1691       jbe = jde-1
1692       jtf = min(jte,jde-1)
1693       ktf = kde-1
1694       IF (variable == 'u') ibe = ide
1695       IF (variable == 'u') itf = min(ite,ide)
1696       IF (variable == 'v') jbe = jde
1697       IF (variable == 'v') jtf = min(jte,jde)
1698       IF (variable == 'w') ktf = kde
1700       IF (jts - jbs .lt. spec_zone) THEN
1701 ! Y-start boundary
1702         DO j = jts, min(jtf,jbs+spec_zone-1)
1703           b_dist = j - jbs
1704           b_limit = b_dist
1705           IF(periodic_x)b_limit = 0
1706           DO k = kts, ktf
1707             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1708               i_inner = max(i,ibs+spec_zone)
1709               i_inner = min(i_inner,ibe-spec_zone)
1710               IF(periodic_x)i_inner = i
1711               field(i,k,j) = field(i_inner,k,jbs+spec_zone)
1712             ENDDO
1713           ENDDO
1714         ENDDO
1715       ENDIF 
1716       IF (jbe - jtf .lt. spec_zone) THEN 
1717 ! Y-end boundary 
1718         DO j = max(jts,jbe-spec_zone+1), jtf 
1719           b_dist = jbe - j 
1720           b_limit = b_dist
1721           IF(periodic_x)b_limit = 0
1722           DO k = kts, ktf 
1723             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1724               i_inner = max(i,ibs+spec_zone)
1725               i_inner = min(i_inner,ibe-spec_zone)
1726               IF(periodic_x)i_inner = i
1727               field(i,k,j) = field(i_inner,k,jbe-spec_zone)
1728             ENDDO
1729           ENDDO
1730         ENDDO
1731       ENDIF 
1733     IF(.NOT.periodic_x)THEN
1734       IF (its - ibs .lt. spec_zone) THEN
1735 ! X-start boundary
1736         DO i = its, min(itf,ibs+spec_zone-1)
1737           b_dist = i - ibs
1738           DO k = kts, ktf
1739             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1740               j_inner = max(j,jbs+spec_zone)
1741               j_inner = min(j_inner,jbe-spec_zone)
1742               field(i,k,j) = field(ibs+spec_zone,k,j_inner)
1743             ENDDO
1744           ENDDO
1745         ENDDO
1746       ENDIF 
1748       IF (ibe - itf .lt. spec_zone) THEN
1749 ! X-end boundary
1750         DO i = max(its,ibe-spec_zone+1), itf
1751           b_dist = ibe - i
1752           DO k = kts, ktf
1753             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1754               j_inner = max(j,jbs+spec_zone)
1755               j_inner = min(j_inner,jbe-spec_zone)
1756               field(i,k,j) = field(ibe-spec_zone,k,j_inner)
1757             ENDDO
1758           ENDDO
1759         ENDDO
1760       ENDIF 
1761     ENDIF
1763    END SUBROUTINE zero_grad_bdy
1764 !------------------------------------------------------------------------
1766    SUBROUTINE flow_dep_bdy  (  field,                     &
1767                                u, v, config_flags, & 
1768                                spec_zone,                  &
1769                                ids,ide, jds,jde, kds,kde,  & ! domain dims
1770                                ims,ime, jms,jme, kms,kme,  & ! memory dims
1771                                ips,ipe, jps,jpe, kps,kpe,  & ! patch  dims
1772                                its,ite, jts,jte, kts,kte )
1774 !  This subroutine sets zero gradient conditions for outflow and zero value
1775 !  for inflow in the boundary specified region. Note that field must be unstaggered.
1776 !  The velocities, u and v, will only be used to check their sign (coupled vels OK)
1777 !  spec_zone is the width of the outer specified b.c.s that are set here.
1778 !  (JD August 2000)
1780       IMPLICIT NONE
1782       INTEGER,      INTENT(IN   )    :: ids,ide, jds,jde, kds,kde
1783       INTEGER,      INTENT(IN   )    :: ims,ime, jms,jme, kms,kme
1784       INTEGER,      INTENT(IN   )    :: ips,ipe, jps,jpe, kps,kpe
1785       INTEGER,      INTENT(IN   )    :: its,ite, jts,jte, kts,kte
1786       INTEGER,      INTENT(IN   )    :: spec_zone
1789       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: field
1790       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN   ) :: u
1791       REAL,  DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN   ) :: v
1792       TYPE( grid_config_rec_type ) config_flags
1794       INTEGER    :: i, j, k, ibs, ibe, jbs, jbe, itf, jtf, ktf, i_inner, j_inner
1795       INTEGER    :: b_dist, b_limit
1796       LOGICAL    :: periodic_x
1798       periodic_x = config_flags%periodic_x
1800       ibs = ids
1801       ibe = ide-1
1802       itf = min(ite,ide-1)
1803       jbs = jds
1804       jbe = jde-1
1805       jtf = min(jte,jde-1)
1806       ktf = kde-1
1808       IF (jts - jbs .lt. spec_zone) THEN
1809 ! Y-start boundary
1810         DO j = jts, min(jtf,jbs+spec_zone-1)
1811           b_dist = j - jbs
1812           b_limit = b_dist
1813           IF(periodic_x)b_limit = 0
1814           DO k = kts, ktf
1815             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1816               i_inner = max(i,ibs+spec_zone)
1817               i_inner = min(i_inner,ibe-spec_zone)
1818               IF(periodic_x)i_inner = i
1819               IF(v(i,k,j) .lt. 0.)THEN
1820                 field(i,k,j) = field(i_inner,k,jbs+spec_zone)
1821               ELSE
1822                 field(i,k,j) = 0.
1823               ENDIF
1824             ENDDO
1825           ENDDO
1826         ENDDO
1827       ENDIF 
1828       IF (jbe - jtf .lt. spec_zone) THEN 
1829 ! Y-end boundary 
1830         DO j = max(jts,jbe-spec_zone+1), jtf 
1831           b_dist = jbe - j 
1832           b_limit = b_dist
1833           IF(periodic_x)b_limit = 0
1834           DO k = kts, ktf 
1835             DO i = max(its,b_limit+ibs), min(itf,ibe-b_limit)
1836               i_inner = max(i,ibs+spec_zone)
1837               i_inner = min(i_inner,ibe-spec_zone)
1838               IF(periodic_x)i_inner = i
1839               IF(v(i,k,j+1) .gt. 0.)THEN
1840                 field(i,k,j) = field(i_inner,k,jbe-spec_zone)
1841               ELSE
1842                 field(i,k,j) = 0.
1843               ENDIF
1844             ENDDO
1845           ENDDO
1846         ENDDO
1847       ENDIF 
1849     IF(.NOT.periodic_x)THEN
1850       IF (its - ibs .lt. spec_zone) THEN
1851 ! X-start boundary
1852         DO i = its, min(itf,ibs+spec_zone-1)
1853           b_dist = i - ibs
1854           DO k = kts, ktf
1855             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1856               j_inner = max(j,jbs+spec_zone)
1857               j_inner = min(j_inner,jbe-spec_zone)
1858               IF(u(i,k,j) .lt. 0.)THEN
1859                 field(i,k,j) = field(ibs+spec_zone,k,j_inner)
1860               ELSE
1861                 field(i,k,j) = 0.
1862               ENDIF
1863             ENDDO
1864           ENDDO
1865         ENDDO
1866       ENDIF 
1868       IF (ibe - itf .lt. spec_zone) THEN
1869 ! X-end boundary
1870         DO i = max(its,ibe-spec_zone+1), itf
1871           b_dist = ibe - i
1872           DO k = kts, ktf
1873             DO j = max(jts,b_dist+jbs+1), min(jtf,jbe-b_dist-1)
1874               j_inner = max(j,jbs+spec_zone)
1875               j_inner = min(j_inner,jbe-spec_zone)
1876               IF(u(i+1,k,j) .gt. 0.)THEN
1877                 field(i,k,j) = field(ibe-spec_zone,k,j_inner)
1878               ELSE
1879                 field(i,k,j) = 0.
1880               ENDIF
1881             ENDDO
1882           ENDDO
1883         ENDDO
1884       ENDIF 
1885     ENDIF
1887    END SUBROUTINE flow_dep_bdy
1889 !------------------------------------------------------------------------------
1891  SUBROUTINE stuff_bdy_new ( data3d , space_bdy_xs, space_bdy_xe, space_bdy_ys, space_bdy_ye, &
1892                              char_stagger , &
1893                              spec_bdy_width , &
1894                              ids, ide, jds, jde, kds, kde , &
1895                              ims, ime, jms, jme, kms, kme , & 
1896                              its, ite, jts, jte, kts, kte )
1898  !  This routine puts the data in the 3d arrays into the proper locations
1899  !  for the lateral boundary arrays.
1901     USE module_state_description
1902     
1903     IMPLICIT NONE
1905     INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
1906     INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
1907     INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
1908     INTEGER , INTENT(IN) :: spec_bdy_width
1909     REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3d
1910     REAL , DIMENSION(jms:jme,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_xs, space_bdy_xe
1911     REAL , DIMENSION(ims:ime,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_ys, space_bdy_ye
1912     CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
1914     INTEGER :: i , ii , j , jj , k
1916     !  There are four lateral boundary locations that are stored.
1918     !  X start boundary
1920     IF ( char_stagger .EQ. 'W' ) THEN
1921        DO j = MAX(jds,jts) , MIN(jde-1,jte)
1922        DO k = kds , kde
1923        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
1924           space_bdy_xs(j,k,i) = data3d(i,k,j)
1925        END DO
1926        END DO
1927        END DO
1928     ELSE IF ( char_stagger .EQ. 'M' ) THEN
1929        DO j = MAX(jds,jts) , MIN(jde-1,jte)
1930        DO k = kds , kde
1931        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
1932           space_bdy_xs(j,k,i) = data3d(i,k,j)
1933        END DO
1934        END DO
1935        END DO
1936     ELSE IF ( char_stagger .EQ. 'V' ) THEN
1937        DO j = MAX(jds,jts) , MIN(jde,jte)
1938        DO k = kds , kde - 1
1939        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
1940           space_bdy_xs(j,k,i) = data3d(i,k,j)
1941        END DO
1942        END DO
1943        END DO
1944     ELSE
1945        DO j = MAX(jds,jts) , MIN(jde-1,jte)
1946        DO k = kds , kde - 1
1947        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
1948           space_bdy_xs(j,k,i) = data3d(i,k,j)
1949        END DO
1950        END DO
1951        END DO
1952     END IF
1954     !  X end boundary
1956     IF      ( char_stagger .EQ. 'U' ) THEN
1957        DO j = MAX(jds,jts) , MIN(jde-1,jte)
1958        DO k = kds , kde - 1
1959        DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
1960           ii = ide - i + 1
1961           space_bdy_xe(j,k,ii) = data3d(i,k,j)
1962        END DO
1963        END DO
1964        END DO
1965     ELSE IF ( char_stagger .EQ. 'V' ) THEN
1966        DO j = MAX(jds,jts) , MIN(jde,jte)
1967        DO k = kds , kde - 1
1968        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
1969           ii = ide - i
1970           space_bdy_xe(j,k,ii) = data3d(i,k,j)
1971        END DO
1972        END DO
1973        END DO
1974     ELSE IF ( char_stagger .EQ. 'W' ) THEN
1975        DO j = MAX(jds,jts) , MIN(jde-1,jte)
1976        DO k = kds , kde
1977        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
1978           ii = ide - i
1979           space_bdy_xe(j,k,ii) = data3d(i,k,j)
1980        END DO
1981        END DO
1982        END DO
1983     ELSE IF ( char_stagger .EQ. 'M' ) THEN
1984        DO j = MAX(jds,jts) , MIN(jde-1,jte)
1985        DO k = kds , kde
1986        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
1987           ii = ide - i
1988           space_bdy_xe(j,k,ii) = data3d(i,k,j)
1989        END DO
1990        END DO
1991        END DO
1992     ELSE
1993        DO j = MAX(jds,jts) , MIN(jde-1,jte)
1994        DO k = kds , kde - 1
1995        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
1996           ii = ide - i
1997           space_bdy_xe(j,k,ii) = data3d(i,k,j)
1998        END DO
1999        END DO
2000        END DO
2001     END IF
2003     !  Y start boundary
2005     IF ( char_stagger .EQ. 'W' ) THEN
2006        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2007        DO k = kds , kde
2008        DO i = MAX(ids,its) , MIN(ide-1,ite)
2009           space_bdy_ys(i,k,j) = data3d(i,k,j)
2010        END DO
2011        END DO
2012        END DO
2013     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2014        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2015        DO k = kds , kde
2016        DO i = MAX(ids,its) , MIN(ide-1,ite)
2017           space_bdy_ys(i,k,j) = data3d(i,k,j)
2018        END DO
2019        END DO
2020        END DO
2021     ELSE IF ( char_stagger .EQ. 'U' ) THEN
2022        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2023        DO k = kds , kde - 1
2024        DO i = MAX(ids,its) , MIN(ide,ite)
2025           space_bdy_ys(i,k,j) = data3d(i,k,j)
2026        END DO
2027        END DO
2028        END DO
2029     ELSE
2030        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2031        DO k = kds , kde - 1
2032        DO i = MAX(ids,its) , MIN(ide-1,ite)
2033           space_bdy_ys(i,k,j) = data3d(i,k,j)
2034        END DO
2035        END DO
2036        END DO
2037     END IF
2039     !  Y end boundary
2041     IF      ( char_stagger .EQ. 'V' ) THEN
2042        DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
2043        DO k = kds , kde - 1
2044        DO i = MAX(ids,its) , MIN(ide-1,ite)
2045           jj = jde - j + 1
2046           space_bdy_ye(i,k,jj) = data3d(i,k,j)
2047        END DO
2048        END DO
2049        END DO
2050     ELSE IF ( char_stagger .EQ. 'U' ) THEN
2051        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2052        DO k = kds , kde - 1
2053        DO i = MAX(ids,its) , MIN(ide,ite)
2054           jj = jde - j
2055           space_bdy_ye(i,k,jj) = data3d(i,k,j)
2056        END DO
2057        END DO
2058        END DO
2059     ELSE IF ( char_stagger .EQ. 'W' ) THEN
2060        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2061        DO k = kds , kde
2062        DO i = MAX(ids,its) , MIN(ide-1,ite)
2063           jj = jde - j
2064           space_bdy_ye(i,k,jj) = data3d(i,k,j)
2065        END DO
2066        END DO
2067        END DO
2068     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2069        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2070        DO k = kds , kde
2071        DO i = MAX(ids,its) , MIN(ide-1,ite)
2072           jj = jde - j
2073           space_bdy_ye(i,k,jj) = data3d(i,k,j)
2074        END DO
2075        END DO
2076        END DO
2077     ELSE
2078        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2079        DO k = kds , kde - 1
2080        DO i = MAX(ids,its) , MIN(ide-1,ite)
2081           jj = jde - j
2082           space_bdy_ye(i,k,jj) = data3d(i,k,j)
2083        END DO
2084        END DO
2085        END DO
2086     END IF
2087     
2088  END SUBROUTINE stuff_bdy_new
2090  SUBROUTINE stuff_bdytend_new ( data3dnew , data3dold , time_diff , &
2091                              space_bdy_xs, space_bdy_xe, space_bdy_ys, space_bdy_ye, &
2092                              char_stagger , &
2093                              spec_bdy_width , &
2094                              ids, ide, jds, jde, kds, kde , &
2095                              ims, ime, jms, jme, kms, kme , & 
2096                              its, ite, jts, jte, kts, kte )
2098  !  This routine puts the tendency data into the proper locations
2099  !  for the lateral boundary arrays.
2101     USE module_state_description
2102     
2103     IMPLICIT NONE
2105     INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
2106     INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
2107     INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
2108     INTEGER , INTENT(IN) :: spec_bdy_width
2109     REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3dnew , data3dold
2110     REAL , DIMENSION(jms:jme,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_xs, space_bdy_xe
2111     REAL , DIMENSION(ims:ime,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_ys, space_bdy_ye
2112     CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
2113     REAL , INTENT(IN) :: time_diff ! seconds
2115     INTEGER :: i , ii , j , jj , k
2117     !  There are four lateral boundary locations that are stored.
2119     !  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_xs(j,k,i) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
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_xs(j,k,i) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
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_xs(j,k,i) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
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_xs(j,k,i) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2150        END DO
2151        END DO
2152        END DO
2153     END IF
2155     !  X end boundary
2157     IF      ( char_stagger .EQ. 'U' ) THEN
2158        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2159        DO k = kds , kde - 1
2160        DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
2161           ii = ide - i + 1
2162           space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2163        END DO
2164        END DO
2165        END DO
2166     ELSE IF ( char_stagger .EQ. 'V' ) THEN
2167        DO j = MAX(jds,jts) , MIN(jde,jte)
2168        DO k = kds , kde - 1
2169        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2170           ii = ide - i
2171           space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2172        END DO
2173        END DO
2174        END DO
2175     ELSE IF ( char_stagger .EQ. 'W' ) THEN
2176        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2177        DO k = kds , kde
2178        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2179           ii = ide - i
2180           space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2181        END DO
2182        END DO
2183        END DO
2184     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2185        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2186        DO k = kds , kde
2187        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2188           ii = ide - i
2189           space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2190        END DO
2191        END DO
2192        END DO
2193     ELSE
2194        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2195        DO k = kds , kde - 1
2196        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2197           ii = ide - i
2198           space_bdy_xe(j,k,ii) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2199        END DO
2200        END DO
2201        END DO
2202     END IF
2204     !  Y start boundary
2206     IF ( char_stagger .EQ. 'W' ) THEN
2207        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2208        DO k = kds , kde
2209        DO i = MAX(ids,its) , MIN(ide-1,ite)
2210           space_bdy_ys(i,k,j) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2211        END DO
2212        END DO
2213        END DO
2214     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2215        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2216        DO k = kds , kde
2217        DO i = MAX(ids,its) , MIN(ide-1,ite)
2218           space_bdy_ys(i,k,j) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2219        END DO
2220        END DO
2221        END DO
2222     ELSE IF ( char_stagger .EQ. 'U' ) THEN
2223        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2224        DO k = kds , kde - 1
2225        DO i = MAX(ids,its) , MIN(ide,ite)
2226           space_bdy_ys(i,k,j) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2227        END DO
2228        END DO
2229        END DO
2230     ELSE
2231        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2232        DO k = kds , kde - 1
2233        DO i = MAX(ids,its) , MIN(ide-1,ite)
2234           space_bdy_ys(i,k,j) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2235        END DO
2236        END DO
2237        END DO
2238     END IF
2240     !  Y end boundary
2242     IF      ( char_stagger .EQ. 'V' ) THEN
2243        DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
2244        DO k = kds , kde - 1
2245        DO i = MAX(ids,its) , MIN(ide-1,ite)
2246           jj = jde - j + 1
2247           space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2248        END DO
2249        END DO
2250        END DO
2251     ELSE IF ( char_stagger .EQ. 'U' ) THEN
2252        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2253        DO k = kds , kde - 1
2254        DO i = MAX(ids,its) , MIN(ide,ite)
2255           jj = jde - j
2256           space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2257        END DO
2258        END DO
2259        END DO
2260     ELSE IF ( char_stagger .EQ. 'W' ) THEN
2261        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2262        DO k = kds , kde
2263        DO i = MAX(ids,its) , MIN(ide-1,ite)
2264           jj = jde - j
2265           space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2266        END DO
2267        END DO
2268        END DO
2269     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2270        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2271        DO k = kds , kde
2272        DO i = MAX(ids,its) , MIN(ide-1,ite)
2273           jj = jde - j
2274           space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2275        END DO
2276        END DO
2277        END DO
2278     ELSE
2279        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2280        DO k = kds , kde - 1
2281        DO i = MAX(ids,its) , MIN(ide-1,ite)
2282           jj = jde - j
2283           space_bdy_ye(i,k,jj) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2284        END DO
2285        END DO
2286        END DO
2287     END IF
2288     
2289  END SUBROUTINE stuff_bdytend_new
2291 !--- old versions for use with modules that use the old bdy data structures ---
2293  SUBROUTINE stuff_bdy_old ( data3d , space_bdy , char_stagger , &
2294                              ijds , ijde , spec_bdy_width , &
2295                              ids, ide, jds, jde, kds, kde , &
2296                              ims, ime, jms, jme, kms, kme , & 
2297                              its, ite, jts, jte, kts, kte )
2299  !  This routine puts the data in the 3d arrays into the proper locations
2300  !  for the lateral boundary arrays.
2302     USE module_state_description
2303     
2304     IMPLICIT NONE
2306     INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
2307     INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
2308     INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
2309     INTEGER , INTENT(IN) :: ijds , ijde , spec_bdy_width
2310     REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3d
2311     REAL , DIMENSION(ijds:ijde,kds:kde,spec_bdy_width,4) , INTENT(OUT) :: space_bdy
2312     CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
2314     INTEGER :: i , ii , j , jj , k
2316     !  There are four lateral boundary locations that are stored.
2318     !  X start boundary
2320     IF ( char_stagger .EQ. 'W' ) THEN
2321        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2322        DO k = kds , kde
2323        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2324           space_bdy(j,k,i,P_XSB) = data3d(i,k,j)
2325        END DO
2326        END DO
2327        END DO
2328     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2329        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2330        DO k = kds , kde
2331        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2332           space_bdy(j,k,i,P_XSB) = data3d(i,k,j)
2333        END DO
2334        END DO
2335        END DO
2336     ELSE IF ( char_stagger .EQ. 'V' ) THEN
2337        DO j = MAX(jds,jts) , MIN(jde,jte)
2338        DO k = kds , kde - 1
2339        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2340           space_bdy(j,k,i,P_XSB) = data3d(i,k,j)
2341        END DO
2342        END DO
2343        END DO
2344     ELSE
2345        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2346        DO k = kds , kde - 1
2347        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2348           space_bdy(j,k,i,P_XSB) = data3d(i,k,j)
2349        END DO
2350        END DO
2351        END DO
2352     END IF
2354     !  X end boundary
2356     IF      ( char_stagger .EQ. 'U' ) THEN
2357        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2358        DO k = kds , kde - 1
2359        DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
2360           ii = ide - i + 1
2361           space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
2362        END DO
2363        END DO
2364        END DO
2365     ELSE IF ( char_stagger .EQ. 'V' ) THEN
2366        DO j = MAX(jds,jts) , MIN(jde,jte)
2367        DO k = kds , kde - 1
2368        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2369           ii = ide - i
2370           space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
2371        END DO
2372        END DO
2373        END DO
2374     ELSE IF ( char_stagger .EQ. 'W' ) THEN
2375        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2376        DO k = kds , kde
2377        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2378           ii = ide - i
2379           space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
2380        END DO
2381        END DO
2382        END DO
2383     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2384        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2385        DO k = kds , kde
2386        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2387           ii = ide - i
2388           space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
2389        END DO
2390        END DO
2391        END DO
2392     ELSE
2393        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2394        DO k = kds , kde - 1
2395        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2396           ii = ide - i
2397           space_bdy(j,k,ii,P_XEB) = data3d(i,k,j)
2398        END DO
2399        END DO
2400        END DO
2401     END IF
2403     !  Y start boundary
2405     IF ( char_stagger .EQ. 'W' ) THEN
2406        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2407        DO k = kds , kde
2408        DO i = MAX(ids,its) , MIN(ide-1,ite)
2409           space_bdy(i,k,j,P_YSB) = data3d(i,k,j)
2410        END DO
2411        END DO
2412        END DO
2413     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2414        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2415        DO k = kds , kde
2416        DO i = MAX(ids,its) , MIN(ide-1,ite)
2417           space_bdy(i,k,j,P_YSB) = data3d(i,k,j)
2418        END DO
2419        END DO
2420        END DO
2421     ELSE IF ( char_stagger .EQ. 'U' ) THEN
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,ite)
2425           space_bdy(i,k,j,P_YSB) = data3d(i,k,j)
2426        END DO
2427        END DO
2428        END DO
2429     ELSE
2430        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2431        DO k = kds , kde - 1
2432        DO i = MAX(ids,its) , MIN(ide-1,ite)
2433           space_bdy(i,k,j,P_YSB) = data3d(i,k,j)
2434        END DO
2435        END DO
2436        END DO
2437     END IF
2439     !  Y end boundary
2441     IF      ( char_stagger .EQ. 'V' ) THEN
2442        DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
2443        DO k = kds , kde - 1
2444        DO i = MAX(ids,its) , MIN(ide-1,ite)
2445           jj = jde - j + 1
2446           space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
2447        END DO
2448        END DO
2449        END DO
2450     ELSE IF ( char_stagger .EQ. 'U' ) THEN
2451        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2452        DO k = kds , kde - 1
2453        DO i = MAX(ids,its) , MIN(ide,ite)
2454           jj = jde - j
2455           space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
2456        END DO
2457        END DO
2458        END DO
2459     ELSE IF ( char_stagger .EQ. 'W' ) THEN
2460        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2461        DO k = kds , kde
2462        DO i = MAX(ids,its) , MIN(ide-1,ite)
2463           jj = jde - j
2464           space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
2465        END DO
2466        END DO
2467        END DO
2468     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2469        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2470        DO k = kds , kde
2471        DO i = MAX(ids,its) , MIN(ide-1,ite)
2472           jj = jde - j
2473           space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
2474        END DO
2475        END DO
2476        END DO
2477     ELSE
2478        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2479        DO k = kds , kde - 1
2480        DO i = MAX(ids,its) , MIN(ide-1,ite)
2481           jj = jde - j
2482           space_bdy(i,k,jj,P_YEB) = data3d(i,k,j)
2483        END DO
2484        END DO
2485        END DO
2486     END IF
2487     
2488  END SUBROUTINE stuff_bdy_old
2490  SUBROUTINE stuff_bdytend_old ( data3dnew , data3dold , time_diff , space_bdy , char_stagger , &
2491                              ijds , ijde , spec_bdy_width , &
2492                              ids, ide, jds, jde, kds, kde , &
2493                              ims, ime, jms, jme, kms, kme , & 
2494                              its, ite, jts, jte, kts, kte )
2496  !  This routine puts the tendency data into the proper locations
2497  !  for the lateral boundary arrays.
2499     USE module_state_description
2500     
2501     IMPLICIT NONE
2503     INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
2504     INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
2505     INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
2506     INTEGER , INTENT(IN) :: ijds , ijde , spec_bdy_width
2507     REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3dnew , data3dold
2508 !    REAL , DIMENSION(:,:,:,:) , INTENT(OUT) :: space_bdy
2509     REAL , DIMENSION(ijds:ijde,kds:kde,spec_bdy_width,4) , INTENT(OUT) :: space_bdy
2510     CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
2511     REAL , INTENT(IN) :: time_diff ! seconds
2513     INTEGER :: i , ii , j , jj , k
2515     !  There are four lateral boundary locations that are stored.
2517     !  X start boundary
2519     IF ( char_stagger .EQ. 'W' ) THEN
2520        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2521        DO k = kds , kde
2522        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2523           space_bdy(j,k,i,P_XSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2524 !         space_bdy(j,k,i,P_XSB) = 0. ! zeroout
2525        END DO
2526        END DO
2527        END DO
2528     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2529        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2530        DO k = kds , kde
2531        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2532           space_bdy(j,k,i,P_XSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2533 !         space_bdy(j,k,i,P_XSB) = 0. ! zeroout
2534        END DO
2535        END DO
2536        END DO
2537     ELSE IF ( char_stagger .EQ. 'V' ) THEN
2538        DO j = MAX(jds,jts) , MIN(jde,jte)
2539        DO k = kds , kde - 1
2540        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2541           space_bdy(j,k,i,P_XSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2542 !         space_bdy(j,k,i,P_XSB) = 0. ! zeroout
2543        END DO
2544        END DO
2545        END DO
2546     ELSE
2547        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2548        DO k = kds , kde - 1
2549        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2550           space_bdy(j,k,i,P_XSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2551 !         space_bdy(j,k,i,P_XSB) = 0. ! zeroout
2552        END DO
2553        END DO
2554        END DO
2555     END IF
2557     !  X end boundary
2559     IF      ( char_stagger .EQ. 'U' ) THEN
2560        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2561        DO k = kds , kde - 1
2562        DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
2563           ii = ide - i + 1
2564           space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2565 !         space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
2566        END DO
2567        END DO
2568        END DO
2569     ELSE IF ( char_stagger .EQ. 'V' ) THEN
2570        DO j = MAX(jds,jts) , MIN(jde,jte)
2571        DO k = kds , kde - 1
2572        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2573           ii = ide - i
2574           space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2575 !         space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
2576        END DO
2577        END DO
2578        END DO
2579     ELSE IF ( char_stagger .EQ. 'W' ) THEN
2580        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2581        DO k = kds , kde
2582        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2583           ii = ide - i
2584           space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2585 !         space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
2586        END DO
2587        END DO
2588        END DO
2589     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2590        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2591        DO k = kds , kde
2592        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2593           ii = ide - i
2594           space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2595 !         space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
2596        END DO
2597        END DO
2598        END DO
2599     ELSE
2600        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2601        DO k = kds , kde - 1
2602        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2603           ii = ide - i
2604           space_bdy(j,k,ii,P_XEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2605 !         space_bdy(j,k,ii,P_XEB) = 0. ! zeroout
2606        END DO
2607        END DO
2608        END DO
2609     END IF
2611     !  Y start boundary
2613     IF ( char_stagger .EQ. 'W' ) THEN
2614        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2615        DO k = kds , kde
2616        DO i = MAX(ids,its) , MIN(ide-1,ite)
2617           space_bdy(i,k,j,P_YSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2618 !         space_bdy(i,k,j,P_YSB) = 0. ! zeroout
2619        END DO
2620        END DO
2621        END DO
2622     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2623        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2624        DO k = kds , kde
2625        DO i = MAX(ids,its) , MIN(ide-1,ite)
2626           space_bdy(i,k,j,P_YSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2627 !         space_bdy(i,k,j,P_YSB) = 0. ! zeroout
2628        END DO
2629        END DO
2630        END DO
2631     ELSE IF ( char_stagger .EQ. 'U' ) THEN
2632        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2633        DO k = kds , kde - 1
2634        DO i = MAX(ids,its) , MIN(ide,ite)
2635           space_bdy(i,k,j,P_YSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2636 !         space_bdy(i,k,j,P_YSB) = 0. ! zeroout
2637        END DO
2638        END DO
2639        END DO
2640     ELSE
2641        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2642        DO k = kds , kde - 1
2643        DO i = MAX(ids,its) , MIN(ide-1,ite)
2644           space_bdy(i,k,j,P_YSB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2645 !         space_bdy(i,k,j,P_YSB) = 0. ! zeroout
2646        END DO
2647        END DO
2648        END DO
2649     END IF
2651     !  Y end boundary
2653     IF      ( char_stagger .EQ. 'V' ) THEN
2654        DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
2655        DO k = kds , kde - 1
2656        DO i = MAX(ids,its) , MIN(ide-1,ite)
2657           jj = jde - j + 1
2658           space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2659 !         space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
2660        END DO
2661        END DO
2662        END DO
2663     ELSE IF ( char_stagger .EQ. 'U' ) THEN
2664        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2665        DO k = kds , kde - 1
2666        DO i = MAX(ids,its) , MIN(ide,ite)
2667           jj = jde - j
2668           space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2669 !         space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
2670        END DO
2671        END DO
2672        END DO
2673     ELSE IF ( char_stagger .EQ. 'W' ) THEN
2674        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2675        DO k = kds , kde
2676        DO i = MAX(ids,its) , MIN(ide-1,ite)
2677           jj = jde - j
2678           space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2679 !         space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
2680        END DO
2681        END DO
2682        END DO
2683     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2684        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2685        DO k = kds , kde
2686        DO i = MAX(ids,its) , MIN(ide-1,ite)
2687           jj = jde - j
2688           space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2689 !         space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
2690        END DO
2691        END DO
2692        END DO
2693     ELSE
2694        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2695        DO k = kds , kde - 1
2696        DO i = MAX(ids,its) , MIN(ide-1,ite)
2697           jj = jde - j
2698           space_bdy(i,k,jj,P_YEB) = ( data3dnew(i,k,j) - data3dold(i,k,j) ) / time_diff
2699 !         space_bdy(i,k,jj,P_YEB) = 0. ! zeroout
2700        END DO
2701        END DO
2702        END DO
2703     END IF
2704     
2705  END SUBROUTINE stuff_bdytend_old
2707  SUBROUTINE stuff_bdy_ijk ( data3d , space_bdy_xs, space_bdy_xe, &
2708                              space_bdy_ys, space_bdy_ye, &
2709                              char_stagger , spec_bdy_width, &
2710                              ids, ide, jds, jde, kds, kde , &
2711                              ims, ime, jms, jme, kms, kme , & 
2712                              its, ite, jts, jte, kts, kte )
2714  !  This routine puts the data in the 3d arrays into the proper locations
2715  !  for the lateral boundary arrays.
2717     USE module_state_description
2718     
2719     IMPLICIT NONE
2721     INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
2722     INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
2723     INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
2724     INTEGER , INTENT(IN) :: spec_bdy_width
2725     REAL , DIMENSION(ims:ime,jms:jme,kms:kme) , INTENT(IN) :: data3d
2726 !    REAL , DIMENSION(:,:,:,:) , INTENT(OUT) :: space_bdy
2727 !    REAL , DIMENSION(ijds:ijde,kds:kde,spec_bdy_width,4,1) , INTENT(OUT) :: space_bdy
2728     REAL , DIMENSION(jms:jme,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_xs, space_bdy_xe
2729     REAL , DIMENSION(ims:ime,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_ys, space_bdy_ye
2730     CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
2732     INTEGER :: i , ii , j , jj , k
2734     !  There are four lateral boundary locations that are stored.
2736     !  X start boundary
2738     IF ( char_stagger .EQ. 'W' ) THEN
2739        DO k = kds , kde
2740        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2741        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2742           space_bdy_xs(j,k,i) = data3d(i,j,k)
2743        END DO
2744        END DO
2745        END DO
2746     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2747        DO k = kds , kde
2748        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2749        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2750           space_bdy_xs(j,k,i) = data3d(i,j,k)
2751        END DO
2752        END DO
2753        END DO
2754     ELSE IF ( char_stagger .EQ. 'V' ) THEN
2755        DO k = kds , kde - 1
2756        DO j = MAX(jds,jts) , MIN(jde,jte)
2757        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2758           space_bdy_xs(j,k,i) = data3d(i,j,k)
2759        END DO
2760        END DO
2761        END DO
2762     ELSE
2763        DO k = kds , kde - 1
2764        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2765        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2766           space_bdy_xs(j,k,i) = data3d(i,j,k)
2767        END DO
2768        END DO
2769        END DO
2770     END IF
2772     !  X end boundary
2774     IF      ( char_stagger .EQ. 'U' ) THEN
2775        DO k = kds , kde - 1
2776        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2777        DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
2778           ii = ide - i + 1
2779           space_bdy_xe(j,k,ii) = data3d(i,j,k)
2780        END DO
2781        END DO
2782        END DO
2783     ELSE IF ( char_stagger .EQ. 'V' ) THEN
2784        DO k = kds , kde - 1
2785        DO j = MAX(jds,jts) , MIN(jde,jte)
2786        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2787           ii = ide - i
2788           space_bdy_xe(j,k,ii) = data3d(i,j,k)
2789        END DO
2790        END DO
2791        END DO
2792     ELSE IF ( char_stagger .EQ. 'W' ) THEN
2793        DO k = kds , kde
2794        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2795        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2796           ii = ide - i
2797           space_bdy_xe(j,k,ii) = data3d(i,j,k)
2798        END DO
2799        END DO
2800        END DO
2801     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2802        DO k = kds , kde
2803        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2804        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2805           ii = ide - i
2806           space_bdy_xe(j,k,ii) = data3d(i,j,k)
2807        END DO
2808        END DO
2809        END DO
2810     ELSE
2811        DO k = kds , kde - 1
2812        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2813        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2814           ii = ide - i
2815           space_bdy_xe(j,k,ii) = data3d(i,j,k)
2816        END DO
2817        END DO
2818        END DO
2819     END IF
2821     !  Y start boundary
2823     IF ( char_stagger .EQ. 'W' ) THEN
2824        DO k = kds , kde
2825        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2826        DO i = MAX(ids,its) , MIN(ide-1,ite)
2827           space_bdy_ys(i,k,j) = data3d(i,j,k)
2828        END DO
2829        END DO
2830        END DO
2831     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2832        DO k = kds , kde
2833        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2834        DO i = MAX(ids,its) , MIN(ide-1,ite)
2835           space_bdy_ys(i,k,j) = data3d(i,j,k)
2836        END DO
2837        END DO
2838        END DO
2839     ELSE IF ( char_stagger .EQ. 'U' ) THEN
2840        DO k = kds , kde - 1
2841        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2842        DO i = MAX(ids,its) , MIN(ide,ite)
2843           space_bdy_ys(i,k,j) = data3d(i,j,k)
2844        END DO
2845        END DO
2846        END DO
2847     ELSE
2848        DO k = kds , kde - 1
2849        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
2850        DO i = MAX(ids,its) , MIN(ide-1,ite)
2851           space_bdy_ys(i,k,j) = data3d(i,j,k)
2852        END DO
2853        END DO
2854        END DO
2855     END IF
2857     !  Y end boundary
2859     IF      ( char_stagger .EQ. 'V' ) THEN
2860        DO k = kds , kde - 1
2861        DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
2862        DO i = MAX(ids,its) , MIN(ide-1,ite)
2863           jj = jde - j + 1
2864           space_bdy_ye(i,k,jj) = data3d(i,j,k)
2865        END DO
2866        END DO
2867        END DO
2868     ELSE IF ( char_stagger .EQ. 'U' ) THEN
2869        DO k = kds , kde - 1
2870        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2871        DO i = MAX(ids,its) , MIN(ide,ite)
2872           jj = jde - j
2873           space_bdy_ye(i,k,jj) = data3d(i,j,k)
2874        END DO
2875        END DO
2876        END DO
2877     ELSE IF ( char_stagger .EQ. 'W' ) THEN
2878        DO k = kds , kde
2879        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2880        DO i = MAX(ids,its) , MIN(ide-1,ite)
2881           jj = jde - j
2882           space_bdy_ye(i,k,jj) = data3d(i,j,k)
2883        END DO
2884        END DO
2885        END DO
2886     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2887        DO k = kds , kde
2888        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2889        DO i = MAX(ids,its) , MIN(ide-1,ite)
2890           jj = jde - j
2891           space_bdy_ye(i,k,jj) = data3d(i,j,k)
2892        END DO
2893        END DO
2894        END DO
2895     ELSE
2896        DO k = kds , kde - 1
2897        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
2898        DO i = MAX(ids,its) , MIN(ide-1,ite)
2899           jj = jde - j
2900           space_bdy_ye(i,k,jj) = data3d(i,j,k)
2901 !        if (K .eq. 54 .and. I .eq. 369) then
2902 !       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)
2903 !       endif
2905        END DO
2906        END DO
2907        END DO
2908     END IF
2909     
2910  END SUBROUTINE stuff_bdy_ijk
2912  SUBROUTINE stuff_bdytend_ijk ( data3dnew , data3dold , time_diff , &
2913                              space_bdy_xs, space_bdy_xe, space_bdy_ys, space_bdy_ye, &
2914                              char_stagger , &
2915                              spec_bdy_width , &
2916                              ids, ide, jds, jde, kds, kde , &
2917                              ims, ime, jms, jme, kms, kme , & 
2918                              its, ite, jts, jte, kts, kte )
2920  !  This routine puts the tendency data into the proper locations
2921  !  for the lateral boundary arrays.
2923     USE module_state_description
2924     
2925     IMPLICIT NONE
2927     INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde
2928     INTEGER , INTENT(IN) :: ims, ime, jms, jme, kms, kme
2929     INTEGER , INTENT(IN) :: its, ite, jts, jte, kts, kte
2930     INTEGER , INTENT(IN) :: spec_bdy_width
2931 !    REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: data3dnew , data3dold
2932     REAL , DIMENSION(ims:ime,jms:jme,kms:kme) , INTENT(IN) :: data3dnew , data3dold
2933     REAL , DIMENSION(jms:jme,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_xs, space_bdy_xe
2934     REAL , DIMENSION(ims:ime,kds:kde,spec_bdy_width) , INTENT(OUT) :: space_bdy_ys, space_bdy_ye
2936     CHARACTER (LEN=1) , INTENT(IN) :: char_stagger
2937     REAL , INTENT(IN) :: time_diff ! seconds
2939     INTEGER :: i , ii , j , jj , k
2941     !  There are four lateral boundary locations that are stored.
2943     !  X start boundary
2945     IF ( char_stagger .EQ. 'W' ) THEN
2946        DO k = kds , kde
2947        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2948        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2949           space_bdy_xs(j,k,i) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
2950        END DO
2951        END DO
2952        END DO
2953     ELSE IF ( char_stagger .EQ. 'M' ) THEN
2954        DO k = kds , kde
2955        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2956        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2957           space_bdy_xs(j,k,i) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
2958        END DO
2959        END DO
2960        END DO
2961     ELSE IF ( char_stagger .EQ. 'V' ) THEN
2962        DO k = kds , kde - 1
2963        DO j = MAX(jds,jts) , MIN(jde,jte)
2964        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2965           space_bdy_xs(j,k,i) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
2966        END DO
2967        END DO
2968        END DO
2969     ELSE
2970        DO k = kds , kde - 1
2971        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2972        DO i = MAX(ids,its) , MIN(ids + spec_bdy_width - 1,ite)
2973           space_bdy_xs(j,k,i) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
2974        END DO
2975        END DO
2976        END DO
2977     END IF
2979     !  X end boundary
2981     IF      ( char_stagger .EQ. 'U' ) THEN
2982        DO k = kds , kde - 1
2983        DO j = MAX(jds,jts) , MIN(jde-1,jte)
2984        DO i = MIN(ide,ite) , MAX(ide - spec_bdy_width + 1,its) , -1
2985           ii = ide - i + 1
2986           space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
2987        END DO
2988        END DO
2989        END DO
2990     ELSE IF ( char_stagger .EQ. 'V' ) THEN
2991        DO k = kds , kde - 1
2992        DO j = MAX(jds,jts) , MIN(jde,jte)
2993        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
2994           ii = ide - i
2995           space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
2996        END DO
2997        END DO
2998        END DO
2999     ELSE IF ( char_stagger .EQ. 'W' ) THEN
3000        DO k = kds , kde
3001        DO j = MAX(jds,jts) , MIN(jde-1,jte)
3002        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
3003           ii = ide - i
3004           space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3005        END DO
3006        END DO
3007        END DO
3008     ELSE IF ( char_stagger .EQ. 'M' ) THEN
3009        DO k = kds , kde
3010        DO j = MAX(jds,jts) , MIN(jde-1,jte)
3011        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
3012           ii = ide - i
3013           space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3014        END DO
3015        END DO
3016        END DO
3017     ELSE
3018        DO k = kds , kde - 1
3019        DO j = MAX(jds,jts) , MIN(jde-1,jte)
3020        DO i = MIN(ide - 1,ite) , MAX(ide - spec_bdy_width,its) , -1
3021           ii = ide - i
3022           space_bdy_xe(j,k,ii) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3023        END DO
3024        END DO
3025        END DO
3026     END IF
3028     !  Y start boundary
3030     IF ( char_stagger .EQ. 'W' ) THEN
3031        DO k = kds , kde
3032        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
3033        DO i = MAX(ids,its) , MIN(ide-1,ite)
3034           space_bdy_ys(i,k,j) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3035        END DO
3036        END DO
3037        END DO
3038     ELSE IF ( char_stagger .EQ. 'M' ) THEN
3039        DO k = kds , kde
3040        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
3041        DO i = MAX(ids,its) , MIN(ide-1,ite)
3042           space_bdy_ys(i,k,j) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3043        END DO
3044        END DO
3045        END DO
3046     ELSE IF ( char_stagger .EQ. 'U' ) THEN
3047        DO k = kds , kde - 1
3048        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
3049        DO i = MAX(ids,its) , MIN(ide,ite)
3050           space_bdy_ys(i,k,j) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3051        END DO
3052        END DO
3053        END DO
3054     ELSE
3055        DO k = kds , kde - 1
3056        DO j = MAX(jds,jts) , MIN(jds + spec_bdy_width - 1,jte)
3057        DO i = MAX(ids,its) , MIN(ide-1,ite)
3058           space_bdy_ys(i,k,j) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3059        END DO
3060        END DO
3061        END DO
3062     END IF
3064     !  Y end boundary
3066     IF      ( char_stagger .EQ. 'V' ) THEN
3067        DO k = kds , kde - 1
3068        DO j = MIN(jde,jte) , MAX(jde - spec_bdy_width + 1,jts) , -1
3069        DO i = MAX(ids,its) , MIN(ide-1,ite)
3070           jj = jde - j + 1
3071           space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3072        END DO
3073        END DO
3074        END DO
3075     ELSE IF ( char_stagger .EQ. 'U' ) THEN
3076        DO k = kds , kde - 1
3077        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
3078        DO i = MAX(ids,its) , MIN(ide,ite)
3079           jj = jde - j
3080           space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3081        END DO
3082        END DO
3083        END DO
3084     ELSE IF ( char_stagger .EQ. 'W' ) THEN
3085        DO k = kds , kde
3086        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
3087        DO i = MAX(ids,its) , MIN(ide-1,ite)
3088           jj = jde - j
3089           space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3090        END DO
3091        END DO
3092        END DO
3093     ELSE IF ( char_stagger .EQ. 'M' ) THEN
3094        DO k = kds , kde
3095        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
3096        DO i = MAX(ids,its) , MIN(ide-1,ite)
3097           jj = jde - j
3098           space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3099        END DO
3100        END DO
3101        END DO
3102     ELSE
3103        DO k = kds , kde - 1
3104        DO j = MIN(jde-1,jte) , MAX(jde - spec_bdy_width,jts) , -1
3105        DO i = MAX(ids,its) , MIN(ide-1,ite)
3106           jj = jde - j
3107           space_bdy_ye(i,k,jj) = ( data3dnew(i,j,k) - data3dold(i,j,k) ) / time_diff
3108 !        if (K .eq. 54 .and. I .eq. 369) then
3109 !       write(0,*) 'N bound i,k,jj,data3dnew,data3dold: ', i,k,jj,data3dnew(I,j,k),data3dold(i,j,k)
3110 !       endif
3111        END DO
3112        END DO
3113        END DO
3114     END IF
3115     
3116  END SUBROUTINE stuff_bdytend_ijk
3118 END MODULE module_bc
3120 SUBROUTINE get_bdyzone_x ( bzx )
3121   USE module_bc
3122   IMPLICIT NONE
3123   INTEGER bzx
3124   bzx = bdyzone_x
3125 END SUBROUTINE get_bdyzone_x
3127 SUBROUTINE get_bdyzone_y ( bzy)
3128   USE module_bc
3129   IMPLICIT NONE
3130   INTEGER bzy
3131   bzy = bdyzone_y
3132 END SUBROUTINE get_bdyzone_y
3134 SUBROUTINE get_bdyzone ( bz)
3135   USE module_bc
3136   IMPLICIT NONE
3137   INTEGER bz
3138   bz = bdyzone
3139 END SUBROUTINE get_bdyzone