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.
divcur_tam.F90 in branches/TAM_V3_0/NEMOTAM/OPATAM_SRC/DYN – NEMO

source: branches/TAM_V3_0/NEMOTAM/OPATAM_SRC/DYN/divcur_tam.F90 @ 2790

Last change on this file since 2790 was 1885, checked in by rblod, 14 years ago

add TAM sources

File size: 55.9 KB
Line 
1MODULE divcur_tam
2#if defined key_tam
3   !!==============================================================================
4   !!       ***  MODULE  divcur_tam : TANGENT/ADJOINT OF MODULE divcur  ***
5   !!
6   !! Ocean diagnostic variable : horizontal divergence and relative vorticity
7   !!
8   !!==============================================================================
9   !! History of the TAM module:
10   !!             7.0  !  95-01  (F. Van den Berghe)
11   !!             8.0  !  96-04  (A. Weaver)
12   !!             8.1  !  98-02  (A. Weaver)
13   !!             8.2  !  00-08  (A. Weaver)
14   !!             9.0  !  08-06  (A. Vidard) Skeleton
15   !!             9.0  !  08-07  (A. Weaver)
16   !!             9.0  !  08-11  (A. Vidard) Nemo v3
17   !!             9.0  !  09-02  (A. Vidard) cleanup
18   !!----------------------------------------------------------------------
19   !!   div_cur_tan     : Compute the horizontal divergence and relative
20   !!                     vorticity fields (tangent routine)
21   !!   div_cur_adj     : Compute the horizontal divergence and relative
22   !!                     vorticity fields (adjoint routine)
23   !!   div_cur_adj_tst : Test of the adjoint routine
24   !!----------------------------------------------------------------------
25   !! * Modules used
26   USE par_kind,       ONLY: & ! Precision variables
27      & wp
28   USE par_oce,        ONLY: & ! Ocean space and time domain variables
29      & jpi,                 &
30      & jpj,                 & 
31      & jpk,                 &
32      & jpim1,               &
33      & jpjm1,               &
34      & jpkm1,               &
35      & jpiglo, jpjglo
36   USE in_out_manager, ONLY: & ! I/O manager
37      & lwp,                 &
38      & numout,              & 
39      & nit000
40   USE dom_oce,        ONLY: & ! Ocean space and time domain
41      & e1u,                 &
42      & e2u,                 &
43      & e1v,                 &
44      & e2v,                 &
45      & e1t,                 &
46      & e2t,                 &
47      & e1f,                 &
48      & e2f,                 &
49#if defined key_zco
50      & e3t_0,               &
51#else
52      & e3u,                 &
53      & e3v,                 &
54      & e3f,                 &
55      & e3t,                 &
56#endif
57      & tmask,               &
58      & fmask,               &
59#if defined key_noslip_accurate
60      & nicoa,               &
61      & njcoa,               &
62      & npcoa,               &
63#endif
64      & mig,                 &
65      & mjg,                 &
66      & nperio,              &
67      & nldi,                &
68      & nldj,                &
69      & nlei,                &
70      & nlej
71#if defined key_obc
72   USE obc_par,        ONLY: & ! Open boundary conditions
73      & lp_obc_east,         &
74      & lp_obc_west,         &
75      & lp_obc_north,        &
76      & lp_obc_south
77   USE obc_oce,        ONLY: & ! Open boundary conditions
78      & nie0p1,              &
79      & nie1p1,              &
80      & njn0p1,              &
81      & njn1p1,              &
82      & nje0,                &
83      & nje1,                &
84      & niw0,                &
85      & niw1,                &
86      & njw0,                &
87      & njw1,                &
88      & nin0,                &
89      & nin1,                &
90      & nis0,                &
91      & nis1,                &
92      & njs0,                &
93      & njs1
94#endif
95#if defined key_bdy
96   USE bdy_oce,        ONLY: & ! Unstructured open boundaries variables
97      & bdytmask
98#endif
99   USE lbclnk,         ONLY: & ! Lateral boundary conditions
100      & lbc_lnk
101
102   USE lbclnk_tam,     ONLY: & ! TAM lateral boundary conditions
103      & lbc_lnk_adj
104   USE oce_tam,        ONLY: & ! TAM ocean dynamics and tracers variables
105      & un_tl,               &
106      & un_ad,               &
107      & vn_tl,               &
108      & vn_ad,               &
109      & hdivb_tl,            &
110      & hdivb_ad,            &
111      & hdivn_tl,            &
112      & hdivn_ad,            &
113      & rotb_tl,             &
114      & rotb_ad,             &
115      & rotn_tl,             &
116      & rotn_ad
117   USE gridrandom,     ONLY: & ! Random Gaussian noise on grids
118      & grid_random
119   USE dotprodfld,     ONLY: & ! Computes dot product for 3D and 2D fields
120      & dot_product
121   USE tstool_tam,     ONLY: &
122      & prntst_adj,          & !
123      & stdu,                & ! stdev for u-velocity
124      & stdv                   !           v-velocity
125 
126   IMPLICIT NONE
127   PRIVATE
128
129   !! * Accessibility
130   PUBLIC div_cur_tan,    &   ! routine called by steptan.F90
131      &   div_cur_adj,    &   ! routine called by stepadj.F90
132      &   div_cur_adj_tst     ! adjoint test routine
133
134   !! * Substitutions
135#  include "domzgr_substitute.h90"
136#  include "vectopt_loop_substitute.h90"
137
138CONTAINS
139
140#if defined key_noslip_accurate
141   !!----------------------------------------------------------------------
142   !!   'key_noslip_accurate'                     2nd order centered scheme
143   !!                                                4th order at the coast
144   !!----------------------------------------------------------------------
145
146   SUBROUTINE div_cur_tan( kt )
147      !!----------------------------------------------------------------------
148      !!                  ***  ROUTINE div_cur_tan  ***
149      !!
150      !! ** Purpose of direct routine :
151      !!      compute the horizontal divergence and the relative
152      !!      vorticity at before and now time-step
153      !!
154      !! ** Method of direct routine :
155      !!      I.  divergence :
156      !!         - save the divergence computed at the previous time-step
157      !!      (note that the Asselin filter has not been applied on hdivb)
158      !!         - compute the now divergence given by :
159      !!         hdivn = 1/(e1t*e2t*e3t) ( di[e2u*e3u un] + dj[e1v*e3v vn] )
160      !!      Note: if lk_zco=T, e3u=e3v=e3t, they are simplified in the
161      !!      above expression
162      !!         - apply lateral boundary conditions on hdivn
163      !!      II. vorticity :
164      !!         - save the curl computed at the previous time-step
165      !!            rotb = rotn
166      !!      (note that the Asselin time filter has not been applied to rotb)
167      !!         - compute the now curl in tensorial formalism:
168      !!            rotn = 1/(e1f*e2f) ( di[e2v vn] - dj[e1u un] )
169      !!         - apply lateral boundary conditions on rotn through a call
170      !!      of lbc_lnk routine.
171      !!         - Coastal boundary condition: 'key_noslip_accurate' defined,
172      !!      the no-slip boundary condition is computed using Schchepetkin
173      !!      and O'Brien (1996) scheme (i.e. 4th order at the coast).
174      !!      For example, along east coast, the one-sided finite difference
175      !!      approximation used for di[v] is:
176      !!         di[e2v vn] =  1/(e1f*e2f)
177      !!                    * ( (e2v vn)(i) + (e2v vn)(i-1) + (e2v vn)(i-2) )
178      !!
179      !! ** Action  : - update hdivb, hdivn, the before & now hor. divergence
180      !!              - update rotb , rotn , the before & now rel. vorticity
181      !!
182      !! History of the direct routine:
183      !!   8.2  !  00-03  (G. Madec)  no slip accurate
184      !!   9.0  !  03-08  (G. Madec)  merged of cur and div, free form, F90
185      !!        !  05-01  (J. Chanut, A. Sellar) unstructured open boundaries
186      !! History of the TAM routine:
187      !!   9.0  !  08-06  (A. Vidard) Skeleton
188      !!        !  08-07  (A. Weaver)
189      !!        !  08-11  (A. Vidard) Nemo v3
190      !!----------------------------------------------------------------------
191      !! * Arguments
192      INTEGER, INTENT( in ) :: &
193         & kt     ! ocean time-step index
194     
195      !! * Local declarations
196      INTEGER :: &
197         & ji,  & ! dummy loop indices
198         & jj,  &
199         & jk     
200      INTEGER :: &
201         & ii,  & ! temporary integer
202         & ij,  &
203         & jl,  &   
204         & ijt, &
205         & iju       
206      REAL(KIND=wp), DIMENSION(   jpi  ,1:jpj+2) :: &
207         & zwu    ! Workspace
208      REAL(KIND=wp), DIMENSION(-1:jpi+2,  jpj  ) :: &
209         & zwv    ! Workspace
210      !!----------------------------------------------------------------------
211
212      IF( kt == nit000 ) THEN
213         IF(lwp) WRITE(numout,*)
214         IF(lwp) WRITE(numout,*) 'div_cur_tan : horizontal velocity', & 
215            &                    ' divergence and relative vorticity'
216         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   NOT optimal for auto-tasking case'
217      ENDIF
218
219      !                                                ! ===============
220      DO jk = 1, jpkm1                                 ! Horizontal slab
221         !                                             ! ===============
222
223         hdivb_tl(:,:,jk) = hdivn_tl(:,:,jk)    ! time swap of div arrays
224         rotb_tl (:,:,jk) = rotn_tl (:,:,jk)    ! time swap of rot arrays
225
226         !                                             ! --------
227         ! Horizontal divergence                       !   div
228         !                                             ! --------
229         DO jj = 2, jpjm1
230            DO ji = fs_2, fs_jpim1   ! vector opt.
231#if defined key_zco
232               hdivn_tl(ji,jj,jk) = (   e2u(ji  ,jj  ) * un_tl(ji  ,jj  ,jk) &
233                  &                   - e2u(ji-1,jj  ) * un_tl(ji-1,jj  ,jk) &
234                  &                   + e1v(ji  ,jj  ) * vn_tl(ji  ,jj  ,jk) &
235                  &                   - e1v(ji  ,jj-1) * vn_tl(ji  ,jj-1,jk) &
236                  &                 ) / ( e1t(ji,jj) * e2t(ji,jj) )
237#else
238               hdivn_tl(ji,jj,jk) =   &
239                  & (   e2u(ji  ,jj  ) * fse3u(ji  ,jj  ,jk) * un_tl(ji  ,jj  ,jk) &
240                  &   - e2u(ji-1,jj  ) * fse3u(ji-1,jj  ,jk) * un_tl(ji-1,jj  ,jk) &
241                  &   + e1v(ji  ,jj  ) * fse3v(ji  ,jj  ,jk) * vn_tl(ji  ,jj  ,jk) &
242                  &   - e1v(ji  ,jj-1) * fse3v(ji  ,jj-1,jk) * vn_tl(ji  ,jj-1,jk) &
243                  & ) / ( e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) )
244#endif
245            END DO
246         END DO
247
248#if defined key_obc
249#if defined key_agrif
250         IF (Agrif_Root() ) THEN
251#endif
252         ! open boundaries (div must be zero behind the open boundary)
253         !  mpp remark: The zeroing of hdivn can probably be extended
254         !              to 1->jpi/jpj for the correct row/column
255         IF( lp_obc_east  ) hdivn_tl(nie0p1:nie1p1,nje0  :nje1  ,jk) = 0.0_wp  ! east
256         IF( lp_obc_west  ) hdivn_tl(niw0  :niw1  ,njw0  :njw1  ,jk) = 0.0_wp  ! west
257         IF( lp_obc_north ) hdivn_tl(nin0  :nin1  ,njn0p1:njn1p1,jk) = 0.0_wp  ! north
258         IF( lp_obc_south ) hdivn_tl(nis0  :nis1  ,njs0  :njs1  ,jk) = 0.0_wp  ! south
259#if defined key_agrif
260         ENDIF
261#endif
262#endif         
263#if defined key_bdy
264         ! unstructured open boundaries (div must be zero behind the open boundary)
265         DO jj = 1, jpj
266           DO ji = 1, jpi
267             hdivn_tl(ji,jj,jk)=hdivn_tl(ji,jj,jk)*bdytmask(ji,jj)
268           END DO
269         END DO
270#endif         
271#if defined key_agrif
272         if ( .NOT. AGRIF_Root() ) then
273           IF ((nbondi ==  1).OR.(nbondi == 2)) hdivn_tl(nlci-1 , :     ,jk) = 0.e0      ! east
274           IF ((nbondi == -1).OR.(nbondi == 2)) hdivn_tl(2      , :     ,jk) = 0.e0      ! west
275           IF ((nbondj ==  1).OR.(nbondj == 2)) hdivn_tl(:      ,nlcj-1 ,jk) = 0.e0      ! north
276           IF ((nbondj == -1).OR.(nbondj == 2)) hdivn_tl(:      ,2      ,jk) = 0.e0      ! south
277         endif
278#endif   
279
280         !                                             ! --------
281         ! relative vorticity                          !   rot
282         !                                             ! --------
283         ! contravariant velocity (extended for lateral b.c.)
284         ! inside the model domain
285         DO jj = 1, jpj
286            DO ji = 1, jpi
287               zwu(ji,jj) = e1u(ji,jj) * un_tl(ji,jj,jk)
288               zwv(ji,jj) = e2v(ji,jj) * vn_tl(ji,jj,jk)
289            END DO 
290         END DO 
291 
292         ! East-West boundary conditions
293         IF( nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN
294            zwv(  0  ,:) = zwv(jpi-2,:)
295            zwv( -1  ,:) = zwv(jpi-3,:)
296            zwv(jpi+1,:) = zwv(  3  ,:)
297            zwv(jpi+2,:) = zwv(  4  ,:)
298         ELSE
299            zwv(  0  ,:) = 0.0_wp
300            zwv( -1  ,:) = 0.0_wp
301            zwv(jpi+1,:) = 0.0_wp
302            zwv(jpi+2,:) = 0.0_wp
303         ENDIF
304
305         ! North-South boundary conditions
306         IF( nperio == 3 .OR. nperio == 4 ) THEN
307            ! north fold ( Grid defined with a T-point pivot) ORCA 2 degre
308            zwu(jpi,jpj+1) = 0.0_wp
309            zwu(jpi,jpj+2) = 0.0_wp
310            DO ji = 1, jpi-1
311               iju = jpi - ji + 1
312               zwu(ji,jpj+1) = - zwu(iju,jpj-3)
313               zwu(ji,jpj+2) = - zwu(iju,jpj-4)
314            END DO
315         ELSEIF( nperio == 5 .OR. nperio == 6 ) THEN
316            ! north fold ( Grid defined with a F-point pivot) ORCA 0.5 degre
317            zwu(jpi,jpj+1) = 0.0_wp
318            zwu(jpi,jpj+2) = 0.0_wp
319            DO ji = 1, jpi-1
320               iju = jpi - ji
321               zwu(ji,jpj  ) = - zwu(iju,jpj-1)
322               zwu(ji,jpj+1) = - zwu(iju,jpj-2)
323               zwu(ji,jpj+2) = - zwu(iju,jpj-3)
324            END DO
325            DO ji = -1, jpi+2
326               ijt = jpi - ji + 1
327               zwv(ji,jpj) = - zwv(ijt,jpj-2)
328            END DO
329            DO ji = jpi/2+1, jpi+2
330               ijt = jpi - ji + 1
331               zwv(ji,jpjm1) = - zwv(ijt,jpjm1)
332            END DO
333         ELSE
334            ! closed
335            zwu(:,jpj+1) = 0.0_wp
336            zwu(:,jpj+2) = 0.0_wp
337         ENDIF
338
339         ! relative vorticity (vertical component of the velocity curl)
340         DO jj = 1, jpjm1
341            DO ji = 1, fs_jpim1   ! vector opt.
342               rotn_tl(ji,jj,jk) = (  zwv(ji+1,jj  ) - zwv(ji,jj)      &
343                  &                 - zwu(ji  ,jj+1) + zwu(ji,jj)  )   &
344                  &         * fmask(ji,jj,jk) / ( e1f(ji,jj) * e2f(ji,jj) )
345            END DO
346         END DO
347
348         ! second order accurate scheme along straight coast
349         DO jl = 1, npcoa(1,jk)
350            ii = nicoa(jl,1,jk)
351            ij = njcoa(jl,1,jk)
352            rotn_tl(ii,ij,jk) =  1.0_wp / ( e1f(ii,ij) * e2f(ii,ij) )  &
353               & * ( + 4.0_wp * zwv(ii+1,ij) - zwv(ii+2,ij) + 0.2_wp * zwv(ii+3,ij) )
354         END DO
355         DO jl = 1, npcoa(2,jk)
356            ii = nicoa(jl,2,jk)
357            ij = njcoa(jl,2,jk)
358            rotn_tl(ii,ij,jk) =  1.0_wp / ( e1f(ii,ij) * e2f(ii,ij) )  &
359               & * ( - 4.0_wp * zwv(ii,ij)   + zwv(ii-1,ij) - 0.2_wp * zwv(ii-2,ij) )
360         END DO
361         DO jl = 1, npcoa(3,jk)
362            ii = nicoa(jl,3,jk)
363            ij = njcoa(jl,3,jk)
364            rotn_tl(ii,ij,jk) = -1.0_wp / ( e1f(ii,ij) * e2f(ii,ij) )  &
365               & * ( + 4.0_wp * zwu(ii,ij+1) - zwu(ii,ij+2) + 0.2_wp * zwu(ii,ij+3) )
366         END DO
367         DO jl = 1, npcoa(4,jk)
368            ii = nicoa(jl,4,jk)
369            ij = njcoa(jl,4,jk)
370            rotn_tl(ii,ij,jk) = -1.0_wp / ( e1f(ii,ij) * e2f(ii,ij) )  &
371               & * ( -4.0_wp * zwu(ii,ij)    + zwu(ii,ij-1) - 0.2_wp * zwu(ii,ij-2) )
372         END DO
373
374         !                                             ! ===============
375      END DO                                           !   End of slab
376      !                                                ! ===============
377     
378      ! 4. Lateral boundary conditions on hdivn and rotn
379      ! ---------------------------------=======---======
380      CALL lbc_lnk( hdivn_tl, 'T', 1.0_wp )   ! T-point, no sign change
381      CALL lbc_lnk( rotn_tl , 'F', 1.0_wp )   ! F-point, no sign change
382   
383   END SUBROUTINE div_cur_tan
384
385   SUBROUTINE div_cur_adj( kt )
386      !!----------------------------------------------------------------------
387      !!                  ***  ROUTINE div_cur_adj  ***
388      !!
389      !! ** Purpose of direct routine :
390      !!      compute the horizontal divergence and the relative
391      !!      vorticity at before and now time-step
392      !!
393      !! ** Method of direct routine :
394      !!      I.  divergence :
395      !!         - save the divergence computed at the previous time-step
396      !!      (note that the Asselin filter has not been applied on hdivb)
397      !!         - compute the now divergence given by :
398      !!         hdivn = 1/(e1t*e2t*e3t) ( di[e2u*e3u un] + dj[e1v*e3v vn] )
399      !!      Note: if lk_zco=T, e3u=e3v=e3t, they are simplified in the
400      !!      above expression
401      !!         - apply lateral boundary conditions on hdivn
402      !!      II. vorticity :
403      !!         - save the curl computed at the previous time-step
404      !!            rotb = rotn
405      !!      (note that the Asselin time filter has not been applied to rotb)
406      !!         - compute the now curl in tensorial formalism:
407      !!            rotn = 1/(e1f*e2f) ( di[e2v vn] - dj[e1u un] )
408      !!         - apply lateral boundary conditions on rotn through a call
409      !!      of lbc_lnk routine.
410      !!         - Coastal boundary condition: 'key_noslip_accurate' defined,
411      !!      the no-slip boundary condition is computed using Schchepetkin
412      !!      and O'Brien (1996) scheme (i.e. 4th order at the coast).
413      !!      For example, along east coast, the one-sided finite difference
414      !!      approximation used for di[v] is:
415      !!         di[e2v vn] =  1/(e1f*e2f)
416      !!                    * ( (e2v vn)(i) + (e2v vn)(i-1) + (e2v vn)(i-2) )
417      !!
418      !! ** Action  : - update hdivb, hdivn, the before & now hor. divergence
419      !!              - update rotb , rotn , the before & now rel. vorticity
420      !!
421      !! History of the direct routine:
422      !!   8.2  !  00-03  (G. Madec)  no slip accurate
423      !!   9.0  !  03-08  (G. Madec)  merged of cur and div, free form, F90
424      !! History of the TAM routine:
425      !!   9.0  !  08-06  (A. Vidard) Skeleton
426      !!   9.0  !  08-07  (A. Weaver)
427      !!----------------------------------------------------------------------
428      !! * Arguments
429      INTEGER, INTENT( in ) :: &
430         & kt     ! ocean time-step index
431     
432      !! * Local declarations
433      INTEGER :: &
434         & ji,  & ! dummy loop indices
435         & jj,  &
436         & jk     
437      INTEGER :: &
438         & ii,  & ! temporary integer
439         & ij,  &
440         & jl,  &   
441         & ijt, &
442         & iju       
443      REAL(wp) :: &
444         & zdiv, &
445         & zdju
446      REAL(KIND=wp), DIMENSION(   jpi  ,1:jpj+2) :: &
447         & zwu    ! Workspace
448      REAL(KIND=wp), DIMENSION(-1:jpi+2,  jpj  ) :: &
449         & zwv    ! Workspace
450      !!----------------------------------------------------------------------
451
452      IF( kt == nit000 ) THEN
453         IF(lwp) WRITE(numout,*)
454         IF(lwp) WRITE(numout,*) 'div_cur_adj : horizontal velocity', & 
455            &                    ' divergence and relative vorticity'
456         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   NOT optimal for auto-tasking case'
457      ENDIF
458
459      ! 4. Lateral boundary conditions on hdivn and rotn
460      ! ---------------------------------=======---======
461      CALL lbc_lnk_adj( rotn_ad , 'F', 1.0_wp )   ! F-point, no sign change
462      CALL lbc_lnk_adj( hdivn_ad, 'T', 1.0_wp )   ! T-point, no sign change
463
464      !                                                ! ===============
465      DO jk = jpkm1, 1, -1                             ! Horizontal slab
466         !                                             ! ===============
467
468         ! local adjoint workspace initialization
469         zwu(:,:) = 0.0_wp
470         zwv(:,:) = 0.0_wp
471
472         !                                             ! --------
473         ! relative vorticity                          !   rot
474         !                                             ! --------
475
476         DO jl = npcoa(4,jk), 1, -1
477            ii = nicoa(jl,4,jk)
478            ij = njcoa(jl,4,jk)
479            rotn_ad(ii,ij,jk) = -1.0_wp * rotn_ad(ii,ij,jk) &
480               &                / ( e1f(ii,ij) * e2f(ii,ij) )
481            zwu(ii,ij  ) = zwu(ii,ij  ) - 4.0_wp * rotn_ad(ii,ij,jk)
482            zwu(ii,ij-1) = zwu(ii,ij-1) +          rotn_ad(ii,ij,jk)
483            zwu(ii,ij-2) = zwu(ii,ij-2) - 0.2_wp * rotn_ad(ii,ij,jk)
484            rotn_ad(ii,ij,jk) = 0.0_wp
485         END DO
486         DO jl = npcoa(3,jk), 1, -1
487            ii = nicoa(jl,3,jk)
488            ij = njcoa(jl,3,jk)
489            rotn_ad(ii,ij,jk) = -1.0_wp * rotn_ad(ii,ij,jk) &
490               &                / ( e1f(ii,ij) * e2f(ii,ij) )
491            zwu(ii,ij+1) = zwu(ii,ij+1) + 4.0_wp * rotn_ad(ii,ij,jk)
492            zwu(ii,ij+2) = zwu(ii,ij+2) -          rotn_ad(ii,ij,jk)
493            zwu(ii,ij+3) = zwu(ii,ij+3) + 0.2_wp * rotn_ad(ii,ij,jk)
494            rotn_ad(ii,ij,jk) = 0.0_wp
495         END DO
496         DO jl = npcoa(2,jk), 1, -1
497            ii = nicoa(jl,2,jk)
498            ij = njcoa(jl,2,jk)
499            rotn_ad(ii,ij,jk) =  1.0_wp * rotn_ad(ii,ij,jk) &
500               &                / ( e1f(ii,ij) * e2f(ii,ij) )
501            zwv(ii  ,ij) = zwv(ii  ,ij) - 4.0_wp * rotn_ad(ii,ij,jk)
502            zwv(ii-1,ij) = zwv(ii-1,ij) +          rotn_ad(ii,ij,jk)
503            zwv(ii-2,ij) = zwv(ii-2,ij) - 0.2_wp * rotn_ad(ii,ij,jk)
504            rotn_ad(ii,ij,jk) = 0.0_wp
505         END DO
506         ! second order accurate scheme along straight coast
507         DO jl = npcoa(1,jk), 1, -1
508            ii = nicoa(jl,1,jk)
509            ij = njcoa(jl,1,jk)
510            rotn_ad(ii,ij,jk) =  1.0_wp * rotn_ad(ii,ij,jk) &
511               &                / ( e1f(ii,ij) * e2f(ii,ij) )
512            zwv(ii+1,ij) = zwv(ii+1,ij) + 4.0_wp * rotn_ad(ii,ij,jk)
513            zwv(ii+2,ij) = zwv(ii+2,ij) -          rotn_ad(ii,ij,jk)
514            zwv(ii+3,ij) = zwv(ii+3,ij) + 0.2_wp * rotn_ad(ii,ij,jk)
515            rotn_ad(ii,ij,jk) = 0.0_wp
516         END DO
517
518         ! relative vorticity (vertical component of the velocity curl)
519         DO jj = jpjm1, 1, -1
520            DO ji = fs_jpim1, 1, -1   ! vector opt.
521               rotn_ad(ji,jj,jk) = rotn_ad(ji,jj,jk) * fmask(ji,jj,jk) &
522                  &                / ( e1f(ji,jj) * e2f(ji,jj) )
523               zwv(ji  ,jj  ) = zwv(ji  ,jj  ) - rotn_ad(ji,jj,jk)
524               zwu(ji  ,jj  ) = zwu(ji  ,jj  ) + rotn_ad(ji,jj,jk)
525               zwu(ji  ,jj+1) = zwu(ji  ,jj+1) - rotn_ad(ji,jj,jk)
526               zwv(ji+1,jj  ) = zwv(ji+1,jj  ) + rotn_ad(ji,jj,jk)
527               rotn_ad(ji,jj,jk) = 0.0
528            END DO
529         END DO
530
531         ! North-South boundary conditions
532         IF( nperio == 3 .OR. nperio == 4 ) THEN
533            ! north fold ( Grid defined with a T-point pivot) ORCA 2 degree
534            DO ji = jpi-1, 1, -1
535               iju = jpi - ji + 1
536               zwu(iju,jpj-4) = zwu(iju,jpj-4) - zwu(ji,jpj+2)
537               zwu(ji ,jpj+2) = 0.0_wp
538               zwu(iju,jpj-3) = zwu(iju,jpj-3) - zwu(ji,jpj+1)
539               zwu(ji ,jpj+1) = 0.0_wp
540            END DO
541            zwu(jpi,jpj+2) = 0.0_wp
542            zwu(jpi,jpj+1) = 0.0_wp
543         ELSEIF( nperio == 5 .OR. nperio == 6 ) THEN
544            ! north fold ( Grid defined with a F-point pivot) ORCA 0.5 degree
545            DO ji = jpi+2, jpi/2+1, -1
546               ijt = jpi - ji + 1
547               zwv(ijt,jpjm1) = zwv(ijt,jpjm1) - zwv(ji,jpjm1)
548               zwv(ji ,jpjm1) = 0.0_wp
549            END DO
550            DO ji = jpi+2, -1, -1
551               ijt = jpi - ji + 1
552               zwv(ijt,jpj-2) = zwv(ijt,jpj-2) - zwv(ji,jpj  )
553               zwv(ji ,jpj  ) = 0.0_wp
554            END DO
555            DO ji = jpi-1, 1, -1
556               iju = jpi - ji
557               zwu(iju,jpj-3) = zwu(iju,jpj-3) - zwu(ji,jpj+2)
558               zwu(ji ,jpj+2) = 0.0_wp
559               zwu(iju,jpj-2) = zwu(iju,jpj-2) - zwu(ji,jpj+1)
560               zwu(ji ,jpj+1) = 0.0_wp
561               zwu(iju,jpj-1) = zwu(iju,jpj-1) - zwu(ji,jpj  )
562               zwu(ji ,jpj  ) = 0.0_wp
563            END DO
564            zwu(jpi,jpj+2) = 0.0_wp
565            zwu(jpi,jpj+1) = 0.0_wp
566         ELSE
567            ! closed
568            zwu(:,jpj+2) = 0.0_wp
569            zwu(:,jpj+1) = 0.0_wp
570         ENDIF
571
572         ! East-West boundary conditions
573         IF( nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN
574            zwv(  4  ,:) = zwv(  4  ,:) + zwv(jpi+2,:)
575            zwv(jpi+2,:) = 0.0_wp
576            zwv(  3  ,:) = zwv(  3  ,:) + zwv(jpi+1,:)
577            zwv(jpi+1,:) = 0.0_wp
578            zwv(jpi-3,:) = zwv(jpi-3,:) + zwv( -1  ,:)
579            zwv( -1  ,:) = 0.0_wp
580            zwv(jpi-2,:) = zwv(jpi-2,:) + zwv(  0  ,:)
581            zwv(  0  ,:) = 0.0_wp
582         ELSE
583            zwv(jpi+2,:) = 0.0_wp
584            zwv(jpi+1,:) = 0.0_wp
585            zwv( -1  ,:) = 0.0_wp
586            zwv(  0  ,:) = 0.0_wp
587         ENDIF
588
589         ! contravariant velocity (extended for lateral b.c.)
590         ! inside the model domain
591         DO jj = jpj, 1, -1
592            DO ji = jpi, 1, -1
593               vn_ad(ji,jj,jk) = vn_ad(ji,jj,jk) + e2v(ji,jj) * zwv(ji,jj)
594               un_ad(ji,jj,jk) = un_ad(ji,jj,jk) + e1u(ji,jj) * zwu(ji,jj)
595            END DO 
596         END DO 
597
598#if defined key_bdy
599         ! unstructured open boundaries (div must be zero behind the open boundary)
600         DO jj = 1, jpj
601           DO ji = 1, jpi
602             hdivn_ad(ji,jj,jk)=hdivn_ad(ji,jj,jk)*bdytmask(ji,jj)
603           END DO
604         END DO
605#endif         
606#if defined key_obc
607#if defined key_agrif
608         IF (Agrif_Root() ) THEN
609#endif
610         ! open boundaries (div must be zero behind the open boundary)
611         !  mpp remark: The zeroing of hdivn can probably be extended
612         !              to 1->jpi/jpj for the correct row/column
613         IF( lp_obc_east  ) hdivn_ad(nie0p1:nie1p1,nje0  :nje1  ,jk) = 0.0_wp  ! east
614         IF( lp_obc_west  ) hdivn_ad(niw0  :niw1  ,njw0  :njw1  ,jk) = 0.0_wp  ! west
615         IF( lp_obc_north ) hdivn_ad(nin0  :nin1  ,njn0p1:njn1p1,jk) = 0.0_wp  ! north
616         IF( lp_obc_south ) hdivn_ad(nis0  :nis1  ,njs0  :njs1  ,jk) = 0.0_wp  ! south
617#if defined key_agrif
618         ENDIF
619#endif
620#endif         
621
622         !                                             ! --------
623         ! Horizontal divergence                       !   div
624         !                                             ! --------
625         DO jj = jpjm1, 2, -1
626            DO ji = fs_jpim1, fs_2, -1   ! vector opt.
627#if defined key_zco
628               hdivn_ad(ji,jj,jk) =  hdivn_ad(ji,jj,jk)  &
629                  &                  / ( e1t(ji,jj) * e2t(ji,jj) )
630               un_ad(ji  ,jj  ,jk) = un_ad(ji  ,jj  ,jk) &
631                  &                  + e2u(ji  ,jj  ) * hdivn_ad(ji,jj,jk)
632               un_ad(ji-1,jj  ,jk) = un_ad(ji-1,jj  ,jk) &
633                  &                  - e2u(ji-1,jj  ) * hdivn_ad(ji,jj,jk)
634               vn_ad(ji  ,jj  ,jk) = vn_ad(ji  ,jj  ,jk) &
635                  &                  + e1v(ji  ,jj  ) * hdivn_ad(ji,jj,jk)
636               vn_ad(ji  ,jj-1,jk) = vn_ad(ji  ,jj-1,jk) &
637                  &                  - e1v(ji  ,jj-1) * hdivn_ad(ji,jj,jk)
638               hdivn_ad(ji,jj,jk) = 0.0_wp
639#else
640               hdivn_ad(ji,jj,jk) =  hdivn_ad(ji,jj,jk)  &
641                  &                  / ( e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) )
642               un_ad(ji  ,jj  ,jk) = un_ad(ji  ,jj  ,jk) &
643                  &                  + e2u(ji  ,jj  ) * fse3u(ji  ,jj  ,jk) &
644                  &                                   * hdivn_ad(ji,jj,jk)
645               un_ad(ji-1,jj  ,jk) = un_ad(ji-1,jj  ,jk) &
646                  &                  - e2u(ji-1,jj  ) * fse3u(ji-1,jj  ,jk) &
647                  &                                   * hdivn_ad(ji,jj,jk)
648               vn_ad(ji  ,jj  ,jk) = vn_ad(ji  ,jj  ,jk) & 
649                  &                  + e1v(ji  ,jj  ) * fse3v(ji  ,jj  ,jk) &
650                  &                                   * hdivn_ad(ji,jj,jk)
651               vn_ad(ji  ,jj-1,jk) = vn_ad(ji  ,jj-1,jk) & 
652                  &                  - e1v(ji  ,jj-1) * fse3v(ji  ,jj-1,jk) &
653                  &                                   * hdivn_ad(ji,jj,jk)
654               hdivn_ad(ji,jj,jk) = 0.0_wp
655#endif
656            END DO 
657         END DO 
658
659         rotn_ad (:,:,jk) = rotn_ad (:,:,jk) + rotb_ad (:,:,jk)  ! time swap
660         rotb_ad (:,:,jk) = 0.0_wp
661         hdivn_ad(:,:,jk) = hdivn_ad(:,:,jk) + hdivb_ad(:,:,jk)  ! time swap
662         hdivb_ad(:,:,jk) = 0.0_wp
663
664         !                                             ! ===============
665      END DO                                           !   End of slab
666      !                                                ! ===============
667
668   END SUBROUTINE div_cur_adj
669   
670#else
671   !!----------------------------------------------------------------------
672   !!   Default option                           2nd order centered schemes
673   !!----------------------------------------------------------------------
674
675   SUBROUTINE div_cur_tan( kt )
676      !!----------------------------------------------------------------------
677      !!                  ***  ROUTINE div_cur_tan  ***
678      !!                   
679      !! ** Purpose of direct routine :
680      !!      compute the horizontal divergence and the relative
681      !!      vorticity at before and now time-step
682      !!
683      !! ** Method of direct routine :
684      !!              - Divergence:
685      !!      - save the divergence computed at the previous time-step
686      !!      (note that the Asselin filter has not been applied on hdivb)
687      !!      - compute the now divergence given by :
688      !!         hdivn = 1/(e1t*e2t*e3t) ( di[e2u*e3u un] + dj[e1v*e3v vn] )
689      !!      Note: if lk_zco=T, e3u=e3v=e3t, they are simplified in the
690      !!      above expression
691      !!      - apply lateral boundary conditions on hdivn
692      !!              - Relavtive Vorticity :
693      !!      - save the curl computed at the previous time-step (rotb = rotn)
694      !!      (note that the Asselin time filter has not been applied to rotb)
695      !!      - compute the now curl in tensorial formalism:
696      !!            rotn = 1/(e1f*e2f) ( di[e2v vn] - dj[e1u un] )
697      !!      - apply lateral boundary conditions on rotn through a call to
698      !!      routine lbc_lnk routine.
699      !!      Note: Coastal boundary condition: lateral friction set through
700      !!      the value of fmask along the coast (see dommsk.F90) and shlat
701      !!      (namelist parameter)
702      !!
703      !! ** Action  : - update hdivb, hdivn, the before & now hor. divergence
704      !!              - update rotb , rotn , the before & now rel. vorticity
705      !!
706      !! History of the direct routine:
707      !!   1.0  !  87-06  (P. Andrich, D. L Hostis)  Original code
708      !!   4.0  !  91-11  (G. Madec)
709      !!   6.0  !  93-03  (M. Guyon)  symetrical conditions
710      !!   7.0  !  96-01  (G. Madec)  s-coordinates
711      !!   8.0  !  97-06  (G. Madec)  lateral boundary cond., lbc
712      !!   8.1  !  97-08  (J.M. Molines)  Open boundaries
713      !!   9.0  !  02-09  (G. Madec, E. Durand)  Free form, F90
714      !!        !  05-01  (J. Chanut) Unstructured open boundaries
715      !! History of the TAM routine:
716      !!   9.0  !  08-06  (A. Vidard) Skeleton
717      !!        !  08-07  (A. Weaver) tangent of the 02-09 version
718      !!        !  08-11  (A. Vidard) tangent of the 05-01 version
719      !!----------------------------------------------------------------------
720      !! * Arguments
721      INTEGER, INTENT( in ) :: &
722         & kt     ! ocean time-step index
723     
724      !! * Local declarations
725      INTEGER :: &
726         & ji,  & ! dummy loop indices
727         & jj,  &
728         & jk     
729      !!----------------------------------------------------------------------
730
731      IF( kt == nit000 ) THEN
732         IF(lwp) WRITE(numout,*)
733         IF(lwp) WRITE(numout,*) 'div_cur_tan : horizontal velocity divergence and'
734         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   relative vorticity'
735      ENDIF
736
737      !                                                ! ===============
738      DO jk = 1, jpkm1                                 ! Horizontal slab
739         !                                             ! ===============
740
741         hdivb_tl(:,:,jk) = hdivn_tl(:,:,jk)    ! time swap of div arrays
742         rotb_tl (:,:,jk) = rotn_tl (:,:,jk)    ! time swap of rot arrays
743
744         !                                             ! --------
745         ! Horizontal divergence                       !   div
746         !                                             ! --------
747         DO jj = 2, jpjm1
748            DO ji = fs_2, fs_jpim1   ! vector opt.
749#if defined key_zco
750               hdivn_tl(ji,jj,jk) = (   e2u(ji  ,jj  ) * un_tl(ji  ,jj  ,jk) &
751                  &                   - e2u(ji-1,jj  ) * un_tl(ji-1,jj  ,jk) &
752                  &                   + e1v(ji  ,jj  ) * vn_tl(ji  ,jj  ,jk) &
753                  &                   - e1v(ji  ,jj-1) * vn_tl(ji  ,jj-1,jk) &
754                  &                 ) / ( e1t(ji,jj) * e2t(ji,jj) )
755#else
756               hdivn_tl(ji,jj,jk) =   &
757                  & (   e2u(ji  ,jj  ) * fse3u(ji  ,jj  ,jk) * un_tl(ji  ,jj  ,jk) &
758                  &   - e2u(ji-1,jj  ) * fse3u(ji-1,jj  ,jk) * un_tl(ji-1,jj  ,jk) &
759                  &   + e1v(ji  ,jj  ) * fse3v(ji  ,jj  ,jk) * vn_tl(ji  ,jj  ,jk) &
760                  &   - e1v(ji  ,jj-1) * fse3v(ji  ,jj-1,jk) * vn_tl(ji  ,jj-1,jk) &
761                  & ) / ( e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) )
762#endif
763            END DO 
764         END DO
765
766#if defined key_obc
767#if defined key_agrif
768         IF ( Agrif_Root() ) THEN
769#endif
770         ! open boundaries (div must be zero behind the open boundary)
771         !  mpp remark: The zeroing of hdivn can probably be extended to 1->jpi/jpj for the correct row/column
772         IF( lp_obc_east  ) hdivn_tl(nie0p1:nie1p1,nje0  :nje1  ,jk) = 0.0_wp ! east
773         IF( lp_obc_west  ) hdivn_tl(niw0  :niw1  ,njw0  :njw1  ,jk) = 0.0_wp ! west
774         IF( lp_obc_north ) hdivn_tl(nin0  :nin1  ,njn0p1:njn1p1,jk) = 0.0_wp ! north
775         IF( lp_obc_south ) hdivn_tl(nis0  :nis1  ,njs0  :njs1  ,jk) = 0.0_wp ! south
776#if defined key_agrif
777         ENDIF
778#endif
779#endif         
780#if defined key_bdy
781         ! unstructured open boundaries (div must be zero behind the open boundary)
782         DO jj = 1, jpj
783           DO ji = 1, jpi
784             hdivn_tl(ji,jj,jk)=hdivn_tl(ji,jj,jk)*bdytmask(ji,jj)
785           END DO
786         END DO
787#endif       
788#if defined key_agrif
789         if ( .NOT. AGRIF_Root() ) then
790            IF ((nbondi ==  1).OR.(nbondi == 2)) hdivn_tl(nlci-1 , :     ,jk) = 0.e0      ! east
791            IF ((nbondi == -1).OR.(nbondi == 2)) hdivn_tl(2      , :     ,jk) = 0.e0      ! west
792            IF ((nbondj ==  1).OR.(nbondj == 2)) hdivn_tl(:      ,nlcj-1 ,jk) = 0.e0      ! north
793            IF ((nbondj == -1).OR.(nbondj == 2)) hdivn_tl(:      ,2      ,jk) = 0.e0      ! south
794         endif
795#endif   
796         !                                             ! --------
797         ! relative vorticity                          !   rot
798         !                                             ! --------
799         DO jj = 1, jpjm1
800            DO ji = 1, fs_jpim1   ! vector opt.
801               rotn_tl(ji,jj,jk) = (   e2v(ji+1,jj  ) * vn_tl(ji+1,jj  ,jk) &
802                  &                  - e2v(ji  ,jj  ) * vn_tl(ji  ,jj  ,jk) &
803                  &                  - e1u(ji  ,jj+1) * un_tl(ji  ,jj+1,jk) &
804                  &                  + e1u(ji  ,jj  ) * un_tl(ji  ,jj  ,jk) &
805                  &                ) * fmask(ji,jj,jk) / ( e1f(ji,jj) * e2f(ji,jj) )
806            END DO
807         END DO
808         !                                             ! ===============
809      END DO                                           !   End of slab
810      !                                                ! ===============
811     
812      ! 4. Lateral boundary conditions on hdivn and rotn
813      ! ---------------------------------=======---======
814      CALL lbc_lnk( hdivn_tl, 'T', 1.0_wp )     ! T-point, no sign change
815      CALL lbc_lnk( rotn_tl , 'F', 1.0_wp )     ! F-point, no sign change
816
817   END SUBROUTINE div_cur_tan
818
819   SUBROUTINE div_cur_adj( kt )
820      !!----------------------------------------------------------------------
821      !!                  ***  ROUTINE div_cur_adj  ***
822      !!                   
823      !! ** Purpose of direct routine :
824      !!      compute the horizontal divergence and the relative
825      !!      vorticity at before and now time-step
826      !!
827      !! ** Method of direct routine :
828      !!              - Divergence:
829      !!      - save the divergence computed at the previous time-step
830      !!      (note that the Asselin filter has not been applied on hdivb)
831      !!      - compute the now divergence given by :
832      !!         hdivn = 1/(e1t*e2t*e3t) ( di[e2u*e3u un] + dj[e1v*e3v vn] )
833      !!      Note: if lk_zco=T, e3u=e3v=e3t, they are simplified in the
834      !!      above expression
835      !!      - apply lateral boundary conditions on hdivn
836      !!              - Relavtive Vorticity :
837      !!      - save the curl computed at the previous time-step (rotb = rotn)
838      !!      (note that the Asselin time filter has not been applied to rotb)
839      !!      - compute the now curl in tensorial formalism:
840      !!            rotn = 1/(e1f*e2f) ( di[e2v vn] - dj[e1u un] )
841      !!      - apply lateral boundary conditions on rotn through a call to
842      !!      routine lbc_lnk routine.
843      !!      Note: Coastal boundary condition: lateral friction set through
844      !!      the value of fmask along the coast (see dommsk.F90) and shlat
845      !!      (namelist parameter)
846      !!
847      !! ** Action  : - update hdivb, hdivn, the before & now hor. divergence
848      !!              - update rotb , rotn , the before & now rel. vorticity
849      !!
850      !! History of the direct routine:
851      !!   1.0  !  87-06  (P. Andrich, D. L Hostis)  Original code
852      !!   4.0  !  91-11  (G. Madec)
853      !!   6.0  !  93-03  (M. Guyon)  symetrical conditions
854      !!   7.0  !  96-01  (G. Madec)  s-coordinates
855      !!   8.0  !  97-06  (G. Madec)  lateral boundary cond., lbc
856      !!   8.1  !  97-08  (J.M. Molines)  Open boundaries
857      !!   9.0  !  02-09  (G. Madec, E. Durand)  Free form, F90
858      !! History of the TAM routine:
859      !!   9.0  !  08-06  (A. Vidard) Skeleton
860      !!   9.0  !  08-07  (A. Weaver)
861      !!----------------------------------------------------------------------
862      !! * Arguments
863      INTEGER, INTENT( in ) :: &
864         & kt     ! ocean time-step index
865     
866      !! * Local declarations
867      INTEGER :: &
868         & ji,  & ! dummy loop indices
869         & jj,  &
870         & jk     
871      !!----------------------------------------------------------------------
872
873      IF( kt == nit000 ) THEN
874         IF(lwp) WRITE(numout,*)
875         IF(lwp) WRITE(numout,*) 'div_cur_adj : horizontal velocity divergence and'
876         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   relative vorticity'
877      ENDIF
878     
879      ! 4. Lateral boundary conditions on hdivn and rotn
880      ! ---------------------------------=======---======
881      CALL lbc_lnk_adj( rotn_ad , 'F', 1.0_wp )     ! F-point, no sign change
882      CALL lbc_lnk_adj( hdivn_ad, 'T', 1.0_wp )     ! T-point, no sign change
883
884      !                                                ! ===============
885      DO jk = jpkm1, 1, -1                             ! Horizontal slab
886         !                                             ! ===============
887
888         !                                             ! --------
889         ! relative vorticity                          !   rot
890         !                                             ! --------
891         DO jj = jpjm1, 1, -1
892            DO ji = fs_jpim1, 1, -1   ! vector opt.
893               rotn_ad(ji,jj,jk) =  rotn_ad(ji,jj,jk) * fmask(ji,jj,jk) &
894                  &                       / ( e1f(ji,jj) * e2f(ji,jj) )
895               un_ad(ji  ,jj  ,jk) = un_ad(ji  ,jj  ,jk) &
896                  &                  + e1u(ji  ,jj  ) * rotn_ad(ji,jj,jk)
897               un_ad(ji  ,jj+1,jk) = un_ad(ji  ,jj+1,jk) &
898                  &                  - e1u(ji  ,jj+1) * rotn_ad(ji,jj,jk)
899               vn_ad(ji  ,jj  ,jk) = vn_ad(ji  ,jj  ,jk) &
900                  &                  - e2v(ji  ,jj  ) * rotn_ad(ji,jj,jk)
901               vn_ad(ji+1,jj  ,jk) = vn_ad(ji+1,jj  ,jk) &
902                  &                  + e2v(ji+1,jj  ) * rotn_ad(ji,jj,jk)
903               rotn_ad(ji,jj,jk) = 0.0_wp
904            END DO
905         END DO
906
907#if defined key_bdy
908         ! unstructured open boundaries (div must be zero behind the open boundary)
909         DO jj = 1, jpj
910           DO ji = 1, jpi
911             hdivn_ad(ji,jj,jk)=hdivn_ad(ji,jj,jk)*bdytmask(ji,jj)
912           END DO
913         END DO
914#endif       
915#if defined key_obc
916         ! open boundaries (div must be zero behind the open boundary)
917         !  mpp remark: The zeroing of hdivn can probably be extended to 1->jpi/jpj for the correct row/column
918#if defined key_agrif
919         IF ( Agrif_Root() ) THEN
920#endif
921         IF( lp_obc_east  ) hdivn_ad(nie0p1:nie1p1,nje0  :nje1  ,jk) = 0.0_wp ! east
922         IF( lp_obc_west  ) hdivn_ad(niw0  :niw1  ,njw0  :njw1  ,jk) = 0.0_wp ! west
923         IF( lp_obc_north ) hdivn_ad(nin0  :nin1  ,njn0p1:njn1p1,jk) = 0.0_wp ! north
924         IF( lp_obc_south ) hdivn_ad(nis0  :nis1  ,njs0  :njs1  ,jk) = 0.0_wp ! south
925#if defined key_agrif
926         ENDIF
927#endif
928#endif         
929
930         !                                             ! --------
931         ! Horizontal divergence                       !   div
932         !                                             ! --------
933         DO jj = jpjm1, 2, -1
934            DO ji = fs_jpim1, fs_2, -1   ! vector opt.
935#if defined key_zco
936               hdivn_ad(ji,jj,jk) =  hdivn_ad(ji,jj,jk)  &
937                  &                  / ( e1t(ji,jj) * e2t(ji,jj) )
938               un_ad(ji  ,jj  ,jk) = un_ad(ji  ,jj  ,jk) &
939                  &                  + e2u(ji  ,jj  ) * hdivn_ad(ji,jj,jk)
940               un_ad(ji-1,jj  ,jk) = un_ad(ji-1,jj  ,jk) &
941                  &                  - e2u(ji-1,jj  ) * hdivn_ad(ji,jj,jk)
942               vn_ad(ji  ,jj  ,jk) = vn_ad(ji  ,jj  ,jk) &
943                  &                  + e1v(ji  ,jj  ) * hdivn_ad(ji,jj,jk)
944               vn_ad(ji  ,jj-1,jk) = vn_ad(ji  ,jj-1,jk) &
945                  &                  - e1v(ji  ,jj-1) * hdivn_ad(ji,jj,jk)
946               hdivn_ad(ji,jj,jk) = 0.0_wp
947#else
948               hdivn_ad(ji,jj,jk) =  hdivn_ad(ji,jj,jk)  &
949                  &                  / ( e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) )
950               un_ad(ji  ,jj  ,jk) = un_ad(ji  ,jj  ,jk) & 
951                  &                  + e2u(ji  ,jj  ) * fse3u(ji  ,jj  ,jk) &
952                  &                                   * hdivn_ad(ji,jj,jk)
953               un_ad(ji-1,jj  ,jk) = un_ad(ji-1,jj  ,jk) &
954                  &                  - e2u(ji-1,jj  ) * fse3u(ji-1,jj  ,jk) &
955                  &                                   * hdivn_ad(ji,jj,jk)
956               vn_ad(ji  ,jj  ,jk) = vn_ad(ji  ,jj  ,jk) &
957                  &                  + e1v(ji  ,jj  ) * fse3v(ji  ,jj  ,jk) &
958                  &                                   * hdivn_ad(ji,jj,jk)
959               vn_ad(ji  ,jj-1,jk) = vn_ad(ji  ,jj-1,jk) &
960                  &                  - e1v(ji  ,jj-1) * fse3v(ji  ,jj-1,jk) &
961                  &                                   * hdivn_ad(ji,jj,jk)
962               hdivn_ad(ji,jj,jk) = 0.0_wp
963#endif
964            END DO 
965         END DO 
966
967         rotn_ad (:,:,jk) = rotn_ad (:,:,jk) + rotb_ad (:,:,jk)  ! time swap
968         rotb_ad (:,:,jk) = 0.0_wp
969         hdivn_ad(:,:,jk) = hdivn_ad(:,:,jk) + hdivb_ad(:,:,jk)  ! time swap
970         hdivb_ad(:,:,jk) = 0.0_wp
971
972         !                                             ! ===============
973      END DO                                           !   End of slab
974      !                                                ! ===============
975
976   END SUBROUTINE div_cur_adj
977   
978#endif
979
980   SUBROUTINE div_cur_adj_tst( kumadt )
981      !!-----------------------------------------------------------------------
982      !!
983      !!          ***  ROUTINE div_cur_adj_tst : TEST OF div_cur_adj  ***
984      !!
985      !! ** Purpose : Test the adjoint routine.
986      !!
987      !! ** Method  : Verify the scalar product
988      !!           
989      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
990      !!
991      !!              where  L   = tangent routine
992      !!                     L^T = adjoint routine
993      !!                     W   = diagonal matrix of scale factors
994      !!                     dx  = input perturbation (random field)
995      !!                     dy  = L dx
996      !!
997      !! ** Action  : Separate tests are applied for the following dx and dy:
998      !!         
999      !!      1) dx = ( un_tl, vn_tl ) and
1000      !!         dy = ( hdivn_tl )
1001      !!      2) dx = ( un_tl, vn_tl ) and
1002      !!         dy = ( rotntl )
1003      !!
1004      !! History :
1005      !!        ! 08-07 (A. Weaver)
1006      !!-----------------------------------------------------------------------
1007
1008      !! * Modules used
1009      !! * Arguments
1010      INTEGER, INTENT(IN) :: &
1011         & kumadt             ! Output unit
1012
1013      INTEGER :: &
1014         & ji,    &        ! dummy loop indices
1015         & jj,    &       
1016         & jk     
1017      INTEGER, DIMENSION(jpi,jpj) :: &
1018         & iseed_2d        ! 2D seed for the random number generator
1019
1020      !! * Local declarations
1021      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
1022         & zun_tlin,     & ! Tangent input: now u-velocity
1023         & zvn_tlin,     & ! Tangent input: now v-velocity
1024         & zhdivn_tlin,  & ! Tangent input: now horizontal divergence
1025         & zrotn_tlin,   & ! Tangent input: now relative vorticity
1026         & zhdivb_tlout, & ! Tangent output: before horizontal divergence
1027         & zhdivn_tlout, & ! Tangent output: now horizontal divergence
1028         & zrotb_tlout,  & ! Tangent output: before relative vorticity
1029         & zrotn_tlout,  & ! Tangent output: now relative vorticity
1030         & zhdivb_adin,  & ! Adjoint input: before horizontal divergence
1031         & zhdivn_adin,  & ! Adjoint input: now horizontal divergence
1032         & zrotb_adin,   & ! Adjoint input: before relative vorticity
1033         & zrotn_adin,   & ! Adjoint input: now relative vorticity
1034         & zun_adout,    & ! Adjoint output: now u-velocity
1035         & zvn_adout,    & ! Adjoint output: now v-velocity
1036         & zhdivn_adout, & ! Adjoint output: now horizontal divergence
1037         & zrotn_adout,  & ! Adjoint output: now relative vorticity
1038         & znu,          & ! 3D random field for u
1039         & znv             ! 3D random field for v
1040
1041      REAL(KIND=wp) :: &
1042                           ! random field standard deviation for:
1043         & zsp1,         & ! scalar product involving the tangent routine
1044         & zsp1_1,       & !   scalar product components
1045         & zsp1_2,       & 
1046         & zsp2,         & ! scalar product involving the adjoint routine
1047         & zsp2_1,       & !   scalar product components
1048         & zsp2_2,       & 
1049         & zsp2_3
1050
1051      CHARACTER(LEN=14) :: cl_name
1052
1053      ! Allocate memory
1054
1055      ALLOCATE( &
1056         & zun_tlin(jpi,jpj,jpk),     &
1057         & zvn_tlin(jpi,jpj,jpk),     &
1058         & zhdivn_tlin(jpi,jpj,jpk),  &
1059         & zrotn_tlin(jpi,jpj,jpk),   &
1060         & zhdivb_tlout(jpi,jpj,jpk), &
1061         & zhdivn_tlout(jpi,jpj,jpk), &
1062         & zrotb_tlout(jpi,jpj,jpk),  &
1063         & zrotn_tlout(jpi,jpj,jpk),  &
1064         & zhdivb_adin(jpi,jpj,jpk),  &
1065         & zhdivn_adin(jpi,jpj,jpk),  &
1066         & zrotb_adin(jpi,jpj,jpk),   &
1067         & zrotn_adin(jpi,jpj,jpk),   &
1068         & zun_adout(jpi,jpj,jpk),    &
1069         & zvn_adout(jpi,jpj,jpk),    &
1070         & zhdivn_adout(jpi,jpj,jpk), &
1071         & zrotn_adout(jpi,jpj,jpk),  &
1072         & znu(jpi,jpj,jpk),          &
1073         & znv(jpi,jpj,jpk)           &
1074         & )
1075     
1076 
1077      !==================================================================
1078      ! 1) dx = ( un_tl, vn_tl, hdivn_tl ) and
1079      !    dy = ( hdivb_tl, hdivn_tl )
1080      !==================================================================
1081
1082      !--------------------------------------------------------------------
1083      ! Reset the tangent and adjoint variables
1084      !--------------------------------------------------------------------
1085
1086      zun_tlin    (:,:,:) = 0.0_wp
1087      zvn_tlin    (:,:,:) = 0.0_wp
1088      zhdivn_tlin (:,:,:) = 0.0_wp
1089      zrotn_tlin  (:,:,:) = 0.0_wp
1090      zhdivb_tlout(:,:,:) = 0.0_wp
1091      zhdivn_tlout(:,:,:) = 0.0_wp
1092      zrotb_tlout (:,:,:) = 0.0_wp
1093      zrotn_tlout (:,:,:) = 0.0_wp
1094      zhdivb_adin (:,:,:) = 0.0_wp
1095      zhdivn_adin (:,:,:) = 0.0_wp
1096      zrotb_adin  (:,:,:) = 0.0_wp
1097      zrotn_adin  (:,:,:) = 0.0_wp
1098      zrotn_adout (:,:,:) = 0.0_wp
1099      zhdivn_adout(:,:,:) = 0.0_wp
1100      zun_adout   (:,:,:) = 0.0_wp
1101      zvn_adout   (:,:,:) = 0.0_wp
1102
1103      un_tl   (:,:,:) = 0.0_wp
1104      vn_tl   (:,:,:) = 0.0_wp
1105      hdivb_tl(:,:,:) = 0.0_wp
1106      hdivn_tl(:,:,:) = 0.0_wp
1107      rotb_tl (:,:,:) = 0.0_wp
1108      rotn_tl (:,:,:) = 0.0_wp
1109      hdivb_ad(:,:,:) = 0.0_wp
1110      hdivn_ad(:,:,:) = 0.0_wp
1111      rotb_ad (:,:,:) = 0.0_wp
1112      rotn_ad (:,:,:) = 0.0_wp
1113      un_ad   (:,:,:) = 0.0_wp
1114      vn_ad   (:,:,:) = 0.0_wp
1115
1116      !--------------------------------------------------------------------
1117      ! Initialize the tangent input with random noise: dx
1118      !--------------------------------------------------------------------
1119
1120      DO jj = 1, jpj
1121         DO ji = 1, jpi
1122            iseed_2d(ji,jj) = - ( 596035 + &
1123               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
1124         END DO
1125      END DO
1126      CALL grid_random( iseed_2d, znu, 'U', 0.0_wp, stdu )
1127
1128      DO jj = 1, jpj
1129         DO ji = 1, jpi
1130            iseed_2d(ji,jj) = - ( 523432 + &
1131               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
1132         END DO
1133      END DO
1134      CALL grid_random( iseed_2d, znv, 'V', 0.0_wp, stdv )
1135
1136      DO jk = 1, jpk
1137         DO jj = nldj, nlej
1138            DO ji = nldi, nlei
1139               zun_tlin(ji,jj,jk) = znu(ji,jj,jk) 
1140               zvn_tlin(ji,jj,jk) = znv(ji,jj,jk) 
1141            END DO
1142         END DO
1143      END DO
1144
1145      un_tl(:,:,:) = zun_tlin(:,:,:)
1146      vn_tl(:,:,:) = zvn_tlin(:,:,:)
1147
1148      CALL div_cur_tan( nit000 )  ! Generate noise for before hdiv/rot fields
1149
1150      DO jk = 1, jpk
1151         DO jj = nldj, nlej
1152            DO ji = nldi, nlei
1153               zhdivn_tlin(ji,jj,jk) = 0.5_wp * hdivn_tl(ji,jj,jk) 
1154               zrotn_tlin (ji,jj,jk) = 0.5_wp * rotn_tl (ji,jj,jk) 
1155            END DO
1156         END DO
1157      END DO
1158
1159      un_tl   (:,:,:) = 0.0_wp
1160      vn_tl   (:,:,:) = 0.0_wp
1161      hdivb_tl(:,:,:) = 0.0_wp
1162      hdivn_tl(:,:,:) = 0.0_wp
1163      rotb_tl (:,:,:) = 0.0_wp
1164      rotn_tl (:,:,:) = 0.0_wp
1165
1166      !--------------------------------------------------------------------
1167      ! Call the tangent routine: dy = L dx
1168      !--------------------------------------------------------------------
1169
1170      un_tl   (:,:,:) = zun_tlin   (:,:,:)
1171      vn_tl   (:,:,:) = zvn_tlin   (:,:,:)
1172      hdivn_tl(:,:,:) = zhdivn_tlin(:,:,:)
1173
1174      CALL div_cur_tan( nit000 ) 
1175
1176      zhdivb_tlout(:,:,:) = hdivb_tl(:,:,:)
1177      zhdivn_tlout(:,:,:) = hdivn_tl(:,:,:)
1178
1179      !--------------------------------------------------------------------
1180      ! Initialize the adjoint variables: dy^* = W dy
1181      !--------------------------------------------------------------------
1182      DO jk = 1, jpk
1183        DO jj = nldj, nlej
1184           DO ji = nldi, nlei
1185              zhdivb_adin(ji,jj,jk) = zhdivb_tlout(ji,jj,jk) &
1186                 &               * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) &
1187                 &               * tmask(ji,jj,jk)
1188              zhdivn_adin(ji,jj,jk) = zhdivn_tlout(ji,jj,jk) &
1189                 &               * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) &
1190                 &               * tmask(ji,jj,jk)
1191            END DO
1192         END DO
1193      END DO
1194
1195      !--------------------------------------------------------------------
1196      ! Compute the scalar product: ( L dx )^T W dy
1197      !--------------------------------------------------------------------
1198
1199      zsp1_1 = DOT_PRODUCT( zhdivb_tlout, zhdivb_adin )
1200      zsp1_2 = DOT_PRODUCT( zhdivn_tlout, zhdivn_adin )
1201      zsp1   = zsp1_1 + zsp1_2
1202
1203      !--------------------------------------------------------------------
1204      ! Call the adjoint routine: dx^* = L^T dy^*
1205      !--------------------------------------------------------------------
1206
1207      hdivb_ad(:,:,:) = zhdivb_adin(:,:,:)
1208      hdivn_ad(:,:,:) = zhdivn_adin(:,:,:)
1209      rotb_ad (:,:,:) = 0.0_wp
1210      rotn_ad (:,:,:) = 0.0_wp
1211
1212      CALL div_cur_adj( nit000 )
1213
1214      zun_adout   (:,:,:) = un_ad   (:,:,:)
1215      zvn_adout   (:,:,:) = vn_ad   (:,:,:)
1216      zhdivn_adout(:,:,:) = hdivn_ad(:,:,:)
1217
1218      !--------------------------------------------------------------------
1219      ! Compute the scalar product: dx^T L^T W dy
1220      !--------------------------------------------------------------------
1221
1222      zsp2_1 = DOT_PRODUCT( zun_tlin,    zun_adout    )
1223      zsp2_2 = DOT_PRODUCT( zvn_tlin,    zvn_adout    )
1224      zsp2_3 = DOT_PRODUCT( zhdivn_tlin, zhdivn_adout )
1225      zsp2   = zsp2_1 + zsp2_2 + zsp2_3
1226
1227      cl_name = 'div_cur_adj T1'
1228      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
1229
1230      !=============================================================
1231      ! 2) dx = ( un_tl, vn_tl, rotn_tl ) and
1232      !    dy = ( rotb_tl, rotn_tl )
1233      !=============================================================
1234
1235      !--------------------------------------------------------------------
1236      ! Reset the tangent and adjoint variables
1237      !--------------------------------------------------------------------
1238
1239      un_tl   (:,:,:) = 0.0_wp
1240      vn_tl   (:,:,:) = 0.0_wp
1241      hdivb_tl(:,:,:) = 0.0_wp
1242      hdivn_tl(:,:,:) = 0.0_wp
1243      rotb_tl (:,:,:) = 0.0_wp
1244      rotn_tl (:,:,:) = 0.0_wp
1245      hdivb_ad(:,:,:) = 0.0_wp
1246      hdivn_ad(:,:,:) = 0.0_wp
1247      rotb_ad (:,:,:) = 0.0_wp
1248      rotn_ad (:,:,:) = 0.0_wp
1249      un_ad   (:,:,:) = 0.0_wp
1250      vn_ad   (:,:,:) = 0.0_wp
1251
1252      !--------------------------------------------------------------------
1253      ! Call the tangent routine: dy = L dx
1254      !--------------------------------------------------------------------
1255
1256      un_tl  (:,:,:) = zun_tlin  (:,:,:)
1257      vn_tl  (:,:,:) = zvn_tlin  (:,:,:)
1258      rotn_tl(:,:,:) = zrotn_tlin(:,:,:)
1259
1260      CALL div_cur_tan( nit000 ) 
1261
1262      zrotb_tlout(:,:,:) = rotb_tl(:,:,:)
1263      zrotn_tlout(:,:,:) = rotn_tl(:,:,:)
1264
1265      !--------------------------------------------------------------------
1266      ! Initialize the adjoint variables: dy^* = W dy
1267      !--------------------------------------------------------------------
1268
1269      DO jk = 1, jpk
1270        DO jj = nldj, nlej
1271           DO ji = nldi, nlei
1272              zrotb_adin(ji,jj,jk) = zrotb_tlout(ji,jj,jk) &
1273                 &               * e1f(ji,jj) * e2f(ji,jj) * fse3f(ji,jj,jk)
1274              zrotn_adin(ji,jj,jk) = zrotn_tlout(ji,jj,jk) &
1275                 &               * e1f(ji,jj) * e2f(ji,jj) * fse3f(ji,jj,jk)
1276            END DO
1277         END DO
1278      END DO
1279
1280      !--------------------------------------------------------------------
1281      ! Compute the scalar product: ( L dx )^T W dy
1282      !--------------------------------------------------------------------
1283
1284      zsp1_1 = DOT_PRODUCT( zrotb_tlout, zrotb_adin )
1285      zsp1_2 = DOT_PRODUCT( zrotn_tlout, zrotn_adin )
1286      zsp1   = zsp1_1 + zsp1_2
1287
1288      !--------------------------------------------------------------------
1289      ! Call the adjoint routine: dx^* = L^T dy^*
1290      !--------------------------------------------------------------------
1291
1292      rotb_ad (:,:,:) = zrotb_adin(:,:,:)
1293      rotn_ad (:,:,:) = zrotn_adin(:,:,:)
1294      hdivb_ad(:,:,:) = 0.0_wp
1295      hdivn_ad(:,:,:) = 0.0_wp
1296
1297      CALL div_cur_adj( nit000 )
1298
1299      zun_adout  (:,:,:) = un_ad  (:,:,:)
1300      zvn_adout  (:,:,:) = vn_ad  (:,:,:)
1301      zrotn_adout(:,:,:) = rotn_ad(:,:,:)
1302
1303      !--------------------------------------------------------------------
1304      ! Compute the scalar product: dx^T L^T W dy
1305      !--------------------------------------------------------------------
1306
1307      zsp2_1 = DOT_PRODUCT( zun_tlin,   zun_adout   )
1308      zsp2_2 = DOT_PRODUCT( zvn_tlin,   zvn_adout   )
1309      zsp2_3 = DOT_PRODUCT( zrotn_tlin, zrotn_adout )
1310      zsp2   = zsp2_1 + zsp2_2 + zsp2_3
1311
1312      cl_name = 'div_cur_adj T2'
1313      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
1314      DEALLOCATE( &
1315         & zun_tlin,     &
1316         & zvn_tlin,     &
1317         & zhdivn_tlin,  &
1318         & zrotn_tlin,   &
1319         & zhdivb_tlout, &
1320         & zhdivn_tlout, &
1321         & zrotb_tlout,  &
1322         & zrotn_tlout,  &
1323         & zhdivb_adin,  &
1324         & zhdivn_adin,  &
1325         & zrotb_adin,   &
1326         & zrotn_adin,   &
1327         & zun_adout,    &
1328         & zvn_adout,    &
1329         & zhdivn_adout, &
1330         & zrotn_adout,  &
1331         & znu,          &
1332         & znv           &
1333         & )
1334
1335   END SUBROUTINE div_cur_adj_tst
1336#endif
1337
1338   !!======================================================================
1339
1340END MODULE divcur_tam
Note: See TracBrowser for help on using the repository browser.