C $Header: /u/gcmpack/MITgcm/pkg/gmredi/gmredi_slope_limit.F,v 1.37 2015/12/29 20:30:31 gforget Exp $ C $Name: $ #include "GMREDI_OPTIONS.h" #ifdef ALLOW_AUTODIFF # include "AUTODIFF_OPTIONS.h" #endif CBOP C !ROUTINE: GMREDI_SLOPE_LIMIT C !INTERFACE: SUBROUTINE GMREDI_SLOPE_LIMIT( O SlopeX, SlopeY, O SlopeSqr, taperFct, U hTransLay, baseSlope, recipLambda, U dSigmaDr, I dSigmaDx, dSigmaDy, I Lrho, hMixLay, depthZ, kLow, I k, bi, bj, myTime, myIter, myThid ) C !DESCRIPTION: \bv C *==========================================================* C | SUBROUTINE GMREDI_SLOPE_LIMIT C | o Calculate slopes for use in GM/Redi tensor C *==========================================================* C | On entry: C | dSigmaDr contains the d/dz Sigma C | dSigmaDx/Dy contains X/Y gradients of sigma C | depthZ contains the depth (< 0 !) [m] C | Lrho C | hMixLay mixed layer depth (> 0) C U hTransLay transition layer depth (> 0) C U baseSlope, recipLambda, C | On exit: C | dSigmaDr contains the effective dSig/dz C | SlopeX/Y contains X/Y slopes C | SlopeSqr contains Sx^2+Sy^2 C | taperFct contains tapering funct. value ; C | = 1 when using no tapering C U hTransLay transition layer depth (> 0) C U baseSlope, recipLambda C *==========================================================* C \ev C !USES: IMPLICIT NONE C == Global variables == #include "SIZE.h" #include "GRID.h" #include "EEPARAMS.h" #include "GMREDI.h" #include "PARAMS.h" #ifdef ALLOW_AUTODIFF_TAMC #include "tamc.h" #include "tamc_keys.h" #endif /* ALLOW_AUTODIFF_TAMC */ C == Routine arguments == C !INPUT PARAMETERS: C dSigmaDx :: zonal gradient of density C dSigmaDy :: meridional gradient of density C Lrho :: C hMixLay :: mixed layer thickness (> 0) [m] C depthZ :: model discretized depth (< 0) [m] C kLow :: bottom level index 2-D array C k :: level index C bi, bj :: tile indices C myTime :: time in simulation C myIter :: iteration number in simulation C myThid :: My Thread Id. number C !OUTPUT PARAMETERS: C SlopeX :: isopycnal slope in X direction C SlopeY :: isopycnal slope in Y direction C SlopeSqr :: square of isopycnal slope C taperFct :: tapering function C hTransLay :: depth of the base of the transition layer (> 0) [m] C baseSlope :: slope at the the base of the transition layer C recipLambda :: Slope vertical gradient at Trans. Layer Base (=recip.Lambda) C dSigmaDr :: vertical gradient of density _RL SlopeX (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL SlopeY (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL SlopeSqr (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL taperFct (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL hTransLay (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL baseSlope (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL recipLambda(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL dSigmaDr (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL dSigmaDx (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL dSigmaDy (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL Lrho (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL hMixLay (1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RS depthZ(*) INTEGER kLow (1-OLx:sNx+OLx,1-OLy:sNy+OLy) INTEGER k, bi,bj _RL myTime INTEGER myIter INTEGER myThid CEOP #ifdef ALLOW_GMREDI C !LOCAL VARIABLES: C == Local variables == #ifdef GMREDI_WITH_STABLE_ADJOINT _RL slopeSqTmp,slopeTmp,slopeMax #endif _RL dSigmMod(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL SlopeMod(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL dRdSigmaLtd(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL tmpFld(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL locVar(1-OLx:sNx+OLx,1-OLy:sNy+OLy) _RL f1,Smod,f2,Rnondim _RL maxSlopeSqr _RL fpi PARAMETER( fpi = PI ) INTEGER i,j _RL dTransLay, rLambMin, DoverLamb _RL taperFctLoc, taperFctHat _RL minTransLay C- need to put this one in GM namelist : _RL GM_bigSlope GM_bigSlope = 1. _d +02 #ifdef ALLOW_AUTODIFF_TAMC C TAF thinks for some reason that depthZ is an active variable. C While this does not make the adjoint code wrong, the resulting C code inhibits vectorization in some cases so we tell TAF here C that depthZ is actually a passive grid variable that needs no adjoint CADJ PASSIVE depthz act1 = bi - myBxLo(myThid) max1 = myBxHi(myThid) - myBxLo(myThid) + 1 act2 = bj - myByLo(myThid) max2 = myByHi(myThid) - myByLo(myThid) + 1 act3 = myThid - 1 max3 = nTx*nTy act4 = ikey_dynamics - 1 ikey = (act1 + 1) + act2*max1 & + act3*max1*max2 & + act4*max1*max2*max3 #endif /* ALLOW_AUTODIFF_TAMC */ DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 dSigmMod(i,j) = 0. _d 0 tmpFld(i,j) = 0. _d 0 ENDDO ENDDO IF (GM_taper_scheme.EQ.'orig' .OR. & GM_taper_scheme.EQ.'clipping') THEN #ifdef GM_EXCLUDE_CLIPPING STOP 'Need to compile without "#define GM_EXCLUDE_CLIPPING"' #else /* GM_EXCLUDE_CLIPPING */ C- Original implementation in mitgcmuv C (this turns out to be the same as Cox slope clipping) C- Cox 1987 "Slope clipping" DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 tmpFld(i,j) = dSigmaDx(i,j)*dSigmaDx(i,j) & + dSigmaDy(i,j)*dSigmaDy(i,j) IF ( tmpFld(i,j) .EQ. 0. ) THEN dSigmMod(i,j) = 0. _d 0 ELSE dSigmMod(i,j) = SQRT( tmpFld(i,j) ) ENDIF ENDDO ENDDO #ifdef ALLOW_AUTODIFF_TAMC cnostore CADJ STORE dSigmMod(:,:) = comlev1_bibj, key=ikey, byte=isbyte cnostore CADJ STORE dSigmaDr(:,:) = comlev1_bibj, key=ikey, byte=isbyte #endif DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF (dSigmMod(i,j) .NE. 0.) THEN tmpFld(i,j) = -dSigmMod(i,j)*GM_rMaxSlope IF ( dSigmaDr(i,j) .GE. tmpFld(i,j) ) & dSigmaDr(i,j) = tmpFld(i,j) ENDIF ENDDO ENDDO #ifdef ALLOW_AUTODIFF_TAMC cnostore CADJ STORE slopeX(:,:) = comlev1_bibj, key=ikey, byte=isbyte cnostore CADJ STORE slopeY(:,:) = comlev1_bibj, key=ikey, byte=isbyte cnostore CADJ STORE dSigmaDr(:,:) = comlev1_bibj, key=ikey, byte=isbyte #endif DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF (dSigmMod(i,j) .EQ. 0.) THEN SlopeX(i,j) = 0. _d 0 SlopeY(i,j) = 0. _d 0 ELSE dRdSigmaLtd(i,j) = 1. _d 0/( dSigmaDr(i,j) ) SlopeX(i,j)=-dSigmaDx(i,j)*dRdSigmaLtd(i,j) SlopeY(i,j)=-dSigmaDy(i,j)*dRdSigmaLtd(i,j) ENDIF ENDDO ENDDO #ifdef ALLOW_AUTODIFF_TAMC cnostore CADJ STORE slopeX(:,:) = comlev1_bibj, key=ikey, byte=isbyte cnostore CADJ STORE slopeY(:,:) = comlev1_bibj, key=ikey, byte=isbyte #endif DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 SlopeSqr(i,j)=SlopeX(i,j)*SlopeX(i,j) & +SlopeY(i,j)*SlopeY(i,j) taperFct(i,j)=1. _d 0 ENDDO ENDDO #endif /* GM_EXCLUDE_CLIPPING */ ELSEIF (GM_taper_scheme.EQ.'fm07' ) THEN C-- Ferrari & Mc.Williams, 2007: #ifdef GM_EXCLUDE_FM07_TAP STOP 'Need to compile without "#define GM_EXCLUDE_FM07_TAP"' #else /* GM_EXCLUDE_FM07_TAP */ C- a) Calculate separately slope magnitude (SlopeMod) C and slope horiz. direction (Slope_X,Y : normalized) DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF ( k.GT.kLow(i,j) ) THEN C- Bottom or below: SlopeX (i,j) = 0. _d 0 SlopeY (i,j) = 0. _d 0 SlopeMod(i,j) = 0. _d 0 taperFct(i,j) = 0. _d 0 ELSE C- Above bottom: IF ( dSigmaDr(i,j).GE. -GM_Small_Number ) & dSigmaDr(i,j) = -GM_Small_Number tmpFld(i,j) = dSigmaDx(i,j)*dSigmaDx(i,j) & + dSigmaDy(i,j)*dSigmaDy(i,j) IF ( tmpFld(i,j).GT.0. ) THEN locVar(i,j) = SQRT( tmpFld(i,j) ) SlopeX (i,j) = dSigmaDx(i,j)/locVar(i,j) SlopeY (i,j) = dSigmaDy(i,j)/locVar(i,j) SlopeMod(i,j) = -locVar(i,j)/dSigmaDr(i,j) taperFct(i,j) = 1. _d 0 ELSE SlopeX (i,j) = 0. _d 0 SlopeY (i,j) = 0. _d 0 SlopeMod(i,j) = 0. _d 0 taperFct(i,j) = 0. _d 0 ENDIF ENDIF ENDDO ENDDO C- b) Set Transition Layer Depth: IF ( k.EQ.1 ) THEN minTransLay = GM_facTrL2dz*( depthZ(k) - depthZ(k+1) ) ELSE minTransLay = GM_facTrL2dz*( depthZ(k-1) - depthZ(k) ) ENDIF DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF ( hTransLay(i,j).LE.0. _d 0 ) THEN C- previously below the transition layer tmpFld(i,j) = Lrho(i,j)*SlopeMod(i,j) C- ensure that transition layer is at least as thick than current level and C not thicker than the larger of the 2 : maxTransLay and facTrL2ML*hMixLay dTransLay = & MIN( MAX( tmpFld(i,j), minTransLay ), & MAX( GM_facTrL2ML*hMixLay(i,j), GM_maxTransLay ) ) IF ( k.GE.kLow(i,j) ) THEN C- bottom & below & 1rst level above the bottom : recipLambda(i,j) = 0. _d 0 baseSlope(i,j) = SlopeMod(i,j) C-- note: do not catch the 1rst level/interface (k=kLow) above the bottom C since no baseSlope has yet been stored (= 0); but might fit C well into transition layer criteria (if locally not stratified) ELSEIF ( dTransLay+hMixLay(i,j)+depthZ(k) .GE. 0. ) THEN C- Found the transition Layer : set depth of base of Transition layer hTransLay(i,j) = -depthZ(k+1) C and compute inverse length scale "1/Lambda" from slope vert. grad IF ( baseSlope(i,j).GT.0. ) THEN recipLambda(i,j) = recipLambda(i,j) & / MIN( baseSlope(i,j), GM_maxSlope ) ELSE recipLambda(i,j) = 0. _d 0 ENDIF C slope^2 & Kwz should remain > 0 : prevent too large negative D/lambda IF ( hMixLay(i,j)+depthZ(k+1).LT.0. ) THEN rLambMin = 1. _d 0 /( hMixLay(i,j)+depthZ(k+1) ) recipLambda(i,j) = MAX( recipLambda(i,j), rLambMin ) ENDIF ELSE C- Still below Trans. layer: store slope & slope vert. grad. recipLambda(i,j) = ( MIN( SlopeMod(i,j), GM_maxSlope ) & - MIN( baseSlope(i,j), GM_maxSlope ) & ) / ( depthZ(k) - depthZ(k+1) ) baseSlope(i,j) = SlopeMod(i,j) ENDIF ENDIF ENDDO ENDDO C- c) Set Slope component according to vertical position C (in Mixed-Layer / in Transition Layer / below Transition Layer) DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF ( hTransLay(i,j).GT.0. _d 0 ) THEN C- already above base of transition layer: DoverLamb = (hTransLay(i,j)-hMixLay(i,j))*recipLambda(i,j) IF ( -depthZ(k).LE.hMixLay(i,j) ) THEN C- compute tapering function -G(z) in the mixed Layer: taperFctLoc = & ( -depthZ(k)/(hTransLay(i,j)+hMixLay(i,j)) & *( 2. _d 0 + DoverLamb ) & ) C- compute tapering function -G^(z) in the mixed Layer taperFctHat = & ( -depthZ(k)/(hTransLay(i,j)+hMixLay(i,j)) & * 2. _d 0 & *( 1. _d 0 + DoverLamb ) & ) ELSE C- compute tapering function -G(z) in the transition Layer: taperFctLoc = & ( -depthZ(k)/(hTransLay(i,j)+hMixLay(i,j)) & *( 2. _d 0 + DoverLamb ) & ) & - ( (depthZ(k)+hMixLay(i,j))*(depthZ(k)+hMixLay(i,j)) & /( hTransLay(i,j)*hTransLay(i,j) & - hMixLay(i,j)*hMixLay(i,j) ) & *( 1. _d 0 + hTransLay(i,j)*recipLambda(i,j) ) & ) C- compute tapering function -G^(z) in the transition Layer: taperFctHat = & ( -depthZ(k)/(hTransLay(i,j)+hMixLay(i,j)) & * 2. _d 0 & *( 1. _d 0 + DoverLamb ) & ) & - ( (depthZ(k)+hMixLay(i,j))*(depthZ(k)+hMixLay(i,j)) & /( hTransLay(i,j)*hTransLay(i,j) & - hMixLay(i,j)*hMixLay(i,j) ) & *( 1. _d 0 + hTransLay(i,j)*recipLambda(i,j)*2. _d 0 ) & ) ENDIF C- modify the slope (above bottom of transition layer): c Smod = baseSlope(i,j) C- safer to limit the slope (even if it might never exceed GM_maxSlope) Smod = MIN( baseSlope(i,j), GM_maxSlope ) SlopeX(i,j) = SlopeX(i,j)*Smod*taperFctLoc SlopeY(i,j) = SlopeY(i,j)*Smod*taperFctLoc c SlopeSqr(i,j) = Smod*Smod*taperFctHat c SlopeSqr(i,j) = baseSlope(i,j)*Smod*taperFctHat SlopeSqr(i,j) = MIN( baseSlope(i,j), GM_bigSlope ) & *Smod*taperFctHat ELSE C-- Still below base of transition layer: c Smod = SlopeMod(i,j) C- safer to limit the slope: Smod = MIN( SlopeMod(i,j), GM_maxSlope ) SlopeX(i,j) = SlopeX(i,j)*Smod SlopeY(i,j) = SlopeY(i,j)*Smod c SlopeSqr(i,j) = Smod*Smod c SlopeSqr(i,j) = SlopeMod(i,j)*Smod SlopeSqr(i,j) = MIN( SlopeMod(i,j), GM_bigSlope ) & *Smod C-- end if baseSlope > 0 / else => above/below base of Trans. Layer ENDIF ENDDO ENDDO #endif /* GM_EXCLUDE_FM07_TAP */ ELSE IF (GM_taper_scheme.EQ.'ac02') THEN #ifdef GM_EXCLUDE_AC02_TAP STOP 'Need to compile without "#define GM_EXCLUDE_AC02_TAP"' #else /* GM_EXCLUDE_AC02_TAP */ C- New Scheme (A. & C. 2002): relax part of the small slope approximation C compute the true slope (no approximation) C but still neglect Kxy & Kyx (assumed to be zero) maxSlopeSqr = GM_maxSlope*GM_maxSlope DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 dRdSigmaLtd(i,j)= & dSigmaDx(i,j)*dSigmaDx(i,j) & + dSigmaDy(i,j)*dSigmaDy(i,j) & + dSigmaDr(i,j)*dSigmaDr(i,j) taperFct(i,j) = 1. _d 0 IF (dRdSigmaLtd(i,j).NE.0.) THEN dRdSigmaLtd(i,j)=1. _d 0 & / ( dRdSigmaLtd(i,j) ) SlopeSqr(i,j)=(dSigmaDx(i,j)*dSigmaDx(i,j) & +dSigmaDy(i,j)*dSigmaDy(i,j))*dRdSigmaLtd(i,j) SlopeX(i,j)=-dSigmaDx(i,j) & *dRdSigmaLtd(i,j)*dSigmaDr(i,j) SlopeY(i,j)=-dSigmaDy(i,j) & *dRdSigmaLtd(i,j)*dSigmaDr(i,j) cph T11(i,j)=(dSigmaDr(i,j)**2)*dRdSigmaLtd(i,j) ENDIF #ifndef ALLOWW_AUTODIFF_TAMC cph-- this part does not adjoint well IF ( SlopeSqr(i,j) .GT. maxSlopeSqr .AND. & SlopeSqr(i,j) .LT. GM_slopeSqCutoff ) THEN taperFct(i,j) = maxSlopeSqr/SlopeSqr(i,j) ELSE IF ( SlopeSqr(i,j) .GT. GM_slopeSqCutoff ) THEN taperFct(i,j) = 0. _d 0 ENDIF #endif ENDDO ENDDO #endif /* GM_EXCLUDE_AC02_TAP */ ELSE #ifdef GM_EXCLUDE_TAPERING STOP 'Need to compile without "#define GM_EXCLUDE_TAPERING"' #else /* GM_EXCLUDE_TAPERING */ C---------------------------------------------------------------------- C- Compute the slope, no clipping, but avoid reverse slope in negatively C stratified (Sigma_Z > 0) region : #ifdef ALLOW_AUTODIFF_TAMC cnostore CADJ STORE dSigmaDr(:,:) = comlev1_bibj, key=ikey, byte=isbyte #endif DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF ( dSigmaDr(i,j) .NE. 0. ) THEN IF (dSigmaDr(i,j).GE.(-GM_Small_Number)) & dSigmaDr(i,j) = -GM_Small_Number ENDIF ENDDO ENDDO #ifdef ALLOW_AUTODIFF_TAMC cnostore CADJ STORE dSigmaDx(:,:) = comlev1_bibj, key=ikey, byte=isbyte cnostore CADJ STORE dSigmaDy(:,:) = comlev1_bibj, key=ikey, byte=isbyte cnostore CADJ STORE dSigmaDr(:,:) = comlev1_bibj, key=ikey, byte=isbyte #endif DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF ( dSigmaDr(i,j) .EQ. 0. ) THEN IF ( dSigmaDx(i,j) .NE. 0. ) THEN SlopeX(i,j) = SIGN( GM_bigSlope, dSigmaDx(i,j) ) ELSE SlopeX(i,j) = 0. _d 0 ENDIF IF ( dSigmaDy(i,j) .NE. 0. ) THEN SlopeY(i,j) = SIGN( GM_bigSlope, dSigmaDy(i,j) ) ELSE SlopeY(i,j) = 0. _d 0 ENDIF ELSE dRdSigmaLtd(i,j) = 1. _d 0 / dSigmaDr(i,j) SlopeX(i,j)=-dSigmaDx(i,j)*dRdSigmaLtd(i,j) SlopeY(i,j)=-dSigmaDy(i,j)*dRdSigmaLtd(i,j) c SlopeX(i,j) = -dSigmaDx(i,j)/dSigmaDr(i,j) c SlopeY(i,j) = -dSigmaDy(i,j)/dSigmaDr(i,j) ENDIF ENDDO ENDDO #ifdef ALLOW_AUTODIFF_TAMC cnostore CADJ STORE slopeX(:,:) = comlev1_bibj, key=ikey, byte=isbyte cnostore CADJ STORE slopeY(:,:) = comlev1_bibj, key=ikey, byte=isbyte #endif DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 SlopeSqr(i,j) = SlopeX(i,j)*SlopeX(i,j) & +SlopeY(i,j)*SlopeY(i,j) taperFct(i,j) = 1. _d 0 IF ( SlopeSqr(i,j) .GT. GM_slopeSqCutoff ) THEN slopeSqr(i,j) = GM_slopeSqCutoff taperFct(i,j) = 0. _d 0 ENDIF ENDDO ENDDO C- Compute the tapering function for the GM+Redi tensor : IF (GM_taper_scheme.EQ.'linear') THEN C- Simplest adiabatic tapering = Smax/Slope (linear) maxSlopeSqr = GM_maxSlope*GM_maxSlope DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF ( SlopeSqr(i,j) .EQ. 0. ) THEN taperFct(i,j) = 1. _d 0 ELSE IF ( SlopeSqr(i,j) .GT. maxSlopeSqr .AND. & SlopeSqr(i,j) .LT. GM_slopeSqCutoff ) THEN taperFct(i,j) = SQRT(maxSlopeSqr / SlopeSqr(i,j)) slopeSqr(i,j) = MIN( slopeSqr(i,j),GM_bigSlope*GM_bigSlope ) ENDIF ENDDO ENDDO ELSEIF (GM_taper_scheme.EQ.'gkw91') THEN C- Gerdes, Koberle and Willebrand, Clim. Dyn. 1991 maxSlopeSqr = GM_maxSlope*GM_maxSlope DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF ( SlopeSqr(i,j) .EQ. 0. ) THEN taperFct(i,j) = 1. _d 0 ELSE IF ( SlopeSqr(i,j) .GT. maxSlopeSqr .AND. & SlopeSqr(i,j) .LT. GM_slopeSqCutoff ) THEN taperFct(i,j) = maxSlopeSqr/SlopeSqr(i,j) ENDIF ENDDO ENDDO ELSEIF (GM_taper_scheme.EQ.'dm95') THEN C- Danabasoglu and McWilliams, J. Clim. 1995 DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF ( SlopeSqr(i,j) .EQ. 0. ) THEN taperFct(i,j) = 1. _d 0 ELSE IF ( SlopeSqr(i,j) .LT. GM_slopeSqCutoff ) THEN Smod=SQRT(SlopeSqr(i,j)) taperFct(i,j)=op5*( 1. _d 0 + tanh( (GM_Scrit-Smod)/GM_Sd )) ENDIF ENDDO ENDDO ELSEIF (GM_taper_scheme.EQ.'ldd97') THEN C- Large, Danabasoglu and Doney, JPO 1997 DO j=1-OLy+1,sNy+OLy-1 DO i=1-OLx+1,sNx+OLx-1 IF (SlopeSqr(i,j) .EQ. 0.) THEN taperFct(i,j) = 1. _d 0 ELSEIF ( SlopeSqr(i,j) .LT. GM_slopeSqCutoff ) THEN Smod=SQRT(SlopeSqr(i,j)) f1=op5*( 1. _d 0 + tanh( (GM_Scrit-Smod)/GM_Sd )) Rnondim= -depthZ(k)/(Lrho(i,j)*Smod) IF ( Rnondim.GE.1. _d 0 ) THEN f2 = 1. _d 0 ELSE f2 = op5*( 1. _d 0 + SIN( fpi*(Rnondim-op5) )) ENDIF taperFct(i,j)=f1*f2 ENDIF ENDDO ENDDO ELSEIF (GM_taper_scheme.EQ.'stableGmAdjTap') THEN #ifndef GMREDI_WITH_STABLE_ADJOINT STOP 'Need to compile wth "#define GMREDI_WITH_STABLE_ADJOINT"' #else /* GMREDI_WITH_STABLE_ADJOINT */ c special choice for adjoint/optimization of parameters c (~ strong clipping, reducing non linearity of kw=f(K)) slopeMax= 2. _d -3 CADJ STORE SlopeX(:,:) = comlev1_bibj, key=ikey, byte=isbyte CADJ STORE SlopeY(:,:) = comlev1_bibj, key=ikey, byte=isbyte DO j=1-OLy,sNy+OLy DO i=1-OLx+1,sNx+OLx slopeSqTmp=SlopeX(i,j)*SlopeX(i,j) & +SlopeY(i,j)*SlopeY(i,j) IF ( slopeSqTmp .GT. slopeMax**2 ) then slopeTmp=sqrt(slopeSqTmp) SlopeX(i,j)=SlopeX(i,j)*slopeMax/slopeTmp SlopeY(i,j)=SlopeY(i,j)*slopeMax/slopeTmp ENDIF SlopeSqr(i,j) = SlopeX(i,j)*SlopeX(i,j) & +SlopeY(i,j)*SlopeY(i,j) taperFct(i,j) = 1. _d 0 ENDDO ENDDO #endif /* GMREDI_WITH_STABLE_ADJOINT */ ELSEIF (GM_taper_scheme.NE.' ') THEN STOP 'GMREDI_SLOPE_LIMIT: Bad GM_taper_scheme' ENDIF #endif /* GM_EXCLUDE_TAPERING */ ENDIF #endif /* ALLOW_GMREDI */ RETURN END