MODULE dynldf !!====================================================================== !! *** MODULE dynldf *** !! Ocean physics: lateral diffusivity trends !!===================================================================== !! History : 9.0 ! 05-11 (G. Madec) Original code (new step architecture) !!---------------------------------------------------------------------- !!---------------------------------------------------------------------- !! dyn_ldf : update the dynamics trend with the lateral diffusion !! dyn_ldf_ctl : initialization, namelist read, and parameters control !!---------------------------------------------------------------------- USE oce ! ocean dynamics and tracers USE dom_oce ! ocean space and time domain USE phycst ! physical constants USE ldfdyn_oce ! ocean dynamics lateral physics USE ldfslp ! lateral mixing: slopes of mixing orientation USE dynldf_bilapg ! lateral mixing (dyn_ldf_bilapg routine) USE dynldf_bilap ! lateral mixing (dyn_ldf_bilap routine) USE dynldf_iso ! lateral mixing (dyn_ldf_iso routine) USE dynldf_lap ! lateral mixing (dyn_ldf_lap routine) USE trdmod ! ocean dynamics and tracer trends USE trdmod_oce ! ocean variables trends USE prtctl ! Print control USE in_out_manager ! I/O manager USE lib_mpp ! distribued memory computing library USE lbclnk ! ocean lateral boundary conditions (or mpp link) IMPLICIT NONE PRIVATE PUBLIC dyn_ldf ! called by step module INTEGER :: nldf = 0 ! type of lateral diffusion used defined from ln_dynldf_... namlist logicals) !! * Substitutions # include "domzgr_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 dyn_ldf( kt ) !!---------------------------------------------------------------------- !! *** ROUTINE dyn_ldf *** !! !! ** Purpose : compute the lateral ocean dynamics physics. !!---------------------------------------------------------------------- INTEGER, INTENT(in) :: kt ! ocean time-step index !! REAL(wp), DIMENSION(jpi,jpj,jpk) :: ztrdu, ztrdv ! 3D workspace !!---------------------------------------------------------------------- IF( kt == nit000 ) CALL dyn_ldf_ctl ! initialisation & control of options IF( l_trddyn ) THEN ! temporary save of ta and sa trends ztrdu(:,:,:) = ua(:,:,:) ztrdv(:,:,:) = va(:,:,:) ENDIF SELECT CASE ( nldf ) ! compute lateral mixing trend and add it to the general trend ! CASE ( 0 ) ; CALL dyn_ldf_lap ( kt ) ! iso-level laplacian CASE ( 1 ) ; CALL dyn_ldf_iso ( kt ) ! rotated laplacian (except dk[ dk[.] ] part) CASE ( 2 ) ; CALL dyn_ldf_bilap ( kt ) ! iso-level bilaplacian CASE ( 3 ) ; CALL dyn_ldf_bilapg ( kt ) ! s-coord. horizontal bilaplacian ! CASE ( -1 ) ! esopa: test all possibility with control print CALL dyn_ldf_lap ( kt ) CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf0 - Ua: ', mask1=umask, & & tab3d_2=va, clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' ) CALL dyn_ldf_iso ( kt ) CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf1 - Ua: ', mask1=umask, & & tab3d_2=va, clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' ) CALL dyn_ldf_bilap ( kt ) CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf2 - Ua: ', mask1=umask, & & tab3d_2=va, clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' ) CALL dyn_ldf_bilapg ( kt ) CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf3 - Ua: ', mask1=umask, & & tab3d_2=va, clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' ) END SELECT IF( l_trddyn ) THEN ! save the horizontal diffusive trends for further diagnostics ztrdu(:,:,:) = ua(:,:,:) - ztrdu(:,:,:) ztrdv(:,:,:) = va(:,:,:) - ztrdv(:,:,:) CALL trd_mod( ztrdu, ztrdv, jpdyn_trd_ldf, 'DYN', kt ) ENDIF ! ! print sum trends (used for debugging) IF(ln_ctl) CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf - Ua: ', mask1=umask, & & tab3d_2=va, clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' ) ! END SUBROUTINE dyn_ldf SUBROUTINE dyn_ldf_ctl !!---------------------------------------------------------------------- !! *** ROUTINE dyn_ldf_ctl *** !! !! ** Purpose : initializations of the horizontal ocean dynamics physics !!---------------------------------------------------------------------- INTEGER :: ioptio, ierr ! temporary integers !!---------------------------------------------------------------------- ! ! Namelist nam_dynldf: already read in ldfdyn module IF(lwp) THEN ! Namelist print WRITE(numout,*) WRITE(numout,*) 'dyn_ldf_ctl : Choice of the lateral diffusive operator on dynamics' WRITE(numout,*) '~~~~~~~~~~~' WRITE(numout,*) ' Namelist nam_dynldf : set lateral mixing parameters (type, direction, coefficients)' WRITE(numout,*) ' laplacian operator ln_dynldf_lap = ', ln_dynldf_lap WRITE(numout,*) ' bilaplacian operator ln_dynldf_bilap = ', ln_dynldf_bilap WRITE(numout,*) ' iso-level ln_dynldf_level = ', ln_dynldf_level WRITE(numout,*) ' horizontal (geopotential) ln_dynldf_hor = ', ln_dynldf_hor WRITE(numout,*) ' iso-neutral ln_dynldf_iso = ', ln_dynldf_iso ENDIF ! ! control the consistency ioptio = 0 IF( ln_dynldf_lap ) ioptio = ioptio + 1 IF( ln_dynldf_bilap ) ioptio = ioptio + 1 IF( ioptio /= 1 ) CALL ctl_stop( ' use ONE of the 2 lap/bilap operator type on dynamics' ) ioptio = 0 IF( ln_dynldf_level ) ioptio = ioptio + 1 IF( ln_dynldf_hor ) ioptio = ioptio + 1 IF( ln_dynldf_iso ) ioptio = ioptio + 1 IF( ioptio /= 1 ) CALL ctl_stop( ' use only ONE direction (level/hor/iso)' ) ! ! Set nldf, the type of lateral diffusion, from ln_dynldf_... logicals ierr = 0 IF ( ln_dynldf_lap ) THEN ! laplacian operator IF ( ln_zco ) THEN ! z-coordinate IF ( ln_dynldf_level ) nldf = 0 ! iso-level (no rotation) IF ( ln_dynldf_hor ) nldf = 0 ! horizontal (no rotation) IF ( ln_dynldf_iso ) nldf = 1 ! isoneutral ( rotation) ENDIF IF ( ln_zps ) THEN ! z-coordinate IF ( ln_dynldf_level ) ierr = 1 ! iso-level not allowed IF ( ln_dynldf_hor ) nldf = 0 ! horizontal (no rotation) IF ( ln_dynldf_iso ) nldf = 1 ! isoneutral ( rotation) ENDIF IF ( ln_sco ) THEN ! z-coordinate IF ( ln_dynldf_level ) nldf = 0 ! iso-level (no rotation) IF ( ln_dynldf_hor ) nldf = 1 ! horizontal ( rotation) IF ( ln_dynldf_iso ) nldf = 1 ! isoneutral ( rotation) ENDIF ENDIF IF( ln_dynldf_bilap ) THEN ! bilaplacian operator IF ( ln_zco ) THEN ! z-coordinate IF ( ln_dynldf_level ) nldf = 2 ! iso-level (no rotation) IF ( ln_dynldf_hor ) nldf = 2 ! horizontal (no rotation) IF ( ln_dynldf_iso ) ierr = 2 ! isoneutral ( rotation) ENDIF IF ( ln_zps ) THEN ! z-coordinate IF ( ln_dynldf_level ) ierr = 1 ! iso-level not allowed IF ( ln_dynldf_hor ) nldf = 2 ! horizontal (no rotation) IF ( ln_dynldf_iso ) ierr = 2 ! isoneutral ( rotation) ENDIF IF ( ln_sco ) THEN ! z-coordinate IF ( ln_dynldf_level ) nldf = 2 ! iso-level (no rotation) IF ( ln_dynldf_hor ) nldf = 3 ! horizontal ( rotation) IF ( ln_dynldf_iso ) ierr = 2 ! isoneutral ( rotation) ENDIF ENDIF IF( lk_esopa ) nldf = -1 ! esopa test IF( ierr == 1 ) CALL ctl_stop( 'iso-level in z-coordinate - partial step, not allowed' ) IF( ierr == 2 ) CALL ctl_stop( 'isoneutral bilaplacian operator does not exist' ) IF( nldf == 1 .OR. nldf == 3 ) THEN ! rotation IF( .NOT.lk_ldfslp ) CALL ctl_stop( 'the rotation of the diffusive tensor require key_ldfslp' ) ENDIF IF(lwp) THEN WRITE(numout,*) IF( nldf == -1 ) WRITE(numout,*) ' ESOPA test All scheme used' IF( nldf == 0 ) WRITE(numout,*) ' laplacian operator' IF( nldf == 1 ) WRITE(numout,*) ' Rotated laplacian operator' IF( nldf == 2 ) WRITE(numout,*) ' bilaplacian operator' IF( nldf == 3 ) WRITE(numout,*) ' Rotated bilaplacian' ENDIF ! END SUBROUTINE dyn_ldf_ctl !!====================================================================== END MODULE dynldf