C $Header: /u/gcmpack/MITgcm/pkg/obcs/obcs_diag_balance.F,v 1.6 2014/12/19 05:41:20 jmc Exp $
C $Name: $
#include "OBCS_OPTIONS.h"
C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
CBOP
C !ROUTINE: OBCS_DIAG_BALANCE
C !INTERFACE:
SUBROUTINE OBCS_DIAG_BALANCE(
U div2d,
I uTrans, vTrans, k,
I myTime, myIter, myThid )
C !DESCRIPTION:
C *==========================================================*
C | SUBROUTINE OBCS_DIAG_BALANCE
C | o For diagnostics purpose, modify horizontal divergence
C | next (but outside) OB to ensure zero net inflow
C *==========================================================*
C !USES:
IMPLICIT NONE
C === Global variables ===
#include "SIZE.h"
#include "EEPARAMS.h"
#include "PARAMS.h"
#include "GRID.h"
#include "OBCS_PARAMS.h"
#include "OBCS_GRID.h"
#include "OBCS_FIELDS.h"
C !INPUT/OUTPUT PARAMETERS:
C div2d :: horizontal divergence x grid-cell volume [m^3/s]
C uTrans :: horizontal transport to balance [m^3/s]
C vTrans :: horizontal transport to balance [m^3/s]
C k :: current level index
C myTime :: current time of simulation (s)
C myIter :: current iteration number
C myThid :: my Thread Id number
_RL div2d (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
_RL uTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
_RL vTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
INTEGER k
_RL myTime
INTEGER myIter
INTEGER myThid
CEOP
#ifdef ALLOW_OBCS
#ifdef ALLOW_DIAGNOSTICS
C !FUNCTIONS:
C !LOCAL VARIABLES:
C bi, bj :: tile indices
C i,j,k :: loop indices
C iB, jB :: local index of open boundary
C msgBuf :: Informational/error message buffer
INTEGER bi, bj, n
INTEGER i, j, iB, jB, iBt, jBt
CHARACTER*(MAX_LEN_MBUF) msgBuf
_RL areaOB(OBCS_maxConnect), tmpA
_RL inFlow(OBCS_maxConnect)
_RL tileAreaOB(nSx,nSy,OBCS_maxConnect)
_RL tileInFlow(nSx,nSy,OBCS_maxConnect)
C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
#ifdef ALLOW_DEBUG
IF (debugMode) CALL DEBUG_ENTER('OBCS_DIAG_BALANCE',myThid)
#endif
C-- Integrate the transport through each OB
DO n=1,OB_connectNumber(k)
areaOB(n)= 0. _d 0
inFlow(n)= 0. _d 0
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
tileAreaOB(bi,bj,n) = 0.
tileInFlow(bi,bj,n) = 0.
ENDDO
ENDDO
ENDDO
#ifdef ALLOW_OBCS_EAST
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
IF ( tileHasOBE(bi,bj) ) THEN
DO j=1,sNy
iB = OB_Ie(j,bi,bj)
IF ( iB.NE.OB_indexNone .AND. iB.GT.1 ) THEN
n = OBE_connect(j,k,bi,bj)
IF ( n.GE.1 ) THEN
tmpA = drF(k)*hFacW(iB,j,k,bi,bj)*dyG(iB,j,bi,bj)
& *maskInW(iB,j,bi,bj)
tileAreaOB(bi,bj,n) = tileAreaOB(bi,bj,n) + tmpA
tileInFlow(bi,bj,n) = tileInFlow(bi,bj,n)
& - uTrans(iB,j,bi,bj)
ENDIF
ENDIF
ENDDO
ENDIF
ENDDO
ENDDO
#endif /* ALLOW_OBCS_EAST */
#ifdef ALLOW_OBCS_WEST
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
IF ( tileHasOBW(bi,bj) ) THEN
DO j=1,sNy
iB = OB_Iw(j,bi,bj)
IF ( iB.NE.OB_indexNone .AND. iB.LT.sNx ) THEN
n = OBW_connect(j,k,bi,bj)
IF ( n.GE.1 ) THEN
iB = 1+iB
tmpA = drF(k)*hFacW(iB,j,k,bi,bj)*dyG(iB,j,bi,bj)
& *maskInW(iB,j,bi,bj)
tileAreaOB(bi,bj,n) = tileAreaOB(bi,bj,n) + tmpA
tileInFlow(bi,bj,n) = tileInFlow(bi,bj,n)
& + uTrans(iB,j,bi,bj)
ENDIF
ENDIF
ENDDO
ENDIF
ENDDO
ENDDO
#endif /* ALLOW_OBCS_WEST */
#ifdef ALLOW_OBCS_NORTH
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
IF ( tileHasOBN(bi,bj) ) THEN
DO i=1,sNx
jB = OB_Jn(i,bi,bj)
IF ( jB.NE.OB_indexNone .AND. jB.GT.1 ) THEN
n = OBN_connect(i,k,bi,bj)
IF ( n.GE.1 ) THEN
tmpA = drF(k)*hFacS(i,jB,k,bi,bj)*dxG(i,jB,bi,bj)
& *maskInS(i,jB,bi,bj)
tileAreaOB(bi,bj,n) = tileAreaOB(bi,bj,n) + tmpA
tileInFlow(bi,bj,n) = tileInFlow(bi,bj,n)
& - vTrans(i,jB,bi,bj)
ENDIF
ENDIF
ENDDO
ENDIF
ENDDO
ENDDO
#endif /* ALLOW_OBCS_NORTH */
#ifdef ALLOW_OBCS_SOUTH
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
IF ( tileHasOBS(bi,bj) ) THEN
DO i=1,sNx
jB = OB_Js(i,bi,bj)
IF ( jB.NE.OB_indexNone .AND. jB.LT.sNy ) THEN
n = OBS_connect(i,k,bi,bj)
IF ( n.GE.1 ) THEN
jB = 1+jB
tmpA = drF(k)*hFacS(i,jB,k,bi,bj)*dxG(i,jB,bi,bj)
& *maskInS(i,jB,bi,bj)
tileAreaOB(bi,bj,n) = tileAreaOB(bi,bj,n) + tmpA
tileInFlow(bi,bj,n) = tileInFlow(bi,bj,n)
& + vTrans(i,jB,bi,bj)
ENDIF
ENDIF
ENDDO
ENDIF
ENDDO
ENDDO
#endif /* ALLOW_OBCS_SOUTH */
C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
C-- For each set of OB connected points, calculate a unique velocity
C correction and correct to the corresponding OB point divergence
DO n=1,OB_connectNumber(k)
CALL GLOBAL_SUM_TILE_RL( tileAreaOB(1,1,n), areaOB(n), myThid )
IF ( areaOB(n).GT.0. ) THEN
CALL GLOBAL_SUM_TILE_RL( tileInFlow(1,1,n), inFlow(n), myThid )
IF ( debugLevel.GE.debLevC ) THEN
WRITE(msgBuf,'(A,I9,2I4,A,1P2E16.8)')
& 'OBCS_DIAG_BALANCE (it,k,n=', myIter, k, n,
& ' ) inFlow:',inFlow(n),inFlow(n)/areaOB(n)
CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
& SQUEEZE_RIGHT, myThid )
ENDIF
inFlow(n) = inFlow(n) / areaOB(n)
ENDIF
ENDDO
C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
C-- Add correction:
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
#ifdef ALLOW_OBCS_EAST
IF ( tileHasOBE(bi,bj) ) THEN
c DO j=1-OLy,sNy+OLy
DO j=1,sNy
IF ( OB_Ie(j,bi,bj).NE.OB_indexNone ) THEN
iB = OB_Ie(j,bi,bj)
n = OBE_connect(j,k,bi,bj)
IF ( n.EQ.0 ) THEN
div2d(iB ,j,bi,bj) = div2d(iB ,j,bi,bj)
& - uTrans(iB,j,bi,bj)
ELSE
div2d(iB ,j,bi,bj) = div2d(iB,j,bi,bj)
& + inFlow(n)*drF(k)*hFacW(iB,j,k,bi,bj)
& *dyG(iB,j,bi,bj)*maskInW(iB,j,bi,bj)
ENDIF
ENDIF
ENDDO
ENDIF
#endif /* ALLOW_OBCS_EAST */
#ifdef ALLOW_OBCS_WEST
IF ( tileHasOBW(bi,bj) ) THEN
c DO j=1-OLy,sNy+OLy
DO j=1,sNy
IF ( OB_Iw(j,bi,bj).NE.OB_indexNone ) THEN
iBt = OB_Iw(j,bi,bj)
iB = 1+iBt
n = OBW_connect(j,k,bi,bj)
IF ( n.EQ.0 ) THEN
div2d(iBt,j,bi,bj) = div2d(iBt,j,bi,bj)
& + uTrans(iB,j,bi,bj)
ELSE
div2d(iBt,j,bi,bj) = div2d(iBt,j,bi,bj)
& + inFlow(n)*drF(k)*hFacW(iB,j,k,bi,bj)
& *dyG(iB,j,bi,bj)*maskInW(iB,j,bi,bj)
ENDIF
ENDIF
ENDDO
ENDIF
#endif /* ALLOW_OBCS_WEST */
#ifdef ALLOW_OBCS_NORTH
IF ( tileHasOBN(bi,bj) ) THEN
c DO i=1-OLx,sNx+OLx
DO i=1,sNx
IF ( OB_Jn(i,bi,bj).NE.OB_indexNone ) THEN
jB = OB_Jn(i,bi,bj)
n = OBN_connect(i,k,bi,bj)
IF ( n.EQ.0 ) THEN
div2d(i,jB ,bi,bj) = div2d(i,jB ,bi,bj)
& - vTrans(i,jB,bi,bj)
ELSE
div2d(i,jB ,bi,bj) = div2d(i,jB ,bi,bj)
& + inFlow(n)*drF(k)*hFacS(i,jB,k,bi,bj)
& *dxG(i,jB,bi,bj)*maskInS(i,jB,bi,bj)
ENDIF
ENDIF
ENDDO
ENDIF
#endif /* ALLOW_OBCS_NORTH */
#ifdef ALLOW_OBCS_SOUTH
IF ( tileHasOBS(bi,bj) ) THEN
c DO i=1-OLx,sNx+OLx
DO i=1,sNx
IF ( OB_Js(i,bi,bj).NE.OB_indexNone ) THEN
jBt = OB_Js(i,bi,bj)
jB = 1+jBt
n = OBS_connect(i,k,bi,bj)
IF ( n.EQ.0 ) THEN
div2d(i,jBt,bi,bj) = div2d(i,jBt,bi,bj)
& + vTrans(i,jB,bi,bj)
ELSE
div2d(i,jBt,bi,bj) = div2d(i,jBt,bi,bj)
& + inFlow(n)*drF(k)*hFacS(i,jB,k,bi,bj)
& *dxG(i,jB,bi,bj)*maskInS(i,jB,bi,bj)
ENDIF
ENDIF
ENDDO
ENDIF
#endif /* ALLOW_OBCS_SOUTH */
ENDDO
ENDDO
#ifdef ALLOW_DEBUG
IF (debugMode) CALL DEBUG_LEAVE('OBCS_DIAG_BALANCE',myThid)
#endif
#endif /* ALLOW_DIAGNOSTICS */
#endif /* ALLOW_OBCS */
RETURN
END