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 trunk/NEMOGCM/NEMO/OPA_SRC/DYN – NEMO

source: trunk/NEMOGCM/NEMO/OPA_SRC/DYN/dynldf.F90 @ 4528

Last change on this file since 4528 was 4522, checked in by rfurner, 10 years ago

split long line over two, as some compilers cant deal with long line length

  • Property svn:keywords set to Id
File size: 12.5 KB
Line 
1MODULE dynldf
2   !!======================================================================
3   !!                       ***  MODULE  dynldf  ***
4   !! Ocean physics:  lateral diffusivity trends
5   !!=====================================================================
6   !! History :  9.0  !  05-11  (G. Madec)  Original code (new step architecture)
7   !!----------------------------------------------------------------------
8
9   !!----------------------------------------------------------------------
10   !!   dyn_ldf      : update the dynamics trend with the lateral diffusion
11   !!   dyn_ldf_init : initialization, namelist read, and parameters control
12   !!----------------------------------------------------------------------
13   USE oce            ! ocean dynamics and tracers
14   USE dom_oce        ! ocean space and time domain
15   USE phycst         ! physical constants
16   USE ldfdyn_oce     ! ocean dynamics lateral physics
17   USE ldfslp         ! lateral mixing: slopes of mixing orientation
18   USE dynldf_bilapg  ! lateral mixing            (dyn_ldf_bilapg routine)
19   USE dynldf_bilap   ! lateral mixing            (dyn_ldf_bilap  routine)
20   USE dynldf_iso     ! lateral mixing            (dyn_ldf_iso    routine)
21   USE dynldf_lap     ! lateral mixing            (dyn_ldf_lap    routine)
22   USE ldftra_oce, ONLY: ln_traldf_hor     ! ocean tracers lateral physics
23   USE trdmod         ! ocean dynamics and tracer trends
24   USE trdmod_oce     ! ocean variables trends
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)
29   USE wrk_nemo        ! Memory Allocation
30   USE timing          ! Timing
31
32
33   IMPLICIT NONE
34   PRIVATE
35
36   PUBLIC   dyn_ldf       ! called by step module
37   PUBLIC   dyn_ldf_init  ! called by opa  module
38
39   INTEGER ::   nldf = -2   ! type of lateral diffusion used defined from ln_dynldf_... namlist logicals)
40
41   !! * Substitutions
42#  include "domzgr_substitute.h90"
43#  include "vectopt_loop_substitute.h90"
44   !!----------------------------------------------------------------------
45   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
46   !! $Id$
47   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
48   !!----------------------------------------------------------------------
49CONTAINS
50
51   SUBROUTINE dyn_ldf( kt )
52      !!----------------------------------------------------------------------
53      !!                  ***  ROUTINE dyn_ldf  ***
54      !!
55      !! ** Purpose :   compute the lateral ocean dynamics physics.
56      !!----------------------------------------------------------------------
57      !
58      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
59      !
60      REAL(wp), POINTER, DIMENSION(:,:,:) ::  ztrdu, ztrdv
61      !!----------------------------------------------------------------------
62      !
63      IF( nn_timing == 1 )  CALL timing_start('dyn_ldf')
64      !
65      IF( l_trddyn )   THEN                      ! temporary save of ta and sa trends
66         CALL wrk_alloc( jpi, jpj, jpk, ztrdu, ztrdv )
67         ztrdu(:,:,:) = ua(:,:,:) 
68         ztrdv(:,:,:) = va(:,:,:) 
69      ENDIF
70
71      SELECT CASE ( nldf )                       ! compute lateral mixing trend and add it to the general trend
72      !
73      CASE ( 0 )    ;   CALL dyn_ldf_lap    ( kt )      ! iso-level laplacian
74      CASE ( 1 )    ;   CALL dyn_ldf_iso    ( kt )      ! rotated laplacian (except dk[ dk[.] ] part)
75      CASE ( 2 )    ;   CALL dyn_ldf_bilap  ( kt )      ! iso-level bilaplacian
76      CASE ( 3 )    ;   CALL dyn_ldf_bilapg ( kt )      ! s-coord. horizontal bilaplacian
77      CASE ( 4 )                                        ! iso-level laplacian + bilaplacian
78         CALL dyn_ldf_lap    ( kt )
79         CALL dyn_ldf_bilap  ( kt )
80      CASE ( 5 )                                        ! rotated laplacian + bilaplacian (s-coord)
81         CALL dyn_ldf_iso    ( kt )
82         CALL dyn_ldf_bilapg ( kt )
83      !
84      CASE ( -1 )                                       ! esopa: test all possibility with control print
85                        CALL dyn_ldf_lap    ( kt )
86                        CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf0 - Ua: ', mask1=umask,   &
87            &                         tab3d_2=va, clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' )
88                        CALL dyn_ldf_iso    ( kt )
89                        CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf1 - Ua: ', mask1=umask,   &
90            &                         tab3d_2=va, clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' )
91                        CALL dyn_ldf_bilap  ( kt )
92                        CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf2 - Ua: ', mask1=umask,   &
93            &                         tab3d_2=va, clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' )
94                        CALL dyn_ldf_bilapg ( kt )
95                        CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf3 - Ua: ', mask1=umask,   &
96            &                         tab3d_2=va, clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' )
97      !
98      CASE ( -2 )                                       ! neither laplacian nor bilaplacian schemes used
99         IF( kt == nit000 ) THEN
100            IF(lwp) WRITE(numout,*)
101            IF(lwp) WRITE(numout,*) 'dyn_ldf : no lateral diffusion on momentum setup'
102            IF(lwp) WRITE(numout,*) '~~~~~~~ '
103         ENDIF
104      END SELECT
105
106      IF( l_trddyn ) THEN                        ! save the horizontal diffusive trends for further diagnostics
107         ztrdu(:,:,:) = ua(:,:,:) - ztrdu(:,:,:)
108         ztrdv(:,:,:) = va(:,:,:) - ztrdv(:,:,:)
109         CALL trd_mod( ztrdu, ztrdv, jpdyn_trd_ldf, 'DYN', kt )
110         CALL wrk_dealloc( jpi, jpj, jpk, ztrdu, ztrdv )
111      ENDIF
112      !                                          ! print sum trends (used for debugging)
113      IF(ln_ctl)   CALL prt_ctl( tab3d_1=ua, clinfo1=' ldf  - Ua: ', mask1=umask,   &
114         &                       tab3d_2=va, clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' )
115      !
116      IF( nn_timing == 1 )  CALL timing_stop('dyn_ldf')
117      !
118   END SUBROUTINE dyn_ldf
119
120
121   SUBROUTINE dyn_ldf_init
122      !!----------------------------------------------------------------------
123      !!                  ***  ROUTINE dyn_ldf_init  ***
124      !!
125      !! ** Purpose :   initializations of the horizontal ocean dynamics physics
126      !!----------------------------------------------------------------------
127      INTEGER ::   ioptio, ierr         ! temporary integers
128      !!----------------------------------------------------------------------
129   
130      !                                   ! Namelist nam_dynldf: already read in ldfdyn module
131
132      IF(lwp) THEN                        ! Namelist print
133         WRITE(numout,*)
134         WRITE(numout,*) 'dyn_ldf_init : Choice of the lateral diffusive operator on dynamics'
135         WRITE(numout,*) '~~~~~~~~~~~'
136         WRITE(numout,*) '       Namelist nam_dynldf : set lateral mixing parameters (type, direction, coefficients)'
137         WRITE(numout,*) '          laplacian operator          ln_dynldf_lap   = ', ln_dynldf_lap
138         WRITE(numout,*) '          bilaplacian operator        ln_dynldf_bilap = ', ln_dynldf_bilap
139         WRITE(numout,*) '          iso-level                   ln_dynldf_level = ', ln_dynldf_level
140         WRITE(numout,*) '          horizontal (geopotential)   ln_dynldf_hor   = ', ln_dynldf_hor
141         WRITE(numout,*) '          iso-neutral                 ln_dynldf_iso   = ', ln_dynldf_iso
142      ENDIF
143
144      !                                   ! control the consistency
145      ioptio = 0
146      IF( ln_dynldf_lap   )   ioptio = ioptio + 1
147      IF( ln_dynldf_bilap )   ioptio = ioptio + 1
148      IF( ioptio <  1 ) CALL ctl_warn( '          neither laplacian nor bilaplacian operator set for dynamics' )
149      ioptio = 0
150      IF( ln_dynldf_level )   ioptio = ioptio + 1
151      IF( ln_dynldf_hor   )   ioptio = ioptio + 1
152      IF( ln_dynldf_iso   )   ioptio = ioptio + 1
153      IF( ioptio >  1 ) CALL ctl_stop( '          use only ONE direction (level/hor/iso)' )
154
155      IF( ln_dynldf_iso .AND. ln_traldf_hor ) CALL ctl_stop &
156      &   ( 'Not sensible to use geopotential diffusion for tracers with isoneutral diffusion for dynamics' )
157
158      !                                   ! Set nldf, the type of lateral diffusion, from ln_dynldf_... logicals
159      ierr = 0
160      IF ( ln_dynldf_lap ) THEN      ! laplacian operator
161         IF ( ln_zco ) THEN                ! z-coordinate
162            IF ( ln_dynldf_level )   nldf = 0      ! iso-level  (no rotation)
163            IF ( ln_dynldf_hor   )   nldf = 0      ! horizontal (no rotation)
164            IF ( ln_dynldf_iso   )   nldf = 1      ! isoneutral (   rotation)
165         ENDIF
166         IF ( ln_zps ) THEN             ! z-coordinate
167            IF ( ln_dynldf_level )   ierr = 1      ! iso-level not allowed
168            IF ( ln_dynldf_hor   )   nldf = 0      ! horizontal (no rotation)
169            IF ( ln_dynldf_iso   )   nldf = 1      ! isoneutral (   rotation)
170         ENDIF
171         IF ( ln_sco ) THEN             ! s-coordinate
172            IF ( ln_dynldf_level )   nldf = 0      ! iso-level  (no rotation)
173            IF ( ln_dynldf_hor   )   nldf = 1      ! horizontal (   rotation)
174            IF ( ln_dynldf_iso   )   nldf = 1      ! isoneutral (   rotation)
175         ENDIF
176      ENDIF
177
178      IF( ln_dynldf_bilap ) THEN      ! bilaplacian operator
179         IF ( ln_zco ) THEN                ! z-coordinate
180            IF ( ln_dynldf_level )   nldf = 2      ! iso-level  (no rotation)
181            IF ( ln_dynldf_hor   )   nldf = 2      ! horizontal (no rotation)
182            IF ( ln_dynldf_iso   )   ierr = 2      ! isoneutral (   rotation)
183         ENDIF
184         IF ( ln_zps ) THEN             ! z-coordinate
185            IF ( ln_dynldf_level )   ierr = 1      ! iso-level not allowed
186            IF ( ln_dynldf_hor   )   nldf = 2      ! horizontal (no rotation)
187            IF ( ln_dynldf_iso   )   ierr = 2      ! isoneutral (   rotation)
188         ENDIF
189         IF ( ln_sco ) THEN             ! s-coordinate
190            IF ( ln_dynldf_level )   nldf = 2      ! iso-level  (no rotation)
191            IF ( ln_dynldf_hor   )   nldf = 3      ! horizontal (   rotation)
192            IF ( ln_dynldf_iso   )   ierr = 2      ! isoneutral (   rotation)
193         ENDIF
194      ENDIF
195     
196      IF( ln_dynldf_lap .AND. ln_dynldf_bilap ) THEN  ! mixed laplacian and bilaplacian operators
197         IF ( ln_zco ) THEN                ! z-coordinate
198            IF ( ln_dynldf_level )   nldf = 4      ! iso-level  (no rotation)
199            IF ( ln_dynldf_hor   )   nldf = 4      ! horizontal (no rotation)
200            IF ( ln_dynldf_iso   )   ierr = 2      ! isoneutral (   rotation)
201         ENDIF
202         IF ( ln_zps ) THEN             ! z-coordinate
203            IF ( ln_dynldf_level )   ierr = 1      ! iso-level not allowed
204            IF ( ln_dynldf_hor   )   nldf = 4      ! horizontal (no rotation)
205            IF ( ln_dynldf_iso   )   ierr = 2      ! isoneutral (   rotation)
206         ENDIF
207         IF ( ln_sco ) THEN             ! s-coordinate
208            IF ( ln_dynldf_level )   nldf = 4      ! iso-level  (no rotation)
209            IF ( ln_dynldf_hor   )   nldf = 5      ! horizontal (   rotation)
210            IF ( ln_dynldf_iso   )   ierr = 2      ! isoneutral (   rotation)
211         ENDIF
212      ENDIF
213
214      IF( lk_esopa )                 nldf = -1     ! esopa test
215
216      IF( ierr == 1 )   CALL ctl_stop( 'iso-level in z-coordinate - partial step, not allowed' )
217      IF( ierr == 2 )   CALL ctl_stop( 'isoneutral bilaplacian operator does not exist' )
218      IF( nldf == 1 .OR. nldf == 3 ) THEN      ! rotation
219         IF( .NOT.lk_ldfslp )   CALL ctl_stop( 'the rotation of the diffusive tensor require key_ldfslp' )
220      ENDIF
221
222      IF(lwp) THEN
223         WRITE(numout,*)
224         IF( nldf == -2 )   WRITE(numout,*) '              neither laplacian nor bilaplacian schemes used'
225         IF( nldf == -1 )   WRITE(numout,*) '              ESOPA test All scheme used'
226         IF( nldf ==  0 )   WRITE(numout,*) '              laplacian operator'
227         IF( nldf ==  1 )   WRITE(numout,*) '              rotated laplacian operator'
228         IF( nldf ==  2 )   WRITE(numout,*) '              bilaplacian operator'
229         IF( nldf ==  3 )   WRITE(numout,*) '              rotated bilaplacian'
230         IF( nldf ==  4 )   WRITE(numout,*) '              laplacian and bilaplacian operators'
231         IF( nldf ==  5 )   WRITE(numout,*) '              rotated laplacian and bilaplacian operators'
232      ENDIF
233      !
234   END SUBROUTINE dyn_ldf_init
235
236   !!======================================================================
237END MODULE dynldf
Note: See TracBrowser for help on using the repository browser.