C $Header: /u/gcmpack/MITgcm/pkg/ctrl/adctrl_bound.F,v 1.11 2012/08/12 19:34:22 jmc Exp $ C $Name: $ #include "CTRL_OPTIONS.h" C-- File ctrl_bound.F: C-- Contents C-- o ADCTRL_BOUND_3D C-- o ADCTRL_BOUND_2D C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| CBOP C !ROUTINE: ADCTRL_BOUND_3D C !INTERFACE: SUBROUTINE ADCTRL_BOUND_3D( U fieldCur, adjFieldCur, I maskFld3d, boundsVec, myThid ) C !DESCRIPTION: \bv C *==========================================================* C | started: Gael Forget gforget@mit.edu 20-Aug-2007 C | C | o in forward mode: impose bounds on ctrl vector values C | o in adjoint mode: do nothing ... or emulate local minimum C *==========================================================* C \ev C !USES: IMPLICIT NONE #include "SIZE.h" #include "EEPARAMS.h" C !INPUT/OUTPUT PARAMETERS: _RL fieldCur (1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr,nSx,nSy) _RL adjFieldCur(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr,nSx,nSy) _RS maskFld3d (1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr,nSx,nSy) _RL boundsVec(5) INTEGER myThid #ifdef ALLOW_ADCTRLBOUND C !LOCAL VARIABLES: INTEGER bi,bj,i,j,k _RL x0,x0p5,l0p5,x1,x2,x2p5,l2p5,x3 _RL tmpCur,xCur,adxCur CEOP x0=boundsVec(1) x1=boundsVec(2) x0p5=(x0+x1)/2.0 l0p5=(x1-x0)/2.0 x2=boundsVec(3) x3=boundsVec(4) x2p5=(x2+x3)/2.0 l2p5=(x3-x2)/2.0 C x0 ctrl_bound and adctrl_bound act on xx/adxx C x0=x3 => ctrl_bound and adctrl_bound DO nothing C otherwise => error IF ( x0.LT.x3 ) THEN IF ( (x0.LT.x1).AND.(x1.LT.x2).AND.(x2.LT.x3) ) THEN DO bj=myByLo(myThid), myByHi(myThid) DO bi=myBxLo(myThid), myBxHi(myThid) DO k = 1,Nr DO j = 1,sNy DO i = 1,sNx IF (maskFld3d(i,j,k,bi,bj).NE.0.) THEN xCur=fieldCur(i,j,k,bi,bj) adxCur=adjFieldCur(i,j,k,bi,bj) IF ( (xCur.GT.x2).AND.(adxCur.LT.0.) ) THEN tmpCur=1.0 adjFieldCur(i,j,k,bi,bj)=abs(adxCur)* & min((xCur-x2p5)/l2p5,tmpCur) ENDIF IF ( (xCur.LT.x1).AND.(adxCur.GT.0.) ) THEN tmpCur=-1.0 adjFieldCur(i,j,k,bi,bj)=abs(adxCur)* & max((xCur-x0p5)/l0p5,tmpCur) ENDIF ENDIF ENDDO ENDDO ENDDO ENDDO ENDDO ELSE PRINT*,"boundsVec is not self-consistent" STOP 'ABNORMAL END: S/R ADCTRL_BOUND_3D' ENDIF ENDIF #endif /* ALLOW_ADCTRLBOUND */ RETURN END C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| CBOP C !ROUTINE: ADCTRL_BOUND_2D C !INTERFACE: SUBROUTINE ADCTRL_BOUND_2D( U fieldCur, adjFieldCur, I maskFld3d, boundsVec, myThid ) C !DESCRIPTION: \bv C *==========================================================* C | started: Gael Forget gforget@mit.edu 20-Aug-2007 C | C | o in forward mode: impose bounds on ctrl vector values C | o in adjoint mode: DO nothing ... or emulate local minimum C *==========================================================* C \ev C !USES: IMPLICIT NONE #include "SIZE.h" #include "EEPARAMS.h" C !INPUT/OUTPUT PARAMETERS: _RL fieldCur (1-Olx:sNx+Olx,1-Oly:sNy+Oly, nSx,nSy) _RL adjFieldCur(1-Olx:sNx+Olx,1-Oly:sNy+Oly, nSx,nSy) _RS maskFld3d (1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr,nSx,nSy) _RL boundsVec(5) INTEGER myThid #ifdef ALLOW_ADCTRLBOUND C !LOCAL VARIABLES: INTEGER bi,bj,i,j _RL x0,x0p5,l0p5,x1,x2,x2p5,l2p5,x3 _RL tmpCur,xCur,adxCur CEOP x0=boundsVec(1) x1=boundsVec(2) x0p5=(x0+x1)/2.0 l0p5=(x1-x0)/2.0 x2=boundsVec(3) x3=boundsVec(4) x2p5=(x2+x3)/2.0 l2p5=(x3-x2)/2.0 C x0 ctrl_bound and adctrl_bound act on xx/adxx C x0=x3 => ctrl_bound and adctrl_bound DO nothing C otherwise => error IF ( x0.LT.x3 ) THEN IF ( (x0.LT.x1).AND.(x1.LT.x2).AND.(x2.LT.x3) ) THEN DO bj=myByLo(myThid), myByHi(myThid) DO bi=myBxLo(myThid), myBxHi(myThid) DO j = 1,sNy DO i = 1,sNx IF (maskFld3d(i,j,1,bi,bj).NE.0.) THEN xCur=fieldCur(i,j,bi,bj) adxCur=adjFieldCur(i,j,bi,bj) IF ( (xCur.GT.x2).AND.(adxCur.LT.0.) ) THEN tmpCur=1.0 adjFieldCur(i,j,bi,bj)=abs(adxCur)* & min((xCur-x2p5)/l2p5,tmpCur) ENDIF IF ( (xCur.LT.x1).AND.(adxCur.GT.0.) ) THEN tmpCur=-1.0 adjFieldCur(i,j,bi,bj)=abs(adxCur)* & max((xCur-x0p5)/l0p5,tmpCur) ENDIF ENDIF ENDDO ENDDO ENDDO ENDDO ELSE PRINT*,"boundsVec is not self-consistent" STOP 'ABNORMAL END: S/R ADCTRL_BOUND_2D' ENDIF ENDIF #endif /* ALLOW_ADCTRLBOUND */ RETURN END