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

source: branches/TAM_V3_0/NEMOTAM/OPATAM_SRC/TRA/traadv_cen2_tam.F90 @ 2587

Last change on this file since 2587 was 2587, checked in by vidard, 13 years ago

refer to ticket #798

File size: 57.4 KB
Line 
1MODULE traadv_cen2_tam
2#if defined key_tam
3   !!======================================================================
4   !!                     ***  MODULE  traadv_cen2_tam  ***
5   !! Ocean active tracers:  horizontal & vertical advective trend
6   !!                         Tangent and Adjoint module
7   !!======================================================================
8   !! History of the direct module:   
9   !!             8.2  !  01-08  (G. Madec, E. Durand)  trahad+trazad=traadv
10   !!             8.5  !  02-06  (G. Madec)  F90: Free form and module
11   !!             9.0  !  04-08  (C. Talandier) New trends organization
12   !!             " "  !  05-11  (V. Garnier) Surface pressure gradient organization
13   !!             " "  !  06-04  (R. Benshila, G. Madec) Step reorganization
14   !!             " "  !  06-07  (G. madec)  add ups_orca_set routine
15   !! History of the T&A module
16   !!             9.0  !  08-12  (A. Vidard) original version
17   !!----------------------------------------------------------------------
18
19   !!----------------------------------------------------------------------
20   !!   tra_adv_cen2 : update the tracer trend with the horizontal and
21   !!                  vertical advection trends using a seconder order
22   !!   ups_orca_set : allow mixed upstream/centered scheme in specific
23   !!                  area (set for orca 2 and 4 only)
24   !!----------------------------------------------------------------------
25   USE par_kind      , ONLY: & ! Precision variables
26      & wp
27   USE par_oce       , ONLY: & ! Ocean space and time domain variables
28      & jpi,                 &
29      & jpj,                 & 
30      & jpk,                 &
31      & jpim1,               &
32      & jpjm1,               &
33      & jpkm1,               &
34      & jpiglo,              &
35      & jp_cfg
36   USE oce           , ONLY: & ! ocean dynamics and active tracers
37      & un,                  &
38      & vn,                  &
39      & tb, sb, &
40      & wn,                  &
41      & tn,                  &
42      & sn
43   USE oce_tam       , ONLY: & ! ocean dynamics and active tracers
44      & un_tl,               &
45      & vn_tl,               &
46      & tb_tl, sb_tl, &
47      & wn_tl,               &
48      & tn_tl,               &
49      & sn_tl,               &
50      & ta_tl,               &
51      & sa_tl,               &
52      & tn_ad,               &
53      & sn_ad,               &
54      & ta_ad,               &
55      & sa_ad 
56   USE dom_oce       , ONLY: & ! ocean space and time domain
57      & tmask,               &
58      & e1t,                 &
59      & e2t,                 &
60      & e2u,                 &
61      & e1v,                 &
62# if defined key_vvl
63      & e3t_1,               &
64# else
65#  if defined key_zco
66      & e3t_0,               &
67#  else
68      & e3t,                 &
69#  endif
70# endif
71# if defined key_zco
72      & e3t_0,               &
73# else
74      & e3u,                 &
75      & e3v,                 &
76# endif
77      & lk_vvl,              &   
78      & tmask,               &
79      & mig,                 &
80      & mjg,                 &
81      & nldi,                &
82      & nldj,                &
83      & nlei,                &
84      & nlej
85   USE gridrandom    , ONLY: & ! Random Gaussian noise on grids
86      & grid_random
87   USE dotprodfld    , ONLY: & ! Computes dot product for 3D and 2D fields
88      & dot_product
89
90!   USE sbc_oce         ! surface boundary condition: ocean
91   USE dynspg_oce    , ONLY: & ! choice/control of key cpp for surface pressure gradient
92      & lk_dynspg_rl
93!   USE eosbn2          ! equation of state
94!   USE trdmod          ! ocean active tracers trends
95!   USE closea          ! closed sea
96!   USE trabbl          ! advective term in the BBL
97!   USE sbcmod          ! surface Boundary Condition
98!   USE sbcrnf          ! river runoffs
99   USE in_out_manager, ONLY: & ! I/O manager
100      & lwp,                 &
101      & numout,              & 
102      & nitend,              & 
103      & nit000
104!   USE lib_mpp
105!   USE lbclnk          ! ocean lateral boundary condition (or mpp link)
106!   USE diaptr          ! poleward transport diagnostics
107!   USE prtctl          ! Print control
108   USE zdf_oce       , ONLY: & ! ocean vertical physics
109      & avmb,                &
110      & avtb
111   USE tstool_tam    , ONLY: &
112      & prntst_adj,          &    !
113      & prntst_tlm,          &    !
114      & stdu,                &    ! stdev for u-velocity
115      & stdv,                &    ! stdev for v-velocity
116      & stdw,                &    ! stdev for w-velocity
117      & stdt,                &    ! stdev for temperature
118      & stds                      !           salinity
119   USE paresp        , ONLY: &
120      & wesp_t,              &
121      & wesp_s
122
123   IMPLICIT NONE
124   PRIVATE
125
126   PUBLIC   tra_adv_cen2_tan    ! routine called by traadv_tam.F90
127   PUBLIC   tra_adv_cen2_adj    ! routine called by traadv_tam.F90
128   PUBLIC   tra_adv_cen2_adj_tst! routine called by tst.F90
129#if defined key_tst_tlm
130   PUBLIC   tra_adv_cen2_tlm_tst! routine called by tamtst.F90
131#endif
132
133   REAL(wp), DIMENSION(jpi,jpj) ::  &
134     & btr2   ! inverse of T-point surface [1/(e1t*e2t)]
135
136   !! * Substitutions
137#  include "domzgr_substitute.h90"
138#  include "vectopt_loop_substitute.h90"
139   !!----------------------------------------------------------------------
140   !!   OPA 9.0 , LOCEAN-IPSL (2006)
141   !! $Id: traadv_cen2.F90 1201 2008-09-24 13:24:21Z rblod $
142   !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
143   !!----------------------------------------------------------------------
144
145CONTAINS
146
147   SUBROUTINE tra_adv_cen2_tan( kt, pun, pvn, pwn, pun_tl, pvn_tl, pwn_tl )
148      !!----------------------------------------------------------------------
149      !!                  ***  ROUTINE tra_adv_cen2_tan  ***
150      !!                 
151      !! ** Purpose of the direct routine:
152      !!      Compute the now trend due to the advection of tracers
153      !!      and add it to the general trend of passive tracer equations.
154      !!
155      !! ** Method  :   The advection is evaluated by a second order centered
156      !!      scheme using now fields (leap-frog scheme). In specific areas
157      !!      (vicinity of major river mouths, some straits, or where tn is
158      !!      approaching the freezing point) it is mixed with an upstream
159      !!      scheme for stability reasons.
160      !!         Part 0 : compute the upstream / centered flag
161      !!                  (3D array, zind, defined at T-point (0<zind<1))
162      !!         Part I : horizontal advection
163      !!       * centered flux:
164      !!               zcenu = e2u*e3u  un  mi(tn)
165      !!               zcenv = e1v*e3v  vn  mj(tn)
166      !!       * upstream flux:
167      !!               zupsu = e2u*e3u  un  (tb(i) or tb(i-1) ) [un>0 or <0]
168      !!               zupsv = e1v*e3v  vn  (tb(j) or tb(j-1) ) [vn>0 or <0]
169      !!       * mixed upstream / centered horizontal advection scheme
170      !!               zcofi = max(zind(i+1), zind(i))
171      !!               zcofj = max(zind(j+1), zind(j))
172      !!               zwx = zcofi * zupsu + (1-zcofi) * zcenu
173      !!               zwy = zcofj * zupsv + (1-zcofj) * zcenv
174      !!       * horizontal advective trend (divergence of the fluxes)
175      !!               zta = 1/(e1t*e2t*e3t) { di-1[zwx] + dj-1[zwy] }
176      !!       * Add this trend now to the general trend of tracer (ta,sa):
177      !!              (ta,sa) = (ta,sa) + ( zta , zsa )
178      !!       * trend diagnostic ('key_trdtra' defined): the trend is
179      !!      saved for diagnostics. The trends saved is expressed as
180      !!      Uh.gradh(T), i.e.
181      !!                     save trend = zta + tn divn
182      !!         In addition, the advective trend in the two horizontal direc-
183      !!      tion is also re-computed as Uh gradh(T). Indeed hadt+tn divn is
184      !!      equal to (in s-coordinates, and similarly in z-coord.):
185      !!         zta+tn*divn=1/(e1t*e2t*e3t) { mi-1( e2u*e3u  un  di[tn] )
186      !!                                      +mj-1( e1v*e3v  vn  mj[tn] )  }
187      !!         NB:in z-coordinate - full step (ln_zco=T) e3u=e3v=e3t, so
188      !!      they vanish from the expression of the flux and divergence.
189      !!
190      !!         Part II : vertical advection
191      !!      For temperature (idem for salinity) the advective trend is com-
192      !!      puted as follows :
193      !!            zta = 1/e3t dk+1[ zwz ]
194      !!      where the vertical advective flux, zwz, is given by :
195      !!            zwz = zcofk * zupst + (1-zcofk) * zcent
196      !!      with
197      !!        zupsv = upstream flux = wn * (tb(k) or tb(k-1) ) [wn>0 or <0]
198      !!        zcenu = centered flux = wn * mk(tn)
199      !!         The surface boundary condition is :
200      !!      rigid-lid (lk_dynspg_frd = T) : zero advective flux
201      !!      free-surf (lk_dynspg_fsc = T) : wn(:,:,1) * tn(:,:,1)
202      !!         Add this trend now to the general trend of tracer (ta,sa):
203      !!            (ta,sa) = (ta,sa) + ( zta , zsa )
204      !!         Trend diagnostic ('key_trdtra' defined): the trend is
205      !!      saved for diagnostics. The trends saved is expressed as :
206      !!             save trend =  w.gradz(T) = zta - tn divn.
207      !!
208      !! ** Action :  - update (ta,sa) with the now advective tracer trends
209      !!              - save trends in (ztrdt,ztrds) ('key_trdtra')
210      !!----------------------------------------------------------------------
211      USE oce_tam, ONLY :   zwxtl => ua_tl   ! use ua as workspace
212      USE oce_tam, ONLY :   zwytl => va_tl   ! use va as workspace
213      !!
214      INTEGER , INTENT(in)                         ::   kt    ! ocean time-step index
215      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pun_tl   ! ocean velocity u-component
216      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pvn_tl   ! ocean velocity v-component
217      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pwn_tl   ! ocean velocity w-component
218      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pun      ! ocean velocity u-component
219      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pvn      ! ocean velocity v-component
220      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pwn      ! ocean velocity w-component
221      !!
222      INTEGER  ::   ji, jj, jk                           ! dummy loop indices
223      REAL(wp) ::   ztatl, zsatl, zbtr, zhw, zhwtl,   &  ! temporary scalars
224         &          ze3tr, zfui  , zfuitl  ,          &  !    "         "
225         &          zfvj  , zfvjtl                       !    "         "
226      REAL(wp) ::   zice                                 !    -         -
227      REAL(wp), DIMENSION(jpi,jpj)     ::   ztfreez            ! 2D workspace
228      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwwtl, zwztl       ! 3D workspace
229      !!----------------------------------------------------------------------
230      IF( kt == nit000 ) THEN
231         IF(lwp) WRITE(numout,*)
232         IF(lwp) WRITE(numout,*) 'tra_adv_cen2_tam : 2nd order centered advection scheme'
233         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~   Vector optimization case'
234         IF(lwp) WRITE(numout,*)
235         !
236         !   
237         btr2(:,:) = 1. / ( e1t(:,:) * e2t(:,:) )        ! inverse of T-point surface
238            IF ( jp_cfg == 2 ) THEN
239            !   Increase the background in the surface layers
240               avmb(1) = 10.  * avmb(1)      ;      avtb(1) = 10.  * avtb(1)
241               avmb(2) = 10.  * avmb(2)      ;      avtb(2) = 10.  * avtb(2)
242               avmb(3) =  5.  * avmb(3)      ;      avtb(3) =  5.  * avtb(3)
243               avmb(4) =  2.5 * avmb(4)      ;      avtb(4) =  2.5 * avtb(4)
244            ENDIF
245      ENDIF
246
247      ! I. Horizontal advective fluxes
248      ! ------------------------------
249      !  Second order centered tracer flux at u and v-points
250      ! -----------------------------------------------------
251      !                                                ! ===============
252      DO jk = 1, jpkm1                                 ! Horizontal slab
253         !                                             ! ===============
254         DO jj = 1, jpjm1
255            DO ji = 1, fs_jpim1   ! vector opt.
256               ! volume fluxes * 1/2
257#if defined key_zco
258               zfuitl = 0.5 * e2u(ji,jj) * pun_tl(ji,jj,jk)
259               zfvjtl = 0.5 * e1v(ji,jj) * pvn_tl(ji,jj,jk)
260               zfui = 0.5 * e2u(ji,jj) * pun(ji,jj,jk)
261               zfvj = 0.5 * e1v(ji,jj) * pvn(ji,jj,jk)
262#else
263               zfuitl = 0.5 * e2u(ji,jj) * fse3u(ji,jj,jk) * pun_tl(ji,jj,jk)
264               zfvjtl = 0.5 * e1v(ji,jj) * fse3v(ji,jj,jk) * pvn_tl(ji,jj,jk)
265               zfui = 0.5 * e2u(ji,jj) * fse3u(ji,jj,jk) * pun(ji,jj,jk)
266               zfvj = 0.5 * e1v(ji,jj) * fse3v(ji,jj,jk) * pvn(ji,jj,jk)
267#endif
268               ! centered scheme
269               zwxtl(ji,jj,jk) = zfuitl * ( tn(ji,jj,jk) + tn(ji+1,jj,jk) ) &
270                  &            + zfui * ( tn_tl(ji,jj,jk) + tn_tl(ji+1,jj,jk) )
271               zwytl(ji,jj,jk) = zfvjtl * ( tn(ji,jj,jk) + tn(ji,jj+1,jk) ) &
272                  &            + zfvj * ( tn_tl(ji,jj,jk) + tn_tl(ji,jj+1,jk) )
273               zwwtl(ji,jj,jk) = zfuitl * ( sn(ji,jj,jk) + sn(ji+1,jj,jk) ) &
274                  &            + zfui * ( sn_tl(ji,jj,jk) + sn_tl(ji+1,jj,jk) )
275               zwztl(ji,jj,jk) = zfvjtl * ( sn(ji,jj,jk) + sn(ji,jj+1,jk) ) &
276                  &            + zfvj * ( sn_tl(ji,jj,jk) + sn_tl(ji,jj+1,jk) )
277            END DO
278         END DO
279
280         !  Tracer flux divergence at t-point added to the general trend
281         ! --------------------------------------------------------------
282         DO jj = 2, jpjm1
283            DO ji = fs_2, fs_jpim1   ! vector opt.
284#if defined key_zco
285               zbtr = btr2(ji,jj)
286#else
287               zbtr = btr2(ji,jj) / fse3t(ji,jj,jk)
288#endif
289               ! horizontal advective trends
290               ztatl = - zbtr * (  zwxtl(ji,jj,jk) - zwxtl(ji-1,jj  ,jk)   &
291                  &            + zwytl(ji,jj,jk) - zwytl(ji  ,jj-1,jk)  )
292               zsatl = - zbtr * (  zwwtl(ji,jj,jk) - zwwtl(ji-1,jj  ,jk)   &
293                  &            + zwztl(ji,jj,jk) - zwztl(ji  ,jj-1,jk)  )
294               ! add it to the general tracer trends
295               ta_tl(ji,jj,jk) = ta_tl(ji,jj,jk) + ztatl
296               sa_tl(ji,jj,jk) = sa_tl(ji,jj,jk) + zsatl
297            END DO
298         END DO
299         !                                             ! ===============
300      END DO                                           !   End of slab
301      !                                                ! ===============
302
303      ! "zonal" mean advective heat and salt transport
304      ! ----------------------------------------------
305
306!      IF( ln_diaptr .AND. ( MOD( kt, nf_ptr ) == 0 ) ) THEN
307!         IF( lk_zco ) THEN
308!            DO jk = 1, jpkm1
309!               DO jj = 2, jpjm1
310!                  DO ji = fs_2, fs_jpim1   ! vector opt.
311!                    zwytl(ji,jj,jk) = zwytl(ji,jj,jk) * fse3v(ji,jj,jk)
312!                    zwztl(ji,jj,jk) = zwztl(ji,jj,jk) * fse3v(ji,jj,jk)
313!                  END DO
314!               END DO
315!            END DO
316!         ENDIF
317!         pht_adv(:) = ptr_vj( zwy(:,:,:) )
318!         pst_adv(:) = ptr_vj( zwz(:,:,:) )
319!      ENDIF
320
321      ! II. Vertical advection
322      ! ----------------------
323
324      ! Bottom value : flux set to zero
325      zwxtl(:,:,jpk) = 0.e0     ;    zwytl(:,:,jpk) = 0.e0
326
327      ! Surface value
328      IF( lk_dynspg_rl .OR. lk_vvl ) THEN
329         ! rigid lid or variable volume: flux set to zero
330         zwxtl(:,:, 1 ) = 0.e0    ;    zwytl(:,:, 1 ) = 0.e0
331      ELSE
332         ! free surface
333         zwxtl(:,:, 1 ) = pwn_tl(:,:,1) * tn(:,:,1) + pwn(:,:,1) * tn_tl(:,:,1)
334         zwytl(:,:, 1 ) = pwn_tl(:,:,1) * sn(:,:,1) + pwn(:,:,1) * sn_tl(:,:,1)
335      ENDIF
336
337      ! 1. Vertical advective fluxes
338      ! ----------------------------
339      ! Second order centered tracer flux at w-point
340      DO jk = 2, jpk
341         DO jj = 2, jpjm1
342            DO ji = fs_2, fs_jpim1   ! vector opt.
343               ! velocity * 1/2
344               zhwtl = 0.5 * pwn_tl(ji,jj,jk)
345               zhw   = 0.5 * pwn(   ji,jj,jk)
346               ! centered scheme
347               zwxtl(ji,jj,jk) = zhwtl * ( tn( ji,jj,jk) + tn(   ji,jj,jk-1) ) &
348                  &            + zhw * ( tn_tl(ji,jj,jk) + tn_tl(ji,jj,jk-1) )
349               zwytl(ji,jj,jk) = zhwtl * ( sn( ji,jj,jk) + sn(   ji,jj,jk-1) ) &
350                  &            + zhw * ( sn_tl(ji,jj,jk) + sn_tl(ji,jj,jk-1) )
351            END DO
352         END DO
353      END DO
354
355      ! 2. Tracer flux divergence at t-point added to the general trend
356      ! -------------------------
357      DO jk = 1, jpkm1
358         DO jj = 2, jpjm1
359            DO ji = fs_2, fs_jpim1   ! vector opt.
360               ze3tr = 1. / fse3t(ji,jj,jk)
361               ! vertical advective trends
362               ztatl = - ze3tr * ( zwxtl(ji,jj,jk) - zwxtl(ji,jj,jk+1) )
363               zsatl = - ze3tr * ( zwytl(ji,jj,jk) - zwytl(ji,jj,jk+1) )
364               ! add it to the general tracer trends
365               ta_tl(ji,jj,jk) = ta_tl(ji,jj,jk) + ztatl
366               sa_tl(ji,jj,jk) = sa_tl(ji,jj,jk) + zsatl
367            END DO
368         END DO
369      END DO
370
371
372      !
373   END SUBROUTINE tra_adv_cen2_tan
374   
375   SUBROUTINE tra_adv_cen2_adj( kt, pun, pvn, pwn, pun_ad, pvn_ad, pwn_ad )
376      !!----------------------------------------------------------------------
377      !!                  ***  ROUTINE tra_adv_cen2_adj  ***
378      !!                 
379      !! ** Purpose of the direct routine:
380      !!      Compute the now trend due to the advection of tracers
381      !!      and add it to the general trend of passive tracer equations.
382      !!
383      !! ** Method  :   The advection is evaluated by a second order centered
384      !!      scheme using now fields (leap-frog scheme). In specific areas
385      !!      (vicinity of major river mouths, some straits, or where tn is
386      !!      approaching the freezing point) it is mixed with an upstream
387      !!      scheme for stability reasons.
388      !!         Part 0 : compute the upstream / centered flag
389      !!                  (3D array, zind, defined at T-point (0<zind<1))
390      !!         Part I : horizontal advection
391      !!       * centered flux:
392      !!               zcenu = e2u*e3u  un  mi(tn)
393      !!               zcenv = e1v*e3v  vn  mj(tn)
394      !!       * upstream flux:
395      !!               zupsu = e2u*e3u  un  (tb(i) or tb(i-1) ) [un>0 or <0]
396      !!               zupsv = e1v*e3v  vn  (tb(j) or tb(j-1) ) [vn>0 or <0]
397      !!       * mixed upstream / centered horizontal advection scheme
398      !!               zcofi = max(zind(i+1), zind(i))
399      !!               zcofj = max(zind(j+1), zind(j))
400      !!               zwx = zcofi * zupsu + (1-zcofi) * zcenu
401      !!               zwy = zcofj * zupsv + (1-zcofj) * zcenv
402      !!       * horizontal advective trend (divergence of the fluxes)
403      !!               zta = 1/(e1t*e2t*e3t) { di-1[zwx] + dj-1[zwy] }
404      !!       * Add this trend now to the general trend of tracer (ta,sa):
405      !!              (ta,sa) = (ta,sa) + ( zta , zsa )
406      !!       * trend diagnostic ('key_trdtra' defined): the trend is
407      !!      saved for diagnostics. The trends saved is expressed as
408      !!      Uh.gradh(T), i.e.
409      !!                     save trend = zta + tn divn
410      !!         In addition, the advective trend in the two horizontal direc-
411      !!      tion is also re-computed as Uh gradh(T). Indeed hadt+tn divn is
412      !!      equal to (in s-coordinates, and similarly in z-coord.):
413      !!         zta+tn*divn=1/(e1t*e2t*e3t) { mi-1( e2u*e3u  un  di[tn] )
414      !!                                      +mj-1( e1v*e3v  vn  mj[tn] )  }
415      !!         NB:in z-coordinate - full step (ln_zco=T) e3u=e3v=e3t, so
416      !!      they vanish from the expression of the flux and divergence.
417      !!
418      !!         Part II : vertical advection
419      !!      For temperature (idem for salinity) the advective trend is com-
420      !!      puted as follows :
421      !!            zta = 1/e3t dk+1[ zwz ]
422      !!      where the vertical advective flux, zwz, is given by :
423      !!            zwz = zcofk * zupst + (1-zcofk) * zcent
424      !!      with
425      !!        zupsv = upstream flux = wn * (tb(k) or tb(k-1) ) [wn>0 or <0]
426      !!        zcenu = centered flux = wn * mk(tn)
427      !!         The surface boundary condition is :
428      !!      rigid-lid (lk_dynspg_frd = T) : zero advective flux
429      !!      free-surf (lk_dynspg_fsc = T) : wn(:,:,1) * tn(:,:,1)
430      !!         Add this trend now to the general trend of tracer (ta,sa):
431      !!            (ta,sa) = (ta,sa) + ( zta , zsa )
432      !!         Trend diagnostic ('key_trdtra' defined): the trend is
433      !!      saved for diagnostics. The trends saved is expressed as :
434      !!             save trend =  w.gradz(T) = zta - tn divn.
435      !!
436      !! ** Action :  - update (ta,sa) with the now advective tracer trends
437      !!              - save trends in (ztrdt,ztrds) ('key_trdtra')
438      !!----------------------------------------------------------------------
439      USE oce_tam, ONLY :   zwxad => ua_ad   ! use ua as workspace
440      USE oce_tam, ONLY :   zwyad => va_ad   ! use va as workspace
441      !!
442      INTEGER , INTENT(in)                         ::   kt    ! ocean time-step index
443      REAL(wp), INTENT(inout), DIMENSION(jpi,jpj,jpk) ::   pun_ad   ! ocean velocity u-component
444      REAL(wp), INTENT(inout), DIMENSION(jpi,jpj,jpk) ::   pvn_ad   ! ocean velocity v-component
445      REAL(wp), INTENT(inout), DIMENSION(jpi,jpj,jpk) ::   pwn_ad   ! ocean velocity w-component
446      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pun      ! ocean velocity u-component
447      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pvn      ! ocean velocity v-component
448      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pwn      ! ocean velocity w-component
449      !!
450      INTEGER  ::   ji, jj, jk                           ! dummy loop indices
451      REAL(wp) ::   ztaad, zsaad, zbtr, zhw, zhwad,   &  ! temporary scalars
452         &          ze3tr, zfui  , zfuiad  ,          &  !    "         "
453         &          zfvj  , zfvjad                       !    "         "
454      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwwad, zwzad       ! 3D workspace
455      !!----------------------------------------------------------------------
456      ztaad = 0.0_wp  ;  zsaad = 0.0_wp  ;  zhwad = 0.0_wp  ;  zfuiad = 0.0_wp  ;  zfvjad = 0.0_wp
457      zwxad(:,:,:) = 0.0_wp  ;  zwyad(:,:,:) = 0.0_wp  ;  zwwad(:,:,:) = 0.0_wp  ;  zwzad(:,:,:) = 0.0_wp
458
459      IF( kt == nitend ) THEN
460         IF(lwp) WRITE(numout,*)
461         IF(lwp) WRITE(numout,*) 'tra_adv_cen2_tam : 2nd order centered advection scheme'
462         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~   Vector optimization case'
463         IF(lwp) WRITE(numout,*)
464         !
465         !   
466         btr2(:,:) = 1. / ( e1t(:,:) * e2t(:,:) )        ! inverse of T-point surface
467            IF ( jp_cfg == 2 ) THEN
468            !   Increase the background in the surface layers
469               avmb(1) = 10.  * avmb(1)      ;      avtb(1) = 10.  * avtb(1)
470               avmb(2) = 10.  * avmb(2)      ;      avtb(2) = 10.  * avtb(2)
471               avmb(3) =  5.  * avmb(3)      ;      avtb(3) =  5.  * avtb(3)
472               avmb(4) =  2.5 * avmb(4)      ;      avtb(4) =  2.5 * avtb(4)
473            ENDIF
474      ENDIF
475      ! II. Vertical advection
476      ! ----------------------
477      ! 2. Tracer flux divergence at t-point added to the general trend
478      ! -------------------------
479      DO jk = jpkm1, 1, -1
480         DO jj = 2, jpjm1
481            DO ji = fs_2, fs_jpim1   ! vector opt.
482               ze3tr = 1. / fse3t(ji,jj,jk)
483               ! add it to the general tracer trends
484               ztaad = ta_ad(ji,jj,jk) + ztaad
485               zsaad = sa_ad(ji,jj,jk) + zsaad
486              ! vertical advective trends
487               zwxad(ji,jj,jk)   = zwxad(ji,jj,jk)   - ze3tr * ztaad
488               zwxad(ji,jj,jk+1) = zwxad(ji,jj,jk+1) + ze3tr * ztaad
489               zwyad(ji,jj,jk)   = zwyad(ji,jj,jk)   - ze3tr * zsaad
490               zwyad(ji,jj,jk+1) = zwyad(ji,jj,jk+1) + ze3tr * zsaad
491               ztaad = 0.0_wp
492               zsaad = 0.0_wp
493            END DO
494         END DO
495      END DO
496      ! 1. Vertical advective fluxes
497      ! ----------------------------
498      ! Second order centered tracer flux at w-point
499      DO jk = jpk, 2, -1
500         DO jj = 2, jpjm1
501            DO ji = fs_2, fs_jpim1   ! vector opt.
502               ! velocity * 1/2
503               zhw   = 0.5 * pwn(   ji,jj,jk)
504               ! centered scheme
505               zhwad = zhwad + zwxad(ji,jj,jk) * ( tn( ji,jj,jk) + tn(   ji,jj,jk-1) )
506               tn_ad(ji,jj,jk)   = tn_ad(ji,jj,jk)   + zwxad(ji,jj,jk) * zhw
507               tn_ad(ji,jj,jk-1) = tn_ad(ji,jj,jk-1) + zwxad(ji,jj,jk) * zhw
508               zwxad(ji,jj,jk) = 0.0_wp
509               zhwad = zhwad + zwyad(ji,jj,jk) * ( sn( ji,jj,jk) + sn(   ji,jj,jk-1) )
510               sn_ad(ji,jj,jk)   = sn_ad(ji,jj,jk)   + zwyad(ji,jj,jk) * zhw
511               sn_ad(ji,jj,jk-1) = sn_ad(ji,jj,jk-1) + zwyad(ji,jj,jk) * zhw
512               zwyad(ji,jj,jk) = 0.0_wp
513               ! velocity * 1/2
514               pwn_ad(ji,jj,jk) = pwn_ad(ji,jj,jk) + 0.5 * zhwad
515               zhwad = 0.0_wp
516           END DO
517         END DO
518      END DO
519      ! Surface value
520      IF( lk_dynspg_rl .OR. lk_vvl ) THEN
521         ! rigid lid or variable volume: flux set to zero
522         zwxad(:,:, 1 ) = 0.0_wp    ;    zwyad(:,:, 1 ) = 0.0_wp
523      ELSE
524         ! free surface
525         pwn_ad(:,:,1) = pwn_ad(:,:,1) + zwxad(:,:, 1 ) * tn(:,:,1) 
526         tn_ad(:,:,1)  = tn_ad(:,:,1)  + zwxad(:,:, 1 ) * pwn(:,:,1)
527         pwn_ad(:,:,1) = pwn_ad(:,:,1) + zwyad(:,:, 1 ) * sn(:,:,1) 
528         sn_ad(:,:,1)  = sn_ad(:,:,1)  + zwyad(:,:, 1 ) * pwn(:,:,1)
529         zwxad(:,:, 1 ) = 0.0_wp
530         zwyad(:,:, 1 ) = 0.0_wp
531      ENDIF
532
533      ! Bottom value : flux set to zero
534      zwxad(:,:,jpk) = 0.0_wp     ;    zwyad(:,:,jpk) = 0.0_wp
535      ! "zonal" mean advective heat and salt transport
536      ! ----------------------------------------------
537
538!      IF( ln_diaptr .AND. ( MOD( kt, nf_ptr ) == 0 ) ) THEN
539!         IF( lk_zco ) THEN
540!            DO jk = 1, jpkm1
541!               DO jj = 2, jpjm1
542!                  DO ji = fs_2, fs_jpim1   ! vector opt.
543!                    zwyad(ji,jj,jk) = zwyad(ji,jj,jk) * fse3v(ji,jj,jk)
544!                    zwzad(ji,jj,jk) = zwzad(ji,jj,jk) * fse3v(ji,jj,jk)
545!                  END DO
546!               END DO
547!            END DO
548!         ENDIF
549!         pht_adv(:) = ptr_vj( zwy(:,:,:) )
550!         pst_adv(:) = ptr_vj( zwz(:,:,:) )
551!      ENDIF
552!
553      ! I. Horizontal advective fluxes
554      ! ------------------------------
555      !  Second order centered tracer flux at u and v-points
556      ! -----------------------------------------------------
557      !                                                ! ===============
558      DO jk = 1, jpkm1                                 ! Horizontal slab
559         !                                             ! ===============
560        !  Tracer flux divergence at t-point added to the general trend
561         ! --------------------------------------------------------------
562         DO jj = jpjm1, 2, -1
563            DO ji = fs_jpim1, fs_2, -1   ! vector opt.
564#if defined key_zco
565               zbtr = btr2(ji,jj)
566#else
567               zbtr = btr2(ji,jj) / fse3t(ji,jj,jk)
568#endif
569               ! add it to the general tracer trends
570               ztaad = ta_ad(ji,jj,jk) + ztaad
571               zsaad = sa_ad(ji,jj,jk) + zsaad
572               ! horizontal advective trends
573               zwxad(ji,jj,jk) = zwxad(ji,jj,jk) - zbtr * ztaad
574               zwxad(ji-1,jj,jk) = zwxad(ji-1,jj,jk) + zbtr * ztaad
575               zwyad(ji,jj,jk) =  zwyad(ji,jj,jk) - zbtr * ztaad
576               zwyad(ji  ,jj-1,jk) = zwyad(ji  ,jj-1,jk) + zbtr * ztaad
577               ztaad = 0.0_wp
578               zwwad(ji,jj,jk) =  zwwad(ji,jj,jk) - zsaad * zbtr
579               zwwad(ji-1,jj  ,jk) = zwwad(ji-1,jj  ,jk) + zsaad * zbtr
580               zwzad(ji,jj,jk) = zwzad(ji,jj,jk) - zsaad * zbtr
581               zwzad(ji  ,jj-1,jk) = zwzad(ji  ,jj-1,jk) + zsaad * zbtr
582               zsaad = 0.0_wp
583            END DO
584         END DO
585         DO jj = jpjm1, 1, -1
586            DO ji = fs_jpim1, 1, -1   ! vector opt.
587               ! volume fluxes * 1/2
588#if defined key_zco
589               zfui = 0.5 * e2u(ji,jj) * pun(ji,jj,jk)
590               zfvj = 0.5 * e1v(ji,jj) * pvn(ji,jj,jk)
591#else
592               zfui = 0.5 * e2u(ji,jj) * fse3u(ji,jj,jk) * pun(ji,jj,jk)
593               zfvj = 0.5 * e1v(ji,jj) * fse3v(ji,jj,jk) * pvn(ji,jj,jk)
594#endif
595               ! centered scheme
596               zfuiad = zfuiad + zwxad(ji,jj,jk) * ( tn(ji,jj,jk) + tn(ji+1,jj,jk) )
597               tn_ad(ji,jj,jk) = tn_ad(ji,jj,jk) + zwxad(ji,jj,jk) * zfui
598               tn_ad(ji+1,jj,jk) = tn_ad(ji+1,jj,jk) + zwxad(ji,jj,jk) * zfui
599               zwxad(ji,jj,jk) = 0.0_wp
600               zfvjad = zfvjad + zwyad(ji,jj,jk) * ( tn(ji,jj,jk) + tn(ji,jj+1,jk) )
601               tn_ad(ji,jj,jk) = tn_ad(ji,jj,jk) + zwyad(ji,jj,jk) * zfvj
602               tn_ad(ji,jj+1,jk) = tn_ad(ji,jj+1,jk) + zwyad(ji,jj,jk) * zfvj
603               zwyad(ji,jj,jk) = 0.0_wp
604               zfuiad = zfuiad + zwwad(ji,jj,jk) * ( sn(ji,jj,jk) + sn(ji+1,jj,jk) ) 
605               sn_ad(ji,jj,jk) = sn_ad(ji,jj,jk) + zwwad(ji,jj,jk) * zfui
606               sn_ad(ji+1,jj,jk) = sn_ad(ji+1,jj,jk) + zwwad(ji,jj,jk) * zfui
607               zwwad(ji,jj,jk) = 0.0_wp
608               zfvjad = zfvjad + zwzad(ji,jj,jk) * ( sn(ji,jj,jk) + sn(ji,jj+1,jk) )
609               sn_ad(ji,jj,jk) = sn_ad(ji,jj,jk) + zwzad(ji,jj,jk) * zfvj
610               sn_ad(ji,jj+1,jk) = sn_ad(ji,jj+1,jk) + zwzad(ji,jj,jk) * zfvj
611               zwzad(ji,jj,jk) = 0.0_wp
612#if defined key_zco
613               pun_ad(ji,jj,jk) = pun_ad(ji,jj,jk) + 0.5 * e2u(ji,jj) * zfuiad
614               pvn_ad(ji,jj,jk) = pvn_ad(ji,jj,jk) + 0.5 * e1v(ji,jj) * zfvjad
615               zfuiad = 0.0_wp
616               zfvjad = 0.0_wp
617#else
618               pun_ad(ji,jj,jk) = pun_ad(ji,jj,jk) + 0.5 * e2u(ji,jj) * fse3u(ji,jj,jk) * zfuiad
619               pvn_ad(ji,jj,jk) = pvn_ad(ji,jj,jk) + 0.5 * e1v(ji,jj) * fse3v(ji,jj,jk) * zfvjad
620               zfuiad = 0.0_wp
621               zfvjad = 0.0_wp
622#endif
623             END DO
624         END DO
625         !                                             ! ===============
626      END DO                                           !   End of slab
627      !                                                ! ===============
628
629
630      !
631   END SUBROUTINE tra_adv_cen2_adj
632SUBROUTINE tra_adv_cen2_adj_tst( kumadt )
633      !!-----------------------------------------------------------------------
634      !!
635      !!                  ***  ROUTINE tra_adv_cen2_adj_tst ***
636      !!
637      !! ** Purpose : Test the adjoint routine.
638      !!
639      !! ** Method  : Verify the scalar product
640      !!           
641      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
642      !!
643      !!              where  L   = tangent routine
644      !!                     L^T = adjoint routine
645      !!                     W   = diagonal matrix of scale factors
646      !!                     dx  = input perturbation (random field)
647      !!                     dy  = L dx
648      !!
649      !!                   
650      !! History :
651      !!        ! 08-08 (A. Vidard)
652      !!-----------------------------------------------------------------------
653      !! * Modules used
654
655      !! * Arguments
656      INTEGER, INTENT(IN) :: &
657         & kumadt             ! Output unit
658 
659      !! * Local declarations
660      INTEGER ::  &
661         & ji,    &        ! dummy loop indices
662         & jj,    &       
663         & jk     
664      INTEGER, DIMENSION(jpi,jpj) :: &
665         & iseed_2d        ! 2D seed for the random number generator
666      REAL(KIND=wp) :: &
667         & zsp1,         & ! scalar product involving the tangent routine
668         & zsp2            ! scalar product involving the adjoint routine
669      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
670         & zun_tlin ,     & ! Tangent input
671         & zvn_tlin ,     & ! Tangent input
672         & zwn_tlin ,     & ! Tangent input
673         & ztn_tlin ,     & ! Tangent input
674         & zsn_tlin ,     & ! Tangent input
675         & zta_tlin ,     & ! Tangent input
676         & zsa_tlin ,     & ! Tangent input
677         & zta_tlout,     & ! Tangent output
678         & zsa_tlout,     & ! Tangent output
679         & zta_adin ,     & ! Adjoint input
680         & zsa_adin ,     & ! Adjoint input
681         & zun_adout,     & ! Adjoint output
682         & zvn_adout,     & ! Adjoint output
683         & zwn_adout,     & ! Adjoint output
684         & ztn_adout,     & ! Adjoint output
685         & zsn_adout,     & ! Adjoint output
686         & zta_adout,     & ! Adjoint output
687         & zsa_adout,     & ! Adjoint output
688         & zr             ! 3D random field
689      CHARACTER(LEN=14) ::&
690         & cl_name
691      ! Allocate memory
692
693      ALLOCATE( &
694         & zun_tlin( jpi,jpj,jpk),     &
695         & zvn_tlin( jpi,jpj,jpk),     &
696         & zwn_tlin( jpi,jpj,jpk),     &
697         & ztn_tlin( jpi,jpj,jpk),     &
698         & zsn_tlin( jpi,jpj,jpk),     &
699         & zta_tlin( jpi,jpj,jpk),     &
700         & zsa_tlin( jpi,jpj,jpk),     &
701         & zta_tlout(jpi,jpj,jpk),     &
702         & zsa_tlout(jpi,jpj,jpk),     &
703         & zta_adin( jpi,jpj,jpk),     &
704         & zsa_adin( jpi,jpj,jpk),     &
705         & zun_adout(jpi,jpj,jpk),     &
706         & zvn_adout(jpi,jpj,jpk),     &
707         & zwn_adout(jpi,jpj,jpk),     &
708         & ztn_adout(jpi,jpj,jpk),     &
709         & zsn_adout(jpi,jpj,jpk),     &
710         & zta_adout(jpi,jpj,jpk),     &
711         & zsa_adout(jpi,jpj,jpk),     &
712         & zr(       jpi,jpj,jpk)      &
713         & )
714      !==================================================================
715      ! 1) dx = ( un_tl, vn_tl, hdivn_tl ) and
716      !    dy = ( hdivb_tl, hdivn_tl )
717      !==================================================================
718
719      !--------------------------------------------------------------------
720      ! Reset the tangent and adjoint variables
721      !--------------------------------------------------------------------
722      zun_tlin( :,:,:) = 0.0_wp
723      zvn_tlin( :,:,:) = 0.0_wp
724      zwn_tlin( :,:,:) = 0.0_wp
725      ztn_tlin( :,:,:) = 0.0_wp
726      zsn_tlin( :,:,:) = 0.0_wp
727      zta_tlin( :,:,:) = 0.0_wp
728      zsa_tlin( :,:,:) = 0.0_wp
729      zta_tlout(:,:,:) = 0.0_wp
730      zsa_tlout(:,:,:) = 0.0_wp
731      zta_adin( :,:,:) = 0.0_wp
732      zsa_adin( :,:,:) = 0.0_wp
733      zun_adout(:,:,:) = 0.0_wp
734      zvn_adout(:,:,:) = 0.0_wp
735      zwn_adout(:,:,:) = 0.0_wp
736      ztn_adout(:,:,:) = 0.0_wp
737      zsn_adout(:,:,:) = 0.0_wp
738      zta_adout(:,:,:) = 0.0_wp
739      zsa_adout(:,:,:) = 0.0_wp
740      zr(       :,:,:) = 0.0_wp
741
742      tn_ad(:,:,:) = 0.0_wp
743      sn_ad(:,:,:) = 0.0_wp 
744     
745       
746      !--------------------------------------------------------------------
747      ! Initialize the tangent input with random noise: dx
748      !--------------------------------------------------------------------
749
750      DO jj = 1, jpj
751         DO ji = 1, jpi
752            iseed_2d(ji,jj) = - ( 596035 + &
753               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
754         END DO
755      END DO
756      CALL grid_random( iseed_2d, zr, 'U', 0.0_wp, stdu )
757      DO jk = 1, jpk
758        DO jj = nldj, nlej
759           DO ji = nldi, nlei
760              zun_tlin(ji,jj,jk) = zr(ji,jj,jk) 
761            END DO
762         END DO
763      END DO
764
765      DO jj = 1, jpj
766         DO ji = 1, jpi
767            iseed_2d(ji,jj) = - ( 371836 + &
768               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
769         END DO
770      END DO
771      CALL grid_random( iseed_2d, zr, 'V', 0.0_wp, stdv ) 
772      DO jk = 1, jpk
773        DO jj = nldj, nlej
774           DO ji = nldi, nlei
775              zvn_tlin(ji,jj,jk) = zr(ji,jj,jk) 
776            END DO
777         END DO
778      END DO
779
780      DO jj = 1, jpj
781         DO ji = 1, jpi
782            iseed_2d(ji,jj) = - ( 148379 + &
783               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
784         END DO
785      END DO
786      CALL grid_random( iseed_2d, zr, 'W', 0.0_wp, stdw )
787      DO jk = 1, jpk
788        DO jj = nldj, nlej
789           DO ji = nldi, nlei
790              zwn_tlin(ji,jj,jk) = zr(ji,jj,jk) 
791            END DO
792         END DO
793      END DO
794
795      DO jj = 1, jpj
796         DO ji = 1, jpi
797            iseed_2d(ji,jj) = - ( 264940 + &
798               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
799         END DO
800      END DO
801      CALL grid_random( iseed_2d, zr, 'T', 0.0_wp, stdt )
802      DO jk = 1, jpk
803        DO jj = nldj, nlej
804           DO ji = nldi, nlei
805              ztn_tlin(ji,jj,jk) = zr(ji,jj,jk) 
806            END DO
807         END DO
808      END DO
809
810      DO jj = 1, jpj
811         DO ji = 1, jpi
812            iseed_2d(ji,jj) = - ( 618304 + &
813               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
814         END DO
815      END DO
816      CALL grid_random( iseed_2d, zr, 'T', 0.0_wp, stds ) 
817      DO jk = 1, jpk
818        DO jj = nldj, nlej
819           DO ji = nldi, nlei
820              zsn_tlin(ji,jj,jk) = zr(ji,jj,jk) 
821            END DO
822         END DO
823      END DO
824
825      DO jj = 1, jpj
826         DO ji = 1, jpi
827            iseed_2d(ji,jj) = - ( 481903 + &
828               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
829         END DO
830      END DO
831      CALL grid_random( iseed_2d, zr, 'T', 0.0_wp, stdt )
832      DO jk = 1, jpk
833        DO jj = nldj, nlej
834           DO ji = nldi, nlei
835              zta_tlin(ji,jj,jk) = zr(ji,jj,jk) 
836            END DO
837         END DO
838      END DO
839
840      DO jj = 1, jpj
841         DO ji = 1, jpi
842            iseed_2d(ji,jj) = - ( 263871 + &
843               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
844         END DO
845      END DO
846      CALL grid_random( iseed_2d, zr, 'T', 0.0_wp, stds ) 
847      DO jk = 1, jpk
848        DO jj = nldj, nlej
849           DO ji = nldi, nlei
850              zsa_tlin(ji,jj,jk) = zr(ji,jj,jk) 
851            END DO
852         END DO
853      END DO
854
855      tn_tl(:,:,:) = ztn_tlin(:,:,:)
856      sn_tl(:,:,:) = zsn_tlin(:,:,:)
857      ta_tl(:,:,:) = zta_tlin(:,:,:)
858      sa_tl(:,:,:) = zsa_tlin(:,:,:)
859
860      CALL tra_adv_cen2_tan(nit000, un, vn, wn, zun_tlin, zvn_tlin, zwn_tlin) 
861
862      zta_tlout(:,:,:) = ta_tl(:,:,:) 
863      zsa_tlout(:,:,:) = sa_tl(:,:,:) 
864
865      !--------------------------------------------------------------------
866      ! Initialize the adjoint variables: dy^* = W dy
867      !--------------------------------------------------------------------
868
869      DO jk = 1, jpk
870        DO jj = nldj, nlej
871           DO ji = nldi, nlei
872              zta_adin(ji,jj,jk) = zta_tlout(ji,jj,jk) &
873                 &               * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) &
874                 &               * tmask(ji,jj,jk) * wesp_t(jk)
875              zsa_adin(ji,jj,jk) = zsa_tlout(ji,jj,jk) &
876                 &               * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) &
877                 &               * tmask(ji,jj,jk) * wesp_s(jk)
878            END DO
879         END DO
880      END DO
881      !--------------------------------------------------------------------
882      ! Compute the scalar product: ( L dx )^T W dy
883      !--------------------------------------------------------------------
884
885      zsp1 = DOT_PRODUCT( zta_tlout, zta_adin ) &
886         & + DOT_PRODUCT( zsa_tlout, zsa_adin )
887
888      !--------------------------------------------------------------------
889      ! Call the adjoint routine: dx^* = L^T dy^*
890      !--------------------------------------------------------------------
891      ta_ad(:,:,:) = zta_adin(:,:,:)
892      sa_ad(:,:,:) = zsa_adin(:,:,:)
893
894      CALL tra_adv_cen2_adj(nit000, un, vn, wn, zun_adout, zvn_adout, zwn_adout)
895
896      ztn_adout(:,:,:) = tn_ad(:,:,:)
897      zsn_adout(:,:,:) = sn_ad(:,:,:)
898      zta_adout(:,:,:) = ta_ad(:,:,:)
899      zsa_adout(:,:,:) = sa_ad(:,:,:)
900
901
902      zsp2 = DOT_PRODUCT( zun_tlin, zun_adout ) &
903         & + DOT_PRODUCT( zvn_tlin, zvn_adout ) &
904         & + DOT_PRODUCT( zwn_tlin, zwn_adout ) &
905         & + DOT_PRODUCT( ztn_tlin, ztn_adout ) &
906         & + DOT_PRODUCT( zsn_tlin, zsn_adout ) &
907         & + DOT_PRODUCT( zta_tlin, zta_adout ) &
908         & + DOT_PRODUCT( zsa_tlin, zsa_adout )
909
910      ! 14 char:'12345678901234'
911      cl_name = 'tra_adv_cen2  '
912      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
913
914      DEALLOCATE(         &
915         & zun_tlin ,     & ! Tangent input
916         & zvn_tlin ,     & ! Tangent input
917         & zwn_tlin ,     & ! Tangent input
918         & ztn_tlin ,     & ! Tangent input
919         & zsn_tlin ,     & ! Tangent input
920         & zta_tlin ,     & ! Tangent input
921         & zsa_tlin ,     & ! Tangent input
922         & zta_tlout,     & ! Tangent output
923         & zsa_tlout,     & ! Tangent output
924         & zta_adin ,     & ! Adjoint input
925         & zsa_adin ,     & ! Adjoint input
926         & zun_adout,     & ! Adjoint output
927         & zvn_adout,     & ! Adjoint output
928         & zwn_adout,     & ! Adjoint output
929         & ztn_adout,     & ! Adjoint output
930         & zsn_adout,     & ! Adjoint output
931         & zta_adout,     & ! Adjoint output
932         & zsa_adout,     & ! Adjoint output
933         & zr             & ! 3D random field
934         & )
935
936
937
938   END SUBROUTINE tra_adv_cen2_adj_tst
939#if defined key_tst_tlm
940SUBROUTINE tra_adv_cen2_tlm_tst( kumadt )
941      !!-----------------------------------------------------------------------
942      !!
943      !!                  ***  ROUTINE tra_adv_cen2_tlm_tst ***
944      !!
945      !! ** Purpose : Test the tangent routine.
946      !!
947      !! ** Method  : Verify the tangent with Taylor expansion
948      !!           
949      !!                 M(x+hdx) = M(x) + L(hdx) + O(h^2)
950      !!
951      !!              where  L   = tangent routine
952      !!                     M   = direct routine
953      !!                     dx  = input perturbation (random field)
954      !!                     h   = ration on perturbation
955      !!   
956      !!    In the tangent test we verify that:
957      !!                M(x+h*dx) - M(x)
958      !!        g(h) = ------------------ --->  1    as  h ---> 0
959      !!                    L(h*dx)
960      !!    and
961      !!                g(h) - 1
962      !!        f(h) = ----------         --->  k (costant) as  h ---> 0
963      !!                    p
964      !!                 
965      !! History :
966      !!        ! 09-08 (A. Vigilant)
967      !!-----------------------------------------------------------------------
968      !! * Modules used
969      USE traadv_cen2         ! horizontal & vertical advective trend
970      USE tamtrj              ! writing out state trajectory
971      USE par_tlm,    ONLY: &
972        & tlm_bch,          &
973        & cur_loop,         &
974        & h_ratio
975      USE istate_mod
976      USE wzvmod             !  vertical velocity
977      USE gridrandom, ONLY: &
978        & grid_rd_sd
979      USE trj_tam
980      USE oce           , ONLY: & ! ocean dynamics and tracers variables
981        & tb, sb, tn, sn, ta,  &
982        & sa, gtu, gsu, gtv,   &
983        & gsv
984      USE opatam_tst_ini, ONLY: &
985       & tlm_namrd
986      USE tamctl,         ONLY: & ! Control parameters
987       & numtan, numtan_sc
988      !! * Arguments
989      INTEGER, INTENT(IN) :: &
990         & kumadt             ! Output unit
991 
992      !! * Local declarations
993      INTEGER ::  &
994         & ji,    &        ! dummy loop indices
995         & jj,    &       
996         & jk     
997      REAL(KIND=wp) :: &
998         & zsp1,         & ! scalar product involving the tangent routine
999         & zsp1_Ta,      &
1000         & zsp1_Sa,      &
1001         & zsp2,         & ! scalar product involving the tangent routine
1002         & zsp2_Ta,      &
1003         & zsp2_Sa,      &
1004         & zsp3,         & ! scalar product involving the tangent routine
1005         & zsp3_Ta,      &
1006         & zsp3_Sa,      &
1007         & zzsp,         & ! scalar product involving the tangent routine
1008         & zzsp_Ta,      &
1009         & zzsp_Sa,      & 
1010         & gamma,            &
1011         & zgsp1,            &
1012         & zgsp2,            &
1013         & zgsp3,            &
1014         & zgsp4,            &
1015         & zgsp5,            &
1016         & zgsp6,            &
1017         & zgsp7 
1018      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
1019         & zun_tlin,      & ! Tangent input
1020         & zvn_tlin,      & ! Tangent input
1021         & zwn_tlin,      & ! Tangent input
1022         & ztn_tlin,      & ! Tangent input
1023         & zsn_tlin,      & ! Tangent input
1024         & zta_tlin,      & ! Tangent input
1025         & zsa_tlin,      & ! Tangent input
1026         & zta_out ,      & ! Direct output
1027         & zsa_out ,      & ! Direct output
1028         & zta_wop ,      & ! Direct output w/o perturbation
1029         & zsa_wop ,      & ! Direct output w/o perturbation
1030         & z3r
1031      CHARACTER(LEN=14)   :: cl_name
1032      CHARACTER (LEN=128) :: file_out, file_wop, file_xdx
1033      CHARACTER (LEN=90)  :: FMT
1034      REAL(KIND=wp), DIMENSION(100):: &
1035         & zscta,zscsa,               &
1036         & zscerrta, zscerrsa
1037      INTEGER, DIMENSION(100)::           &
1038         & iiposta, iipossa,              &
1039         & ijposta, ijpossa,              & 
1040         & ikposta, ikpossa
1041      INTEGER::             &
1042         & ii,              &
1043         & isamp=40,        &
1044         & jsamp=40,        &
1045         & ksamp=10,        &
1046         & numsctlm
1047     REAL(KIND=wp), DIMENSION(jpi,jpj,jpk) :: &
1048         & zerrta, zerrsa   
1049      ! Allocate memory
1050
1051      ALLOCATE( &
1052         & zun_tlin( jpi,jpj,jpk),     &
1053         & zvn_tlin( jpi,jpj,jpk),     &
1054         & zwn_tlin( jpi,jpj,jpk),     &
1055         & ztn_tlin( jpi,jpj,jpk),     &
1056         & zsn_tlin( jpi,jpj,jpk),     &
1057         & zta_tlin( jpi,jpj,jpk),     &
1058         & zsa_tlin( jpi,jpj,jpk),     &
1059         & zta_out ( jpi,jpj,jpk),     &
1060         & zsa_out ( jpi,jpj,jpk),     &
1061         & zta_wop ( jpi,jpj,jpk),     &
1062         & zsa_wop ( jpi,jpj,jpk),     &
1063         & z3r     ( jpi,jpj,jpk)      &
1064         & )
1065
1066      !--------------------------------------------------------------------
1067      ! Reset variables
1068      !--------------------------------------------------------------------
1069      zun_tlin( :,:,:) = 0.0_wp
1070      zvn_tlin( :,:,:) = 0.0_wp
1071      zwn_tlin( :,:,:) = 0.0_wp
1072      ztn_tlin( :,:,:) = 0.0_wp
1073      zsn_tlin( :,:,:) = 0.0_wp
1074      zta_tlin( :,:,:) = 0.0_wp
1075      zsa_tlin( :,:,:) = 0.0_wp
1076      zta_out ( :,:,:) = 0.0_wp
1077      zsa_out ( :,:,:) = 0.0_wp
1078      zta_wop ( :,:,:) = 0.0_wp
1079      zsa_wop ( :,:,:) = 0.0_wp
1080
1081      zscta(:)         = 0.0_wp
1082      zscsa(:)         = 0.0_wp
1083      zscerrta(:)      = 0.0_wp
1084      zscerrsa(:)      = 0.0_wp
1085
1086      !--------------------------------------------------------------------
1087      ! Output filename Xn=F(X0)
1088      !--------------------------------------------------------------------
1089      CALL tlm_namrd
1090      gamma = h_ratio     
1091      file_wop='trj_wop_tradv_cen2'
1092      file_xdx='trj_xdx_tradv_cen2'   
1093      !--------------------------------------------------------------------
1094      ! Initialize the tangent input with random noise: dx
1095      !--------------------------------------------------------------------
1096      IF (( cur_loop .NE. 0) .OR. ( gamma .NE. 0.0_wp) )THEN
1097         CALL grid_rd_sd( 596035, z3r,  'U', 0.0_wp, stdu)
1098         DO jk = 1, jpk
1099            DO jj = nldj, nlej
1100               DO ji = nldi, nlei
1101                  zun_tlin(ji,jj,jk) = z3r(ji,jj,jk)
1102               END DO
1103            END DO
1104         END DO
1105         CALL grid_rd_sd( 371836, z3r,  'V', 0.0_wp, stdv)
1106         DO jk = 1, jpk
1107            DO jj = nldj, nlej
1108               DO ji = nldi, nlei
1109                  zvn_tlin(ji,jj,jk) = z3r(ji,jj,jk)
1110               END DO
1111            END DO
1112         END DO
1113         CALL grid_rd_sd( 148379, z3r,  'W', 0.0_wp, stdw)
1114         DO jk = 1, jpk
1115            DO jj = nldj, nlej
1116               DO ji = nldi, nlei
1117                  zwn_tlin(ji,jj,jk) = z3r(ji,jj,jk)
1118               END DO
1119            END DO
1120         END DO
1121         CALL grid_rd_sd( 264940, z3r,  'T', 0.0_wp, stdt)
1122         DO jk = 1, jpk
1123            DO jj = nldj, nlej
1124               DO ji = nldi, nlei
1125                  ztn_tlin(ji,jj,jk) = z3r(ji,jj,jk)
1126               END DO
1127            END DO
1128         END DO
1129         CALL grid_rd_sd( 618304, z3r,  'T', 0.0_wp, stds) 
1130         DO jk = 1, jpk
1131            DO jj = nldj, nlej
1132               DO ji = nldi, nlei
1133                  zsn_tlin(ji,jj,jk) = z3r(ji,jj,jk)
1134               END DO
1135            END DO
1136         END DO
1137         CALL grid_rd_sd( 481903, z3r,  'T', 0.0_wp, stdt)
1138         DO jk = 1, jpk
1139            DO jj = nldj, nlej
1140               DO ji = nldi, nlei
1141                  zta_tlin(ji,jj,jk) = z3r(ji,jj,jk)
1142               END DO
1143            END DO
1144         END DO
1145         CALL grid_rd_sd( 263871, z3r,  'T', 0.0_wp, stds) 
1146         DO jk = 1, jpk
1147            DO jj = nldj, nlej
1148               DO ji = nldi, nlei
1149                  zsa_tlin(ji,jj,jk) = z3r(ji,jj,jk)
1150               END DO
1151            END DO
1152         END DO
1153      ENDIF       
1154      !--------------------------------------------------------------------
1155      ! Complete Init for Direct
1156      !-------------------------------------------------------------------
1157      IF ( tlm_bch /= 2 ) CALL istate_p 
1158
1159      ! *** initialize the reference trajectory
1160      ! ------------
1161      CALL  trj_rea( nit000-1, 1 )
1162      CALL  trj_rea( nit000, 1 )
1163
1164      IF (( cur_loop .NE. 0) .OR. ( gamma .NE. 0.0_wp) )THEN
1165         zun_tlin(:,:,:) = gamma * zun_tlin(:,:,:)
1166         un(:,:,:)       = un(:,:,:) + zun_tlin(:,:,:)
1167
1168         zvn_tlin(:,:,:) = gamma * zvn_tlin(:,:,:)
1169         vn(:,:,:)       = vn(:,:,:) + zvn_tlin(:,:,:)
1170
1171         zwn_tlin(:,:,:) = gamma * zwn_tlin(:,:,:)
1172         wn(:,:,:)       = wn(:,:,:) + zwn_tlin(:,:,:)
1173
1174         ztn_tlin(:,:,:) = gamma * ztn_tlin(:,:,:)
1175         tn(:,:,:)       = tn(:,:,:) + ztn_tlin(:,:,:)
1176
1177         zsn_tlin(:,:,:) = gamma * zsn_tlin(:,:,:)
1178         sn(:,:,:)       = sn(:,:,:) + zsn_tlin(:,:,:)
1179
1180         zta_tlin(:,:,:) = gamma * zta_tlin(:,:,:)
1181         ta(:,:,:)       = ta(:,:,:) + zta_tlin(:,:,:)
1182
1183         zsa_tlin(:,:,:) = gamma * zsa_tlin(:,:,:)
1184         sa(:,:,:)       = sa(:,:,:) + zsa_tlin(:,:,:)
1185      ENDIF 
1186
1187      !--------------------------------------------------------------------
1188      !  Compute the direct model F(X0,t=n) = Xn
1189      !--------------------------------------------------------------------
1190      IF ( tlm_bch /= 2 ) CALL tra_adv_cen2(nit000, un, vn, wn)
1191      IF ( tlm_bch == 0 ) CALL trj_wri_spl(file_wop)
1192      IF ( tlm_bch == 1 ) CALL trj_wri_spl(file_xdx)
1193      !--------------------------------------------------------------------
1194      !  Compute the Tangent
1195      !--------------------------------------------------------------------
1196      IF ( tlm_bch == 2 ) THEN       
1197         !--------------------------------------------------------------------
1198         ! Initialize the tangent variables: dy^* = W dy 
1199         !--------------------------------------------------------------------
1200         CALL  trj_rea( nit000-1, 1 ) 
1201         CALL  trj_rea( nit000, 1 ) 
1202         tn_tl  (:,:,:) = ztn_tlin  (:,:,:)
1203         sn_tl  (:,:,:) = zsn_tlin  (:,:,:)
1204         ta_tl  (:,:,:) = zta_tlin  (:,:,:)
1205         sa_tl  (:,:,:) = zsa_tlin  (:,:,:)
1206
1207         !-----------------------------------------------------------------------
1208         !  Initialization of the dynamics and tracer fields for the tangent
1209         !-----------------------------------------------------------------------
1210         CALL tra_adv_cen2_tan(nit000, un, vn, wn, zun_tlin, zvn_tlin, zwn_tlin)
1211
1212         !--------------------------------------------------------------------
1213         ! Compute the scalar product: ( L(t0,tn) gamma dx0 ) )
1214         !--------------------------------------------------------------------
1215         zsp2_Ta    = DOT_PRODUCT( ta_tl, ta_tl  )
1216         zsp2_Sa    = DOT_PRODUCT( sa_tl, sa_tl  )
1217
1218         zsp2      = zsp2_Ta + zsp2_Sa
1219         !--------------------------------------------------------------------
1220         !  Storing data
1221         !--------------------------------------------------------------------
1222         CALL trj_rd_spl(file_wop) 
1223         zta_wop  (:,:,:) = ta  (:,:,:)
1224         zsa_wop  (:,:,:) = sa  (:,:,:)
1225         CALL trj_rd_spl(file_xdx) 
1226         zta_out  (:,:,:) = ta  (:,:,:)
1227         zsa_out  (:,:,:) = sa  (:,:,:)
1228         !--------------------------------------------------------------------
1229         ! Compute the Linearization Error
1230         ! Nn = M( X0+gamma.dX0, t0,tn) - M(X0, t0,tn)
1231         ! and
1232         ! Compute the Linearization Error
1233         ! En = Nn -TL(gamma.dX0, t0,tn)
1234         !--------------------------------------------------------------------
1235         ! Warning: Here we re-use local variables z()_out and z()_wop
1236         ii=0
1237         DO jk = 1, jpk
1238            DO jj = 1, jpj
1239               DO ji = 1, jpi
1240                  zta_out   (ji,jj,jk) = zta_out    (ji,jj,jk) - zta_wop  (ji,jj,jk)
1241                  zta_wop   (ji,jj,jk) = zta_out    (ji,jj,jk) - ta_tl    (ji,jj,jk)
1242                  IF (  ta_tl(ji,jj,jk) .NE. 0.0_wp ) &
1243                     & zerrta(ji,jj,jk) = zta_out(ji,jj,jk)/ta_tl(ji,jj,jk)
1244                  IF( (MOD(ji, isamp) .EQ. 0) .AND. &
1245                  &   (MOD(jj, jsamp) .EQ. 0) .AND. &
1246                  &   (MOD(jk, ksamp) .EQ. 0)     ) THEN
1247                      ii = ii+1
1248                      iiposta(ii) = ji
1249                      ijposta(ii) = jj
1250                      ikposta(ii) = jk
1251                      IF ( INT(tmask(ji,jj,jk)) .NE. 0)  THEN
1252                         zscta (ii) =  zta_wop(ji,jj,jk)
1253                         zscerrta (ii) =  ( zerrta(ji,jj,jk) - 1.0_wp ) / gamma
1254                      ENDIF
1255                  ENDIF
1256               END DO
1257            END DO
1258         END DO
1259         ii=0
1260         DO jk = 1, jpk
1261            DO jj = 1, jpj
1262               DO ji = 1, jpi
1263                  zsa_out   (ji,jj,jk) = zsa_out    (ji,jj,jk) - zsa_wop  (ji,jj,jk)
1264                  zsa_wop   (ji,jj,jk) = zsa_out    (ji,jj,jk) - sa_tl    (ji,jj,jk)
1265                  IF (  sa_tl(ji,jj,jk) .NE. 0.0_wp ) &
1266                     & zerrsa(ji,jj,jk) = zsa_out(ji,jj,jk)/sa_tl(ji,jj,jk)
1267                  IF( (MOD(ji, isamp) .EQ. 0) .AND. &
1268                  &   (MOD(jj, jsamp) .EQ. 0) .AND. &
1269                  &   (MOD(jk, ksamp) .EQ. 0)     ) THEN
1270                      ii = ii+1
1271                      iipossa(ii) = ji
1272                      ijpossa(ii) = jj
1273                      ikpossa(ii) = jk
1274                      IF ( INT(tmask(ji,jj,jk)) .NE. 0)  THEN
1275                         zscsa (ii) =  zsa_wop(ji,jj,jk)
1276                         zscerrsa (ii) =  ( zerrsa(ji,jj,jk) - 1.0_wp ) / gamma
1277                      ENDIF
1278                  ENDIF
1279               END DO
1280            END DO
1281         END DO
1282
1283         zsp1_Ta    = DOT_PRODUCT( zta_out, zta_out  )
1284         zsp1_Sa    = DOT_PRODUCT( zsa_out, zsa_out  )
1285
1286         zsp1      = zsp1_Ta + zsp1_Sa
1287
1288         zsp3_Ta    = DOT_PRODUCT( zta_wop, zta_wop  )
1289         zsp3_Sa    = DOT_PRODUCT( zsa_wop, zsa_wop  )
1290
1291         zsp3      = zsp3_Ta + zsp3_Sa
1292
1293         !--------------------------------------------------------------------
1294         ! Print the linearization error En - norme 2
1295         !--------------------------------------------------------------------
1296         ! 14 char:'12345678901234'
1297         cl_name = 'traadv_tam:En '
1298         zzsp    = SQRT(zsp3)
1299         zzsp_Ta = SQRT(zsp3_Ta)
1300         zzsp_Sa = SQRT(zsp3_Sa)
1301         zgsp5   = zzsp
1302         CALL prntst_tlm( cl_name, kumadt, zzsp, h_ratio )
1303
1304         !--------------------------------------------------------------------
1305         ! Compute TLM norm2
1306         !--------------------------------------------------------------------
1307         zzsp     = SQRT(zsp2)
1308         zzsp_Ta  = SQRT(zsp2_Ta)
1309         zzsp_Sa  = SQRT(zsp2_Sa)
1310         zgsp4    = zzsp
1311         cl_name  = 'traadv_tam:Ln2'
1312         CALL prntst_tlm( cl_name, kumadt, zzsp, h_ratio )
1313
1314         !--------------------------------------------------------------------
1315         ! Print the linearization error Nn - norme 2
1316         !--------------------------------------------------------------------
1317         zzsp     = sqrt(zsp1)
1318         zzsp_Ta  = sqrt(zsp1_Ta)
1319         zzsp_Sa  = sqrt(zsp1_Sa)
1320
1321         cl_name = 'traadv:Mhdx-Mx'
1322         CALL prntst_tlm( cl_name, kumadt, zzsp, h_ratio )
1323
1324         zgsp3    = SQRT( zsp3/zsp2 )
1325         zgsp7    = zgsp3/gamma
1326         zgsp1    = zzsp
1327         zgsp2    = zgsp1 / zgsp4
1328         zgsp6    = (zgsp2 - 1.0_wp)/gamma
1329
1330         FMT = "(A8,2X,I4.4,2X,E6.1,2X,E20.13,2X,E20.13,2X,E20.13,2X,E20.13,2X,E20.13,2X,E20.13,2X,E20.13)"
1331         WRITE(numtan,FMT) 'tadvcen2', cur_loop, h_ratio, zgsp1, zgsp2, zgsp3, zgsp4, zgsp5, zgsp6, zgsp7
1332         !--------------------------------------------------------------------
1333         ! Unitary calculus
1334         !--------------------------------------------------------------------
1335         FMT = "(A8,2X,A8,2X,I4.4,2X,E6.1,2X,I4.4,2X,I4.4,2X,I4.4,2X,E20.13,1X)"
1336         cl_name = 'tadvcen2'
1337         IF(lwp) THEN
1338            DO ii=1, 100, 1
1339               IF ( zscta(ii) .NE. 0.0_wp ) WRITE(numtan_sc,FMT) cl_name, 'zscta     ', &
1340                    & cur_loop, h_ratio, ii, iiposta(ii), ijposta(ii), zscta(ii)
1341            ENDDO
1342            DO ii=1, 100, 1
1343               IF ( zscsa(ii) .NE. 0.0_wp ) WRITE(numtan_sc,FMT) cl_name, 'zscsa     ', &
1344                    & cur_loop, h_ratio, ii, iipossa(ii), ijpossa(ii), zscsa(ii)
1345            ENDDO
1346            DO ii=1, 100, 1
1347               IF ( zscerrta(ii) .NE. 0.0_wp ) WRITE(numtan_sc,FMT) cl_name, 'zscerrta  ', &
1348                    & cur_loop, h_ratio, ii, iiposta(ii), ijposta(ii), zscerrta(ii)
1349            ENDDO
1350            DO ii=1, 100, 1
1351               IF ( zscerrsa(ii) .NE. 0.0_wp ) WRITE(numtan_sc,FMT) cl_name, 'zscerrsa  ', &
1352                    & cur_loop, h_ratio, ii, iipossa(ii), ijpossa(ii), zscerrsa(ii)
1353            ENDDO
1354            ! write separator
1355            WRITE(numtan_sc,"(A4)") '===='
1356         ENDIF
1357
1358      ENDIF
1359
1360      DEALLOCATE(                           &
1361         & zun_tlin, zvn_tlin,              &
1362         & zwn_tlin, ztn_tlin,              &
1363         & zsn_tlin,                        &
1364         & zta_tlin, zsa_tlin,              & 
1365         & zta_out, zsa_out,                & 
1366         & zta_wop, zsa_wop,                &
1367         & z3r                              &
1368         & )
1369
1370  END SUBROUTINE  tra_adv_cen2_tlm_tst
1371#endif
1372#endif
1373   !!======================================================================
1374END MODULE traadv_cen2_tam
Note: See TracBrowser for help on using the repository browser.