MODULE dynspg !!====================================================================== !! *** MODULE dynspg *** !! Ocean dynamics: surface pressure gradient control !!====================================================================== !! History : 9.0 ! 05-12 (C. Talandier, G. Madec) Original code !! 9.0 ! 05-12 (V. Garnier) dyn_spg_ctl: Original code !!---------------------------------------------------------------------- !!---------------------------------------------------------------------- !! dyn_spg : update the dynamics trend with the lateral diffusion !! dyn_spg_ctl : initialization, namelist read, and parameters control !!---------------------------------------------------------------------- USE oce ! ocean dynamics and tracers variables USE dom_oce ! ocean space and time domain variables USE obc_oce ! ocean open boundary conditions USE dynspg_oce ! surface pressure gradient variables USE dynspg_exp ! surface pressure gradient (dyn_spg_exp routine) USE dynspg_ts ! surface pressure gradient (dyn_spg_ts routine) USE dynspg_flt ! surface pressure gradient (dyn_spg_flt routine) USE dynspg_rl ! surface pressure gradient (dyn_spg_rl routine) USE trdmod ! ocean dynamics trends USE trdmod_oce ! ocean variables trends USE prtctl ! Print control (prt_ctl routine) USE in_out_manager ! I/O manager IMPLICIT NONE PRIVATE PUBLIC dyn_spg ! routine called by step module !! * module variables INTEGER :: nspg = 0 ! type of surface pressure gradient scheme defined from lk_dynspg_... !! * Substitutions # include "domzgr_substitute.h90" # include "vectopt_loop_substitute.h90" !!---------------------------------------------------------------------- !! OPA 9.0 , LOCEAN-IPSL (2005) !! $Header$ !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt) !!---------------------------------------------------------------------- CONTAINS SUBROUTINE dyn_spg( kt, kindic ) !!---------------------------------------------------------------------- !! *** ROUTINE dyn_spg *** !! !! ** Purpose : compute the lateral ocean dynamics physics. !!---------------------------------------------------------------------- INTEGER, INTENT( in ) :: kt ! ocean time-step index INTEGER, INTENT( out ) :: kindic ! solver flag !! REAL(wp) :: z2dt ! temporary scalar REAL(wp), DIMENSION(jpi,jpj,jpk) :: ztrdu, ztrdv ! 3D workspace !!---------------------------------------------------------------------- IF( kt == nit000 ) CALL dyn_spg_ctl ! initialisation & control of options IF( l_trddyn ) THEN ! temporary save of ta and sa trends ztrdu(:,:,:) = ua(:,:,:) ztrdv(:,:,:) = va(:,:,:) ENDIF SELECT CASE ( nspg ) ! compute surf. pressure gradient trend and add it to the general trend ! CASE ( 0 ) ; CALL dyn_spg_exp ( kt ) ! explicit CASE ( 1 ) ; CALL dyn_spg_ts ( kt ) ! time-splitting CASE ( 2 ) ; CALL dyn_spg_flt ( kt, kindic ) ! filtered CASE ( 3 ) ; CALL dyn_spg_rl ( kt, kindic ) ! rigid lid ! CASE ( -1 ) ! esopa: test all possibility with control print ; CALL dyn_spg_exp ( kt ) ; CALL prt_ctl( tab3d_1=ua, clinfo1=' spg0 - Ua: ', mask1=umask, & & tab3d_2=va, clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' ) ; CALL dyn_spg_ts ( kt ) ; CALL prt_ctl( tab3d_1=ua, clinfo1=' spg1 - Ua: ', mask1=umask, & & tab3d_2=va, clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' ) ; CALL dyn_spg_flt ( kt, kindic ) ; CALL prt_ctl( tab3d_1=ua, clinfo1=' spg2 - 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 SELECT CASE ( nspg ) CASE ( 0, 1, 3, 10, 11 ) ztrdu(:,:,:) = ua(:,:,:) - ztrdu(:,:,:) ztrdv(:,:,:) = va(:,:,:) - ztrdv(:,:,:) CASE( 2, 12 ) z2dt = 2. * rdt IF( neuler == 0 .AND. kt == nit000 ) z2dt = rdt ztrdu(:,:,:) = ( ua(:,:,:) - ub(:,:,:) ) / z2dt - ztrdu(:,:,:) ztrdv(:,:,:) = ( va(:,:,:) - vb(:,:,:) ) / z2dt - ztrdv(:,:,:) END SELECT CALL trd_mod( ztrdu, ztrdv, jpdyn_trd_spg, 'DYN', kt ) ENDIF ! ! print mean trends (used for debugging) IF(ln_ctl) CALL prt_ctl( tab3d_1=ua, clinfo1=' spg - Ua: ', mask1=umask, & & tab3d_2=va, clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' ) ! END SUBROUTINE dyn_spg SUBROUTINE dyn_spg_ctl !!--------------------------------------------------------------------- !! *** ROUTINE dyn_spg_ctl *** !! !! ** Purpose : Control the consistency between cpp options for !! surface pressure gradient schemes !!---------------------------------------------------------------------- !! * Local declarations INTEGER :: ioptio !!---------------------------------------------------------------------- ! Parameter control and print ! --------------------------- ! Control print IF(lwp) THEN WRITE(numout,*) WRITE(numout,*) 'dyn_spg_ctl : choice of the surface pressure gradient scheme' WRITE(numout,*) '~~~~~~~~~~~' WRITE(numout,*) ' Explicit free surface lk_dynspg_exp = ', lk_dynspg_exp WRITE(numout,*) ' Free surface with time splitting lk_dynspg_ts = ', lk_dynspg_ts WRITE(numout,*) ' Filtered free surface cst volume lk_dynspg_flt = ', lk_dynspg_flt WRITE(numout,*) ' Rigid-lid case lk_dynspg_rl = ', lk_dynspg_rl ENDIF ! Control of surface pressure gradient scheme options ! --------------------------------------------------- ioptio = 0 IF(lk_dynspg_exp) ioptio = ioptio + 1 IF(lk_dynspg_ts ) ioptio = ioptio + 1 IF(lk_dynspg_flt) ioptio = ioptio + 1 IF(lk_dynspg_rl ) ioptio = ioptio + 1 IF( ( ioptio > 1 .AND. .NOT. lk_esopa ) .OR. ioptio == 0 ) & & CALL ctl_stop( ' Choose only one surface pressure gradient scheme with a key cpp' ) IF( lk_esopa ) nspg = -1 IF( lk_dynspg_exp) nspg = 0 IF( lk_dynspg_ts ) nspg = 1 IF( lk_dynspg_flt) nspg = 2 IF( lk_dynspg_rl ) nspg = 3 IF( nspg == 13 ) nspg = 3 IF( lk_esopa ) nspg = -1 IF(lwp) THEN WRITE(numout,*) IF( nspg == -1 ) WRITE(numout,*) ' ESOPA test All scheme used except rigid-lid' IF( nspg == 0 ) WRITE(numout,*) ' explicit free surface' IF( nspg == 1 ) WRITE(numout,*) ' free surface with time splitting scheme' IF( nspg == 2 ) WRITE(numout,*) ' filtered free surface' IF( nspg == 3 ) WRITE(numout,*) ' rigid-lid' ENDIF ! Control of timestep choice ! -------------------------- IF( lk_dynspg_ts ) THEN IF( MOD( rdt , rdtbt ) /= 0. ) & & CALL ctl_stop( ' The barotropic timestep must be an integer divisor of the baroclinic timestep' ) ENDIF #if key_obc ! Conservation of ocean volume (key_dynspg_flt) ! --------------------------------------------- IF( lk_dynspg_flt ) ln_vol_cst = .true. ! Application of Flather's algorithm at open boundaries ! ----------------------------------------------------- IF( lk_dynspg_flt ) ln_obc_fla = .false. IF( lk_dynspg_exp ) ln_obc_fla = .true. IF( lk_dynspg_ts ) ln_obc_fla = .true. #endif END SUBROUTINE dyn_spg_ctl !!====================================================================== END MODULE dynspg