Newer
Older
MODULE dynvor
!!======================================================================
!! *** MODULE dynvor ***
!! Ocean dynamics: Update the momentum trend with the relative and
!! planetary vorticity trends
!!======================================================================
!! History : OPA ! 1989-12 (P. Andrich) vor_ens: Original code
!! 5.0 ! 1991-11 (G. Madec) vor_ene, vor_mix: Original code
!! 6.0 ! 1996-01 (G. Madec) s-coord, suppress work arrays
!! NEMO 0.5 ! 2002-08 (G. Madec) F90: Free form and module
!! 1.0 ! 2004-02 (G. Madec) vor_een: Original code
!! - ! 2003-08 (G. Madec) add vor_ctl
!! - ! 2005-11 (G. Madec) add dyn_vor (new step architecture)
!! 2.0 ! 2006-11 (G. Madec) flux form advection: add metric term
!! 3.2 ! 2009-04 (R. Benshila) vvl: correction of een scheme
!! 3.3 ! 2010-10 (C. Ethe, G. Madec) reorganisation of initialisation phase
!! 3.7 ! 2014-04 (G. Madec) trend simplification: suppress jpdyn_trd_dat vorticity
!! - ! 2014-06 (G. Madec) suppression of velocity curl from in-core memory
!! - ! 2016-12 (G. Madec, E. Clementi) add Stokes-Coriolis trends (ln_stcor=T)
!! 4.0 ! 2017-07 (G. Madec) linear dynamics + trends diag. with Stokes-Coriolis
!! - ! 2018-03 (G. Madec) add two new schemes (ln_dynvor_enT and ln_dynvor_eet)
!! - ! 2018-04 (G. Madec) add pre-computed gradient for metric term calculation
!! 4.x ! 2020-03 (G. Madec, A. Nasser) make ln_dynvor_msk truly efficient on relative vorticity
!! 4.2 ! 2020-12 (G. Madec, E. Clementi) add vortex force trends (ln_vortex_force=T)
!! 4.5 ! 2022-06 (S. Techene, G, Madec) refactorization to reduce local memory usage
!!----------------------------------------------------------------------
!!----------------------------------------------------------------------
!! dyn_vor : Update the momentum trend with the vorticity trend
!! vor_enT : energy conserving scheme at T-pt (ln_dynvor_enT=T)
!! vor_ene : energy conserving scheme (ln_dynvor_ene=T)
!! vor_ens : enstrophy conserving scheme (ln_dynvor_ens=T)
!! vor_een : energy and enstrophy conserving (ln_dynvor_een=T)
!! vor_eeT : energy conserving at T-pt (ln_dynvor_eeT=T)
!! dyn_vor_init : set and control of the different vorticity option
!!----------------------------------------------------------------------
USE oce ! ocean dynamics and tracers
USE dom_oce ! ocean space and time domain
USE dommsk ! ocean mask
USE dynadv ! momentum advection
USE trd_oce ! trends: ocean variables
USE trddyn ! trend manager: dynamics
USE sbcwave ! Surface Waves (add Stokes-Coriolis force)
USE sbc_oce, ONLY : ln_stcor, ln_vortex_force ! use Stoke-Coriolis force
!
USE lbclnk ! ocean lateral boundary conditions (or mpp link)
USE prtctl ! Print control
USE in_out_manager ! I/O manager
USE lib_mpp ! MPP library
USE timing ! Timing
IMPLICIT NONE
PRIVATE
INTERFACE dyn_vor
MODULE PROCEDURE dyn_vor_3D, dyn_vor_RK3
END INTERFACE
PUBLIC dyn_vor ! routine called by step.F90
PUBLIC dyn_vor_init ! routine called by nemogcm.F90
! !!* Namelist namdyn_vor: vorticity term
LOGICAL, PUBLIC :: ln_dynvor_ens !: enstrophy conserving scheme (ENS)
LOGICAL, PUBLIC :: ln_dynvor_ene !: f-point energy conserving scheme (ENE)
LOGICAL, PUBLIC :: ln_dynvor_enT !: t-point energy conserving scheme (ENT)
LOGICAL, PUBLIC :: ln_dynvor_eeT !: t-point energy conserving scheme (EET)
LOGICAL, PUBLIC :: ln_dynvor_een !: energy & enstrophy conserving scheme (EEN)
LOGICAL, PUBLIC :: ln_dynvor_mix !: mixed scheme (MIX)
LOGICAL, PUBLIC :: ln_dynvor_msk !: vorticity multiplied by fmask (=T) or not (=F) (all vorticity schemes)
INTEGER, PUBLIC :: nn_e3f_typ !: e3f=masked averaging of e3t divided by 4 (=0) or by the sum of mask (=1)
INTEGER, PUBLIC :: nvor_scheme !: choice of the type of advection scheme
! ! associated indices:
INTEGER, PUBLIC, PARAMETER :: np_ENS = 0 ! ENS scheme
INTEGER, PUBLIC, PARAMETER :: np_ENE = 1 ! ENE scheme
INTEGER, PUBLIC, PARAMETER :: np_ENT = 2 ! ENT scheme (t-point vorticity)
INTEGER, PUBLIC, PARAMETER :: np_EET = 3 ! EET scheme (EEN using e3t)
INTEGER, PUBLIC, PARAMETER :: np_EEN = 4 ! EEN scheme
INTEGER, PUBLIC, PARAMETER :: np_MIX = 5 ! MIX scheme
! !: choice of calculated vorticity
INTEGER, PUBLIC :: ncor, nrvm, ntot ! Coriolis, relative vorticity, total vorticity
! ! associated indices:
INTEGER, PUBLIC, PARAMETER :: np_COR = 1 ! Coriolis (planetary)
INTEGER, PUBLIC, PARAMETER :: np_RVO = 2 ! relative vorticity
INTEGER, PUBLIC, PARAMETER :: np_MET = 3 ! metric term
INTEGER, PUBLIC, PARAMETER :: np_CRV = 4 ! relative + planetary (total vorticity)
INTEGER, PUBLIC, PARAMETER :: np_CME = 5 ! Coriolis + metric term
REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: di_e2u_2 ! = di(e2u)/2 used in T-point metric term calculation
REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: dj_e1v_2 ! = dj(e1v)/2 - - - -
REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: di_e2v_2e1e2f ! = di(e2u)/(2*e1e2f) used in F-point metric term calculation
REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: dj_e1u_2e1e2f ! = dj(e1v)/(2*e1e2f) - - - -
!
REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: e3f_0vor ! e3f used in EEN, ENE and ENS cases (key_qco only)
REAL(wp) :: r1_4 = 0.250_wp ! =1/4
REAL(wp) :: r1_8 = 0.125_wp ! =1/8
REAL(wp) :: r1_12 = 1._wp / 12._wp ! 1/12
!! * Substitutions
# include "do_loop_substitute.h90"
# include "domzgr_substitute.h90"
!!----------------------------------------------------------------------
!! NEMO/OCE 4.0 , NEMO Consortium (2018)
!! $Id: dynvor.F90 14547 2021-02-25 17:07:15Z techene $
!! Software governed by the CeCILL license (see ./LICENSE)
!!----------------------------------------------------------------------
CONTAINS
SUBROUTINE dyn_vor_3D( kt, Kmm, puu, pvv, Krhs )
!!----------------------------------------------------------------------
!!
!! ** Purpose : compute the lateral ocean tracer physics.
!!
!! ** Action : - Update (puu(:,:,:,Krhs),pvv(:,:,:,Krhs)) with the now vorticity term trend
!! - save the trends in (ztrdu,ztrdv) in 2 parts (relative
!! and planetary vorticity trends) and send them to trd_dyn
!! for futher diagnostics (l_trddyn=T)
!!----------------------------------------------------------------------
INTEGER , INTENT( in ) :: kt ! ocean time-step index
INTEGER , INTENT( in ) :: Kmm, Krhs ! ocean time level indices
REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), INTENT(inout) :: puu, pvv ! ocean velocity field and RHS of momentum equation
!
REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: ztrdu, ztrdv
!!----------------------------------------------------------------------
!
IF( ln_timing ) CALL timing_start('dyn_vor_3D')
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
!
IF( l_trddyn ) THEN !== trend diagnostics case : split the added trend in two parts ==!
!
ALLOCATE( ztrdu(jpi,jpj,jpk), ztrdv(jpi,jpj,jpk) )
!
ztrdu(:,:,:) = puu(:,:,:,Krhs) !* planetary vorticity trend
ztrdv(:,:,:) = pvv(:,:,:,Krhs)
SELECT CASE( nvor_scheme )
CASE( np_ENS ) ; CALL vor_ens( kt, Kmm, ncor, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! enstrophy conserving scheme
CASE( np_ENE, np_MIX ) ; CALL vor_ene( kt, Kmm, ncor, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! energy conserving scheme
CASE( np_ENT ) ; CALL vor_enT( kt, Kmm, ncor, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! energy conserving scheme (T-pts)
CASE( np_EET ) ; CALL vor_eeT( kt, Kmm, ncor, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! energy conserving scheme (een with e3t)
CASE( np_EEN ) ; CALL vor_een( kt, Kmm, ncor, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! energy & enstrophy scheme
END SELECT
ztrdu(:,:,:) = puu(:,:,:,Krhs) - ztrdu(:,:,:)
ztrdv(:,:,:) = pvv(:,:,:,Krhs) - ztrdv(:,:,:)
CALL trd_dyn( ztrdu, ztrdv, jpdyn_pvo, kt, Kmm )
!
IF( n_dynadv /= np_LIN_dyn ) THEN !* relative vorticity or metric trend (only in non-linear case)
ztrdu(:,:,:) = puu(:,:,:,Krhs)
ztrdv(:,:,:) = pvv(:,:,:,Krhs)
SELECT CASE( nvor_scheme )
CASE( np_ENT ) ; CALL vor_enT( kt, Kmm, nrvm, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! energy conserving scheme (T-pts)
CASE( np_EET ) ; CALL vor_eeT( kt, Kmm, nrvm, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! energy conserving scheme (een with e3t)
CASE( np_ENE ) ; CALL vor_ene( kt, Kmm, nrvm, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! energy conserving scheme
CASE( np_ENS, np_MIX ) ; CALL vor_ens( kt, Kmm, nrvm, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! enstrophy conserving scheme
CASE( np_EEN ) ; CALL vor_een( kt, Kmm, nrvm, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! energy & enstrophy scheme
END SELECT
ztrdu(:,:,:) = puu(:,:,:,Krhs) - ztrdu(:,:,:)
ztrdv(:,:,:) = pvv(:,:,:,Krhs) - ztrdv(:,:,:)
CALL trd_dyn( ztrdu, ztrdv, jpdyn_rvo, kt, Kmm )
ENDIF
!
DEALLOCATE( ztrdu, ztrdv )
!
ELSE !== total vorticity trend added to the general trend ==!
!
SELECT CASE ( nvor_scheme ) !== vorticity trend added to the general trend ==!
CASE( np_ENT ) !* energy conserving scheme (T-pts)
CALL vor_enT( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! total vorticity trend
IF( ln_stcor .AND. .NOT. ln_vortex_force ) THEN
CALL vor_enT( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend
ELSE IF( ln_stcor .AND. ln_vortex_force ) THEN
CALL vor_enT( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend and vortex force
ENDIF
CASE( np_EET ) !* energy conserving scheme (een scheme using e3t)
IF( nn_hls == 1 ) THEN
CALL vor_eeT_hls1( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! total vorticity trend
IF( ln_stcor .AND. .NOT. ln_vortex_force ) THEN
CALL vor_eeT_hls1( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend
ELSE IF( ln_stcor .AND. ln_vortex_force ) THEN
CALL vor_eeT_hls1( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend and vortex force
ENDIF
ELSE
CALL vor_eeT( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! total vorticity trend
IF( ln_stcor .AND. .NOT. ln_vortex_force ) THEN
CALL vor_eeT( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend
ELSE IF( ln_stcor .AND. ln_vortex_force ) THEN
CALL vor_eeT( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend and vortex force
ENDIF
CASE( np_ENE ) !* energy conserving scheme
CALL vor_ene( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! total vorticity trend
IF( ln_stcor .AND. .NOT. ln_vortex_force ) THEN
CALL vor_ene( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend
ELSE IF( ln_stcor .AND. ln_vortex_force ) THEN
CALL vor_ene( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend and vortex force
ENDIF
CASE( np_ENS ) !* enstrophy conserving scheme
CALL vor_ens( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! total vorticity trend
Loading
Loading full blame...