New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
dynldf.F90 in branches/2016/dev_r6519_HPC_4/NEMOGCM/NEMO/OPA_SRC/DYN – NEMO

source: branches/2016/dev_r6519_HPC_4/NEMOGCM/NEMO/OPA_SRC/DYN/dynldf.F90 @ 7508

Last change on this file since 7508 was 7508, checked in by mocavero, 7 years ago

changes on code duplication and workshare construct

  • Property svn:keywords set to Id
File size: 10.8 KB
RevLine 
[456]1MODULE dynldf
2   !!======================================================================
3   !!                       ***  MODULE  dynldf  ***
4   !! Ocean physics:  lateral diffusivity trends
5   !!=====================================================================
[5836]6   !! History :  2.0  ! 2005-11  (G. Madec)  Original code (new step architecture)
7   !!            3.7  ! 2014-01  (F. Lemarie, G. Madec)  restructuration/simplification of ahm specification,
8   !!                 !                                  add velocity dependent coefficient and optional read in file
[503]9   !!----------------------------------------------------------------------
[456]10
11   !!----------------------------------------------------------------------
[2528]12   !!   dyn_ldf      : update the dynamics trend with the lateral diffusion
13   !!   dyn_ldf_init : initialization, namelist read, and parameters control
[456]14   !!----------------------------------------------------------------------
[503]15   USE oce            ! ocean dynamics and tracers
16   USE dom_oce        ! ocean space and time domain
17   USE phycst         ! physical constants
[5836]18   USE ldfdyn         ! lateral diffusion: eddy viscosity coef.
19   USE ldfslp         ! lateral diffusion: slopes of mixing orientation
20   USE dynldf_lap_blp ! lateral mixing   (dyn_ldf_lap & dyn_ldf_blp routines)
21   USE dynldf_iso     ! lateral mixing                 (dyn_ldf_iso routine )
[4990]22   USE trd_oce        ! trends: ocean variables
[5836]23   USE trddyn         ! trend manager: dynamics   (trd_dyn      routine)
[4990]24   !
[503]25   USE prtctl         ! Print control
26   USE in_out_manager ! I/O manager
27   USE lib_mpp        ! distribued memory computing library
28   USE lbclnk         ! ocean lateral boundary conditions (or mpp link)
[5836]29   USE wrk_nemo       ! Memory Allocation
30   USE timing         ! Timing
[456]31
32   IMPLICIT NONE
33   PRIVATE
34
[2528]35   PUBLIC   dyn_ldf       ! called by step module
36   PUBLIC   dyn_ldf_init  ! called by opa  module
[456]37
[6140]38   !                      ! Parameter to control the type of lateral viscous operator
[5836]39   INTEGER, PARAMETER, PUBLIC ::   np_ERROR  =-10   ! error in setting the operator
40   INTEGER, PARAMETER, PUBLIC ::   np_no_ldf = 00   ! without operator (i.e. no lateral viscous trend)
41   !                          !!      laplacian     !    bilaplacian    !
42   INTEGER, PARAMETER, PUBLIC ::   np_lap    = 10   ,   np_blp    = 20  ! iso-level operator
43   INTEGER, PARAMETER, PUBLIC ::   np_lap_i  = 11                       ! iso-neutral or geopotential operator
[456]44
[5836]45   INTEGER ::   nldf   ! type of lateral diffusion used defined from ln_dynldf_... (namlist logicals)
46
[456]47   !! * Substitutions
48#  include "vectopt_loop_substitute.h90"
[2528]49   !!----------------------------------------------------------------------
[5836]50   !! NEMO/OPA 3.7 , NEMO Consortium (2015)
[1152]51   !! $Id$
[2715]52   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
[503]53   !!----------------------------------------------------------------------
[456]54CONTAINS
55
56   SUBROUTINE dyn_ldf( kt )
57      !!----------------------------------------------------------------------
58      !!                  ***  ROUTINE dyn_ldf  ***
59      !!
60      !! ** Purpose :   compute the lateral ocean dynamics physics.
[503]61      !!----------------------------------------------------------------------
62      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
[7508]63      INTEGER ::   jk, jj, ji
[3294]64      !
65      REAL(wp), POINTER, DIMENSION(:,:,:) ::  ztrdu, ztrdv
[456]66      !!----------------------------------------------------------------------
[2715]67      !
[3294]68      IF( nn_timing == 1 )  CALL timing_start('dyn_ldf')
69      !
[5836]70      IF( l_trddyn )   THEN                      ! temporary save of momentum trends
71         CALL wrk_alloc( jpi,jpj,jpk,   ztrdu, ztrdv )
[7508]72!$OMP PARALLEL DO schedule(static) private(jk, jj, ji)
73        DO jk = 1, jpk
74           DO jj = 1, jpj
75              DO ji = 1, jpi
76                 ztrdu(ji,jj,jk) = ua(ji,jj,jk)
77                 ztrdv(ji,jj,jk) = va(ji,jj,jk)
78              END DO
79           END DO
80        END DO
[456]81      ENDIF
82
83      SELECT CASE ( nldf )                       ! compute lateral mixing trend and add it to the general trend
[503]84      !
[5836]85      CASE ( np_lap   )    ;   CALL dyn_ldf_lap  ( kt, ub, vb, ua, va, 1 )      ! iso-level    laplacian
86      CASE ( np_lap_i )    ;   CALL dyn_ldf_iso  ( kt )                         ! rotated      laplacian
87      CASE ( np_blp   )    ;   CALL dyn_ldf_blp  ( kt, ub, vb, ua, va    )      ! iso-level bi-laplacian
[503]88      !
[456]89      END SELECT
90
[503]91      IF( l_trddyn ) THEN                        ! save the horizontal diffusive trends for further diagnostics
[7508]92!$OMP PARALLEL DO schedule(static) private(jk, jj, ji)
93           DO jk = 1, jpk
94              DO jj = 1, jpj
95                 DO ji = 1, jpi
96                    ztrdu(ji,jj,jk) = ua(ji,jj,jk) - ztrdu(ji,jj,jk)
97                    ztrdv(ji,jj,jk) = va(ji,jj,jk) - ztrdv(ji,jj,jk)
98                 END DO
99              END DO
100           END DO
[4990]101         CALL trd_dyn( ztrdu, ztrdv, jpdyn_ldf, kt )
[5836]102         CALL wrk_dealloc( jpi,jpj,jpk,   ztrdu, ztrdv )
[456]103      ENDIF
[503]104      !                                          ! print sum trends (used for debugging)
105      IF(ln_ctl)   CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf  - Ua: ', mask1=umask,   &
106         &                       tab3d_2=va, clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' )
107      !
[3294]108      IF( nn_timing == 1 )  CALL timing_stop('dyn_ldf')
[2715]109      !
[456]110   END SUBROUTINE dyn_ldf
111
112
[2528]113   SUBROUTINE dyn_ldf_init
[456]114      !!----------------------------------------------------------------------
[2528]115      !!                  ***  ROUTINE dyn_ldf_init  ***
[456]116      !!
117      !! ** Purpose :   initializations of the horizontal ocean dynamics physics
118      !!----------------------------------------------------------------------
119      INTEGER ::   ioptio, ierr         ! temporary integers
120      !!----------------------------------------------------------------------
[5836]121      !
[503]122      !                                   ! Namelist nam_dynldf: already read in ldfdyn module
[5836]123      !
[503]124      IF(lwp) THEN                        ! Namelist print
[456]125         WRITE(numout,*)
[2528]126         WRITE(numout,*) 'dyn_ldf_init : Choice of the lateral diffusive operator on dynamics'
[456]127         WRITE(numout,*) '~~~~~~~~~~~'
[503]128         WRITE(numout,*) '       Namelist nam_dynldf : set lateral mixing parameters (type, direction, coefficients)'
[5836]129         WRITE(numout,*) '          laplacian operator          ln_dynldf_lap = ', ln_dynldf_lap
130         WRITE(numout,*) '          bilaplacian operator        ln_dynldf_blp = ', ln_dynldf_blp
131         WRITE(numout,*) '          iso-level                   ln_dynldf_lev = ', ln_dynldf_lev
132         WRITE(numout,*) '          horizontal (geopotential)   ln_dynldf_hor = ', ln_dynldf_hor
133         WRITE(numout,*) '          iso-neutral                 ln_dynldf_iso = ', ln_dynldf_iso
[456]134      ENDIF
[5836]135      !                                   ! use of lateral operator or not
136      nldf = np_ERROR
[456]137      ioptio = 0
[5836]138      IF( ln_dynldf_lap )   ioptio = ioptio + 1
139      IF( ln_dynldf_blp )   ioptio = ioptio + 1
140      IF( ioptio >  1   )   CALL ctl_stop( 'dyn_ldf_init: use ONE or NONE of the 2 lap/bilap operator type on momentum' )
141      IF( ioptio == 0   )   nldf = np_no_ldf     ! No lateral mixing operator
142      !
143      IF( nldf /= np_no_ldf ) THEN        ! direction ==>> type of operator 
144         ioptio = 0
145         IF( ln_dynldf_lev )   ioptio = ioptio + 1
146         IF( ln_dynldf_hor )   ioptio = ioptio + 1
147         IF( ln_dynldf_iso )   ioptio = ioptio + 1
148         IF( ioptio >  1   )   CALL ctl_stop( '          use only ONE direction (level/hor/iso)' )
149         IF( ioptio == 0   )   CALL ctl_stop( '          use at least ONE direction (level/hor/iso)' )
150         !
151         !                                   ! Set nldf, the type of lateral diffusion, from ln_dynldf_... logicals
152         ierr = 0
153         IF ( ln_dynldf_lap ) THEN      ! laplacian operator
154            IF ( ln_zco ) THEN                ! z-coordinate
155               IF ( ln_dynldf_lev )   nldf = np_lap     ! iso-level = horizontal (no rotation)
156               IF ( ln_dynldf_hor )   nldf = np_lap     ! iso-level = horizontal (no rotation)
157               IF ( ln_dynldf_iso )   nldf = np_lap_i   ! iso-neutral            (   rotation)
158            ENDIF
159            IF ( ln_zps ) THEN             ! z-coordinate with partial step
160               IF ( ln_dynldf_lev )   nldf = np_lap     ! iso-level              (no rotation)
161               IF ( ln_dynldf_hor )   nldf = np_lap     ! iso-level              (no rotation)
162               IF ( ln_dynldf_iso )   nldf = np_lap_i   ! iso-neutral            (   rotation)
163            ENDIF
164            IF ( ln_sco ) THEN             ! s-coordinate
165               IF ( ln_dynldf_lev )   nldf = np_lap     ! iso-level = horizontal (no rotation)
166               IF ( ln_dynldf_hor )   nldf = np_lap_i   ! horizontal             (   rotation)
167               IF ( ln_dynldf_iso )   nldf = np_lap_i   ! iso-neutral            (   rotation)
168            ENDIF
[456]169         ENDIF
[5836]170         !
171         IF( ln_dynldf_blp ) THEN          ! bilaplacian operator
172            IF ( ln_zco ) THEN                ! z-coordinate
173               IF ( ln_dynldf_lev )   nldf = np_blp     ! iso-level = horizontal (no rotation)
174               IF ( ln_dynldf_hor )   nldf = np_blp     ! iso-level = horizontal (no rotation)
175               IF ( ln_dynldf_iso )   ierr = 2          ! iso-neutral            (   rotation)
176            ENDIF
177            IF ( ln_zps ) THEN             ! z-coordinate with partial step
178               IF ( ln_dynldf_lev )   nldf = np_blp     ! iso-level              (no rotation)
179               IF ( ln_dynldf_hor )   nldf = np_blp     ! iso-level              (no rotation)
180               IF ( ln_dynldf_iso )   ierr = 2          ! iso-neutral            (   rotation)
181            ENDIF
182            IF ( ln_sco ) THEN             ! s-coordinate
183               IF ( ln_dynldf_lev )   nldf = np_blp     ! iso-level              (no rotation)
184               IF ( ln_dynldf_hor )   ierr = 2          ! horizontal             (   rotation)
185               IF ( ln_dynldf_iso )   ierr = 2          ! iso-neutral            (   rotation)
186            ENDIF
[456]187         ENDIF
[5836]188         !
189         IF( ierr == 2 )   CALL ctl_stop( 'rotated bi-laplacian operator does not exist' )
190         !
191         IF( nldf == np_lap_i )   l_ldfslp = .TRUE.      ! rotation require the computation of the slopes
192         !
[456]193      ENDIF
194
195      IF(lwp) THEN
196         WRITE(numout,*)
[5836]197         IF( nldf == np_no_ldf )   WRITE(numout,*) '              NO lateral viscosity'
198         IF( nldf == np_lap    )   WRITE(numout,*) '              iso-level laplacian operator'
199         IF( nldf == np_lap_i  )   WRITE(numout,*) '              rotated laplacian operator with iso-level background'
200         IF( nldf == np_blp    )   WRITE(numout,*) '              iso-level bi-laplacian operator'
[456]201      ENDIF
[503]202      !
[2528]203   END SUBROUTINE dyn_ldf_init
[456]204
205   !!======================================================================
206END MODULE dynldf
Note: See TracBrowser for help on using the repository browser.