C $Header: /u/gcmpack/MITgcm/pkg/generic_advdiff/gad_som_prep_cs_corner.F,v 1.2 2008/05/09 21:43:16 jmc Exp $ C $Name: $ #include "GAD_OPTIONS.h" CBOP C !ROUTINE: GAD_SOM_PREP_CS_CORNER C !INTERFACE: SUBROUTINE GAD_SOM_PREP_CS_CORNER( U smVol, smTr0, smTr, smCorners, I prep4dirX, overlapOnly, interiorOnly, I N_edge, S_edge, E_edge, W_edge, I iPass, k, myNz, bi, bj, myThid ) C !DESCRIPTION: \bv C *==========================================================* C | SUBROUTINE GAD_SOM_PREP_CS_CORNER C | o Prepare for Horizontal SOM Advection : C | when using Cubed-Sphere Grid, fill corner-halo regions C | of all Tracer-moments with proper values C *==========================================================* C \ev C !USES: IMPLICIT NONE C === Global variables === #include "SIZE.h" #include "EEPARAMS.h" #include "GAD.h" C !INPUT/OUTPUT PARAMETERS: C === Routine arguments === C smVol :: grid-cell volume C smTr0 :: tracer Zero Order moment C smTr :: tracer 1rst & 2nd Order moments C smCorners :: Temporary storage of Corner-halo-regions values C ( 3rd dim = Number of corners = 4 : SW, SE, NE, NW ) C prep4dirX :: True = prepare for X direction advection C otherwise, prepare for Y direction advection. C overlapOnly :: only update the edges of myTile, but not the interior C interiorOnly :: only update the interior of myTile, but not the edges C [N,S,E,W]_edge :: true if N,S,E,W edge of myTile is an Edge of the cube C iPass :: current passage index in SOM_ADVECT C k :: current level index C myNz :: 3rd dimension of array to exchange C bi,bj :: current tile indices C myThid :: my Thread Id number INTEGER myNz _RL smVol(1-OLx:sNx+OLx,1-OLy:sNy+OLy,myNz) _RL smTr0(1-OLx:sNx+OLx,1-OLy:sNy+OLy,myNz) _RL smTr (1-OLx:sNx+OLx,1-OLy:sNy+OLy,myNz,nSx,nSy,nSOM) _RL smCorners(OLx,OLy,4,-1:nSOM) LOGICAL prep4dirX, overlapOnly, interiorOnly LOGICAL N_edge, S_edge, E_edge, W_edge INTEGER iPass, k, bi, bj INTEGER myThid CEOP C !LOCAL VARIABLES: C === Local variables === INTEGER i,j, jPass, n LOGICAL southWestCorner LOGICAL southEastCorner LOGICAL northEastCorner LOGICAL northWestCorner southWestCorner = S_edge .AND. W_edge southEastCorner = S_edge .AND. E_edge northEastCorner = N_edge .AND. E_edge northWestCorner = N_edge .AND. W_edge IF ( overlapOnly ) THEN C-- to avoid repeating 2 times the full sequence of FILL_CS_CORNER calls, C add a loop on jPass (from iPass to 2) to reproduce the following logic: C 1 ) overlapOnly & iPass = 1 (face 3 & 6) C - fill corners for the other direction C - then store the corner values C 2 ) IF overlapOnly :: fill corners for the current direction C ELSEIF .NOT.interiorOnly :: get the corner values back from storage C ENDIF DO jPass = iPass,2 IF ( ( jPass.EQ.2 .AND. prep4dirX ) .OR. & ( jPass.EQ.1 .AND. .NOT.prep4dirX ) ) THEN C-- Fill corners to prepare for calculations in X CALL GAD_SOM_FILL_CS_CORNER( .TRUE., U smVol(1-OLx,1-OLy,k), U smTr0(1-OLx,1-OLy,k), U smTr(1-OLx,1-OLy,k,bi,bj,1), U smTr(1-OLx,1-OLy,k,bi,bj,2), U smTr(1-OLx,1-OLy,k,bi,bj,3), U smTr(1-OLx,1-OLy,k,bi,bj,4), U smTr(1-OLx,1-OLy,k,bi,bj,5), U smTr(1-OLx,1-OLy,k,bi,bj,6), U smTr(1-OLx,1-OLy,k,bi,bj,7), U smTr(1-OLx,1-OLy,k,bi,bj,8), U smTr(1-OLx,1-OLy,k,bi,bj,9), I bi, bj, myThid ) C-- End of filling for X dir c ENDIF ELSE C Note: the 2 IF tests are equivalent to just 1 if/else test; C use this later option and leave the former commented. c IF ( ( jPass.EQ.1 .AND. prep4dirX ) .OR. c & ( jPass.EQ.2 .AND. .NOT.prep4dirX ) ) THEN C-- Fill corners to prepare for calculations in Y CALL GAD_SOM_FILL_CS_CORNER( .FALSE., U smVol(1-OLx,1-OLy,k), U smTr0(1-OLx,1-OLy,k), U smTr(1-OLx,1-OLy,k,bi,bj,1), U smTr(1-OLx,1-OLy,k,bi,bj,2), U smTr(1-OLx,1-OLy,k,bi,bj,3), U smTr(1-OLx,1-OLy,k,bi,bj,4), U smTr(1-OLx,1-OLy,k,bi,bj,5), U smTr(1-OLx,1-OLy,k,bi,bj,6), U smTr(1-OLx,1-OLy,k,bi,bj,7), U smTr(1-OLx,1-OLy,k,bi,bj,8), U smTr(1-OLx,1-OLy,k,bi,bj,9), I bi, bj, myThid ) C-- End of filling for Y dir ENDIF IF ( jPass.EQ.1 ) THEN C-- Store corner values (to be used on the next iPass) IF ( southWestCorner ) THEN DO j=1,OLy DO i=1,OLx smCorners(i,j,1,-1) = smVol(i-OLx,j-OLy,k) smCorners(i,j,1, 0) = smTr0(i-OLx,j-OLy,k) DO n=1,nSOM smCorners(i,j,1,n) = smTr (i-OLx,j-OLy,k,bi,bj,n) ENDDO ENDDO ENDDO ENDIF IF ( southEastCorner ) THEN DO j=1,OLy DO i=1,OLx smCorners(i,j,2,-1) = smVol(sNx+i,j-OLy,k) smCorners(i,j,2, 0) = smTr0(sNx+i,j-OLy,k) DO n=1,nSOM smCorners(i,j,2,n) = smTr (sNx+i,j-OLy,k,bi,bj,n) ENDDO ENDDO ENDDO ENDIF IF ( northEastCorner ) THEN DO j=1,OLy DO i=1,OLx smCorners(i,j,3,-1) = smVol(sNx+i,sNy+j,k) smCorners(i,j,3, 0) = smTr0(sNx+i,sNy+j,k) DO n=1,nSOM smCorners(i,j,3,n) = smTr (sNx+i,sNy+j,k,bi,bj,n) ENDDO ENDDO ENDDO ENDIF IF ( northWestCorner ) THEN DO j=1,OLy DO i=1,OLx smCorners(i,j,4,-1) = smVol(i-OLx,sNy+j,k) smCorners(i,j,4, 0) = smTr0(i-OLx,sNy+j,k) DO n=1,nSOM smCorners(i,j,4,n) = smTr (i-OLx,sNy+j,k,bi,bj,n) ENDDO ENDDO ENDDO ENDIF C-- End storing block ENDIF C-- End of loop on jPass ENDDO ELSEIF ( .NOT.interiorOnly ) THEN C-- Get back corner values from storage IF ( southWestCorner ) THEN DO j=1,OLy DO i=1,OLx smVol(i-OLx,j-OLy,k ) = smCorners(i,j,1,-1) smTr0(i-OLx,j-OLy,k ) = smCorners(i,j,1, 0) DO n=1,nSOM smTr(i-OLx,j-OLy,k,bi,bj,n) = smCorners(i,j,1, n) ENDDO ENDDO ENDDO ENDIF IF ( southEastCorner ) THEN DO j=1,OLy DO i=1,OLx smVol(sNx+i,j-OLy,k ) = smCorners(i,j,2,-1) smTr0(sNx+i,j-OLy,k ) = smCorners(i,j,2, 0) DO n=1,nSOM smTr(sNx+i,j-OLy,k,bi,bj,n) = smCorners(i,j,2, n) ENDDO ENDDO ENDDO ENDIF IF ( northEastCorner ) THEN DO j=1,OLy DO i=1,OLx smVol(sNx+i,sNy+j,k ) = smCorners(i,j,3,-1) smTr0(sNx+i,sNy+j,k ) = smCorners(i,j,3, 0) DO n=1,nSOM smTr(sNx+i,sNy+j,k,bi,bj,n) = smCorners(i,j,3, n) ENDDO ENDDO ENDDO ENDIF IF ( northWestCorner ) THEN DO j=1,OLy DO i=1,OLx smVol(i-OLx,sNy+j,k ) = smCorners(i,j,4,-1) smTr0(i-OLx,sNy+j,k ) = smCorners(i,j,4, 0) DO n=1,nSOM smTr(i-OLx,sNy+j,k,bi,bj,n) = smCorners(i,j,4, n) ENDDO ENDDO ENDDO ENDIF C-- End getting back corner values from storage C--- End if/else - overlapOnly - block ENDIF RETURN END