123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- MODULE trczdf
- !!==============================================================================
- !! *** MODULE trczdf ***
- !! Ocean Passive tracers : vertical diffusive trends
- !!=====================================================================
- !! History : 9.0 ! 2005-11 (G. Madec) Original code
- !! NEMO 3.0 ! 2008-01 (C. Ethe, G. Madec) merge TRC-TRA
- !!----------------------------------------------------------------------
- #if defined key_top
- !!----------------------------------------------------------------------
- !! 'key_top' TOP models
- !!----------------------------------------------------------------------
- !! trc_ldf : update the tracer trend with the lateral diffusion
- !! ldf_ctl : initialization, namelist read, and parameters control
- !!----------------------------------------------------------------------
- USE oce_trc ! ocean dynamics and active tracers
- USE trc ! ocean passive tracers variables
- USE trcnam_trp ! passive tracers transport namelist variables
- USE trazdf_exp ! vertical diffusion: explicit (tra_zdf_exp routine)
- USE trazdf_imp ! vertical diffusion: implicit (tra_zdf_imp routine)
- USE trd_oce
- USE trdtra
- USE prtctl_trc ! Print control
- IMPLICIT NONE
- PRIVATE
- PUBLIC trc_zdf ! called by step.F90
- PUBLIC trc_zdf_alloc ! called by nemogcm.F90
- INTEGER :: nzdf = 0 ! type vertical diffusion algorithm used
- ! ! defined from ln_zdf... namlist logicals)
- REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:) :: r2dt ! vertical profile time-step, = 2 rdttra
- ! ! except at nittrc000 (=rdttra) if neuler=0
- !! * Substitutions
- # include "domzgr_substitute.h90"
- # include "zdfddm_substitute.h90"
- # include "vectopt_loop_substitute.h90"
- !!----------------------------------------------------------------------
- !! NEMO/TOP 3.3 , NEMO Consortium (2010)
- !! $Id: trczdf.F90 4990 2014-12-15 16:42:49Z timgraham $
- !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
- !!----------------------------------------------------------------------
- CONTAINS
-
- INTEGER FUNCTION trc_zdf_alloc()
- !!----------------------------------------------------------------------
- !! *** ROUTINE trc_zdf_alloc ***
- !!----------------------------------------------------------------------
- ALLOCATE( r2dt(jpk) , STAT=trc_zdf_alloc )
- !
- IF( trc_zdf_alloc /= 0 ) CALL ctl_warn('trc_zdf_alloc : failed to allocate array.')
- !
- END FUNCTION trc_zdf_alloc
- SUBROUTINE trc_zdf( kt )
- !!----------------------------------------------------------------------
- !! *** ROUTINE trc_zdf ***
- !!
- !! ** Purpose : compute the vertical ocean tracer physics.
- !!---------------------------------------------------------------------
- INTEGER, INTENT( in ) :: kt ! ocean time-step index
- !
- INTEGER :: jk, jn
- CHARACTER (len=22) :: charout
- REAL(wp), POINTER, DIMENSION(:,:,:,:) :: ztrtrd ! 4D workspace
- !!---------------------------------------------------------------------
- !
- IF( nn_timing == 1 ) CALL timing_start('trc_zdf')
- !
- IF( kt == nittrc000 ) CALL zdf_ctl ! initialisation & control of options
- IF( ( neuler == 0 .AND. kt == nittrc000 ) .OR. ln_top_euler ) THEN ! at nittrc000
- r2dt(:) = rdttrc(:) ! = rdttrc (use or restarting with Euler time stepping)
- ELSEIF( kt <= nittrc000 + nn_dttrc ) THEN ! at nittrc000 or nittrc000+1
- r2dt(:) = 2. * rdttrc(:) ! = 2 rdttrc (leapfrog)
- ENDIF
- IF( l_trdtrc ) THEN
- CALL wrk_alloc( jpi, jpj, jpk, jptra, ztrtrd )
- ztrtrd(:,:,:,:) = tra(:,:,:,:)
- ENDIF
- 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, nittrc000, 'TRC', r2dt, nn_trczdf_exp, trb, tra, jptra )
- WRITE(charout, FMT="('zdf1 ')") ; CALL prt_ctl_trc_info(charout)
- CALL prt_ctl_trc( tab4d=tra, mask=tmask, clinfo=ctrcnm, clinfo2='trd' )
- CALL tra_zdf_imp( kt, nittrc000, 'TRC', r2dt, trb, tra, jptra )
- WRITE(charout, FMT="('zdf2 ')") ; CALL prt_ctl_trc_info(charout)
- CALL prt_ctl_trc( tab4d=tra, mask=tmask, clinfo=ctrcnm, clinfo2='trd' )
- CASE ( 0 ) ; CALL tra_zdf_exp( kt, nittrc000, 'TRC', r2dt, nn_trczdf_exp, trb, tra, jptra ) ! explicit scheme
- CASE ( 1 ) ; CALL tra_zdf_imp( kt, nittrc000, 'TRC', r2dt, trb, tra, jptra ) ! implicit scheme
- END SELECT
- IF( l_trdtrc ) THEN ! save the vertical diffusive trends for further diagnostics
- DO jn = 1, jptra
- DO jk = 1, jpkm1
- ztrtrd(:,:,jk,jn) = ( ( tra(:,:,jk,jn) - trb(:,:,jk,jn) ) / r2dt(jk) ) - ztrtrd(:,:,jk,jn)
- END DO
- CALL trd_tra( kt, 'TRC', jn, jptra_zdf, ztrtrd(:,:,:,jn) )
- END DO
- CALL wrk_dealloc( jpi, jpj, jpk, jptra, ztrtrd )
- ENDIF
- ! ! print mean trends (used for debugging)
- IF( ln_ctl ) THEN
- WRITE(charout, FMT="('zdf ')") ; CALL prt_ctl_trc_info(charout)
- CALL prt_ctl_trc( tab4d=tra, mask=tmask, clinfo=ctrcnm, clinfo2='trd' )
- END IF
- !
- IF( nn_timing == 1 ) CALL timing_stop('trc_zdf')
- !
- END SUBROUTINE trc_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_trczdf_exp=T)
- !! = 1 implicit (euler backward) scheme (ln_trczdf_exp=F)
- !! NB: The implicit scheme is required when using :
- !! - rotated lateral mixing operator
- !! - TKE, GLS or KPP vertical mixing scheme
- !!----------------------------------------------------------------------
- ! Define the vertical tracer physics scheme
- ! ==========================================
- ! Choice from ln_zdfexp already read in namelist in zdfini module
- IF( ln_trczdf_exp ) THEN ! use explicit scheme
- nzdf = 0
- ELSE ! use implicit scheme
- nzdf = 1
- ENDIF
- ! Force implicit schemes
- IF( ln_trcldf_iso ) nzdf = 1 ! iso-neutral lateral physics
- IF( ln_trcldf_hor .AND. ln_sco ) nzdf = 1 ! horizontal lateral physics in s-coordinate
- #if defined key_zdftke || defined key_zdfgls || defined key_zdfkpp
- nzdf = 1 ! TKE, GLS or KPP physics
- #endif
- IF( ln_trczdf_exp .AND. nzdf == 1 ) THEN
- CALL ctl_stop( 'trc_zdf : If using the rotated lateral mixing operator or TKE, GLS or KPP vertical scheme ', &
- & ' the implicit scheme is required, set ln_trczdf_exp = .false.' )
- ENDIF
- ! Test: esopa
- IF( lk_esopa ) nzdf = -1 ! All schemes used
- IF(lwp) THEN
- WRITE(numout,*)
- WRITE(numout,*) 'trc:zdf_ctl : vertical passive 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
- #else
- !!----------------------------------------------------------------------
- !! Default option Empty module
- !!----------------------------------------------------------------------
- CONTAINS
- SUBROUTINE trc_zdf( kt )
- INTEGER, INTENT(in) :: kt
- WRITE(*,*) 'trc_zdf: You should not have seen this print! error?', kt
- END SUBROUTINE trc_zdf
- #endif
- !!==============================================================================
- END MODULE trczdf
|