Back to home page

MITgcm

 
 

    


Warning, /eesupp/src/exch1_bg_rx_cube.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
ba0dad37f4 Jean*0001 #include "CPP_EEOPTIONS.h"
                0002 
                0003 CBOP
                0004 
                0005 C     !ROUTINE: EXCH1_BG_RX_CUBE
                0006 
                0007 C     !INTERFACE:
                0008       SUBROUTINE EXCH1_BG_RX_CUBE(
                0009      U                 uField, vField,
                0010      I                 withSigns,
                0011      I                 myOLw, myOLe, myOLs, myOLn, myNz,
                0012      I                 exchWidthX, exchWidthY,
                0013      I                 cornerMode, myThid )
                0014 
                0015 C     !DESCRIPTION:
                0016 C     *==========================================================*
                0017 C     | SUBROUTINE EXCH1_BG_RX_CUBE
                0018 C     | o Forward-mode edge exchanges for RX vector on CS config:
                0019 C     |   Fill overlap region through tile exchanges,
                0020 C     |   according to CS topology,
                0021 C     |   for a 2-Components B-Grid vector field RX arrays.
                0022 C     *==========================================================*
                0023 C     | Proceeds in 2 steps :
                0024 C     |  1) fill the edges to get valid fields over (1:sNx+1,1:sNy+1)
                0025 C     |  2) fill in overlap region:
                0026 C     |     (1-Olx:0 & sNx+2:sNx+Olx) x (1-Oly:0 & sNy+2:sNy+Oly)
                0027 C     | Only works: a) with exactly 6 tiles (1 per face)
                0028 C     |             b) no MPI
                0029 C     |             c) thread shared arrays (in common block)
                0030 C     *==========================================================*
                0031 
                0032 C     !USES:
                0033       IMPLICIT NONE
                0034 
                0035 C     == Global data ==
                0036 #include "SIZE.h"
                0037 #include "EEPARAMS.h"
                0038 
                0039 C     !INPUT/OUTPUT PARAMETERS:
                0040 C     == Routine arguments ==
                0041 C     uField     :: 1rst component array with overlap to exchange.
                0042 C     vField     :: 2nd  component array with overlap to exchange.
                0043 C     withSigns  :: sign of uField,vField depends on orientation.
                0044 C     myOLw,myOLe :: West  and East  overlap region sizes.
                0045 C     myOLs,myOLn :: South and North overlap region sizes.
                0046 C     exchWidthX  :: Width of data region exchanged in X.
                0047 C     exchWidthY  :: Width of data region exchanged in Y.
                0048 C                    Note --
                0049 C                    1. In theory one could have a send width and
                0050 C                    a receive width for each face of each tile. The only
                0051 C                    restriction would be that the send width of one
                0052 C                    face should equal the receive width of the sent to
                0053 C                    tile face. Dont know if this would be useful. I
                0054 C                    have left it out for now as it requires additional
                0055 C                    bookeeping.
                0056 C     cornerMode  :: Flag indicating whether corner updates are needed.
                0057 C     myThid      :: my Thread Id number
                0058 
                0059       INTEGER myOLw, myOLe, myOLs, myOLn, myNz
                0060       _RX uField( 1-myOLw:sNx+myOLe, 1-myOLs:sNy+myOLn,
                0061      &            myNz, nSx, nSy )
                0062       _RX vField( 1-myOLw:sNx+myOLe, 1-myOLs:sNy+myOLn,
                0063      &            myNz, nSx, nSy )
                0064       LOGICAL withSigns
                0065       INTEGER exchWidthX
                0066       INTEGER exchWidthY
                0067       INTEGER cornerMode
                0068       INTEGER myThid
                0069 
                0070 C     !LOCAL VARIABLES:
                0071 C     == Local variables ==
                0072 C     theSimulationMode :: Holds working copy of simulation mode
                0073 C     theCornerMode     :: Holds working copy of corner mode
                0074 C     i,j,k,repeat      :: Loop counters and index
                0075 C     bt,bn,bs,be,bw
                0076 c     INTEGER theSimulationMode
                0077 c     INTEGER theCornerMode
                0078       INTEGER i,j,k
                0079       INTEGER updateEdges, j1, j2, j3
                0080       INTEGER bt,bn,bs,be,bw
                0081       CHARACTER*(MAX_LEN_MBUF) msgBuf
                0082       _RX negOne
                0083 
                0084 C     == Statement function ==
                0085       INTEGER tilemod
                0086       tilemod(i)=1+mod(i-1+6,6)
                0087 CEOP
                0088 
                0089 c     theSimulationMode = FORWARD_SIMULATION
                0090 c     theCornerMode     = cornerMode
                0091 
                0092 c     IF ( simulationMode.EQ.REVERSE_SIMULATION ) THEN
                0093 c       WRITE(msgBuf,'(A)')'EXCH1_BG_RX_CUBE: AD mode not implemented'
                0094 c       CALL PRINT_ERROR( msgBuf, myThid )
                0095 c       STOP 'ABNORMAL END: EXCH1_BG_RX_CUBE: no AD code'
                0096 c     ENDIF
                0097       IF ( sNx.NE.sNy .OR.
                0098      &     nSx.NE.6 .OR. nSy.NE.1 .OR.
                0099      &     nPx.NE.1 .OR. nPy.NE.1 ) THEN
                0100         WRITE(msgBuf,'(2A)') 'EXCH1_BG_RX_CUBE: Wrong Tiling'
                0101         CALL PRINT_ERROR( msgBuf, myThid )
                0102         WRITE(msgBuf,'(2A)') 'EXCH1_BG_RX_CUBE: ',
                0103      &   'works only with sNx=sNy & nSx=6 & nSy=nPx=nPy=1'
                0104         CALL PRINT_ERROR( msgBuf, myThid )
                0105         STOP 'ABNORMAL END: EXCH1_BG_RX_CUBE: Wrong Tiling'
                0106       ENDIF
                0107 
                0108 C-- Could by-pass 1rst step (with updateEdges= 0) if vector field is
                0109 C   valid over (1:sNx+1,1:sNy+1); In general this should be the case
                0110 C   for correct computation domain; but some exceptions ? + I/O problems
                0111 C-- Exch of 2-Components vector (assumed to be 90.deg apart) at corner
                0112 C   point is ill defined since we have 3 axes @ 120.deg apart.
                0113 C   go with 3 options :
                0114 C      updateEdges = 1 : do not touch corner values ;
                0115 C      updateEdges = 2 : copy from corresponding face S.W corner (<= clear owner)
                0116 C                        and do nothing for missing corners ;
                0117 C      updateEdges = 3 : copy all corner values.
                0118 C------
                0119       updateEdges = 2
                0120       IF ( withSigns ) updateEdges = MIN(1,updateEdges)
                0121 
                0122       negOne = 1.
                0123       IF (withSigns) negOne = -1.
                0124 
                0125 C     For now tile<->tile exchanges are sequentialised through
                0126 C     thread 1. This is a temporary feature for preliminary testing until
                0127 C     general tile decomposistion is in place (CNH April 11, 2001)
                0128       CALL BAR2( myThid )
                0129       _BEGIN_MASTER( myThid )
                0130 
                0131 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
                0132 
                0133       IF ( updateEdges.GT.0 ) THEN
                0134 C-- 1rst Step : Just fill-in North (j=sNy+1) & East (i=sNx+1) edges
                0135 
                0136        j1 = 2
                0137        j2 = 2
                0138        j3 = sNy
                0139        IF ( updateEdges.GE.2 ) THEN
                0140          j1 = 1
                0141          j3 = sNy+1
                0142        ENDIF
                0143        IF ( updateEdges.EQ.3 ) j2 = 1
                0144 
                0145        DO bt = 1,nSx
                0146         IF ( MOD(bt,2).EQ.1 ) THEN
                0147 C      Odd face Number:
                0148 
                0149          bn=tilemod(bt+2)
                0150          bs=tilemod(bt-1)
                0151          be=tilemod(bt+1)
                0152          bw=tilemod(bt-2)
                0153 
                0154          i = 1
                0155          DO k = 1, myNz
                0156 C         Tile Odd:Odd+2 [get] [North<-West]
                0157           DO j = j2, j3
                0158            uField(j,sNy+i,k,bt,1) = vField(i,sNy+2-j,k,bn,1)*negOne
                0159            vField(j,sNy+i,k,bt,1) = uField(i,sNy+2-j,k,bn,1)
                0160           ENDDO
                0161 C         Tile Odd:Odd+1 [get] [East<-West]
                0162           DO j = j1, sNy
                0163            uField(sNx+i,j,k,bt,1) = uField(i,j,k,be,1)
                0164            vField(sNx+i,j,k,bt,1) = vField(i,j,k,be,1)
                0165           ENDDO
                0166          ENDDO
                0167 
                0168         ELSE
                0169 C      Even face Number:
                0170 
                0171          bn=tilemod(bt+1)
                0172          bs=tilemod(bt-2)
                0173          be=tilemod(bt+2)
                0174          bw=tilemod(bt-1)
                0175 
                0176          i = 1
                0177          DO k = 1, myNz
                0178 C         Tile Even:Even+1 [get] [North<-South]
                0179           DO j = j1, sNy
                0180            uField(j,sNy+i,k,bt,1) = uField(j,i,k,bn,1)
                0181            vField(j,sNy+i,k,bt,1) = vField(j,i,k,bn,1)
                0182           ENDDO
                0183 C         Tile Even:Even+2 [get] [East<-South]
                0184           DO j = j2, j3
                0185            uField(sNx+i,j,k,bt,1) = vField(sNx+2-j,i,k,be,1)
                0186            vField(sNx+i,j,k,bt,1) = uField(sNx+2-j,i,k,be,1)*negOne
                0187           ENDDO
                0188          ENDDO
                0189 
                0190 C--    end odd/even face number
                0191         ENDIF
                0192 C--    end loop on tile index bt
                0193        ENDDO
                0194 
                0195 C-- End of 1rst Step
                0196       ENDIF
                0197 
                0198 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
                0199 
                0200 C-- 2nd Step: fill-in (true) overlap regions:
                0201 
                0202       DO bt = 1,nSx
                0203        IF ( MOD(bt,2).EQ.1 ) THEN
                0204 C      Odd face Number:
                0205 
                0206          bn=tilemod(bt+2)
                0207          bs=tilemod(bt-1)
                0208          be=tilemod(bt+1)
                0209          bw=tilemod(bt-2)
                0210 
                0211          DO k = 1, myNz
                0212           DO j = 1, sNy+1
                0213            DO i = 2, exchWidthX
                0214 
                0215 C          Tile Odd:Odd+2 [get] [North<-West]
                0216            uField(j,sNy+i,k,bt,1) = vField(i,sNy+2-j,k,bn,1)*negOne
                0217            vField(j,sNy+i,k,bt,1) = uField(i,sNy+2-j,k,bn,1)
                0218 C          Tile Odd:Odd+1 [get] [East<-West]
                0219            uField(sNx+i,j,k,bt,1) = uField(i,j,k,be,1)
                0220            vField(sNx+i,j,k,bt,1) = vField(i,j,k,be,1)
                0221 
                0222           ENDDO
                0223           DO i = 1-exchWidthX, 0
                0224 
                0225 C          Tile Odd:Odd-1 [get] [South<-North]
                0226            uField(j,i,k,bt,1) = uField(j,sNy+i,k,bs,1)
                0227            vField(j,i,k,bt,1) = vField(j,sNy+i,k,bs,1)
                0228 C          Tile Odd:Odd-2 [get] [West<-North]
                0229            uField(i,j,k,bt,1) = vField(sNx+2-j,sNy+i,k,bw,1)
                0230            vField(i,j,k,bt,1) = uField(sNx+2-j,sNy+i,k,bw,1)*negOne
                0231 
                0232           ENDDO
                0233          ENDDO
                0234         ENDDO
                0235 
                0236        ELSE
                0237 C      Even face Number:
                0238 
                0239         bn=tilemod(bt+1)
                0240         bs=tilemod(bt-2)
                0241         be=tilemod(bt+2)
                0242         bw=tilemod(bt-1)
                0243 
                0244         DO k = 1, myNz
                0245          DO j = 1, sNy+1
                0246           DO i = 2, exchWidthX
                0247 
                0248 C          Tile Even:Even+2 [get] [East<-South]
                0249            uField(sNx+i,j,k,bt,1) = vField(sNx+2-j,i,k,be,1)
                0250            vField(sNx+i,j,k,bt,1) = uField(sNx+2-j,i,k,be,1)*negOne
                0251 C          Tile Even:Even+1 [get] [North<-South]
                0252            uField(j,sNy+i,k,bt,1) = uField(j,i,k,bn,1)
                0253            vField(j,sNy+i,k,bt,1) = vField(j,i,k,bn,1)
                0254 
                0255           ENDDO
                0256           DO i = 1-exchWidthX, 0
                0257 
                0258 C          Tile Even:Even-2 [get] [South<-East]
                0259            uField(j,i,k,bt,1) = vField(sNx+i,sNy+2-j,k,bs,1)*negOne
                0260            vField(j,i,k,bt,1) = uField(sNx+i,sNy+2-j,k,bs,1)
                0261 C          Tile Even:Even-1 [get] [West<-East]
                0262            uField(i,j,k,bt,1) = uField(sNx+i,j,k,bw,1)
                0263            vField(i,j,k,bt,1) = vField(sNx+i,j,k,bw,1)
                0264 
                0265           ENDDO
                0266          ENDDO
                0267         ENDDO
                0268 
                0269 C--    end odd/even face number
                0270        ENDIF
                0271 C--    end loop on tile index bt
                0272       ENDDO
                0273 
                0274       _END_MASTER( myThid )
                0275       CALL BAR2(myThid)
                0276 
                0277       RETURN
                0278       END