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.
dynspg_flt_tam.F90 in branches/2012/dev_v3_4_STABLE_2012/NEMOGCM/NEMO/OPATAM_SRC/DYN – NEMO

source: branches/2012/dev_v3_4_STABLE_2012/NEMOGCM/NEMO/OPATAM_SRC/DYN/dynspg_flt_tam.F90 @ 5196

Last change on this file since 5196 was 5170, checked in by pabouttier, 9 years ago

Add missing lbc_lnk adj and remove extra ones in dynspg_flt ; See Ticket #1500

  • Property svn:executable set to *
File size: 39.1 KB
Line 
1MODULE dynspg_flt_tam
2   !!----------------------------------------------------------------------
3   !!    This software is governed by the CeCILL licence (Version 2)
4   !!----------------------------------------------------------------------
5#if defined key_tam
6   !!======================================================================
7   !!  ***  MODULE  dynspg_flt_tam : TANGENT/ADJOINT OF MODULE dynspg_flt  ***
8   !!
9   !! Ocean dynamics:  surface pressure gradient trend
10   !!
11   !!======================================================================
12   !! History of the direct module:
13   !! History    OPA  !  1998-05  (G. Roullet)  free surface
14   !!                 !  1998-10  (G. Madec, M. Imbard)  release 8.2
15   !!   NEMO     O.1  !  2002-08  (G. Madec)  F90: Free form and module
16   !!             -   !  2002-11  (C. Talandier, A-M Treguier) Open boundaries
17   !!            1.0  !  2004-08  (C. Talandier) New trends organization
18   !!             -   !  2005-11  (V. Garnier) Surface pressure gradient organization
19   !!            2.0  !  2006-07  (S. Masson)  distributed restart using iom
20   !!             -   !  2006-08  (J.Chanut, A.Sellar) Calls to BDY routines.
21   !!            3.2  !  2009-03  (G. Madec, M. Leclair, R. Benshila) introduce sshwzv module
22   !! History of the TAM module:
23   !!            9.0  ! 2008-08  (A. Vidard) skeleton
24   !!             -   ! 2008-08  (A. Weaver) original version
25   !!   NEMO     3.2  ! 2010-04  (F. Vigilant) converison to 3.2
26   !!   NEMO     3.4  ! 2012-07  (P.-A. Bouttier) converison to 3.4
27   !!----------------------------------------------------------------------
28# if defined key_dynspg_flt   ||   defined key_esopa
29   !!----------------------------------------------------------------------
30   !!   'key_dynspg_flt'                              filtered free surface
31   !!----------------------------------------------------------------------
32   !!----------------------------------------------------------------------
33   !!   dyn_spg_flt_tan  : update the momentum trend with the surface pressure
34   !!                      gradient in the filtered free surface case
35   !!                      (tangent routine)
36   !!   dyn_spg_flt_adj  : update the momentum trend with the surface pressure
37   !!                      gradient in the filtered free surface case
38   !!                      (adjoint routine)
39   !!   dyn_spg_flt_adj_tst : Test of the adjoint routine
40   !!----------------------------------------------------------------------
41   USE prtctl                  ! Print control
42   USE par_oce
43   USE in_out_manager
44   USE phycst
45   USE lib_mpp
46   USE dom_oce
47   USE solver
48   USE dynspg_flt
49   USE sol_oce
50   USE oce_tam
51   USE sbc_oce_tam
52   USE sol_oce
53   USE sol_oce_tam
54   USE solsor_tam
55   USE lbclnk
56   USE lbclnk_tam
57   USE gridrandom
58   USE dotprodfld
59   USE paresp
60   USE dynadv
61   USE cla_tam
62   USE tstool_tam
63   USE wrk_nemo        ! Memory Allocation
64   USE lib_fortran
65   USE timing
66   USE iom
67
68
69
70   IMPLICIT NONE
71   PRIVATE
72
73   !! * Accessibility
74   PUBLIC dyn_spg_flt_tan,     & ! routine called by step_tan.F90
75      &   dyn_spg_flt_adj,     & ! routine called by step_adj.F90
76      &   dyn_spg_flt_adj_tst    ! routine called by the tst.F90
77   !! * Substitutions
78#  include "domzgr_substitute.h90"
79#  include "vectopt_loop_substitute.h90"
80   !!----------------------------------------------------------------------
81CONTAINS
82
83   SUBROUTINE dyn_spg_flt_tan( kt, kindic )
84      !!---------------------------------------------------------------------
85      !!                  ***  routine dyn_spg_flt_tan  ***
86      !!
87      !! ** Purpose of the direct routine:
88      !!      Compute the now trend due to the surface pressure
89      !!      gradient in case of filtered free surface formulation  and add
90      !!      it to the general trend of momentum equation.
91      !!
92      !! ** Method of the direct routine:
93      !!      Filtered free surface formulation. The surface
94      !!      pressure gradient is given by:
95      !!         spgu = 1/rau0 d/dx(ps) =  1/e1u di( sshn + btda )
96      !!         spgv = 1/rau0 d/dy(ps) =  1/e2v dj( sshn + btda )
97      !!      where sshn is the free surface elevation and btda is the after
98      !!      time derivative of the free surface elevation
99      !!       -1- evaluate the surface presure trend (including the addi-
100      !!      tional force) in three steps:
101      !!        a- compute the right hand side of the elliptic equation:
102      !!            gcb = 1/(e1t e2t) [ di(e2u spgu) + dj(e1v spgv) ]
103      !!         where (spgu,spgv) are given by:
104      !!            spgu = vertical sum[ e3u (ub+ 2 rdt ua ) ]
105      !!                 - grav 2 rdt hu /e1u di[sshn + emp]
106      !!            spgv = vertical sum[ e3v (vb+ 2 rdt va) ]
107      !!                 - grav 2 rdt hv /e2v dj[sshn + emp]
108      !!         and define the first guess from previous computation :
109      !!            zbtd = btda
110      !!            btda = 2 zbtd - btdb
111      !!            btdb = zbtd
112      !!        b- compute the relative accuracy to be reached by the
113      !!         iterative solver
114      !!        c- apply the solver by a call to sol... routine
115      !!       -2- compute and add the free surface pressure gradient inclu-
116      !!      ding the additional force used to stabilize the equation.
117      !!
118      !! ** Action : - Update (ua,va) with the surf. pressure gradient trend
119      !!
120      !! References : Roullet and Madec 1999, JGR.
121      !!---------------------------------------------------------------------
122      !! * Arguments
123      INTEGER, INTENT( IN  ) :: &
124         &  kt         ! ocean time-step index
125      INTEGER, INTENT( OUT ) :: &
126         &  kindic     ! solver convergence flag (<0 if not converge)
127
128      !! * Local declarations
129      INTEGER  :: &
130         & ji,    &     ! dummy loop indices
131         & jj,    &
132         & jk
133      REAL(wp) ::  &
134         & z2dt,   & ! temporary scalars
135         & z2dtg,  &
136         & zgcb,   &
137         & zbtd,   &
138         & ztdgu,  &
139         & ztdgv
140      !!----------------------------------------------------------------------
141      !
142      !
143      IF( nn_timing == 1 )  CALL timing_start('dyn_spg_flt_tan')
144      !
145      IF( kt == nit000 ) THEN
146
147         IF(lwp) WRITE(numout,*)
148         IF(lwp) WRITE(numout,*) 'dyn_spg_flt_tan : surface pressure gradient trend'
149         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~   (free surface constant volume case)'
150         ! set to zero free surface specific arrays
151         spgu_tl(:,:) = 0.0_wp                    ! surface pressure gradient (i-direction)
152         spgv_tl(:,:) = 0.0_wp                    ! surface pressure gradient (j-direction)
153         ! Reinitialize the solver arrays
154         gcxb_tl(:,:) = 0.e0
155         gcx_tl (:,:) = 0.e0
156         CALL sol_mat( nit000 )
157      ENDIF
158      ! Local constant initialization
159      z2dt = 2. * rdt                                             ! time step: leap-frog
160      IF( neuler == 0 .AND. kt == nit000   )   z2dt = rdt         ! time step: Euler if restart from rest
161      IF( neuler == 0 .AND. kt == nit000+1 )   CALL sol_mat( kt )
162      z2dtg  = grav * z2dt
163      ! Evaluate the masked next velocity (effect of the additional force not included)
164      IF( lk_vvl ) THEN          ! variable volume  (surface pressure gradient already included in dyn_hpg)
165         CALL ctl_stop('key_vvl is not implemented in TAM yet')
166         !
167      ELSE                       ! fixed volume  (add the surface pressure gradient + unweighted time stepping)
168         !
169         DO jj = 2, jpjm1              ! Surface pressure gradient (now)
170            DO ji = fs_2, fs_jpim1   ! vector opt.
171               spgu_tl(ji,jj) = - grav * ( sshn_tl(ji+1,jj) - sshn_tl(ji,jj) ) / e1u(ji,jj)
172               spgv_tl(ji,jj) = - grav * ( sshn_tl(ji,jj+1) - sshn_tl(ji,jj) ) / e2v(ji,jj)
173            END DO
174         END DO
175
176         DO jk = 1, jpkm1              ! unweighted time stepping
177            DO jj = 2, jpjm1
178               DO ji = fs_2, fs_jpim1   ! vector opt.
179                  ua_tl(ji,jj,jk) = (  ub_tl(ji,jj,jk) + z2dt * ( ua_tl(ji,jj,jk) + spgu_tl(ji,jj) )  ) * umask(ji,jj,jk)
180                  va_tl(ji,jj,jk) = (  vb_tl(ji,jj,jk) + z2dt * ( va_tl(ji,jj,jk) + spgv_tl(ji,jj) )  ) * vmask(ji,jj,jk)
181               END DO
182            END DO
183         END DO
184         !
185      ENDIF
186      IF( nn_cla == 1 )   CALL cla_dynspg_tan( kt )      ! Cross Land Advection (update (ua,va))
187
188      ! compute the next vertically averaged velocity (effect of the additional force not included)
189      ! ---------------------------------------------
190      DO jj = 2, jpjm1
191         DO ji = fs_2, fs_jpim1   ! vector opt.
192            spgu_tl(ji,jj) = 0.0_wp
193            spgv_tl(ji,jj) = 0.0_wp
194         END DO
195      END DO
196
197      ! vertical sum
198!CDIR NOLOOPCHG
199      IF( lk_vopt_loop ) THEN          ! vector opt., forced unroll
200         DO jk = 1, jpkm1
201            DO ji = 1, jpij
202               spgu_tl(ji,1) = spgu_tl(ji,1) + fse3u(ji,1,jk) * ua_tl(ji,1,jk)
203               spgv_tl(ji,1) = spgv_tl(ji,1) + fse3v(ji,1,jk) * va_tl(ji,1,jk)
204            END DO
205         END DO
206      ELSE                        ! No  vector opt.
207         DO jk = 1, jpkm1
208            DO jj = 2, jpjm1
209               DO ji = 2, jpim1
210                  spgu_tl(ji,jj) = spgu_tl(ji,jj) + fse3u(ji,jj,jk) * ua_tl(ji,jj,jk)
211                  spgv_tl(ji,jj) = spgv_tl(ji,jj) + fse3v(ji,jj,jk) * va_tl(ji,jj,jk)
212               END DO
213            END DO
214         END DO
215      ENDIF
216
217      ! transport: multiplied by the horizontal scale factor
218      DO jj = 2, jpjm1
219         DO ji = fs_2, fs_jpim1   ! vector opt.
220            spgu_tl(ji,jj) = spgu_tl(ji,jj) * e2u(ji,jj)
221            spgv_tl(ji,jj) = spgv_tl(ji,jj) * e1v(ji,jj)
222         END DO
223      END DO
224
225      CALL lbc_lnk( spgu_tl, 'U', -1.0_wp )       ! lateral boundary conditions
226      CALL lbc_lnk( spgv_tl, 'V', -1.0_wp )
227
228      IF( lk_vvl ) CALL ctl_stop( 'dyn_spg_flt_tan: lk_vvl is not available' )
229
230      ! Right hand side of the elliptic equation and first guess
231      ! -----------------------------------------------------------
232      DO jj = 2, jpjm1
233         DO ji = fs_2, fs_jpim1   ! vector opt.
234            ! Divergence of the after vertically averaged velocity
235            zgcb =  spgu_tl(ji,jj) - spgu_tl(ji-1,jj)   &
236               &  + spgv_tl(ji,jj) - spgv_tl(ji,jj-1)
237            gcb_tl(ji,jj) = gcdprc(ji,jj) * zgcb
238            ! First guess of the after barotropic transport divergence
239            zbtd = gcx_tl(ji,jj)
240            gcx_tl (ji,jj) = 2.0_wp * zbtd - gcxb_tl(ji,jj)
241            gcxb_tl(ji,jj) =          zbtd
242         END DO
243      END DO
244
245      ! apply the lateral boundary conditions
246      IF( nn_solv == 2 .AND. MAX( jpr2di, jpr2dj ) > 0 ) CALL lbc_lnk_e( gcb_tl, c_solver_pt, 1.0_wp )
247
248      ! Relative precision
249      ! ------------------
250
251      rnorme = GLOB_SUM( gcb_tl(1:jpi,1:jpj) * gcdmat(1:jpi,1:jpj) * gcb_tl(1:jpi,1:jpj) * bmask(:,:) )
252
253      epsr = eps * eps * rnorme
254      ncut = 0
255      ! if rnorme is 0, the solution is 0, the solver is not called
256      IF( rnorme == 0.0_wp ) THEN
257         gcx_tl(:,:) = 0.0_wp
258         res   = 0.0_wp
259         niter = 0
260         ncut  = 999
261      ENDIF
262
263      ! Evaluate the next transport divergence
264      ! --------------------------------------
265      !    Iterarive solver for the elliptic equation (except IF sol.=0)
266      !    (output in gcx with boundary conditions applied)
267      kindic = 0
268      IF( ncut == 0 ) THEN
269         IF    ( nn_solv == 1 ) THEN  ;  CALL ctl_stop('sol_pcg_tan not available in TAM yet')   ! diagonal preconditioned conjuguate gradient
270         ELSEIF( nn_solv == 2 ) THEN  ;  CALL sol_sor_tan( kt, kindic )   ! successive-over-relaxation
271         ENDIF
272      ENDIF
273
274      ! Transport divergence gradient multiplied by z2dt
275      ! --------------------------------------------====
276      DO jj = 2, jpjm1
277         DO ji = fs_2, fs_jpim1   ! vector opt.
278            ! trend of Transport divergence gradient
279            ztdgu = z2dtg * ( gcx_tl(ji+1,jj  ) - gcx_tl(ji,jj) ) / e1u(ji,jj)
280            ztdgv = z2dtg * ( gcx_tl(ji  ,jj+1) - gcx_tl(ji,jj) ) / e2v(ji,jj)
281            ! multiplied by z2dt
282            spgu_tl(ji,jj) = z2dt * ztdgu
283            spgv_tl(ji,jj) = z2dt * ztdgv
284         END DO
285      END DO
286
287      ! Add the trends multiplied by z2dt to the after velocity
288      ! -------------------------------------------------------
289      !     ( c a u t i o n : (ua_tl,va_tl) here are the after velocity not the
290      !                       trend, the leap-frog time stepping will not
291      !                       be done in dynnxt_tan.F90 routine)
292      DO jk = 1, jpkm1
293         DO jj = 2, jpjm1
294            DO ji = fs_2, fs_jpim1   ! vector opt.
295               ua_tl(ji,jj,jk) = ( ua_tl(ji,jj,jk) + spgu_tl(ji,jj) ) * umask(ji,jj,jk)
296               va_tl(ji,jj,jk) = ( va_tl(ji,jj,jk) + spgv_tl(ji,jj) ) * vmask(ji,jj,jk)
297            END DO
298         END DO
299      END DO
300
301      !
302      IF( nn_timing == 1 )  CALL timing_stop('dyn_spg_flt_tan')
303      !
304   END SUBROUTINE dyn_spg_flt_tan
305
306   SUBROUTINE dyn_spg_flt_adj( kt, kindic )
307      !!----------------------------------------------------------------------
308      !!                  ***  routine dyn_spg_flt_adj  ***
309      !!
310      !! ** Purpose of the direct routine:
311      !!      Compute the now trend due to the surface pressure
312      !!      gradient in case of filtered free surface formulation  and add
313      !!      it to the general trend of momentum equation.
314      !!
315      !! ** Method of the direct routine:
316      !!      Filtered free surface formulation. The surface
317      !!      pressure gradient is given by:
318      !!         spgu = 1/rau0 d/dx(ps) =  1/e1u di( sshn + btda )
319      !!         spgv = 1/rau0 d/dy(ps) =  1/e2v dj( sshn + btda )
320      !!      where sshn is the free surface elevation and btda is the after
321      !!      time derivative of the free surface elevation
322      !!       -1- evaluate the surface presure trend (including the addi-
323      !!      tional force) in three steps:
324      !!        a- compute the right hand side of the elliptic equation:
325      !!            gcb = 1/(e1t e2t) [ di(e2u spgu) + dj(e1v spgv) ]
326      !!         where (spgu,spgv) are given by:
327      !!            spgu = vertical sum[ e3u (ub+ 2 rdt ua ) ]
328      !!                 - grav 2 rdt hu /e1u di[sshn + emp]
329      !!            spgv = vertical sum[ e3v (vb+ 2 rdt va) ]
330      !!                 - grav 2 rdt hv /e2v dj[sshn + emp]
331      !!         and define the first guess from previous computation :
332      !!            zbtd = btda
333      !!            btda = 2 zbtd - btdb
334      !!            btdb = zbtd
335      !!        b- compute the relative accuracy to be reached by the
336      !!         iterative solver
337      !!        c- apply the solver by a call to sol... routine
338      !!       -2- compute and add the free surface pressure gradient inclu-
339      !!      ding the additional force used to stabilize the equation.
340      !!
341      !! ** Action : - Update (ua,va) with the surf. pressure gradient trend
342      !!
343      !! References : Roullet and Madec 1999, JGR.
344      !!---------------------------------------------------------------------
345      !! * Arguments
346      INTEGER, INTENT( IN  ) :: &
347         &  kt         ! ocean time-step index
348      INTEGER, INTENT( OUT ) :: &
349         &  kindic     ! solver convergence flag (<0 if not converge)
350
351      !! * Local declarations
352      INTEGER  :: &
353         & ji, &     ! dummy loop indices
354         & jj, &
355         & jk
356      REAL(wp) :: &
357         & z2dt,   & ! temporary scalars
358         & z2dtg,  &
359         & zgcb,   &
360         & zbtd,   &
361         & ztdgu,  &
362         & ztdgv
363      !!----------------------------------------------------------------------
364      !
365      !
366      IF( nn_timing == 1 )  CALL timing_start('dyn_spg_flt_adj')
367      !
368      IF( kt == nitend ) THEN
369         IF(lwp) WRITE(numout,*)
370         IF(lwp) WRITE(numout,*) 'dyn_spg_flt_adj : surface pressure gradient trend'
371         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~   (free surface constant volume case)'
372      ENDIF
373
374      ! Local constant initialization
375      IF     ( neuler == 0 .AND. kt == nit000     ) THEN
376
377         z2dt = rdt             ! time step: Euler if restart from rest
378         CALL sol_mat(kt)       ! initialize matrix
379
380      ELSEIF (                   kt == nitend     ) THEN
381
382         z2dt = 2.0_wp * rdt    ! time step: leap-frog
383         CALL sol_mat(kt)       ! reinitialize matrix
384
385      ELSE
386
387         z2dt = 2.0_wp * rdt    ! time step: leap-frog
388
389      ENDIF
390
391      z2dtg  = grav * z2dt
392
393      ! set to zero free surface specific arrays (they are actually local variables)
394      spgu_ad(:,:) = 0.0_wp    ;      spgv_ad(:,:) = 0.0_wp
395
396      ! Add the trends multiplied by z2dt to the after velocity
397      ! -----------------------------------------------------------
398      !     ( c a u t i o n : (ua_ad,va_ad) here are the after velocity not the
399      !                       trend, the leap-frog time stepping will not
400      !                       be done in dynnxt_adj.F90 routine)
401      DO jk = 1, jpkm1
402         DO jj = 2, jpjm1
403            DO ji = fs_2, fs_jpim1   ! vector opt.
404               ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) * umask(ji,jj,jk)
405               va_ad(ji,jj,jk) = va_ad(ji,jj,jk) * vmask(ji,jj,jk)
406               spgu_ad(ji,jj)  = spgu_ad(ji,jj)  + ua_ad(ji,jj,jk)
407               spgv_ad(ji,jj)  = spgv_ad(ji,jj)  + va_ad(ji,jj,jk)
408            END DO
409         END DO
410      END DO
411
412      ! Transport divergence gradient multiplied by z2dt
413      ! --------------------------------------------====
414      DO jj = 2, jpjm1
415         DO ji = fs_2, fs_jpim1   ! vector opt.
416            ! multiplied by z2dt
417            ztdgu = z2dt * spgu_ad(ji,jj)
418            ztdgv = z2dt * spgv_ad(ji,jj)
419            spgu_ad(ji,jj) = 0.0_wp
420            spgv_ad(ji,jj) = 0.0_wp
421            ! trend of Transport divergence gradient
422            ztdgu = ztdgu * z2dtg / e1u(ji,jj)
423            ztdgv = ztdgv * z2dtg / e2v(ji,jj)
424            gcx_ad(ji  ,jj  ) = gcx_ad(ji  ,jj  ) - ztdgu - ztdgv
425            gcx_ad(ji  ,jj+1) = gcx_ad(ji  ,jj+1) + ztdgv
426            gcx_ad(ji+1,jj  ) = gcx_ad(ji+1,jj  ) + ztdgu
427         END DO
428      END DO
429
430      ! Evaluate the next transport divergence
431      ! --------------------------------------
432      !    Iterative solver for the elliptic equation (except IF sol.=0)
433      !    (output in gcx_ad with boundary conditions applied)
434
435      kindic = 0
436      ncut = 0    !  Force solver
437      IF( ncut == 0 ) THEN
438         IF    ( nn_solv == 1 ) THEN ;  CALL ctl_stop('sol_pcg_adj not available in TMA yet')   ! diagonal preconditioned conjuguate gradient
439         ELSEIF( nn_solv == 2 ) THEN ;  CALL sol_sor_adj( kt, kindic )   ! successive-over-relaxation
440         ENDIF
441      ENDIF
442
443      ! Right hand side of the elliptic equation and first guess
444      ! --------------------------------------------------------
445      ! apply the lateral boundary conditions
446      IF( nn_solv == 2 .AND. MAX( jpr2di, jpr2dj ) > 0 ) &
447         &    CALL lbc_lnk_e_adj( gcb_ad, c_solver_pt, 1.0_wp )
448
449      DO jj = 2, jpjm1
450         DO ji = fs_2, fs_jpim1   ! vector opt.
451            ! First guess of the after barotropic transport divergence
452            zbtd = gcxb_ad(ji,jj) + 2.0_wp * gcx_ad(ji,jj)
453            gcxb_ad(ji,jj) = - gcx_ad(ji,jj)
454            gcx_ad (ji,jj) = zbtd
455            ! Divergence of the after vertically averaged velocity
456            zgcb = gcb_ad(ji,jj) * gcdprc(ji,jj)
457            gcb_ad(ji,jj) = 0.0_wp
458            spgu_ad(ji-1,jj  ) = spgu_ad(ji-1,jj  ) - zgcb
459            spgu_ad(ji  ,jj  ) = spgu_ad(ji  ,jj  ) + zgcb
460            spgv_ad(ji  ,jj-1) = spgv_ad(ji  ,jj-1) - zgcb
461            spgv_ad(ji  ,jj  ) = spgv_ad(ji  ,jj  ) + zgcb
462         END DO
463      END DO
464
465      IF( lk_vvl ) CALL ctl_stop( 'dyn_spg_flt_adj: lk_vvl is not available' )
466
467      ! Boundary conditions on (spgu_ad,spgv_ad)
468      CALL lbc_lnk_adj( spgu_ad, 'U', -1.0_wp )
469      CALL lbc_lnk_adj( spgv_ad, 'V', -1.0_wp )
470
471      ! transport: multiplied by the horizontal scale factor
472      DO jj = 2,jpjm1
473         DO ji = fs_2,fs_jpim1   ! vector opt.
474            spgu_ad(ji,jj) = spgu_ad(ji,jj) * e2u(ji,jj)
475            spgv_ad(ji,jj) = spgv_ad(ji,jj) * e1v(ji,jj)
476         END DO
477      END DO
478
479      ! compute the next vertically averaged velocity (effect of the additional force not included)
480      ! ---------------------------------------------
481
482      ! vertical sum
483!CDIR NOLOOPCHG
484      IF( lk_vopt_loop ) THEN     ! vector opt., forced unroll
485         DO jk = 1, jpkm1
486            DO ji = 1, jpij
487               ua_ad(ji,1,jk) = ua_ad(ji,1,jk) + fse3u(ji,1,jk) * spgu_ad(ji,1)
488               va_ad(ji,1,jk) = va_ad(ji,1,jk) + fse3v(ji,1,jk) * spgv_ad(ji,1)
489            END DO
490         END DO
491      ELSE                        ! No  vector opt.
492         DO jk = 1, jpkm1
493            DO jj = 2, jpjm1
494               DO ji = 2, jpim1
495                  ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) + fse3u(ji,jj,jk) * spgu_ad(ji,jj)
496                  va_ad(ji,jj,jk) = va_ad(ji,jj,jk) + fse3v(ji,jj,jk) * spgv_ad(ji,jj)
497               END DO
498            END DO
499         END DO
500      ENDIF
501
502      DO jj = 2, jpjm1
503         DO ji = fs_2, fs_jpim1 ! vector opt.
504            spgu_ad(ji,jj) = 0.0_wp
505            spgv_ad(ji,jj) = 0.0_wp
506         END DO
507      END DO
508
509      IF( nn_cla == 1 )   CALL cla_dynspg_adj( kt )      ! Cross Land Advection (update (ua,va))
510
511      ! Evaluate the masked next velocity (effect of the additional force not included)
512      IF( lk_vvl ) THEN          ! variable volume  (surface pressure gradient already included in dyn_hpg)
513         !
514         IF( ln_dynadv_vec ) THEN      ! vector form : applied on velocity
515            DO jk = 1, jpkm1
516               DO jj = 2, jpjm1
517                  DO ji = fs_2, fs_jpim1   ! vector opt.
518                     ub_ad(ji,jj,jk) = ub_ad(ji,jj,jk) + z2dt * ua_ad(ji,jj,jk) * umask(ji,jj,jk)
519                     ua_ad(ji,jj,jk) = z2dt * ua_ad(ji,jj,jk) * umask(ji,jj,jk)
520                     vb_ad(ji,jj,jk) = vb_ad(ji,jj,jk) + z2dt * va_ad(ji,jj,jk) * vmask(ji,jj,jk)
521                     va_ad(ji,jj,jk) = z2dt * va_ad(ji,jj,jk) * vmask(ji,jj,jk)
522                  END DO
523               END DO
524            END DO
525            !
526         ELSE                          ! flux form : applied on thickness weighted velocity
527            DO jk = 1, jpkm1
528               DO jj = 2, jpjm1
529                  DO ji = fs_2, fs_jpim1   ! vector opt.
530                     ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) / fse3u_a(ji,jj,jk) * umask(ji,jj,jk)
531                     ub_ad(ji,jj,jk) = ub_ad(ji,jj,jk) + ua_ad(ji,jj,jk) * fse3u_b(ji,jj,jk)
532                     ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) * z2dt * fse3u_n(ji,jj,jk)
533                     va_ad(ji,jj,jk) = va_ad(ji,jj,jk) / fse3v_a(ji,jj,jk) * vmask(ji,jj,jk)
534                     vb_ad(ji,jj,jk) = vb_ad(ji,jj,jk) + va_ad(ji,jj,jk) * fse3v_b(ji,jj,jk)
535                     va_ad(ji,jj,jk) = va_ad(ji,jj,jk) * z2dt * fse3v_n(ji,jj,jk)
536                 END DO
537               END DO
538            END DO
539            !
540         ENDIF
541         !
542      ELSE                       ! fixed volume  (add the surface pressure gradient + unweighted time stepping)
543         !
544         DO jk = 1, jpkm1               ! unweighted time stepping
545            DO jj = 2, jpjm1
546               DO ji = fs_2, fs_jpim1   ! vector opt.
547                  ua_ad(  ji,jj,jk) = ua_ad(ji,jj,jk) * umask(ji,jj,jk)
548                  ub_ad(  ji,jj,jk) = ub_ad(ji,jj,jk) + ua_ad(ji,jj,jk)
549                  ua_ad(  ji,jj,jk) = ua_ad(ji,jj,jk) * z2dt
550                  spgu_ad(ji,jj   ) = spgu_ad(ji,jj)  + ua_ad(ji,jj,jk)
551                  va_ad(  ji,jj,jk) = va_ad(ji,jj,jk) * vmask(ji,jj,jk)
552                  vb_ad(  ji,jj,jk) = vb_ad(ji,jj,jk) + va_ad(ji,jj,jk)
553                  va_ad(  ji,jj,jk) = va_ad(ji,jj,jk) * z2dt
554                  spgv_ad(ji,jj   ) = spgv_ad(ji,jj)  + va_ad(ji,jj,jk)
555               END DO
556            END DO
557         END DO
558         DO jj = 2, jpjm1              ! Surface pressure gradient (now)
559            DO ji = fs_2, fs_jpim1     ! vector opt.
560               spgu_ad(ji  ,jj  ) = spgu_ad(ji  ,jj  ) * grav / e1u(ji,jj)
561               spgv_ad(ji  ,jj  ) = spgv_ad(ji  ,jj  ) * grav / e2v(ji,jj)
562               sshn_ad(ji  ,jj  ) = sshn_ad(ji  ,jj  ) + spgv_ad(ji,jj)
563               sshn_ad(ji  ,jj+1) = sshn_ad(ji  ,jj+1) - spgv_ad(ji,jj)
564               sshn_ad(ji  ,jj  ) = sshn_ad(ji  ,jj  ) + spgu_ad(ji,jj)
565               sshn_ad(ji+1,jj  ) = sshn_ad(ji+1,jj  ) - spgu_ad(ji,jj)
566               spgu_ad(ji  ,jj  ) = 0.0_wp
567               spgv_ad(ji  ,jj  ) = 0.0_wp
568            END DO
569         END DO
570      ENDIF
571
572      IF( kt == nit000 ) THEN
573         ! set to zero free surface specific arrays
574         spgu_ad(:,:) = 0.0_wp                    ! surface pressure gradient (i-direction)
575         spgv_ad(:,:) = 0.0_wp                    ! surface pressure gradient (j-direction)
576         ! Reinitialize the solver arrays
577         gcxb_ad(:,:) = 0.e0
578         gcx_ad (:,:) = 0.e0
579      ENDIF
580      !
581      IF( nn_timing == 1 )  CALL timing_stop('dyn_spg_flt_adj')
582      !
583   END SUBROUTINE dyn_spg_flt_adj
584
585   SUBROUTINE dyn_spg_flt_adj_tst( kumadt )
586      !!-----------------------------------------------------------------------
587      !!
588      !!                  ***  ROUTINE dyn_spg_flt_adj_tst ***
589      !!
590      !! ** Purpose : Test the adjoint routine.
591      !!
592      !! ** Method  : Verify the scalar product
593      !!
594      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
595      !!
596      !!              where  L   = tangent routine
597      !!                     L^T = adjoint routine
598      !!                     W   = diagonal matrix of scale factors
599      !!                     dx  = input perturbation (random field)
600      !!                     dy  = L dx
601      !!
602      !! ** Action  :
603      !!
604      !! History :
605      !!        ! 09-01 (A. Weaver)
606      !!-----------------------------------------------------------------------
607      !! * Modules used
608
609      !! * Arguments
610      INTEGER, INTENT(IN) :: &
611         & kumadt        ! Output unit
612
613      !! * Local declarations
614      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
615         & zua_tlin,    & ! Tangent input: ua_tl
616         & zva_tlin,    & ! Tangent input: va_tl
617         & zub_tlin,    & ! Tangent input: ub_tl
618         & zvb_tlin,    & ! Tangent input: vb_tl
619         & zua_tlout,   & ! Tangent output: ua_tl
620         & zva_tlout,   & ! Tangent output: va_tl
621         & zua_adin,    & ! Adjoint input: ua_ad
622         & zva_adin,    & ! Adjoint input: va_ad
623         & zua_adout,   & ! Adjoint output: ua_ad
624         & zva_adout,   & ! Adjoint output: va_ad
625         & zub_adout,   & ! Adjoint oputput: ub_ad
626         & zvb_adout,   & ! Adjoint output: vb_ad
627         & znu            ! 3D random field for u
628
629      REAL(wp), DIMENSION(:,:), ALLOCATABLE :: &
630         & zgcx_tlin, zgcxb_tlin, zgcx_tlout, zgcxb_tlout,  &
631         & zgcx_adin, zgcxb_adin, zgcx_adout, zgcxb_adout
632
633      REAL(KIND=wp), DIMENSION(:,:), ALLOCATABLE :: &
634         & zsshn_tlin, & ! Tangent input: sshn_tl
635         & zsshn_adout,& ! Adjoint output: sshn_ad
636         & znssh         ! 2D random field for SSH
637      REAL(wp) :: &
638         & zsp1,    &   ! scalar product involving the tangent routine
639         & zsp2         ! scalar product involving the adjoint routine
640      INTEGER :: &
641         & indic, &
642         & istp
643      INTEGER :: &
644         & ji, &
645         & jj, &
646         & jk, &
647         & kmod, &
648         & jstp
649      CHARACTER (LEN=14) :: &
650         & cl_name
651      INTEGER ::             &
652         & jpert
653      INTEGER, PARAMETER :: jpertmax = 6
654
655      ! Allocate memory
656
657      ALLOCATE( &
658         & zua_tlin(jpi,jpj,jpk),  &
659         & zva_tlin(jpi,jpj,jpk),  &
660         & zub_tlin(jpi,jpj,jpk),  &
661         & zvb_tlin(jpi,jpj,jpk),  &
662         & zua_tlout(jpi,jpj,jpk), &
663         & zva_tlout(jpi,jpj,jpk), &
664         & zua_adin(jpi,jpj,jpk),  &
665         & zva_adin(jpi,jpj,jpk),  &
666         & zua_adout(jpi,jpj,jpk), &
667         & zva_adout(jpi,jpj,jpk), &
668         & zub_adout(jpi,jpj,jpk), &
669         & zvb_adout(jpi,jpj,jpk), &
670         & znu(jpi,jpj,jpk)        &
671         & )
672      ALLOCATE( &
673         & zsshn_tlin(jpi,jpj), &
674         & zsshn_adout(jpi,jpj),&
675         & znssh(jpi,jpj)       &
676         & )
677
678      ALLOCATE( zgcx_tlin (jpi,jpj), zgcx_tlout (jpi,jpj), zgcx_adin (jpi,jpj), zgcx_adout (jpi,jpj),  &
679                zgcxb_tlin(jpi,jpj), zgcxb_tlout(jpi,jpj), zgcxb_adin(jpi,jpj), zgcxb_adout(jpi,jpj)   )
680
681      !=========================================================================
682      !     dx = ( sshb_tl, sshn_tl, ub_tl, ua_tl, vb_tl, va_tl, wn_tl, emp_tl )
683      ! and dy = ( sshb_tl, sshn_tl, ua_tl, va_tl )
684      !=========================================================================
685
686      ! Test for time steps nit000 and nit000 + 1 (the matrix changes)
687
688      DO jstp = nit000, nitend, nitend-nit000
689         DO jpert = jpertmax, jpertmax
690            istp = jstp
691
692            !--------------------------------------------------------------------
693            ! Reset the tangent and adjoint variables
694            !--------------------------------------------------------------------
695
696            zub_tlin (:,:,:) = 0.0_wp
697            zvb_tlin (:,:,:) = 0.0_wp
698            zua_tlin (:,:,:) = 0.0_wp
699            zva_tlin (:,:,:) = 0.0_wp
700            zua_tlout(:,:,:) = 0.0_wp
701            zva_tlout(:,:,:) = 0.0_wp
702            zua_adin (:,:,:) = 0.0_wp
703            zva_adin (:,:,:) = 0.0_wp
704            zub_adout(:,:,:) = 0.0_wp
705            zvb_adout(:,:,:) = 0.0_wp
706            zua_adout(:,:,:) = 0.0_wp
707            zva_adout(:,:,:) = 0.0_wp
708
709            zsshn_tlin (:,:) = 0.0_wp
710            zsshn_adout(:,:) = 0.0_wp
711
712            zgcx_tlout (:,:) = 0.0_wp ; zgcx_adin (:,:) = 0.0_wp ; zgcx_adout (:,:) = 0.0_wp
713            zgcxb_tlout(:,:) = 0.0_wp ; zgcxb_adin(:,:) = 0.0_wp ; zgcxb_adout(:,:) = 0.0_wp
714
715            ub_tl(:,:,:) = 0.0_wp
716            vb_tl(:,:,:) = 0.0_wp
717            ua_tl(:,:,:) = 0.0_wp
718            va_tl(:,:,:) = 0.0_wp
719            sshn_tl(:,:) = 0.0_wp
720            gcx_tl(:,:)  = 0.0_wp
721            gcxb_tl(:,:) = 0.0_wp
722            spgu_tl(:,:) = 0.0_wp
723            spgv_tl(:,:) = 0.0_wp
724            ub_ad(:,:,:) = 0.0_wp
725            vb_ad(:,:,:) = 0.0_wp
726            ua_ad(:,:,:) = 0.0_wp
727            va_ad(:,:,:) = 0.0_wp
728            sshn_ad(:,:) = 0.0_wp
729            gcb_ad(:,:)  = 0.0_wp
730            gcx_ad(:,:)  = 0.0_wp
731            gcxb_ad(:,:) = 0.0_wp
732            spgu_ad(:,:) = 0.0_wp
733            spgv_ad(:,:) = 0.0_wp
734            !--------------------------------------------------------------------
735            ! Initialize the tangent input with random noise: dx
736            !--------------------------------------------------------------------
737            IF ( (jpert == 1) .OR. (jpert == jpertmax) ) THEN
738
739               CALL grid_random(  znu, 'U', 0.0_wp, stdu )
740
741               DO jk = 1, jpk
742                  DO jj = nldj, nlej
743                     DO ji = nldi, nlei
744                        zua_tlin(ji,jj,jk) = znu(ji,jj,jk)
745                     END DO
746                  END DO
747               END DO
748
749            ENDIF
750            IF ( (jpert == 2) .OR. (jpert == jpertmax) ) THEN
751               CALL grid_random(  znu, 'V', 0.0_wp, stdv )
752
753               DO jk = 1, jpk
754                  DO jj = nldj, nlej
755                     DO ji = nldi, nlei
756                        zva_tlin(ji,jj,jk) = znu(ji,jj,jk)
757                     END DO
758                  END DO
759               END DO
760
761            ENDIF
762            IF ( (jpert == 3) .OR. (jpert == jpertmax) ) THEN
763               CALL grid_random(  znu, 'U', 0.0_wp, stdu )
764
765               DO jk = 1, jpk
766                  DO jj = nldj, nlej
767                     DO ji = nldi, nlei
768                        zub_tlin(ji,jj,jk) = znu(ji,jj,jk)
769                     END DO
770                  END DO
771               END DO
772
773            ENDIF
774            IF ( (jpert == 4) .OR. (jpert == jpertmax) ) THEN
775               CALL grid_random(  znu, 'V', 0.0_wp, stdv )
776
777               DO jk = 1, jpk
778                  DO jj = nldj, nlej
779                     DO ji = nldi, nlei
780                        zvb_tlin(ji,jj,jk) = znu(ji,jj,jk)
781                     END DO
782                  END DO
783               END DO
784
785            ENDIF
786            IF ( (jpert == 5) .OR. (jpert == jpertmax) ) THEN
787
788               CALL grid_random(  znssh, 'T', 0.0_wp, stdssh )
789               DO jj = nldj, nlej
790                  DO ji = nldi, nlei
791                     zsshn_tlin(ji,jj) = znssh(ji,jj)
792                  END DO
793               END DO
794            END IF
795            zgcx_tlin  (:,:) = ( zua_tlin(:,:,1) + zub_tlin(:,:,1) ) / 10.
796            zgcxb_tlin (:,:) = ( zua_tlin(:,:,2) + zub_tlin(:,:,2) ) / 10.
797            !--------------------------------------------------------------------
798            ! Call the tangent routine: dy = L dx
799            !--------------------------------------------------------------------
800
801            ua_tl(:,:,:) = zua_tlin(:,:,:)
802            va_tl(:,:,:) = zva_tlin(:,:,:)
803            ub_tl(:,:,:) = zub_tlin(:,:,:)
804            vb_tl(:,:,:) = zvb_tlin(:,:,:)
805            sshn_tl(:,:) = zsshn_tlin(:,:)
806
807            gcb_tl (:,:) = 0.e0
808            gcx_tl (:,:) = zgcx_tlin (:,:)   ;   gcxb_tl(:,:) = zgcxb_tlin(:,:)
809
810            CALL sol_mat( istp ) ! for nitend, it is not called in _tan so it is still set to the nit000 case
811            CALL dyn_spg_flt_tan( istp, indic )
812
813            zua_tlout(:,:,:) = ua_tl(:,:,:)   ;   zva_tlout(:,:,:) = va_tl(:,:,:)
814            zgcxb_tlout(:,:) = gcxb_tl(:,:)   ;   zgcx_tlout (:,:) = gcx_tl (:,:)
815
816            !--------------------------------------------------------------------
817            ! Initialize the adjoint variables: dy^* = W dy
818            !--------------------------------------------------------------------
819
820            DO jk = 1, jpk
821               DO jj = nldj, nlej
822                  DO ji = nldi, nlei
823                     zua_adin(ji,jj,jk) = zua_tlout(ji,jj,jk) &
824                        &               * e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) &
825                        &               * umask(ji,jj,jk)
826                     zva_adin(ji,jj,jk) = zva_tlout(ji,jj,jk) &
827                        &               * e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk) &
828                        &               * vmask(ji,jj,jk)
829                  END DO
830               END DO
831            END DO
832            DO jj = nldj, nlej
833               DO ji = nldi, nlei
834                  zgcx_adin (ji,jj) = zgcx_tlout (ji,jj) &
835                     &              * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,1) * tmask(ji,jj,1)
836                  zgcxb_adin(ji,jj) = zgcxb_tlout(ji,jj) &
837                     &              * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,1) * tmask(ji,jj,1)
838               END DO
839            END DO
840
841            !--------------------------------------------------------------------
842            ! Compute the scalar product: ( L dx )^T W dy
843            !--------------------------------------------------------------------
844
845            zsp1 =   DOT_PRODUCT( zua_tlout   , zua_adin   ) &
846               &   + DOT_PRODUCT( zgcx_tlout  , zgcx_adin  ) &
847               &   + DOT_PRODUCT( zgcxb_tlout , zgcxb_adin ) &
848               &   + DOT_PRODUCT( zva_tlout   , zva_adin   )
849
850
851            !--------------------------------------------------------------------
852            ! Call the adjoint routine: dx^* = L^T dy^*
853            !--------------------------------------------------------------------
854
855            ua_ad(:,:,:) = zua_adin(:,:,:)
856            va_ad(:,:,:) = zva_adin(:,:,:)
857
858            gcx_ad (:,:)   = zgcx_adin (:,:)   ;   gcxb_ad(:,:) = zgcxb_adin (:,:)
859            ub_ad  (:,:,:) = 0.0_wp ;  vb_ad  (:,:,:) = 0.0_wp
860
861            CALL dyn_spg_flt_adj( istp, indic )
862
863            zua_adout(:,:,:) = ua_ad(:,:,:)
864            zva_adout(:,:,:) = va_ad(:,:,:)
865            zub_adout(:,:,:) = ub_ad(:,:,:)
866            zvb_adout(:,:,:) = vb_ad(:,:,:)
867            zsshn_adout(:,:) = sshn_ad(:,:)
868            zgcx_adout (:,:) = gcx_ad (:,:)
869            zgcxb_adout(:,:) = gcxb_ad(:,:)
870
871            !--------------------------------------------------------------------
872            ! Compute the scalar product: dx^T L^T W dy
873            !--------------------------------------------------------------------
874
875            zsp2 =   DOT_PRODUCT( zua_tlin  , zua_adout   ) &
876               &   + DOT_PRODUCT( zva_tlin  , zva_adout   ) &
877               &   + DOT_PRODUCT( zub_tlin  , zub_adout   ) &
878               &   + DOT_PRODUCT( zvb_tlin  , zvb_adout   ) &
879               &   + DOT_PRODUCT( zgcx_tlin , zgcx_adout  ) &
880               &   + DOT_PRODUCT( zgcxb_tlin, zgcxb_adout ) &
881               &   + DOT_PRODUCT( zsshn_tlin, zsshn_adout )
882
883            ! Compare the scalar products
884
885            !    14 char:'12345678901234'
886            IF ( istp == nit000 ) THEN
887               SELECT CASE (jpert)
888               CASE(1)
889                  cl_name = 'spg_flt  Ua T1'
890               CASE(2)
891                  cl_name = 'spg_flt  Va T1'
892               CASE(3)
893                  cl_name = 'spg_flt  Ub T1'
894               CASE(4)
895                  cl_name = 'spg_flt  Vb T1'
896               CASE(5)
897                  cl_name = 'spg_flt ssh T1'
898               CASE(jpertmax)
899                  cl_name = 'dyn_spg_flt T1'
900               END SELECT
901            ELSEIF ( istp == nitend ) THEN
902               SELECT CASE (jpert)
903               CASE(1)
904                  cl_name = 'spg_flt  Ua T2'
905               CASE(2)
906                  cl_name = 'spg_flt  Va T2'
907               CASE(3)
908                  cl_name = 'spg_flt  Ub T2'
909               CASE(4)
910                  cl_name = 'spg_flt  Vb T2'
911               CASE(5)
912                  cl_name = 'spg_flt ssh T2'
913               CASE(jpertmax)
914                  cl_name = 'dyn_spg_flt T2'
915               END SELECT
916            END IF
917            CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
918
919         END DO
920      END DO
921
922      nitsor(:) = jp_it0adj  ! restore nitsor to avoid non reproducible results with or without the tests
923
924      ! Deallocate memory
925
926      DEALLOCATE( &
927         & zua_tlin,  &
928         & zva_tlin,  &
929         & zub_tlin,  &
930         & zvb_tlin,  &
931         & zua_tlout, &
932         & zva_tlout, &
933         & zua_adin,  &
934         & zva_adin,  &
935         & zua_adout, &
936         & zva_adout, &
937         & zub_adout, &
938         & zvb_adout, &
939         & znu        &
940         & )
941      DEALLOCATE( &
942         & zsshn_tlin, &
943         & zsshn_adout,&
944         & znssh       &
945         & )
946      DEALLOCATE( zgcx_tlin , zgcx_tlout , zgcx_adin , zgcx_adout,  &
947         & zgcxb_tlin, zgcxb_tlout, zgcxb_adin, zgcxb_adout         )
948   END SUBROUTINE dyn_spg_flt_adj_tst
949
950# else
951   !!----------------------------------------------------------------------
952   !!   Default case :   Empty module   No standart explicit free surface
953   !!----------------------------------------------------------------------
954CONTAINS
955   SUBROUTINE dyn_spg_flt_tan( kt, kindic )       ! Empty routine
956      WRITE(*,*) 'dyn_spg_flt: You should not have seen this print! error?', kt
957   END SUBROUTINE dyn_spg_flt_tan
958   SUBROUTINE dyn_spg_flt_adj( kt, kindic )       ! Empty routine
959      WRITE(*,*) 'dyn_spg_flt: You should not have seen this print! error?', kt
960   END SUBROUTINE dyn_spg_flt_adj
961   SUBROUTINE dyn_spg_flt_adj_tst( kt )       ! Empty routine
962      WRITE(*,*) 'dyn_spg_flt: You should not have seen this print! error?', kt
963   END SUBROUTINE dyn_spg_flt_adj_tst
964   SUBROUTINE dyn_spg_flt_tlm_tst( kt )       ! Empty routine
965      WRITE(*,*) 'dyn_spg_flt: You should not have seen this print! error?', kt
966   END SUBROUTINE dyn_spg_flt_tlm_tst
967# endif
968#endif
969END MODULE dynspg_flt_tam
Note: See TracBrowser for help on using the repository browser.