C $Header: /u/gcmpack/MITgcm/model/src/calc_viscosity.F,v 1.12 2017/11/02 18:00:52 jmc Exp $ C $Name: $ #include "PACKAGES_CONFIG.h" #include "CPP_OPTIONS.h" CBOP C !ROUTINE: CALC_VISCOSITY C !INTERFACE: SUBROUTINE CALC_VISCOSITY( I bi,bj, iMin,iMax,jMin,jMax, O kappaRU, kappaRV, I myThid ) C !DESCRIPTION: \bv C *==========================================================* C | SUBROUTINE CALC_VISCOSITY C | o Calculate net vertical viscosity C *==========================================================* C \ev C !USES: IMPLICIT NONE C == GLobal variables == #include "SIZE.h" #include "EEPARAMS.h" #include "PARAMS.h" #include "DYNVARS.h" #include "GRID.h" C !INPUT/OUTPUT PARAMETERS: C == Routine arguments == C iMin,iMax,jMin,jMax :: Range of points for which calculation C bi,bj :: current tile indices C kappaRU :: Total vertical viscosity for zonal flow. C kappaRV :: Total vertical viscosity for meridional flow. C myThid :: my Thread Id number INTEGER iMin,iMax,jMin,jMax INTEGER bi,bj _RL kappaRU(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr+1) _RL kappaRV(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr+1) INTEGER myThid C !LOCAL VARIABLES: C == Local variables == C i, j, k :: Loop counters INTEGER i,j,k INTEGER ki #ifndef EXCLUDE_PCELL_MIX_CODE INTEGER km, mixSurf, mixBott _RL pC_kFac _RL tmpFac(1-OLx:sNx+OLx,1-OLy:sNy+OLy) #endif CEOP DO k = 1,Nr+1 ki = MIN(k,Nr) DO j = 1-OLy, sNy+OLy DO i = 1-OLx, sNx+OLx kappaRU(i,j,k) = viscArNr(ki) kappaRV(i,j,k) = viscArNr(ki) ENDDO ENDDO #ifdef ALLOW_KPP IF ( useKPP .AND. k.LE.Nr ) THEN CALL KPP_CALC_VISC( I bi,bj, iMin,iMax,jMin,jMax, k, O kappaRU, kappaRV, I myThid) ENDIF #endif #ifdef ALLOW_PP81 IF ( usePP81 .AND. k.LE.Nr ) THEN CALL PP81_CALC_VISC( I bi,bj, iMin,iMax,jMin,jMax, k, O kappaRU, kappaRV, I myThid) ENDIF #endif #ifdef ALLOW_KL10 IF ( useKL10 .AND. k.LE.Nr ) THEN CALL KL10_CALC_VISC( I bi,bj, iMin,iMax,jMin,jMax, k, O kappaRU, kappaRV, I myThid) ENDIF #endif #ifdef ALLOW_MY82 IF ( useMY82 .AND. k.LE.Nr ) THEN CALL MY82_CALC_VISC( I bi,bj, iMin,iMax,jMin,jMax, k, O kappaRU, kappaRV, I myThid) ENDIF #endif #ifdef ALLOW_GGL90 IF ( useGGL90 .AND. k.LE.Nr ) THEN CALL GGL90_CALC_VISC( I bi,bj, iMin,iMax,jMin,jMax, k, O kappaRU, kappaRV, I myThid) ENDIF #endif IF ( k.EQ.Nr+1 .AND. & ( usePP81 .OR. useKL10 .OR. useMY82 .OR. useGGL90 ) & ) THEN DO j = 1-OLy, sNy+OLy DO i = 1-OLx, sNx+OLx kappaRU(i,j,k) = kappaRU(i,j,ki) kappaRV(i,j,k) = kappaRV(i,j,ki) ENDDO ENDDO ENDIF C-- end of k loop ENDDO #ifndef EXCLUDE_PCELL_MIX_CODE IF ( interViscAr_pCell ) THEN C-- This is a hack: alter vertical viscosity (instead of changing many S/R) C in order to account for missing hFac in viscous term DO k = 2,Nr km = k - 1 C- account for true distance (including hFac) in vertical gradient DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx IF ( k.GT.kSurfW(i,j,bi,bj) .AND. & k.LE.MIN( kLowC(i,j,bi,bj), kLowC(i-1,j,bi,bj) ) & ) THEN kappaRU(i,j,k) = kappaRU(i,j,k) & *twoRL/(hFacW(i,j,km,bi,bj)+hFacW(i,j,k,bi,bj)) ENDIF ENDDO ENDDO DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx IF ( k.GT.kSurfS(i,j,bi,bj) .AND. & k.LE.MIN( kLowC(i,j,bi,bj), kLowC(i,j-1,bi,bj) ) & ) THEN kappaRV(i,j,k) = kappaRV(i,j,k) & *twoRL/(hFacS(i,j,km,bi,bj)+hFacS(i,j,k,bi,bj)) ENDIF ENDDO ENDDO ENDDO ENDIF IF ( pCellMix_select.GT.0 ) THEN C-- This is a hack: alter vertical viscosity (instead of changing many S/R) C in order to to increase mixing for too thin surface/bottom partial cell mixSurf = pCellMix_select/10 mixBott = MOD(pCellMix_select,10) DO k = 2,Nr km = k - 1 pC_kFac = 1. IF ( pCellMix_delR.LT.drF(k) ) & pC_kFac = pCellMix_delR*recip_drF(k) C- Increase KappaRU above bottom level: IF ( mixBott.GE.1 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = 0. _d 0 IF ( k.EQ.MIN( kLowC(i,j,bi,bj), kLowC(i-1,j,bi,bj) ) & .AND. k.GT.kSurfW(i,j,bi,bj) ) THEN tmpFac(i,j) = pC_kFac*_recip_hFacW(i,j,k,bi,bj) ENDIF ENDDO ENDDO ENDIF IF ( mixBott.EQ.2 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ELSEIF ( mixBott.EQ.3 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ELSEIF ( mixBott.EQ.4 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j) & *tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ENDIF IF ( mixBott.GE.1 ) THEN C- increase mixing above bottom (by ~(1/hFac)^mixBott) if too thin p-cell DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = MIN( tmpFac(i,j), pCellMix_maxFac ) kappaRU(i,j,k) = MAX( kappaRU(i,j,k), & pCellMix_viscAr(k)*tmpFac(i,j) ) ENDDO ENDDO ENDIF C- Increase KappaRV above bottom level: IF ( mixBott.GE.1 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = 0. _d 0 IF ( k.EQ.MIN( kLowC(i,j,bi,bj), kLowC(i,j-1,bi,bj) ) & .AND. k.GT.kSurfS(i,j,bi,bj) ) THEN tmpFac(i,j) = pC_kFac*_recip_hFacS(i,j,k,bi,bj) ENDIF ENDDO ENDDO ENDIF IF ( mixBott.EQ.2 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ELSEIF ( mixBott.EQ.3 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ELSEIF ( mixBott.EQ.4 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j) & *tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ENDIF IF ( mixBott.GE.1 ) THEN C- increase mixing above bottom (by ~(1/hFac)^mixBott) if too thin p-cell DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = MIN( tmpFac(i,j), pCellMix_maxFac ) kappaRV(i,j,k) = MAX( kappaRV(i,j,k), & pCellMix_viscAr(k)*tmpFac(i,j) ) ENDDO ENDDO ENDIF pC_kFac = 1. IF ( pCellMix_delR.LT.drF(km) ) & pC_kFac = pCellMix_delR*recip_drF(km) C- Increase KappaRU below surface level: IF ( mixSurf.GE.1 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = 0. _d 0 IF ( km.EQ.kSurfW(i,j,bi,bj) .AND. & km.LT.MIN( kLowC(i,j,bi,bj), kLowC(i-1,j,bi,bj) ) & ) THEN tmpFac(i,j) = pC_kFac*_recip_hFacW(i,j,km,bi,bj) ENDIF ENDDO ENDDO ENDIF IF ( mixSurf.EQ.2 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ELSEIF ( mixSurf.EQ.3 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ELSEIF ( mixSurf.EQ.4 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j) & *tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ENDIF IF ( mixSurf.GE.1 ) THEN C- increase mixing below surface (by ~(1/hFac)^mixSurf) if too thin p-cell DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = MIN( tmpFac(i,j), pCellMix_maxFac ) kappaRU(i,j,k) = MAX( kappaRU(i,j,k), & pCellMix_viscAr(k)*tmpFac(i,j) ) ENDDO ENDDO ENDIF C- Increase KappaRV below surface level: IF ( mixSurf.GE.1 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = 0. _d 0 IF ( km.EQ.kSurfS(i,j,bi,bj) .AND. & km.LT.MIN( kLowC(i,j,bi,bj), kLowC(i,j-1,bi,bj) ) & ) THEN tmpFac(i,j) = pC_kFac*_recip_hFacS(i,j,km,bi,bj) ENDIF ENDDO ENDDO ENDIF IF ( mixSurf.EQ.2 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ELSEIF ( mixSurf.EQ.3 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ELSEIF ( mixSurf.EQ.4 ) THEN DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = tmpFac(i,j)*tmpFac(i,j) & *tmpFac(i,j)*tmpFac(i,j) ENDDO ENDDO ENDIF IF ( mixSurf.GE.1 ) THEN C- increase mixing below surface (by ~(1/hFac)^mixSurf) if too thin p-cell DO j = 2-OLy, sNy+OLy DO i = 2-OLx, sNx+OLx tmpFac(i,j) = MIN( tmpFac(i,j), pCellMix_maxFac ) kappaRV(i,j,k) = MAX( kappaRV(i,j,k), & pCellMix_viscAr(k)*tmpFac(i,j) ) ENDDO ENDDO ENDIF C-- end of k loop ENDDO ENDIF #endif /* ndef EXCLUDE_PCELL_MIX_CODE */ RETURN END