Page MenuHomec4science

advect.F
No OneTemporary

File Metadata

Created
Mon, Jul 21, 06:54

advect.F

C $Header: /u/gcmpack/MITgcm/pkg/seaice/advect.F,v 1.30 2014/10/20 03:20:57 gforget Exp $
C $Name: $
#include "SEAICE_OPTIONS.h"
#ifdef ALLOW_AUTODIFF
# include "AUTODIFF_OPTIONS.h"
#endif
CBOP
C !ROUTINE: ADVECT
C !INTERFACE:
SUBROUTINE ADVECT(
I UI, VI,
U fld,
O fldNm1,
I iceMsk, myThid )
C !DESCRIPTION: \bv
C *==========================================================*
C | S/R ADVECT
C | o Calculate advection and diffusion
C | and update the input ice-field
C *==========================================================*
C \ev
C !USES:
IMPLICIT NONE
C == Global variables ===
#include "SIZE.h"
#include "EEPARAMS.h"
#include "PARAMS.h"
#include "GRID.h"
#include "SEAICE_SIZE.h"
#include "SEAICE_PARAMS.h"
#ifdef ALLOW_AUTODIFF_TAMC
# include "tamc.h"
#endif
C !INPUT/OUTPUT PARAMETERS:
C == Routine arguments ==
C UI, VI :: ice velocity components
C fld :: input and updated ice-field
C fldNm1 :: copy of the input ice-field
C iceMsk :: Ocean/Land mask
C myThid :: my Thread Id. number
_RL UI (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
_RL VI (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
_RL fld (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
_RL fldNm1 (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
_RL iceMsk (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
INTEGER myThid
CEOP
C !LOCAL VARIABLES:
C == Local variables ==
C i,j,k,bi,bj :: Loop counters
INTEGER i, j, bi, bj
INTEGER k
_RL DELTT
_RL DIFFA (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
_RL tmpFld (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
_RL afx (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
_RL afy (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
DELTT=SEAICE_deltaTtherm
C save fld from previous time step
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
DO j=1-OLy,sNy+OLy
DO i=1-OLx,sNx+OLx
fldNm1(i,j,bi,bj) = fld(i,j,bi,bj)
ENDDO
ENDDO
ENDDO
ENDDO
DO k=1,2
cph IF ( k .EQ. 1 ) THEN
C Prediction step
cph DO bj=myByLo(myThid),myByHi(myThid)
cph DO bi=myBxLo(myThid),myBxHi(myThid)
cph DO j=1-OLy,sNy+OLy
cph DO i=1-OLx,sNx+OLx
cph tmpFld(i,j,bi,bj) = fld(i,j,bi,bj)
cph ENDDO
cph ENDDO
cph ENDDO
cph ENDDO
cph ELSE
C Backward Euler correction step
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
DO j=1-OLy,sNy+OLy
DO i=1-OLx,sNx+OLx
cph for k=1 this is same as tmpFld = fld
tmpFld(i,j,bi,bj)=HALF*(fld(i,j,bi,bj)
& +fldNm1(i,j,bi,bj))
ENDDO
ENDDO
ENDDO
ENDDO
cph ENDIF
#ifdef ALLOW_AUTODIFF_TAMC
cphCADJ STORE fld = comlev1, key = ikey_dynamics
cphCADJ STORE fldNm1 = comlev1, key = ikey_dynamics
cphCADJ STORE tmpFld = comlev1, key = ikey_dynamics
DO J=1-Oly,sNy+Oly
DO I=1-Olx,sNx+Olx
afx(i,j) = 0. _d 0
afy(i,j) = 0. _d 0
ENDDO
ENDDO
#endif /* ALLOW_AUTODIFF_TAMC */
C NOW GO THROUGH STANDARD CONSERVATIVE ADVECTION
IF ( .NOT. SEAICEuseFluxForm ) THEN
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
DO j=0,sNy+1
DO i=0,sNx+1
CML This formulation gives the same result as the original code on a
CML lat-lon-grid, but may not be accurate on irregular grids
fld(i,j,bi,bj)=fldNm1(i,j,bi,bj)
& -DELTT*(
& ( tmpFld(i ,j ,bi,bj)+tmpFld(i+1,j ,bi,bj))
& * UI(i+1,j, bi,bj) -
& ( tmpFld(i ,j ,bi,bj)+tmpFld(i-1,j ,bi,bj))
& * UI(i ,j, bi,bj) )*maskInC(i,j,bi,bj)
& *(HALF * _recip_dxF(i,j,bi,bj))
& -DELTT*(
& ( tmpFld(i ,j ,bi,bj)+tmpFld(i ,j+1,bi,bj))
& * VI(i ,j+1, bi,bj)
& * _dxG(i ,j+1,bi,bj) -
& ( tmpFld(i ,j ,bi,bj)+tmpFld(i ,j-1,bi,bj))
& * VI(i ,j , bi,bj)
& * _dxG(i,j,bi,bj))*maskInC(i,j,bi,bj)
& *(HALF * _recip_dyF(i,j,bi,bj) * _recip_dxF(i,j,bi,bj))
ENDDO
ENDDO
ENDDO
ENDDO
ELSE
C-- Use flux form for MITgcm compliance, unfortunately changes results
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
C-- first compute fluxes across cell faces
DO j=1,sNy+1
DO i=1,sNx+1
afx(i,j) = _dyG(i,j,bi,bj) * UI(i,j,bi,bj)
& * 0.5 _d 0 * (tmpFld(i,j,bi,bj)+tmpFld(i-1,j,bi,bj))
afy(i,j) = _dxG(i,j,bi,bj) * VI(i,j,bi,bj)
& * 0.5 _d 0 * (tmpFld(i,j,bi,bj)+tmpFld(i,j-1,bi,bj))
ENDDO
ENDDO
DO j=1,sNy
DO i=1,sNx
fld(i,j,bi,bj)=fldNm1(i,j,bi,bj)
& -DELTT * (
& afx(i+1,j) - afx(i,j)
& + afy(i,j+1) - afy(i,j)
& )*recip_rA(i,j,bi,bj)*maskInC(i,j,bi,bj)
ENDDO
ENDDO
ENDDO
ENDDO
ENDIF
CALL EXCH_XY_RL( fld, myThid )
ENDDO
IF ( DIFF1.GT.0. _d 0 ) THEN
C NOW DO DIFFUSION
C make a working copy of field from last time step
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
DO j=1-OLy,sNy+OLy
DO i=1-OLx,sNx+OLx
tmpFld(i,j,bi,bj) = fldNm1(i,j,bi,bj)
ENDDO
ENDDO
ENDDO
ENDDO
C NOW CALCULATE DIFFUSION COEF ROUGHLY
C 1rst pass: compute changes due to harmonic diffusion and add it to ice-field
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
DO j=1-OLy,sNy+OLy
DO i=1-OLx,sNx+OLx
DIFFA(i,j,bi,bj) = MIN( _dxF(i,j,bi,bj), _dyF(i,j,bi,bj) )
ENDDO
ENDDO
ENDDO
ENDDO
C- Compute laplacian of ice-field; return result in same array
CALL DIFFUS( tmpFld, DIFFA, iceMsk, myThid )
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
DO j=1-OLy,sNy+OLy
DO i=1-OLx,sNx+OLx
fld(i,j,bi,bj) = ( fld(i,j,bi,bj)
& +tmpFld(i,j,bi,bj)*DIFF1*DELTT
& )*iceMsk(i,j,bi,bj)
ENDDO
ENDDO
ENDDO
ENDDO
c IF ( useBiHarmonic ) THEN
C 2nd pass: compute changes due to biharmonic diffusion and add it to ice-field
_EXCH_XY_RL( tmpFld, myThid )
C use some strange quadratic form for the second time around
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
DO j=1-OLy,sNy+OLy
DO i=1-OLx,sNx+OLx
#ifdef ALLOW_AUTODIFF_TAMC
C to avoid recomputations when there was a k loop; not needed anymore
c DIFFA(i,j,bi,bj) = MIN( _dxF(i,j,bi,bj), _dyF(i,j,bi,bj) )
#endif
DIFFA(i,j,bi,bj) = - DIFFA(i,j,bi,bj)*DIFFA(i,j,bi,bj)
ENDDO
ENDDO
ENDDO
ENDDO
C- Compute bilaplacian (laplacian of laplacian); return result in same array
CALL DIFFUS( tmpFld, DIFFA, iceMsk, myThid )
DO bj=myByLo(myThid),myByHi(myThid)
DO bi=myBxLo(myThid),myBxHi(myThid)
DO j=1-OLy,sNy+OLy
DO i=1-OLx,sNx+OLx
fld(i,j,bi,bj) = ( fld(i,j,bi,bj)
& +tmpFld(i,j,bi,bj)*DIFF1*DELTT
& )*iceMsk(i,j,bi,bj)
ENDDO
ENDDO
ENDDO
ENDDO
C-- end biharmonic block
c ENDIF
C-- end DIFF1 > 0 block
ENDIF
RETURN
END

Event Timeline