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

source: branches/TAM_V3_0/NEMOTAM/OPATAM_SRC/DYN/wzvmod_tam.F90 @ 1885

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

add TAM sources

File size: 23.6 KB
Line 
1MODULE wzvmod_tam
2#if defined key_tam
3   !!==========================================================================
4   !!     ***  MODULE  wzvmod_tam : TANGENT/ADJOINT OF MODULE wzvmod  ***
5   !!
6   !! Ocean diagnostic variable : vertical velocity
7   !!
8   !!==========================================================================
9   !! History of the direct module:
10   !!             5.0  !  90-10  (C. Levy, G. Madec)  Original code
11   !!             7.0  !  96-01  (G. Madec)  Statement function for e3
12   !!             8.5  !  02-07  (G. Madec)  Free form, F90
13   !!                  !  07-07  (D. Storkey) Zero zhdiv at open boundary (BDY)
14   !! History of the TAM module:
15   !!             7.0  !  95-01  (F. Van den Berghe)
16   !!             8.0  !  96-01  (A. Weaver)
17   !!             8.1  !  98-03  (A. Weaver)
18   !!             8.2  !  00-08  (A. Weaver)
19   !!             9.0  !  08-06  (A. Vidard) Skeleton
20   !!             9.0  !  08-07  (A. Weaver) Tam of the 02-07 version
21   !!             9.0  !  08-07  (A. Vidard) Tam of the 07-07 version
22   !!----------------------------------------------------------------------
23   !!   wzv_tan        : Compute the vertical velocity: tangent routine
24   !!   wzv_adj        : Compute the vertical velocity: adjoint routine
25   !!   wzv_adj_tst    : Test of the adjoint routine
26   !!----------------------------------------------------------------------
27   !! * Modules used
28   USE par_kind      , ONLY: & ! Precision variables
29      & wp
30   USE par_oce       , ONLY: & ! Ocean space and time domain variables
31      & jpi,                 &
32      & jpj,                 & 
33      & jpk,                 &
34      & jpim1,               &
35      & jpjm1,               &
36      & jpkm1,               &
37      & jpiglo
38   USE in_out_manager, ONLY: & ! I/O manager
39      & lwp,                 &
40      & numout,              & 
41      & nit000,              &
42      & ln_ctl
43   USE dom_oce       , ONLY: & ! Ocean space and time domain
44      & e2u,                 &
45      & e1v,                 &
46      & e1t,                 &
47      & e2t,                 &
48# if defined key_vvl
49      & e3t_1,               &
50# else
51#  if defined key_zco
52      & e3t_0,               &
53#  else
54      & e3t,                 &
55#  endif
56# endif
57# if defined key_zco
58!      & e3u_0,               &  scale factor is identical to e3t_0
59!      & e3v_0,               &
60# else
61      & e3u,                 &
62      & e3v,                 &
63# endif
64      & lk_vvl,              &
65      & rdt,                 &
66      & neuler,              &
67      & tmask,               &
68      & mig,                 &
69      & mjg,                 &
70      & nldi,                &
71      & nldj,                &
72      & nlei,                &
73      & nlej
74   USE prtctl        , ONLY: & ! Print control
75      & prt_ctl
76   USE domvvl        , ONLY: & ! Variable volume
77      & mut
78   USE phycst        , ONLY: & ! Physical constants
79      & rauw
80# if defined key_obc
81   USE obc_par       , ONLY: & ! Open boundary conditions
82      & lp_obc_east,         &
83      & lp_obc_west,         &
84      & lp_obc_north,        &
85      & lp_obc_south
86   USE obc_oce       , ONLY: & ! Open boundary conditions
87      & nie0p1,              &
88      & nie1p1,              &
89      & njn0p1,              &
90      & njn1p1,              &
91      & nje0,                &
92      & nje1,                &
93      & niw0,                &
94      & niw1,                &
95      & njw0,                &
96      & njw1,                &
97      & nin0,                &
98      & nin1,                &
99      & nis0,                &
100      & nis1,                &
101      & njs0,                &
102      & njs1
103# endif
104   USE lbclnk        , ONLY: & ! Lateral boundary conditions
105      & lbc_lnk
106
107   USE lbclnk_tam    , ONLY: & ! TAM lateral boundary conditions
108      & lbc_lnk_adj
109   USE divcur_tam    , ONLY: & ! TAM horizontal divergence and relative
110      & div_cur_tan            ! vorticity
111   USE oce_tam       , ONLY: & ! TAM ocean dynamics and tracers variables
112      & un_tl,               &
113      & un_ad,               &
114      & vn_tl,               &
115      & vn_ad,               &
116      & wn_tl,               &
117      & wn_ad,               &
118      & hdivn_tl,            &
119      & hdivn_ad,            &
120      & sshb_tl,             &
121      & sshb_ad
122   USE sbc_oce_tam   , ONLY: & ! surface variables
123      & emp_tl,              &
124      & emp_ad
125   USE gridrandom    , ONLY: & ! Random Gaussian noise on grids
126      & grid_random
127   USE dotprodfld,     ONLY: & ! Computes dot product for 3D and 2D fields
128      & dot_product
129   USE tstool_tam    , ONLY: &
130      & prntst_adj,          &
131      & stdssh,              &
132      & stdu,                &
133      & stdv
134
135   IMPLICIT NONE
136   PRIVATE
137
138   !! * Routine accessibility
139   PUBLIC wzv_tan,    &   !: tangent routine called by steptan.F90
140      &   wzv_adj,    &   !: adjoint routine called by stepadj.F90
141      &   wzv_adj_tst     !: adjoint test routine
142
143   !! * Substitutions
144#  include "domzgr_substitute.h90"
145
146CONTAINS
147
148   SUBROUTINE wzv_tan( kt )
149      !!----------------------------------------------------------------------
150      !!               ***  ROUTINE wzv_tan : TANGENT OF wzv  ***
151      !!
152      !! ** Purpose of direct routine :
153      !!                Compute the now vertical velocity after the array swap
154      !!
155      !! ** Method of direct routine :  Using the incompressibility hypothesis,
156      !!      the vertical velocity is computed by integrating the horizontal
157      !!      divergence from the bottom to the surface.
158      !!        The boundary conditions are w=0 at the bottom (no flux) and,
159      !!      in regid-lid case, w=0 at the sea surface.
160      !!
161      !! ** action  :   wn array : the now vertical velocity
162      !!----------------------------------------------------------------------
163      !! * Arguments
164      INTEGER, INTENT( in ) :: &
165         & kt           ! ocean time-step index
166
167      !! * Local declarations
168      INTEGER  :: &
169         & jk           ! dummy loop indices
170      !! Variable volume
171      INTEGER  :: &
172         & ji,    &     ! dummy loop indices
173         & jj           
174      REAL(wp) :: &
175         & z2dt,  &     ! temporary scalar
176         & zraur         
177      REAL(wp), DIMENSION (jpi,jpj) :: &
178         & zssha, &
179         & zun,   &
180         & zvn,   &
181         & zhdiv
182      !!----------------------------------------------------------------------
183
184      IF( kt == nit000 ) THEN
185         IF(lwp) WRITE(numout,*)
186         IF(lwp) WRITE(numout,*) 'wzv_tan  : vertical velocity from continuity eq.'
187         IF(lwp) WRITE(numout,*) '~~~~~~~ ' 
188
189         ! bottom boundary condition: w=0 (set once for all)
190         wn_tl(:,:,jpk) = 0.0_wp
191      ENDIF
192
193      IF( lk_vvl ) THEN                ! Variable volume
194         !
195         z2dt = 2.0_wp * rdt                                   ! time step: leap-frog
196         IF( neuler == 0 .AND. kt == nit000 ) z2dt = rdt       ! time step: Euler if restart from rest
197         zraur  = 1.0_wp / rauw
198
199         ! Vertically integrated quantities
200         ! --------------------------------
201         zun(:,:) = 0.0_wp
202         zvn(:,:) = 0.0_wp
203         !
204         DO jk = 1, jpkm1             ! Vertically integrated transports (now)
205            zun(:,:) = zun(:,:) + fse3u(:,:,jk) * un_tl(:,:,jk)
206            zvn(:,:) = zvn(:,:) + fse3v(:,:,jk) * vn_tl(:,:,jk)
207         END DO
208
209         ! Horizontal divergence of barotropic transports
210         !--------------------------------------------------
211         zhdiv(:,:) = 0.0_wp
212         DO jj = 2, jpjm1
213            DO ji = 2, jpim1   ! vector opt.
214               zhdiv(ji,jj) = (  e2u(ji  ,jj  ) * zun(ji  ,jj  )     &
215                  &            - e2u(ji-1,jj  ) * zun(ji-1,jj  )     &
216                  &            + e1v(ji  ,jj  ) * zvn(ji  ,jj  )     &
217                  &            - e1v(ji  ,jj-1) * zvn(ji  ,jj-1) )   &
218                  &           / ( e1t(ji,jj) * e2t(ji,jj) )
219            END DO
220         END DO
221
222# if defined key_obc && ( defined key_dynspg_exp || defined key_dynspg_ts )
223         ! open boundaries (div must be zero behind the open boundary)
224         !  mpp remark: The zeroing of hdiv can probably be extended to 1->jpi/jpj for the correct row/column
225         IF( lp_obc_east  )  zhdiv(nie0p1:nie1p1,nje0  :nje1)   = 0.0_wp ! east
226         IF( lp_obc_west  )  zhdiv(niw0  :niw1  ,njw0  :njw1)   = 0.0_wp ! west
227         IF( lp_obc_north )  zhdiv(nin0  :nin1  ,njn0p1:njn1p1) = 0.0_wp ! north
228         IF( lp_obc_south )  zhdiv(nis0  :nis1  ,njs0  :njs1)   = 0.0_wp ! south
229# endif
230# if defined key_bdy
231         jgrd=1 !: tracer grid.
232         DO jb = 1, nblenrim(jgrd)
233           ji = nbi(jb,jgrd)
234           jj = nbj(jb,jgrd)
235           zhdiv(ji,jj) = 0.e0
236         END DO
237# endif
238
239         CALL lbc_lnk( zhdiv, 'T', 1.0_wp )
240
241         ! Sea surface elevation time stepping
242         ! -----------------------------------
243         zssha(:,:) = sshb_tl(:,:) - z2dt * ( zraur * emp_tl(:,:) &
244            &                      + zhdiv(:,:) ) * tmask(:,:,1)
245
246         ! Vertical velocity computed from bottom
247         ! --------------------------------------
248         DO jk = jpkm1, 1, -1
249            wn_tl(:,:,jk) = wn_tl(:,:,jk+1) - fse3t(:,:,jk) * hdivn_tl(:,:,jk) &
250              &             - ( zssha(:,:) - sshb_tl(:,:) ) &
251              &               * fsve3t(:,:,jk) * mut(:,:,jk) / z2dt
252         END DO
253
254      ELSE                             ! Fixed volume
255
256         ! Vertical velocity computed from bottom
257         ! --------------------------------------
258         DO jk = jpkm1, 1, -1
259            wn_tl(:,:,jk) = wn_tl(:,:,jk+1) - fse3t(:,:,jk) * hdivn_tl(:,:,jk)
260         END DO
261     
262      ENDIF
263
264      IF(ln_ctl) CALL prt_ctl(tab3d_1=wn_tl, clinfo1=' w**2 -   : ', mask1=wn_tl)
265
266   END SUBROUTINE wzv_tan
267
268
269   SUBROUTINE wzv_adj( kt )
270      !!----------------------------------------------------------------------
271      !!               ***  ROUTINE wzv_adj : ADJOINT OF wzv_tan  ***
272      !!
273      !! ** Purpose of direct routine :
274      !!                Compute the now vertical velocity after the array swap
275      !!
276      !! ** Method of direct routine :  Using the incompressibility hypothesis,
277      !!      the vertical velocity is computed by integrating the horizontal
278      !!      divergence from the bottom to the surface.
279      !!        The boundary conditions are w=0 at the bottom (no flux) and,
280      !!      in regid-lid case, w=0 at the sea surface.
281      !!
282      !! ** action  :   wn array : the now vertical velocity
283      !!----------------------------------------------------------------------
284      !! * Arguments
285      INTEGER, INTENT( in ) ::   kt      ! ocean time-step index
286
287      !! * Local declarations
288      INTEGER  :: &
289         & jk           ! dummy loop indices
290      !! Variable volume
291      INTEGER  :: &
292         & ji,    &     ! dummy loop indices
293         & jj           
294      REAL(wp) :: &
295         & z2dt,  &     ! temporary scalars
296         & zraur
297      REAL(wp), DIMENSION (jpi,jpj) :: &
298         & zssha, &     ! workspace
299         & zun,   &
300         & zvn,   &
301         & zhdiv, &
302         & zfac1, &
303         & zfac2         
304
305      IF( lk_vvl ) THEN                ! Variable volume
306         !
307         z2dt = 2.0_wp * rdt                                   ! time step: leap-frog
308         IF( neuler == 0 .AND. kt == nit000 ) z2dt = rdt       ! time step: Euler if restart from rest
309         zraur  = 1.0_wp / rauw
310       
311         ! Local adjoint variable initialization
312         ! -------------------------------------
313         zssha(:,:) = 0.0_wp
314         zun  (:,:) = 0.0_wp
315         zvn  (:,:) = 0.0_wp
316
317         ! Vertical velocity computed from bottom
318         ! --------------------------------------
319         DO jk = 1, jpkm1
320            zfac1(:,:)       = fsve3t(:,:,jk) * mut(:,:,jk) / z2dt
321            hdivn_ad(:,:,jk) = hdivn_ad(:,:,jk) - wn_ad(:,:,jk) * fse3t(:,:,jk)
322            wn_ad(:,:,jk+1)  = wn_ad(:,:,jk+1)  + wn_ad(:,:,jk)
323            wn_ad(:,:,jk  )  =                    wn_ad(:,:,jk  ) * zfac1(:,:)
324            sshb_ad(:,:)     = sshb_ad(:,:)     + wn_ad(:,:,jk) 
325            zssha(:,:)       = zssha(:,:)       - wn_ad(:,:,jk)
326            wn_ad(:,:,jk  )  = 0.0_wp
327         END DO
328
329         ! Sea surface elevation time stepping
330         ! -----------------------------------
331         zfac2(:,:)   = z2dt * tmask(:,:,1)
332         zhdiv(:,:)   =              - zssha(:,:) * zfac2(:,:)
333         emp_ad(:,:)  = emp_ad(:,:)  - zssha(:,:) * zraur * zfac2(:,:)
334         sshb_ad(:,:) = sshb_ad(:,:) + zssha(:,:)
335         zssha(:,:)   = 0.0_wp 
336
337         CALL lbc_lnk_adj( zhdiv, 'T', 1.0_wp )
338
339# if defined key_bdy
340         jgrd=1 !: tracer grid.
341         DO jb = 1, nblenrim(jgrd)
342           ji = nbi(jb,jgrd)
343           jj = nbj(jb,jgrd)
344           zhdiv(ji,jj) = 0.0_wp
345         END DO
346# endif
347# if defined key_obc && ( key_dynspg_exp || key_dynspg_ts )
348         ! open boundaries (div must be zero behind the open boundary)
349         !  mpp remark: The zeroing of hdiv can probably be extended to 1->jpi/jpj for the correct row/column
350         IF( lp_obc_east  )  zhdiv(nie0p1:nie1p1,nje0  :nje1)   = 0.0_wp ! east
351         IF( lp_obc_west  )  zhdiv(niw0  :niw1  ,njw0  :njw1)   = 0.0_wp ! west
352         IF( lp_obc_north )  zhdiv(nin0  :nin1  ,njn0p1:njn1p1) = 0.0_wp ! north
353         IF( lp_obc_south )  zhdiv(nis0  :nis1  ,njs0  :njs1)   = 0.0_wp ! south
354# endif
355
356         ! Horizontal divergence of barotropic transports
357         !--------------------------------------------------
358         DO jj = jpjm1, 2, -1
359            DO ji = jpim1, 2, -1   ! vector opt.
360               zhdiv(ji,jj)   = zhdiv(ji,jj) / ( e1t(ji,jj) * e2t(ji,jj) )
361               zun(ji  ,jj  ) = zun(ji  ,jj  ) + zhdiv(ji,jj) * e2u(ji  ,jj  )
362               zun(ji-1,jj  ) = zun(ji-1,jj  ) - zhdiv(ji,jj) * e2u(ji-1,jj  )
363               zvn(ji  ,jj  ) = zvn(ji  ,jj  ) + zhdiv(ji,jj) * e1v(ji  ,jj  )
364               zvn(ji  ,jj-1) = zvn(ji  ,jj-1) - zhdiv(ji,jj) * e1v(ji  ,jj-1)
365               zhdiv(ji,jj)   = 0.0_wp
366            END DO
367         END DO
368
369         DO jk = jpkm1, 1, -1          ! Vertically integrated transports (now)
370            un_ad(:,:,jk) = un_ad(:,:,jk) + zun(:,:) * fse3u(:,:,jk)
371            vn_ad(:,:,jk) = vn_ad(:,:,jk) + zvn(:,:) * fse3v(:,:,jk)
372         END DO
373
374         ! Vertically integrated quantities
375         ! --------------------------------
376         zun(:,:) = 0.0_wp
377         zvn(:,:) = 0.0_wp
378
379      ELSE                             ! Fixed volume
380
381         ! Vertical velocity computed from bottom
382         ! --------------------------------------
383         DO jk = 1, jpkm1
384            hdivn_ad(:,:,jk) = hdivn_ad(:,:,jk) &
385                 &             - fse3t(:,:,jk) * wn_ad(:,:,jk)
386            wn_ad(:,:,jk+1)  = wn_ad(:,:,jk+1) + wn_ad(:,:,jk)
387            wn_ad(:,:,jk  )  = 0.0_wp
388         END DO
389     
390      ENDIF
391
392   END SUBROUTINE wzv_adj
393
394   SUBROUTINE wzv_adj_tst( kumadt )
395      !!-----------------------------------------------------------------------
396      !!
397      !!          ***  ROUTINE wzv_adj_tst : TEST OF wzv_adj  ***
398      !!
399      !! ** Purpose : Test the adjoint routine.
400      !!
401      !! ** Method  : Verify the scalar product
402      !!           
403      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
404      !!
405      !!              where  L   = tangent routine
406      !!                     L^T = adjoint routine
407      !!                     W   = diagonal matrix of scale factors
408      !!                     dx  = input perturbation (random field)
409      !!                     dy  = L dx
410      !!
411      !! ** Action  : Separate tests are applied for the following dx and dy:
412      !!         
413      !!      If variable volume ( lk_vvl = .TRUE ) then
414      !!         1) dx = ( un_tl, vn_tl, emp_tl, sshb_tl ) and
415      !!            dy = ( wn_tl )
416      !!      Otherwise
417      !!         2) dx = ( hdivn_tl ) and
418      !!            dy = ( wn_tl )
419      !!
420      !! History :
421      !!        ! 08-07 (A. Weaver)
422      !!-----------------------------------------------------------------------
423
424      !! * Modules used
425      !! * Arguments
426      INTEGER, INTENT(IN) :: &
427         & kumadt             ! Output unit
428
429      !! * Local declarations
430      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
431         & zhdivn_tlin,  & ! Tangent input: now horizontal divergence
432         & zun_tlin,     & ! Tangent input: now u-velocity
433         & zvn_tlin,     & ! Tangent input: now v-velocity
434         & zwn_tlout,    & ! Tangent output: now w-velocity
435         & zwn_adin,     & ! Adjoint input: now w-velocity
436         & zhdivn_adout, & ! Adjoint output: now horizontal divergence
437         & zun_adout,    & ! Adjoint output: now u-velocity
438         & zvn_adout,    & ! Adjoint output: now v-velocity
439         & znu,          & ! 3D random field for u
440         & znv             ! 3D random field for v
441      REAL(KIND=wp), DIMENSION(:,:), ALLOCATABLE :: &
442         & zsshb_tlin,   & ! Tangent input: before SSH
443         & zsshb_adout,  & ! Adjoint output: before SSH
444         & zemp_tlin,    & ! Tangent input: EmP
445         & zemp_adout,   & ! Adjoint output: EmP
446         & znssh,        & ! 2D random field for SSH
447         & znemp           ! 2D random field for EmP
448
449      INTEGER :: &
450         & ji,    &        ! dummy loop indices
451         & jj,    &       
452         & jk     
453      INTEGER, DIMENSION(jpi,jpj) :: &
454         & iseed_2d           ! 2D seed for the random number generator
455      REAL(KIND=wp) :: &
456                              ! random field standard deviation for:
457         & zstdu,           & !   u-velocity
458         & zstdv,           & !   v-velocity
459         & zstdssh,         & !   SSH
460         & zstdemp,         & !   EMP
461         & zsp1,            & ! scalar product involving the tangent routine
462         & zsp2,            & ! scalar product involving the adjoint routine
463         & zsp2_1,          & !   scalar product components
464         & zsp2_2,          & 
465         & zsp2_3,          & 
466         & zsp2_4,          & 
467         & zsp2_5,          & 
468         & z2dt,            & ! temporary scalars
469         & zraur
470      CHARACTER (LEN=14) :: &
471         & cl_name
472
473      ! Allocate memory
474
475      ALLOCATE( &
476         & zhdivn_tlin(jpi,jpj,jpk),  &
477         & zun_tlin(jpi,jpj,jpk),     &
478         & zvn_tlin(jpi,jpj,jpk),     &
479         & zwn_tlout(jpi,jpj,jpk),    &
480         & zwn_adin(jpi,jpj,jpk),     &
481         & zhdivn_adout(jpi,jpj,jpk), &
482         & zun_adout(jpi,jpj,jpk),    &
483         & zvn_adout(jpi,jpj,jpk),    &
484         & znu(jpi,jpj,jpk),          &
485         & znv(jpi,jpj,jpk)           &
486         & )
487      ALLOCATE( &
488         & zsshb_tlin(jpi,jpj),       &
489         & zsshb_adout(jpi,jpj),      &
490         & zemp_tlin(jpi,jpj),        &
491         & zemp_adout(jpi,jpj),       &
492         & znssh(jpi,jpj),            &
493         & znemp(jpi,jpj)             &
494         & )
495     
496
497      ! Initialize constants
498
499      z2dt  = 2.0_wp * rdt       ! time step: leap-frog
500      zraur = 1.0_wp / rauw      ! inverse density of pure water (m3/kg)
501
502      !=============================================================
503      ! 1) dx = ( un_tl, vn_tl, emp_tl, sshb_tl ) and dy = ( wn_tl )
504      !                   - or -
505      ! 2) dx = ( hdivn_tl ) and dy = ( wn_tl )   
506      !=============================================================
507
508      !--------------------------------------------------------------------
509      ! Initialize the tangent input with random noise: dx
510      !--------------------------------------------------------------------
511
512      DO jj = 1, jpj
513         DO ji = 1, jpi
514            iseed_2d(ji,jj) = - ( 785483 + &
515               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
516         END DO
517      END DO
518      CALL grid_random( iseed_2d, znssh, 'T', 0.0_wp, stdssh )
519
520      DO jj = 1, jpj
521         DO ji = 1, jpi
522            iseed_2d(ji,jj) = - ( 358606 + &
523               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
524         END DO
525      END DO
526      CALL grid_random( iseed_2d, znemp, 'T', 0.0_wp, stdssh )
527
528      DO jj = 1, jpj
529         DO ji = 1, jpi
530            iseed_2d(ji,jj) = - ( 596035 + &
531               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
532         END DO
533      END DO
534      CALL grid_random( iseed_2d, znu, 'U', 0.0_wp, stdu )
535
536      DO jj = 1, jpj
537         DO ji = 1, jpi
538            iseed_2d(ji,jj) = - ( 523432 + &
539               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
540         END DO
541      END DO
542      CALL grid_random( iseed_2d, znv, 'V', 0.0_wp, stdv )
543
544      DO jk = 1, jpk
545         DO jj = nldj, nlej
546            DO ji = nldi, nlei
547               un_tl(ji,jj,jk) = znu(ji,jj,jk) 
548               vn_tl(ji,jj,jk) = znv(ji,jj,jk) 
549            END DO
550         END DO
551      END DO
552
553      CALL div_cur_tan( nit000 )    ! Generate noise hdivn
554
555      DO jk = 1, jpk
556         DO jj = nldj, nlej
557            DO ji = nldi, nlei
558               zun_tlin   (ji,jj,jk) = znu     (ji,jj,jk) 
559               zvn_tlin   (ji,jj,jk) = znv     (ji,jj,jk) 
560               zhdivn_tlin(ji,jj,jk) = hdivn_tl(ji,jj,jk) 
561            END DO
562         END DO
563      END DO
564      DO jj = nldj, nlej
565         DO ji = nldi, nlei
566            zsshb_tlin(ji,jj) = znssh(ji,jj)
567            zemp_tlin (ji,jj) = znemp(ji,jj) / ( z2dt * zraur )
568         END DO
569      END DO
570
571      !--------------------------------------------------------------------
572      ! Call the tangent routine: dy = L dx
573      !--------------------------------------------------------------------
574
575      un_tl   (:,:,:) = zun_tlin   (:,:,:)
576      vn_tl   (:,:,:) = zvn_tlin   (:,:,:)
577      hdivn_tl(:,:,:) = zhdivn_tlin(:,:,:)
578
579      sshb_tl(:,:) = zsshb_tlin(:,:)
580      emp_tl (:,:) = zemp_tlin (:,:)
581
582      CALL wzv_tan( nit000 ) 
583
584      zwn_tlout(:,:,:) = wn_tl(:,:,:)
585
586      !--------------------------------------------------------------------
587      ! Initialize the adjoint variables: dy^* = W dy
588      !--------------------------------------------------------------------
589
590      DO jk = 1, jpk
591        DO jj = nldj, nlej
592           DO ji = nldi, nlei
593              zwn_adin(ji,jj,jk) = zwn_tlout(ji,jj,jk) &
594                 &               * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) &
595                 &               * tmask(ji,jj,jk)
596            END DO
597         END DO
598      END DO
599
600      !--------------------------------------------------------------------
601      ! Compute the scalar product: ( L dx )^T W dy
602      !--------------------------------------------------------------------
603
604      zsp1 = DOT_PRODUCT( zwn_tlout, zwn_adin )
605
606      !--------------------------------------------------------------------
607      ! Call the adjoint routine: dx^* = L^T dy^*
608      !--------------------------------------------------------------------
609
610      wn_ad(:,:,:) = zwn_adin(:,:,:)
611
612      CALL wzv_adj( nit000 )
613
614      zun_adout   (:,:,:) = un_ad   (:,:,:)
615      zvn_adout   (:,:,:) = vn_ad   (:,:,:)
616      zhdivn_adout(:,:,:) = hdivn_ad(:,:,:)
617
618      zsshb_adout(:,:) = sshb_ad(:,:)
619      zemp_adout (:,:) = emp_ad (:,:)
620
621      !--------------------------------------------------------------------
622      ! Compute the scalar product: dx^T L^T W dy
623      !--------------------------------------------------------------------
624
625      zsp2_1 = DOT_PRODUCT( zun_tlin,    zun_adout    )
626      zsp2_2 = DOT_PRODUCT( zvn_tlin,    zvn_adout    )
627      zsp2_3 = DOT_PRODUCT( zhdivn_tlin, zhdivn_adout )
628      zsp2_4 = DOT_PRODUCT( zemp_tlin,   zemp_adout   )
629      zsp2_5 = DOT_PRODUCT( zsshb_tlin,  zsshb_adout  )
630 
631      IF( lk_vvl ) THEN
632         zsp2 = zsp2_1 + zsp2_2 + zsp2_3 + zsp2_4 + zsp2_5
633      ELSE
634         zsp2 = zsp2_3
635      ENDIF
636
637      ! Compare the scalar products
638      ! 14 char:'12345678901234'
639      cl_name = 'wzv_adj       '
640      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
641
642   END SUBROUTINE wzv_adj_tst
643
644   !!======================================================================
645#endif
646END MODULE wzvmod_tam
Note: See TracBrowser for help on using the repository browser.