Back to home page

MITgcm

 
 

    


Warning, /eesupp/src/exch1_rx.template is written in an unsupported language. File is not indexed.

view on githubraw file Latest commit add29e06 on 2018-01-31 20:35:05 UTC
b56f9aa5e6 Jean*0001 #include "CPP_EEOPTIONS.h"
                0002 
                0003 CBOP
                0004 
                0005 C     !ROUTINE: EXCH1_RX
                0006 
                0007 C     !INTERFACE:
                0008       SUBROUTINE EXCH1_RX(
                0009      U                 array,
                0010      I                 myOLw, myOLe, myOLs, myOLn, myNz,
                0011      I                 exchWidthX, exchWidthY,
                0012      I                 cornerMode, myThid )
                0013 
                0014 C     !DESCRIPTION:
                0015 C     *==========================================================*
                0016 C     | SUBROUTINE EXCH1_RX
                0017 C     | o Control forward-mode edge exchanges for RX array.
                0018 C     *==========================================================*
                0019 C     | Controlling routine for exchange of XY edges of an array
                0020 C     | distributed in X and Y. The routine interfaces to
                0021 C     | communication routines that can use messages passing
                0022 C     | exchanges, put type exchanges or get type exchanges.
                0023 C     |  This allows anything from MPI to raw memory channel to
                0024 C     | memmap segments to be used as a inter-process and/or
                0025 C     | inter-thread communiation and synchronisation
                0026 C     | mechanism.
                0027 C     | Notes --
                0028 C     | 1. Some low-level mechanisms such as raw memory-channel
                0029 C     | or SGI/CRAY shmem put do not have direct Fortran bindings
                0030 C     | and are invoked through C stub routines.
                0031 C     | 2. Although this routine is fairly general but it does
                0032 C     | require nSx and nSy are the same for all innvocations.
                0033 C     | There are many common data structures ( myByLo,
                0034 C     | westCommunicationMode, mpiIdW etc... ) tied in with
                0035 C     | (nSx,nSy). To support arbitray nSx and nSy would require
                0036 C     | general forms of these.
                0037 C     | 3. RX arrays are used to generate code for both _RL and
                0038 C     | _RS forms.
                0039 C     *==========================================================*
                0040 
                0041 C     !USES:
                0042       IMPLICIT NONE
                0043 
                0044 C     == Global data ==
                0045 #include "SIZE.h"
                0046 #include "EEPARAMS.h"
                0047 #include "EXCH.h"
                0048 
                0049 C     !INPUT/OUTPUT PARAMETERS:
                0050 C     == Routine arguments ==
                0051 C     array       :: Array with edges to exchange.
                0052 C     myOLw,myOLe :: West  and East  overlap region sizes.
                0053 C     myOLs,myOLn :: South and North overlap region sizes.
                0054 C     exchWidthX  :: Width of data region exchanged in X.
                0055 C     exchWidthY  :: Width of data region exchanged in Y.
                0056 C                    Note --
                0057 C                    1. In theory one could have a send width and
                0058 C                    a receive width for each face of each tile. The only
                0059 C                    restriction would be that the send width of one
                0060 C                    face should equal the receive width of the sent to
                0061 C                    tile face. Dont know if this would be useful. I
                0062 C                    have left it out for now as it requires additional
                0063 C                    bookeeping.
                0064 C     cornerMode  :: Flag indicating whether corner updates are needed.
                0065 C     myThid      :: my Thread Id number
                0066 
                0067       INTEGER myOLw, myOLe, myOLs, myOLn, myNz
                0068       _RX     array( 1-myOLw:sNx+myOLe,
                0069      &               1-myOLs:sNy+myOLn,
                0070      &               myNz, nSx, nSy )
                0071       INTEGER exchWidthX
                0072       INTEGER exchWidthY
                0073       INTEGER cornerMode
                0074       INTEGER myThid
                0075 
                0076 C     !LOCAL VARIABLES:
                0077 C     == Local variables ==
                0078 C     theSimulationMode :: Holds working copy of simulation mode
                0079 C     theCornerMode     :: Holds working copy of corner mode
                0080 C     i,j,k,bi,bj       :: Loop counters
                0081       INTEGER theSimulationMode
                0082       INTEGER theCornerMode
                0083       INTEGER i,j,k,bi,bj
                0084 CEOP
                0085 
                0086       theSimulationMode = FORWARD_SIMULATION
                0087       theCornerMode     = cornerMode
                0088 
                0089 C--   Error checks
                0090       IF ( exchWidthX .GT. myOLw   )
                0091      &  STOP ' S/R EXCH1_RX: exchWidthX .GT. myOLw'
                0092       IF ( exchWidthX .GT. myOLe   )
                0093      &  STOP ' S/R EXCH1_RX: exchWidthX .GT. myOLe'
                0094       IF ( exchWidthY .GT. myOLs   )
                0095      &  STOP ' S/R EXCH1_RX: exchWidthY .GT. myOLs'
                0096       IF ( exchWidthY .GT. myOLn   )
                0097      &  STOP ' S/R EXCH1_RX: exchWidthY .GT. myOLn'
                0098       IF ( myOLw      .GT. MAX_OLX_EXCH )
                0099      &  STOP ' S/R EXCH1_RX: myOLw .GT. MAX_OLX_EXCH'
                0100       IF ( myOLe      .GT. MAX_OLX_EXCH )
                0101      &  STOP ' S/R EXCH1_RX: myOLe .GT. MAX_OLX_EXCH'
f603e2d124 Jean*0102       IF ( myOLn      .GT. MAX_OLY_EXCH )
b56f9aa5e6 Jean*0103      &  STOP ' S/R EXCH1_RX: myOLn .GT. MAX_OLY_EXCH'
                0104       IF ( myOLs      .GT. MAX_OLY_EXCH )
                0105      &  STOP ' S/R EXCH1_RX: myOLs .GT. MAX_OLY_EXCH'
                0106       IF ( myNz       .GT. MAX_NR_EXCH  )
                0107      &  STOP ' S/R EXCH1_RX: myNz  .GT. MAX_NR_EXCH '
                0108       IF (       theCornerMode .NE. EXCH_IGNORE_CORNERS
                0109      &     .AND. theCornerMode .NE. EXCH_UPDATE_CORNERS
                0110      &   ) STOP ' S/R EXCH1_RX: Unrecognised cornerMode '
                0111 
                0112 C--   Cycle edge buffer level
                0113       CALL EXCH_CYCLE_EBL( myThid )
                0114 
                0115       IF ( theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
                0116 
                0117        IF ( Nx .EQ. 1 ) THEN
                0118 C      Special case for zonal average model i.e. case where Nx == 1
                0119 C      In this case a reverse mode exchange simply add values from all i <> 1
                0120 C      to i=1 element and reset to zero.
                0121          DO bj=myByLo(myThid),myByHi(myThid)
                0122           DO bi=myBxLo(myThid),myBxHi(myThid)
                0123            DO k = 1,myNz
                0124             DO j = 1-myOLs,sNy+myOLn
                0125              DO i = 1-myOLw,0
                0126               array(1,j,k,bi,bj) = array(1,j,k,bi,bj)
                0127      &                           + array(i,j,k,bi,bj)
                0128               array(i,j,k,bi,bj) = 0.
                0129              ENDDO
                0130              DO i = sNx+1,sNx+myOLe
                0131               array(1,j,k,bi,bj) = array(1,j,k,bi,bj)
                0132      &                           + array(i,j,k,bi,bj)
                0133               array(i,j,k,bi,bj) = 0.
                0134              ENDDO
                0135             ENDDO
                0136            ENDDO
                0137           ENDDO
                0138          ENDDO
                0139        ENDIF
                0140 
                0141        IF ( Ny .EQ. 1 ) THEN
                0142 C      Special case for X-slice domain i.e. case where Ny == 1
                0143 C      In this case a reverse mode exchange simply add values from all j <> 1
                0144 C      to j=1 element and reset to zero.
                0145          DO bj=myByLo(myThid),myByHi(myThid)
                0146           DO bi=myBxLo(myThid),myBxHi(myThid)
                0147            DO k = 1,myNz
                0148             DO j = 1-myOLs,0
                0149              DO i = 1-myOLw,sNx+myOLe
                0150               array(i,1,k,bi,bj) = array(i,1,k,bi,bj)
                0151      &                           + array(i,j,k,bi,bj)
                0152               array(i,j,k,bi,bj) = 0.
                0153              ENDDO
                0154             ENDDO
                0155             DO j = sNy+1,sNy+myOLn
                0156              DO i = 1-myOLw,sNx+myOLe
                0157               array(i,1,k,bi,bj) = array(i,1,k,bi,bj)
                0158      &                           + array(i,j,k,bi,bj)
                0159               array(i,j,k,bi,bj) = 0.
                0160              ENDDO
                0161             ENDDO
                0162            ENDDO
                0163           ENDDO
                0164          ENDDO
                0165        ENDIF
                0166 
                0167 C--   end of special cases of forward exch
                0168       ENDIF
                0169 
                0170       IF ( theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
                0171 C--     "Put" east and west edges.
                0172         CALL EXCH_RX_SEND_PUT_X( array,
                0173      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0174      I              exchWidthX, exchWidthY,
                0175      I              theSimulationMode, theCornerMode, myThid )
                0176 C--     If corners are important then sync and update east and west edges
                0177 C--     before doing north and south exchanges.
                0178         IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
                0179          CALL EXCH_RX_RECV_GET_X( array,
                0180      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0181      I              exchWidthX, exchWidthY,
                0182      I              theSimulationMode, theCornerMode, myThid )
                0183         ENDIF
                0184 C       "Put" north and south edges.
                0185         CALL EXCH_RX_SEND_PUT_Y( array,
                0186      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0187      I              exchWidthX, exchWidthY,
                0188      I              theSimulationMode, theCornerMode, myThid )
                0189 C--     Sync and update north, south (and east, west if corner updating
                0190 C--     not active).
                0191         IF ( theCornerMode .NE. EXCH_UPDATE_CORNERS ) THEN
                0192          CALL EXCH_RX_RECV_GET_X( array,
                0193      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0194      I              exchWidthX, exchWidthY,
                0195      I              theSimulationMode, theCornerMode, myThid )
                0196         ENDIF
                0197         CALL EXCH_RX_RECV_GET_Y( array,
                0198      I             myOLw, myOLe, myOLs, myOLn, myNz,
                0199      I             exchWidthX, exchWidthY,
                0200      I             theSimulationMode, theCornerMode, myThid )
                0201       ENDIF
                0202 
                0203       IF ( theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
                0204 C       "Put" north and south edges.
                0205         CALL EXCH_RX_SEND_PUT_Y( array,
                0206      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0207      I              exchWidthX, exchWidthY,
                0208      I              theSimulationMode, theCornerMode, myThid )
                0209 C--     If corners are important then sync and update east and west edges
                0210 C--     before doing north and south exchanges.
                0211         IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
                0212          CALL EXCH_RX_RECV_GET_Y( array,
                0213      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0214      I              exchWidthX, exchWidthY,
                0215      I              theSimulationMode, theCornerMode, myThid )
                0216         ENDIF
                0217 C--     "Put" east and west edges.
                0218         CALL EXCH_RX_SEND_PUT_X( array,
                0219      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0220      I              exchWidthX, exchWidthY,
                0221      I              theSimulationMode, theCornerMode, myThid )
                0222 C--     Sync and update east, west (and north, south if corner updating
                0223 C--     not active).
                0224         IF ( theCornerMode .NE. EXCH_UPDATE_CORNERS ) THEN
                0225          CALL EXCH_RX_RECV_GET_Y( array,
                0226      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0227      I              exchWidthX, exchWidthY,
                0228      I              theSimulationMode, theCornerMode, myThid )
                0229         ENDIF
                0230         CALL EXCH_RX_RECV_GET_X( array,
                0231      I             myOLw, myOLe, myOLs, myOLn, myNz,
                0232      I             exchWidthX, exchWidthY,
                0233      I             theSimulationMode, theCornerMode, myThid )
                0234       ENDIF
                0235 
                0236       IF ( theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
                0237 
                0238        IF ( Nx .EQ. 1 ) THEN
                0239 C      Special case for zonal average model i.e. case where Nx == 1
                0240 C      In this case a forward mode exchange simply sets array to
                0241 C      the i=1 value for all i.
                0242          DO bj=myByLo(myThid),myByHi(myThid)
                0243           DO bi=myBxLo(myThid),myBxHi(myThid)
                0244            DO k = 1,myNz
                0245             DO j = 1-myOLs,sNy+myOLn
                0246              DO i = 1-myOLw,sNx+myOLe
                0247               array(i,j,k,bi,bj) = array(1,j,k,bi,bj)
                0248              ENDDO
                0249             ENDDO
                0250            ENDDO
                0251           ENDDO
                0252          ENDDO
                0253        ENDIF
                0254 
                0255        IF ( Ny .EQ. 1 ) THEN
                0256 C      Special case for X-slice domain i.e. case where Ny == 1
                0257 C      In this case a forward mode exchange simply sets array to
                0258 C      the j=1 value for all j.
                0259          DO bj=myByLo(myThid),myByHi(myThid)
                0260           DO bi=myBxLo(myThid),myBxHi(myThid)
                0261            DO k = 1,myNz
                0262             DO j = 1-myOLs,sNy+myOLn
                0263              DO i = 1-myOLw,sNx+myOLe
                0264               array(i,j,k,bi,bj) = array(i,1,k,bi,bj)
                0265              ENDDO
                0266             ENDDO
                0267            ENDDO
                0268           ENDDO
                0269          ENDDO
                0270        ENDIF
                0271 
                0272 C--    end of special cases of forward exch
                0273       ENDIF
                0274 
                0275       RETURN
                0276       END