C $Header: /u/gcmpack/MITgcm/pkg/mom_fluxform/mom_uv_boundary.F,v 1.1 2007/10/28 21:38:21 jmc Exp $ C $Name: $ #include "MOM_FLUXFORM_OPTIONS.h" CBOP C !ROUTINE: MOM_UV_BOUNDARY C !INTERFACE: ========================================================== SUBROUTINE MOM_UV_BOUNDARY ( I bi,bj,k, I uFld, vFld, O uBnd, vBnd, I myTime, myIter, myThid ) C !DESCRIPTION: C Set velocity at a boundary for a momentum conserving advection C Note: really conserve momentum when "steps" (vertical plane) C or coastline (horizontal plane) are only 1 grid-point wide. C !USES: =============================================================== C == Global variables == IMPLICIT NONE #include "SIZE.h" #include "EEPARAMS.h" #include "PARAMS.h" #include "GRID.h" C !INPUT PARAMETERS: =================================================== C bi,bj :: tile indices C k :: vertical level C uFld :: zonal velocity C vFld :: meridional velocity C myTime :: current time C myIter :: current iteration number C myThid :: My Thread Id. number INTEGER bi,bj INTEGER k _RL uFld(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr,nSx,nSy) _RL vFld(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr,nSx,nSy) _RL myTime INTEGER myIter INTEGER myThid C !OUTPUT PARAMETERS: ================================================== C uBnd :: zonal velocity extended to boundaries C vBnd :: meridional velocity extended to boundaries _RL uBnd(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL vBnd(1-OLx:sNx+OLx,1-OLy:sNy+OLy) #ifdef MOM_BOUNDARY_CONSERVE C !LOCAL VARIABLES: ==================================================== C i,j :: loop indices INTEGER i,j INTEGER km1,kp1 _RL maskM1, maskP1 _RL uTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL vTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL aBndU(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL aBndV(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL aBndW(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL tmpVar LOGICAL useMomBndConserve PARAMETER ( useMomBndConserve = .TRUE. ) CEOP C Initialise output array DO j=1-OLy,sNy+OLy DO i=1-OLx,sNx+OLx uBnd(i,j) = uFld(i,j,k,bi,bj) vBnd(i,j) = vFld(i,j,k,bi,bj) ENDDO ENDDO IF ( useMomBndConserve ) THEN C- Initialise intermediate arrays: km1 = MAX( k-1, 1 ) kp1 = MIN( k+1, Nr ) maskM1 = 1. maskP1 = 1. IF ( k.EQ.1 ) maskM1 = 0. IF ( k.EQ.Nr ) maskP1 = 0. DO j=1-OLy,sNy+OLy DO i=1-OLx,sNx+OLx aBndU(i,j) = 0. aBndV(i,j) = 0. aBndW(i,j) = 0. ENDDO ENDDO C- Calculate Divergence in 3 directions: DO j=1-OLy,sNy+OLy DO i=1-OLx,sNx+OLx uTrans(i,j) = uFld(i,j,k,bi,bj) & * dyG(i,j,bi,bj)*deepFacC(k) & * drF(k)*hFacW(i,j,k,bi,bj)*rhoFacC(k) vTrans(i,j) = vFld(i,j,k,bi,bj) & * dxG(i,j,bi,bj)*deepFacC(k) & * drF(k)*hFacS(i,j,k,bi,bj)*rhoFacC(k) ENDDO ENDDO DO j=1-OLy,sNy+OLy-1 DO i=1-OLx,sNx+OLx-1 aBndU(i,j) = uTrans(i+1,j)-uTrans(i,j) aBndV(i,j) = vTrans(i,j+1)-vTrans(i,j) aBndW(i,j) = ABS(aBndU(i,j)+aBndV(i,j)) aBndU(i,j) = ABS(aBndU(i,j)) aBndV(i,j) = ABS(aBndV(i,j)) ENDDO ENDDO C- Normalise by the sum: DO j=1-OLy,sNy+OLy-1 DO i=1-OLx,sNx+OLx-1 tmpVar = aBndU(i,j)+aBndV(i,j)+aBndW(i,j) IF ( tmpVar.GT.0. ) THEN tmpVar = 1. _d 0 / tmpVar aBndU(i,j) = aBndU(i,j)*tmpVar aBndV(i,j) = aBndV(i,j)*tmpVar aBndW(i,j) = aBndW(i,j)*tmpVar ENDIF ENDDO ENDDO C- At a boundary, replace uFld,vFld by a weighted average C Note: multiply by 2 to cancel the 1/2 factor in advections S/R DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF (maskW(i,j,k,bi,bj).EQ.0.) THEN C Note: only 1 set of aBnd_U,V,W is non-zero (either i-1 or i) C and only 1 uFld is non-zero (either i-1 or i+1) C and only 1 uFld is non-zero (either k-1 or k+1) uBnd(i,j) = ( & (aBndU(i-1,j)+aBndU(i,j)) & *(uFld(i-1,j,k,bi,bj)+uFld(i+1,j,k,bi,bj)) & +(aBndV(i-1,j)+aBndV(i,j)) & *(uFld(i,j-1,k,bi,bj)+uFld(i,j+1,k,bi,bj)) & +(aBndW(i-1,j)+aBndW(i,j)) & *(uFld(i,j,km1,bi,bj)*maskM1 & +uFld(i,j,kp1,bi,bj)*maskP1) & )*2. _d 0 ENDIF IF (maskS(i,j,k,bi,bj).EQ.0.) THEN C Note: only 1 set of aBnd_U,V,W is non-zero (either j-1 or j) C and only 1 vFld is non-zero (either j-1 or j+1) C and only 1 vFld is non-zero (either k-1 or k+1) vBnd(i,j) = ( & (aBndU(i,j-1)+aBndU(i,j)) & *(vFld(i-1,j,k,bi,bj)+vFld(i+1,j,k,bi,bj)) & +(aBndV(i,j-1)+aBndV(i,j)) & *(vFld(i,j-1,k,bi,bj)+vFld(i,j+1,k,bi,bj)) & +(aBndW(i,j-1)+aBndW(i,j)) & *(vFld(i,j,km1,bi,bj)*maskM1 & +vFld(i,j,kp1,bi,bj)*maskP1) & )*2. _d 0 ENDIF ENDDO ENDDO ENDIF #endif /* MOM_BOUNDARY_CONSERVE */ RETURN END