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.
dynnxt_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/dynnxt_tam.F90 @ 5196

Last change on this file since 5196 was 4577, checked in by pabouttier, 10 years ago

Fix wrong calls to lbc_lnk_adj in dyn_nxt_adj, see Ticket #1272

  • Property svn:executable set to *
File size: 27.7 KB
Line 
1MODULE dynnxt_tam
2#ifdef key_tam
3   !!======================================================================
4   !!                       ***  MODULE  dynnxt_tam  ***
5   !! Ocean dynamics: time stepping
6   !!                 Tangent and Adjoint Module
7   !!======================================================================
8   !! History of the direct module:
9   !!            OPA  !  1987-02  (P. Andrich, D. L Hostis)  Original code
10   !!                 !  1990-10  (C. Levy, G. Madec)
11   !!            7.0  !  1993-03  (M. Guyon)  symetrical conditions
12   !!            8.0  !  1997-02  (G. Madec & M. Imbard)  opa, release 8.0
13   !!            8.2  !  1997-04  (A. Weaver)  Euler forward step
14   !!             -   !  1997-06  (G. Madec)  lateral boudary cond., lbc routine
15   !!    NEMO    1.0  !  2002-08  (G. Madec)  F90: Free form and module
16   !!             -   !  2002-10  (C. Talandier, A-M. Treguier) Open boundary cond.
17   !!            2.0  !  2005-11  (V. Garnier) Surface pressure gradient organization
18   !!            2.3  !  2007-07  (D. Storkey) Calls to BDY routines.
19   !!            3.2  !  2009-06  (G. Madec, R.Benshila)  re-introduce the vvl option
20   !! History of the TAM routine:
21   !!            9.0  !  2008-06  (A. Vidard) Skeleton
22   !!                 !  2008-08  (A. Vidard) tangent of the 05-11 version
23   !!                 !  2008-08  (A. Vidard) tangent of the 07-07 version
24   !!            3.2  !  2010-04  (F. Vigilant) 3.2 conversion
25   !!            3.4  !  2012-07  (P.-A. Bouttier) 3.4 conversion
26   !!-------------------------------------------------------------------------
27   !!----------------------------------------------------------------------
28   !!   dyn_nxt_tan  : update the horizontal velocity from the momentum trend
29   !!   dyn_nxt_adj  : update the horizontal velocity from the momentum trend
30   !!----------------------------------------------------------------------
31   !! * Modules used
32   USE par_kind
33   USE par_oce
34   USE oce_tam
35   USE dom_oce
36   USE in_out_manager
37   USE dynspg_oce
38   USE dynadv
39   USE lbclnk
40   USE lbclnk_tam
41   USE gridrandom
42   USE dotprodfld
43   USE tstool_tam
44   USE lib_mpp
45   USE wrk_nemo
46   USE timing
47
48   IMPLICIT NONE
49   PRIVATE
50
51   !! * Accessibility
52   PUBLIC dyn_nxt_tan            ! routine called by step.F90
53   PUBLIC dyn_nxt_adj            ! routine called by step.F90
54   PUBLIC dyn_nxt_adj_tst        ! routine called by step.F90
55   !! * Substitutions
56#  include "domzgr_substitute.h90"
57   !!----------------------------------------------------------------------
58
59CONTAINS
60
61   SUBROUTINE dyn_nxt_tan ( kt )
62      !!----------------------------------------------------------------------
63      !!                  ***  ROUTINE dyn_nxt_tan  ***
64      !!
65      !! ** Purpose :   Compute the after horizontal velocity. Apply the boundary
66      !!             condition on the after velocity, achieved the time stepping
67      !!             by applying the Asselin filter on now fields and swapping
68      !!             the fields.
69      !!
70      !! ** Method  : * After velocity is compute using a leap-frog scheme:
71      !!                       (ua,va) = (ub,vb) + 2 rdt (ua,va)
72      !!             Note that with flux form advection and variable volume layer
73      !!             (lk_vvl=T), the leap-frog is applied on thickness weighted
74      !!             velocity.
75      !!             Note also that in filtered free surface (lk_dynspg_flt=T),
76      !!             the time stepping has already been done in dynspg module
77      !!
78      !!              * Apply lateral boundary conditions on after velocity
79      !!             at the local domain boundaries through lbc_lnk call,
80      !!             at the radiative open boundaries (lk_obc=T),
81      !!             at the relaxed   open boundaries (lk_bdy=T), and
82      !!             at the AGRIF zoom     boundaries (lk_agrif=T)
83      !!
84      !!              * Apply the time filter applied and swap of the dynamics
85      !!             arrays to start the next time step:
86      !!                (ub,vb) = (un,vn) + atfp [ (ub,vb) + (ua,va) - 2 (un,vn) ]
87      !!                (un,vn) = (ua,va).
88      !!             Note that with flux form advection and variable volume layer
89      !!             (lk_vvl=T), the time filter is applied on thickness weighted
90      !!             velocity.
91      !!
92      !! ** Action :   ub,vb   filtered before horizontal velocity of next time-step
93      !!               un,vn   now horizontal velocity of next time-step
94      !!----------------------------------------------------------------------
95      !! * Arguments
96      INTEGER, INTENT( in ) ::   kt      ! ocean time-step index
97      !! * Local declarations
98#if ! defined key_dynspg_flt
99      REAL(wp) ::   z2dt         ! temporary scalar
100#endif
101      INTEGER  ::   ji, jj, jk, iku, ikv         ! dummy loop indices
102      REAL(wp) ::   zue3atl , zue3ntl , zue3btl  ! temporary scalar
103      REAL(wp) ::   zve3atl , zve3ntl , zve3btl  !    -         -
104      REAL(wp) ::   zuftl   , zvftl              !    -         -
105      !!----------------------------------------------------------------------
106      !
107      !
108      IF( nn_timing == 1 )  CALL timing_start('dyn_nxt_tan')
109      !
110      IF( kt == nit000 ) THEN
111         IF(lwp) WRITE(numout,*)
112         IF(lwp) WRITE(numout,*) 'dyn_nxt_tan : time stepping'
113         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
114      ENDIF
115
116#if defined key_dynspg_flt
117      !
118      ! Next velocity :   Leap-frog time stepping already done in dynspg_flt.F routine
119      ! -------------
120
121      ! Update after velocity on domain lateral boundaries      (only local domain required)
122      ! --------------------------------------------------
123      CALL lbc_lnk( ua_tl, 'U', -1.0_wp )         ! local domain boundaries
124      CALL lbc_lnk( va_tl, 'V', -1.0_wp )
125      !
126#else
127      ! Next velocity :   Leap-frog time stepping
128      ! -------------
129      z2dt = 2. * rdt                                 ! Euler or leap-frog time step
130      IF( neuler == 0 .AND. kt == nit000 )  z2dt = rdt
131      !
132      IF( ln_dynadv_vec .OR. .NOT. lk_vvl ) THEN      ! applied on velocity
133         DO jk = 1, jpkm1
134            ua_tl(:,:,jk) = ( ub_tl(:,:,jk) + z2dt * ua_tl(:,:,jk) ) * umask(:,:,jk)
135            va_tl(:,:,jk) = ( vb_tl(:,:,jk) + z2dt * va_tl(:,:,jk) ) * vmask(:,:,jk)
136         END DO
137      ELSE                                            ! applied on thickness weighted velocity
138         DO jk = 1, jpkm1
139            ua_tl(:,:,jk) = (          ub_tl(:,:,jk) * fse3u_b(:,:,jk)      &
140               &              + z2dt * ua_tl(:,:,jk) * fse3u_n(:,:,jk)  )   &
141               &            / fse3u_a(:,:,jk) * umask(:,:,jk)
142            va_tl(:,:,jk) = (          vb_tl(:,:,jk) * fse3v_b(:,:,jk)      &
143               &              + z2dt * va_tl(:,:,jk) * fse3v_n(:,:,jk)  )   &
144               &            / fse3v_a(:,:,jk) * vmask(:,:,jk)
145         END DO
146      ENDIF
147
148      ! Update after velocity on domain lateral boundaries
149      ! --------------------------------------------------
150      CALL lbc_lnk( ua_tl, 'U', -1.0_wp )     !* local domain boundaries
151      CALL lbc_lnk( va_tl, 'V', -1.0_wp )
152      !
153#endif
154      ! Time filter and swap of dynamics arrays
155      ! ------------------------------------------
156      IF( neuler == 0 .AND. kt == nit000 ) THEN        !* Euler at first time-step: only swap
157         DO jk = 1, jpkm1
158            un_tl(:,:,jk) = ua_tl(:,:,jk)                          ! un <-- ua
159            vn_tl(:,:,jk) = va_tl(:,:,jk)
160         END DO
161      ELSE                                             !* Leap-Frog : Asselin filter and swap
162         IF( .NOT. lk_vvl ) THEN          ! applied on velocity
163            DO jk = 1, jpkm1
164               DO jj = 1, jpj
165                  DO ji = 1, jpi
166                     zuftl = un_tl(ji,jj,jk) + atfp * ( ub_tl(ji,jj,jk) - 2._wp * un_tl(ji,jj,jk) + ua_tl(ji,jj,jk) )
167                     zvftl = vn_tl(ji,jj,jk) + atfp * ( vb_tl(ji,jj,jk) - 2._wp * vn_tl(ji,jj,jk) + va_tl(ji,jj,jk) )
168                     !
169                     ub_tl(ji,jj,jk) = zuftl                      ! ub <-- filtered velocity
170                     vb_tl(ji,jj,jk) = zvftl
171                     un_tl(ji,jj,jk) = ua_tl(ji,jj,jk)             ! un <-- ua
172                     vn_tl(ji,jj,jk) = va_tl(ji,jj,jk)
173                  END DO
174               END DO
175            END DO
176         ELSE                                                ! applied on thickness weighted velocity
177            CALL ctl_stop ( 'dyn_nxt_tan: key_vvl not available yet in TAM' )
178         ENDIF
179      ENDIF
180      !
181      IF( nn_timing == 1 )  CALL timing_stop('dyn_nxt_tan')
182      !
183   END SUBROUTINE dyn_nxt_tan
184
185   SUBROUTINE dyn_nxt_adj ( kt )
186      !!----------------------------------------------------------------------
187      !!                  ***  ROUTINE dyn_nxt_tan  ***
188      !!
189      !! ** Purpose :   Compute the after horizontal velocity. Apply the boundary
190      !!             condition on the after velocity, achieved the time stepping
191      !!             by applying the Asselin filter on now fields and swapping
192      !!             the fields.
193      !!
194      !! ** Method  : * After velocity is compute using a leap-frog scheme:
195      !!                       (ua,va) = (ub,vb) + 2 rdt (ua,va)
196      !!             Note that with flux form advection and variable volume layer
197      !!             (lk_vvl=T), the leap-frog is applied on thickness weighted
198      !!             velocity.
199      !!             Note also that in filtered free surface (lk_dynspg_flt=T),
200      !!             the time stepping has already been done in dynspg module
201      !!
202      !!              * Apply lateral boundary conditions on after velocity
203      !!             at the local domain boundaries through lbc_lnk call,
204      !!             at the radiative open boundaries (lk_obc=T),
205      !!             at the relaxed   open boundaries (lk_bdy=T), and
206      !!             at the AGRIF zoom     boundaries (lk_agrif=T)
207      !!
208      !!              * Apply the time filter applied and swap of the dynamics
209      !!             arrays to start the next time step:
210      !!                (ub,vb) = (un,vn) + atfp [ (ub,vb) + (ua,va) - 2 (un,vn) ]
211      !!                (un,vn) = (ua,va).
212      !!             Note that with flux form advection and variable volume layer
213      !!             (lk_vvl=T), the time filter is applied on thickness weighted
214      !!             velocity.
215      !!
216      !! ** Action :   ub,vb   filtered before horizontal velocity of next time-step
217      !!               un,vn   now horizontal velocity of next time-step
218      !!----------------------------------------------------------------------
219      !! * Arguments
220      INTEGER, INTENT( in ) ::   kt      ! ocean time-step index
221#if ! defined key_dynspg_flt
222      REAL(wp) ::   z2dt         ! temporary scalar
223#endif
224      INTEGER  ::   ji, jj, jk, iku, ikv   ! dummy loop indices
225      REAL(wp) ::   zue3aad , zue3nad , zue3bad  ! temporary scalar
226      REAL(wp) ::   zve3aad , zve3nad , zve3bad  !    -         -
227      REAL(wp) ::   zufad   , zvfad              !    -         -
228      !!----------------------------------------------------------------------
229      !
230      IF( nn_timing == 1 )  CALL timing_start('dyn_nxt_adj')
231      !
232      ! adjoint local variables initialization
233      zue3aad = 0.0_wp ;  zue3nad = 0.0_wp ; zue3bad = 0.0_wp
234      zve3aad = 0.0_wp ;  zve3nad = 0.0_wp ; zve3bad = 0.0_wp
235      zufad   = 0.0_wp ;  zvfad   = 0.0_wp
236
237      IF( kt == nitend ) THEN
238         IF(lwp) WRITE(numout,*)
239         IF(lwp) WRITE(numout,*) 'dyn_nxt_adj : time stepping'
240         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
241      ENDIF
242      !
243      ! Time filter and swap of dynamics arrays
244      ! ------------------------------------------
245      IF( neuler == 0 .AND. kt == nit000 ) THEN        !* Euler at first time-step: only swap
246         DO jk = 1, jpkm1
247            ua_ad(:,:,jk) = ua_ad(:,:,jk) + un_ad(:,:,jk)          ! un_ad <-- ua_ad
248            va_ad(:,:,jk) = va_ad(:,:,jk) + vn_ad(:,:,jk)
249            un_ad(:,:,jk) = 0.0_wp
250            vn_ad(:,:,jk) = 0.0_wp
251         END DO
252      ELSE                                             !* Leap-Frog : Asselin filter and swap
253         IF( .NOT. lk_vvl ) THEN          ! applied on velocity
254            DO jk = 1, jpkm1
255               DO jj = 1, jpj
256                  DO ji = 1, jpi
257                     va_ad(ji,jj,jk) = va_ad(ji,jj,jk) + vn_ad(ji,jj,jk)
258                     ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) + un_ad(ji,jj,jk)
259                     un_ad(ji,jj,jk) = 0.0_wp
260                     vn_ad(ji,jj,jk) = 0.0_wp
261                     zvfad           = zvfad + vb_ad(ji,jj,jk)
262                     zufad           = zufad + ub_ad(ji,jj,jk)
263                     ub_ad(ji,jj,jk) = 0.0_wp
264                     vb_ad(ji,jj,jk) = 0.0_wp
265
266                     ub_ad(ji,jj,jk) = ub_ad(ji,jj,jk) + atfp  * zufad
267                     ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) + atfp  * zufad
268                     un_ad(ji,jj,jk) = un_ad(ji,jj,jk) + ( 1 - 2._wp * atfp ) * zufad
269                     vb_ad(ji,jj,jk) = vb_ad(ji,jj,jk) + atfp  * zvfad
270                     va_ad(ji,jj,jk) = va_ad(ji,jj,jk) + atfp  * zvfad
271                     vn_ad(ji,jj,jk) = vn_ad(ji,jj,jk) + ( 1 - 2._wp * atfp ) * zvfad
272                     zufad           = 0.0_wp
273                     zvfad           = 0.0_wp
274                  END DO
275               END DO
276            END DO
277         ELSE                                                ! applied on thickness weighted velocity
278            CALL ctl_stop ( 'dyn_nxt_adj: key_vvl not available yet in TAM' )
279         ENDIF
280      ENDIF
281
282#if defined key_dynspg_flt
283      !
284      ! Next velocity :   Leap-frog time stepping already done in dynspg_flt.F routine
285      ! -------------
286
287      ! Update after velocity on domain lateral boundaries      (only local domain required)
288      ! --------------------------------------------------
289      CALL lbc_lnk_adj( ua_ad, 'U', -1.0_wp )         ! local domain boundaries
290      CALL lbc_lnk_adj( va_ad, 'V', -1.0_wp )
291      !
292#else
293      ! Update after velocity on domain lateral boundaries
294      ! --------------------------------------------------
295      CALL lbc_lnk_adj( va_ad, 'V', -1.0_wp )     !* local domain boundaries
296      CALL lbc_lnk_adj( ua_ad, 'U', -1.0_wp )
297      ! Next velocity :   Leap-frog time stepping
298      ! -------------
299      z2dt = 2. * rdt                                 ! Euler or leap-frog time step
300      IF( neuler == 0 .AND. kt == nit000 )  z2dt = rdt
301      !
302      IF( ln_dynadv_vec .OR. .NOT. lk_vvl ) THEN      ! applied on velocity
303         DO jk = 1, jpkm1
304            ua_ad(:,:,jk) = ua_ad(:,:,jk) * umask(:,:,jk)
305            va_ad(:,:,jk) = va_ad(:,:,jk) * vmask(:,:,jk)
306            ub_ad(:,:,jk) = ub_ad(:,:,jk) + ua_ad(:,:,jk)
307            vb_ad(:,:,jk) = vb_ad(:,:,jk) + va_ad(:,:,jk)
308            ua_ad(:,:,jk) = ua_ad(:,:,jk) * z2dt
309            va_ad(:,:,jk) = va_ad(:,:,jk) * z2dt
310         END DO
311      ELSE                                            ! applied on thickness weighted velocity
312         DO jk = 1, jpkm1
313            ua_ad(:,:,jk) = ua_ad(:,:,jk)  / fse3u_a(:,:,jk) * umask(:,:,jk)
314            va_ad(:,:,jk) = va_ad(:,:,jk)  / fse3v_a(:,:,jk) * vmask(:,:,jk)
315            ub_ad(:,:,jk) = ub_ad(:,:,jk) + ua_ad(:,:,jk)  * fse3u_b(:,:,jk)
316            vb_ad(:,:,jk) = vb_ad(:,:,jk) + va_ad(:,:,jk)  * fse3v_b(:,:,jk)
317            ua_ad(:,:,jk) = ua_ad(:,:,jk) * z2dt *fse3u_n(:,:,jk)
318            va_ad(:,:,jk) = va_ad(:,:,jk) * z2dt *fse3v_n(:,:,jk)
319         END DO
320      ENDIF
321#endif
322      !
323      IF( nn_timing == 1 )  CALL timing_stop('dyn_nxt_adj')
324      !
325   END SUBROUTINE dyn_nxt_adj
326
327   SUBROUTINE dyn_nxt_adj_tst( kumadt )
328      !!-----------------------------------------------------------------------
329      !!
330      !!                  ***  ROUTINE dyn_nxt_adj_tst ***
331      !!
332      !! ** Purpose : Test the adjoint routine.
333      !!
334      !! ** Method  : Verify the scalar product
335      !!
336      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
337      !!
338      !!              where  L   = tangent routine
339      !!                     L^T = adjoint routine
340      !!                     W   = diagonal matrix of scale factors
341      !!                     dx  = input perturbation (random field)
342      !!                     dy  = L dx
343      !!
344      !! ** Action  : Separate tests are applied for the following dx and dy:
345      !!
346      !!              1) dx = ( SSH ) and dy = ( SSH )
347      !!
348      !! History :
349      !!        ! 08-08 (A. Vidard)
350      !!-----------------------------------------------------------------------
351      !! * Modules used
352
353      !! * Arguments
354      INTEGER, INTENT(IN) :: &
355         & kumadt             ! Output unit
356
357      INTEGER :: &
358         & ji,    &        ! dummy loop indices
359         & jj,    &
360         & jk
361      INTEGER, DIMENSION(jpi,jpj) :: &
362         & iseed_2d        ! 2D seed for the random number generator
363
364      !! * Local declarations
365      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
366         & zun_tlin,     & ! Tangent input:   now   u-velocity
367         & zvn_tlin,     & ! Tangent input:   now   v-velocity
368         & zua_tlin,     & ! Tangent input:  after  u-velocity
369         & zva_tlin,     & ! Tangent input:  after  u-velocity
370         & zub_tlin,     & ! Tangent input:  before u-velocity
371         & zvb_tlin,     & ! Tangent input:  before u-velocity
372         & zun_adin,     & ! Adjoint input:   now   u-velocity
373         & zvn_adin,     & ! Adjoint input:   now   v-velocity
374         & zua_adin,     & ! Adjoint input:  after  u-velocity
375         & zva_adin,     & ! Adjoint input:  after  u-velocity
376         & zub_adin,     & ! Adjoint input:  before u-velocity
377         & zvb_adin,     & ! Adjoint input:  before u-velocity
378         & zun_tlout,    & ! Tangent output:  now   u-velocity
379         & zvn_tlout,    & ! Tangent output:  now   v-velocity
380         & zua_tlout,    & ! Tangent output: after  u-velocity
381         & zva_tlout,    & ! Tangent output: after  u-velocity
382         & zub_tlout,    & ! Tangent output: before u-velocity
383         & zvb_tlout,    & ! Tangent output: before u-velocity
384         & zun_adout,    & ! Adjoint output:  now   u-velocity
385         & zvn_adout,    & ! Adjoint output:  now   v-velocity
386         & zua_adout,    & ! Adjoint output: after  u-velocity
387         & zva_adout,    & ! Adjoint output: after  u-velocity
388         & zub_adout,    & ! Adjoint output: before u-velocity
389         & zvb_adout,    & ! Adjoint output: before u-velocity
390         & znu,          & ! 3D random field for u
391         & znv,          & ! 3D random field for v
392         & zbu,          & ! 3D random field for u
393         & zbv,          & ! 3D random field for v
394         & zau,          & ! 3D random field for u
395         & zav             ! 3D random field for v
396
397      REAL(KIND=wp) :: &
398         & zsp1,         & ! scalar product involving the tangent routine
399         & zsp1_1,       & !   scalar product components
400         & zsp1_2,       &
401         & zsp1_3,       &
402         & zsp1_4,       &
403         & zsp1_5,       &
404         & zsp1_6,       &
405         & zsp2,         & ! scalar product involving the adjoint routine
406         & zsp2_1,       & !   scalar product components
407         & zsp2_2,       &
408         & zsp2_3,       &
409         & zsp2_4,       &
410         & zsp2_5,       &
411         & zsp2_6
412      CHARACTER(LEN=14) :: cl_name
413
414      ! Allocate memory
415
416      ALLOCATE( &
417         & zun_tlin(jpi,jpj,jpk),     &
418         & zvn_tlin(jpi,jpj,jpk),     &
419         & zua_tlin(jpi,jpj,jpk),     &
420         & zva_tlin(jpi,jpj,jpk),     &
421         & zub_tlin(jpi,jpj,jpk),     &
422         & zvb_tlin(jpi,jpj,jpk),     &
423         & zun_adin(jpi,jpj,jpk),     &
424         & zvn_adin(jpi,jpj,jpk),     &
425         & zua_adin(jpi,jpj,jpk),     &
426         & zva_adin(jpi,jpj,jpk),     &
427         & zub_adin(jpi,jpj,jpk),     &
428         & zvb_adin(jpi,jpj,jpk),     &
429         & zun_tlout(jpi,jpj,jpk),    &
430         & zvn_tlout(jpi,jpj,jpk),    &
431         & zua_tlout(jpi,jpj,jpk),    &
432         & zva_tlout(jpi,jpj,jpk),    &
433         & zub_tlout(jpi,jpj,jpk),    &
434         & zvb_tlout(jpi,jpj,jpk),    &
435         & zun_adout(jpi,jpj,jpk),    &
436         & zvn_adout(jpi,jpj,jpk),    &
437         & zua_adout(jpi,jpj,jpk),    &
438         & zva_adout(jpi,jpj,jpk),    &
439         & zub_adout(jpi,jpj,jpk),    &
440         & zvb_adout(jpi,jpj,jpk),    &
441         & znu(jpi,jpj,jpk),          &
442         & znv(jpi,jpj,jpk),          &
443         & zbu(jpi,jpj,jpk),          &
444         & zbv(jpi,jpj,jpk),          &
445         & zau(jpi,jpj,jpk),          &
446         & zav(jpi,jpj,jpk)           &
447         & )
448
449
450      !==================================================================
451      ! 1) dx = ( un_tl, vn_tl, hdivn_tl ) and
452      !    dy = ( hdivb_tl, hdivn_tl )
453      !==================================================================
454
455      !--------------------------------------------------------------------
456      ! Reset the tangent and adjoint variables
457      !--------------------------------------------------------------------
458
459          zun_tlin(:,:,:) = 0.0_wp
460          zvn_tlin(:,:,:) = 0.0_wp
461          zua_tlin(:,:,:) = 0.0_wp
462          zva_tlin(:,:,:) = 0.0_wp
463          zub_tlin(:,:,:) = 0.0_wp
464          zvb_tlin(:,:,:) = 0.0_wp
465          zun_adin(:,:,:) = 0.0_wp
466          zvn_adin(:,:,:) = 0.0_wp
467          zua_adin(:,:,:) = 0.0_wp
468          zva_adin(:,:,:) = 0.0_wp
469          zub_adin(:,:,:) = 0.0_wp
470          zvb_adin(:,:,:) = 0.0_wp
471          zun_tlout(:,:,:) = 0.0_wp
472          zvn_tlout(:,:,:) = 0.0_wp
473          zua_tlout(:,:,:) = 0.0_wp
474          zva_tlout(:,:,:) = 0.0_wp
475          zub_tlout(:,:,:) = 0.0_wp
476          zvb_tlout(:,:,:) = 0.0_wp
477          zun_adout(:,:,:) = 0.0_wp
478          zvn_adout(:,:,:) = 0.0_wp
479          zua_adout(:,:,:) = 0.0_wp
480          zva_adout(:,:,:) = 0.0_wp
481          zub_adout(:,:,:) = 0.0_wp
482          zvb_adout(:,:,:) = 0.0_wp
483          znu(:,:,:) = 0.0_wp
484          znv(:,:,:) = 0.0_wp
485          zbu(:,:,:) = 0.0_wp
486          zbv(:,:,:) = 0.0_wp
487          zau(:,:,:) = 0.0_wp
488          zav(:,:,:) = 0.0_wp
489
490          un_tl(:,:,:) = 0.0_wp
491          vn_tl(:,:,:) = 0.0_wp
492          ua_tl(:,:,:) = 0.0_wp
493          va_tl(:,:,:) = 0.0_wp
494          ub_tl(:,:,:) = 0.0_wp
495          vb_tl(:,:,:) = 0.0_wp
496          un_ad(:,:,:) = 0.0_wp
497          vn_ad(:,:,:) = 0.0_wp
498          ua_ad(:,:,:) = 0.0_wp
499          va_ad(:,:,:) = 0.0_wp
500          ub_ad(:,:,:) = 0.0_wp
501          vb_ad(:,:,:) = 0.0_wp
502
503
504      !--------------------------------------------------------------------
505      ! Initialize the tangent input with random noise: dx
506      !--------------------------------------------------------------------
507
508      CALL grid_random(  znu, 'U', 0.0_wp, stdu )
509      CALL grid_random(  znv, 'V', 0.0_wp, stdv )
510      CALL grid_random(  zbu, 'U', 0.0_wp, stdu )
511      CALL grid_random(  zbv, 'V', 0.0_wp, stdv )
512      CALL grid_random(  zau, 'U', 0.0_wp, stdu )
513      CALL grid_random(  zav, 'V', 0.0_wp, stdv )
514
515      DO jk = 1, jpk
516         DO jj = nldj, nlej
517            DO ji = nldi, nlei
518               zun_tlin(ji,jj,jk) = znu(ji,jj,jk)
519               zvn_tlin(ji,jj,jk) = znv(ji,jj,jk)
520               zub_tlin(ji,jj,jk) = zbu(ji,jj,jk)
521               zvb_tlin(ji,jj,jk) = zbv(ji,jj,jk)
522               zua_tlin(ji,jj,jk) = zau(ji,jj,jk)
523               zva_tlin(ji,jj,jk) = zav(ji,jj,jk)
524            END DO
525         END DO
526      END DO
527
528      un_tl(:,:,:) = zun_tlin(:,:,:)
529      vn_tl(:,:,:) = zvn_tlin(:,:,:)
530      ub_tl(:,:,:) = zub_tlin(:,:,:)
531      vb_tl(:,:,:) = zvb_tlin(:,:,:)
532      ua_tl(:,:,:) = zua_tlin(:,:,:)
533      va_tl(:,:,:) = zva_tlin(:,:,:)
534
535      call dyn_nxt_tan ( nit000 )
536
537      zun_tlout(:,:,:) = un_tl(:,:,:)
538      zvn_tlout(:,:,:) = vn_tl(:,:,:)
539      zub_tlout(:,:,:) = ub_tl(:,:,:)
540      zvb_tlout(:,:,:) = vb_tl(:,:,:)
541      zua_tlout(:,:,:) = ua_tl(:,:,:)
542      zva_tlout(:,:,:) = va_tl(:,:,:)
543
544      !--------------------------------------------------------------------
545      ! Initialize the adjoint variables: dy^* = W dy
546      !--------------------------------------------------------------------
547
548      DO jk = 1, jpk
549        DO jj = nldj, nlej
550           DO ji = nldi, nlei
551              zun_adin(ji,jj,jk) = zun_tlout(ji,jj,jk) &
552                 &               * e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) &
553                 &               * umask(ji,jj,jk)
554              zvn_adin(ji,jj,jk) = zvn_tlout(ji,jj,jk) &
555                 &               * e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk) &
556                 &               * vmask(ji,jj,jk)
557              zub_adin(ji,jj,jk) = zub_tlout(ji,jj,jk) &
558                 &               * e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) &
559                 &               * umask(ji,jj,jk)
560              zvb_adin(ji,jj,jk) = zvb_tlout(ji,jj,jk) &
561                 &               * e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk) &
562                 &               * vmask(ji,jj,jk)
563              zua_adin(ji,jj,jk) = zua_tlout(ji,jj,jk) &
564                 &               * e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) &
565                 &               * umask(ji,jj,jk)
566              zva_adin(ji,jj,jk) = zva_tlout(ji,jj,jk) &
567                 &               * e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk) &
568                 &               * vmask(ji,jj,jk)
569            END DO
570         END DO
571      END DO
572      !--------------------------------------------------------------------
573      ! Compute the scalar product: ( L dx )^T W dy
574      !--------------------------------------------------------------------
575
576      zsp1_1 = DOT_PRODUCT( zun_tlout, zun_adin )
577      zsp1_2 = DOT_PRODUCT( zvn_tlout, zvn_adin )
578      zsp1_3 = DOT_PRODUCT( zub_tlout, zub_adin )
579      zsp1_4 = DOT_PRODUCT( zvb_tlout, zvb_adin )
580      zsp1_5 = DOT_PRODUCT( zua_tlout, zua_adin )
581      zsp1_6 = DOT_PRODUCT( zva_tlout, zva_adin )
582      zsp1   = zsp1_1 + zsp1_2 + zsp1_3 + zsp1_4 + zsp1_5 + zsp1_6
583
584      !--------------------------------------------------------------------
585      ! Call the adjoint routine: dx^* = L^T dy^*
586      !--------------------------------------------------------------------
587
588      un_ad(:,:,:) = zun_adin(:,:,:)
589      vn_ad(:,:,:) = zvn_adin(:,:,:)
590      ub_ad(:,:,:) = zub_adin(:,:,:)
591      vb_ad(:,:,:) = zvb_adin(:,:,:)
592      ua_ad(:,:,:) = zua_adin(:,:,:)
593      va_ad(:,:,:) = zva_adin(:,:,:)
594
595      CALL dyn_nxt_adj ( nit000 )
596
597      zun_adout(:,:,:) = un_ad(:,:,:)
598      zvn_adout(:,:,:) = vn_ad(:,:,:)
599      zub_adout(:,:,:) = ub_ad(:,:,:)
600      zvb_adout(:,:,:) = vb_ad(:,:,:)
601      zua_adout(:,:,:) = ua_ad(:,:,:)
602      zva_adout(:,:,:) = va_ad(:,:,:)
603
604      zsp2_1 = DOT_PRODUCT( zun_tlin, zun_adout )
605      zsp2_2 = DOT_PRODUCT( zvn_tlin, zvn_adout )
606      zsp2_3 = DOT_PRODUCT( zub_tlin, zub_adout )
607      zsp2_4 = DOT_PRODUCT( zvb_tlin, zvb_adout )
608      zsp2_5 = DOT_PRODUCT( zua_tlin, zua_adout )
609      zsp2_6 = DOT_PRODUCT( zva_tlin, zva_adout )
610      zsp2   = zsp2_1 + zsp2_2 + zsp2_3 + zsp2_4 + zsp2_5 + zsp2_6
611
612      ! Compare the scalar products
613      ! 14 char:'12345678901234'
614      cl_name = 'dyn_nxt_adj   '
615      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
616
617      DEALLOCATE( &
618         & zun_tlin,     &
619         & zvn_tlin,     &
620         & zua_tlin,     &
621         & zva_tlin,     &
622         & zub_tlin,     &
623         & zvb_tlin,     &
624         & zun_adin,     &
625         & zvn_adin,     &
626         & zua_adin,     &
627         & zva_adin,     &
628         & zub_adin,     &
629         & zvb_adin,     &
630         & zun_tlout,    &
631         & zvn_tlout,    &
632         & zua_tlout,    &
633         & zva_tlout,    &
634         & zub_tlout,    &
635         & zvb_tlout,    &
636         & zun_adout,    &
637         & zvn_adout,    &
638         & zua_adout,    &
639         & zva_adout,    &
640         & zub_adout,    &
641         & zvb_adout,    &
642         & znu,          &
643         & znv,          &
644         & zbu,          &
645         & zbv,          &
646         & zau,          &
647         & zav           &
648         & )
649
650
651   END SUBROUTINE dyn_nxt_adj_tst
652   !!======================================================================
653#endif
654END MODULE dynnxt_tam
Note: See TracBrowser for help on using the repository browser.