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 tags/TAM_v3_0/NEMOTAM/OPATAM_SRC/TRA – NEMO

source: tags/TAM_v3_0/NEMOTAM/OPATAM_SRC/TRA/traadv_cen2_tam.F90 @ 8068

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

add TAM sources

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