MODULE trazdf !!============================================================================== !! *** MODULE trazdf *** !! Ocean active tracers: vertical component of the tracer mixing trend !!============================================================================== !! History : 9.0 ! 05-11 (G. Madec) Original code !!---------------------------------------------------------------------- !!---------------------------------------------------------------------- !! tra_zdf : Update the tracer trend with the vertical diffusion !! zdf_ctl : ??? !!---------------------------------------------------------------------- USE oce ! ocean dynamics and tracers variables USE dom_oce ! ocean space and time domain variables USE zdf_oce ! ocean vertical physics variables USE sbc_oce ! surface boundary condition: ocean USE dynspg_oce USE trazdf_exp ! vertical diffusion: explicit (tra_zdf_exp routine) USE trazdf_imp ! vertical diffusion: implicit (tra_zdf_imp routine) USE ldftra_oce ! ocean active tracers: lateral physics USE trdmod ! ocean active tracers trends USE trdmod_oce ! ocean variables trends USE in_out_manager ! I/O manager USE prtctl ! Print control USE phycst USE lbclnk ! ocean lateral boundary conditions (or mpp link) USE domvvl ! variable volume IMPLICIT NONE PRIVATE PUBLIC tra_zdf ! routine called by step.F90 INTEGER :: nzdf = 0 ! type vertical diffusion algorithm used ! ! defined from ln_zdf... namlist logicals) REAL(wp), DIMENSION(jpk) :: r2dt ! vertical profile time-step, = 2 rdttra ! ! except at nit000 (=rdttra) if neuler=0 !! * Substitutions # include "domzgr_substitute.h90" # include "zdfddm_substitute.h90" # include "vectopt_loop_substitute.h90" !!---------------------------------------------------------------------- !! OPA 9.0 , LOCEAN-IPSL (2005) !! $Id$ !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt) !!---------------------------------------------------------------------- CONTAINS SUBROUTINE tra_zdf( kt ) !!---------------------------------------------------------------------- !! *** ROUTINE tra_zdf *** !! !! ** Purpose : compute the vertical ocean tracer physics. !!--------------------------------------------------------------------- INTEGER, INTENT( in ) :: kt ! ocean time-step index INTEGER :: jk ! Dummy loop indices REAL(wp), DIMENSION(jpi,jpj,jpk) :: ztrdt, ztrds ! 3D workspace !!--------------------------------------------------------------------- IF( kt == nit000 ) CALL zdf_ctl ! initialisation & control of options ! ! set time step IF( neuler == 0 .AND. kt == nit000 ) THEN ! at nit000 r2dt(:) = rdttra(:) ! = rdtra (restarting with Euler time stepping) ELSEIF( kt <= nit000 + 1) THEN ! at nit000 or nit000+1 r2dt(:) = 2. * rdttra(:) ! = 2 rdttra (leapfrog) ENDIF IF( l_trdtra ) THEN ! temporary save of ta and sa trends ztrdt(:,:,:) = ta(:,:,:) ztrds(:,:,:) = sa(:,:,:) ENDIF IF( lk_vvl ) CALL dom_vvl_ssh( kt ) ! compute ssha field SELECT CASE ( nzdf ) ! compute lateral mixing trend and add it to the general trend CASE ( -1 ) ! esopa: test all possibility with control print CALL tra_zdf_exp ( kt, r2dt ) CALL prt_ctl( tab3d_1=ta, clinfo1=' zdf0 - Ta: ', mask1=tmask, & & tab3d_2=sa, clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' ) CALL tra_zdf_imp ( kt, r2dt ) CALL prt_ctl( tab3d_1=ta, clinfo1=' zdf1 - Ta: ', mask1=tmask, & & tab3d_2=sa, clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' ) CASE ( 0 ) ! explicit scheme CALL tra_zdf_exp ( kt, r2dt ) CASE ( 1 ) ! implicit scheme CALL tra_zdf_imp ( kt, r2dt ) END SELECT IF( l_trdtra ) THEN ! save the vertical diffusive trends for further diagnostics DO jk = 1, jpkm1 ztrdt(:,:,jk) = ( ( ta(:,:,jk) - tb(:,:,jk) ) / r2dt(jk) ) - ztrdt(:,:,jk) ztrds(:,:,jk) = ( ( sa(:,:,jk) - sb(:,:,jk) ) / r2dt(jk) ) - ztrds(:,:,jk) END DO CALL trd_mod( ztrdt, ztrds, jptra_trd_zdf, 'TRA', kt ) ENDIF ! ! print mean trends (used for debugging) IF(ln_ctl) CALL prt_ctl( tab3d_1=ta, clinfo1=' zdf - Ta: ', mask1=tmask, & & tab3d_2=sa, clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' ) END SUBROUTINE tra_zdf SUBROUTINE zdf_ctl !!---------------------------------------------------------------------- !! *** ROUTINE zdf_ctl *** !! !! ** Purpose : Choose the vertical mixing scheme !! !! ** Method : Set nzdf from ln_zdfexp !! nzdf = 0 explicit (time-splitting) scheme (ln_zdfexp=T) !! = 1 implicit (euler backward) scheme (ln_zdfexp=F) !! NB: rotation of lateral mixing operator or TKE or KPP scheme, !! the implicit scheme is required. !!---------------------------------------------------------------------- USE zdftke USE zdfkpp !!---------------------------------------------------------------------- ! Define the vertical tracer physics scheme ! ========================================== ! Choice from ln_zdfexp already read in namelist in zdfini module IF( ln_zdfexp ) THEN ! use explicit scheme nzdf = 0 ELSE ! use implicit scheme nzdf = 1 ENDIF ! Force implicit schemes IF( lk_zdftke .OR. lk_zdfkpp ) nzdf = 1 ! TKE or KPP physics IF( ln_traldf_iso ) nzdf = 1 ! iso-neutral lateral physics IF( ln_traldf_hor .AND. ln_sco ) nzdf = 1 ! horizontal lateral physics in s-coordinate IF( ln_zdfexp .AND. nzdf == 1 ) THEN CALL ctl_stop( 'tra_zdf : If using the rotation of lateral mixing operator or TKE ', & & ' or KPP scheme, the implicit scheme is required, set ln_zdfexp = .false.' ) ENDIF ! Test: esopa IF( lk_esopa ) nzdf = -1 ! All schemes used IF(lwp) THEN WRITE(numout,*) WRITE(numout,*) 'tra:zdf_ctl : vertical tracer physics scheme' WRITE(numout,*) '~~~~~~~~~~~' IF( nzdf == -1 ) WRITE(numout,*) ' ESOPA test All scheme used' IF( nzdf == 0 ) WRITE(numout,*) ' Explicit time-splitting scheme' IF( nzdf == 1 ) WRITE(numout,*) ' Implicit (euler backward) scheme' ENDIF END SUBROUTINE zdf_ctl !!============================================================================== END MODULE trazdf