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.
dynhpg_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/dynhpg_tam.F90 @ 3753

Last change on this file since 3753 was 3611, checked in by pabouttier, 12 years ago

Add TAM code and ORCA2_TAM configuration - see Ticket #1007

  • Property svn:executable set to *
File size: 40.9 KB
Line 
1MODULE dynhpg_tam
2#ifdef key_tam
3   !!======================================================================
4   !!                       ***  MODULE  dynhpg_tam  ***
5   !! Ocean dynamics:  hydrostatic pressure gradient trend
6   !!                  Tangent and Adjoint module
7   !!======================================================================
8   !! History of the direct module:
9   !!            1.0  !  87-09  (P. Andrich, M.-A. Foujols)  hpg_zco: Original code
10   !!            5.0  !  91-11  (G. Madec)
11   !!            7.0  !  96-01  (G. Madec)  hpg_sco: Original code for s-coordinates
12   !!            8.0  !  97-05  (G. Madec)  split dynber into dynkeg and dynhpg
13   !!            8.5  !  02-07  (G. Madec)  F90: Free form and module
14   !!            8.5  !  02-08  (A. Bozec)  hpg_zps: Original code
15   !!            9.0  !  05-10  (A. Beckmann, B.W. An)  various s-coordinate options
16   !!                           Original code for hpg_ctl, hpg_hel hpg_wdj, hpg_djc, hpg_rot
17   !!            9.0  !  05-11  (G. Madec) style & small optimisation
18   !! History of the TAM module:
19   !!            9.0  !  08-06  (A. Vidard) Skeleton
20   !!                 !  08-11  (A. Vidard) Nemo v3
21   !!                 !  12-07  (P.-A. Bouttier) 3.4 version
22   !!----------------------------------------------------------------------
23
24   !!----------------------------------------------------------------------
25   !!   dyn_hpg      : update the momentum trend with the now horizontal
26   !!                  gradient of the hydrostatic pressure
27   !!       hpg_ctl  : initialisation and control of options
28   !!       hpg_zco  : z-coordinate scheme
29   !!       hpg_zps  : z-coordinate plus partial steps (interpolation)
30   !!       hpg_sco  : s-coordinate (standard jacobian formulation)
31   !!       hpg_hel  : s-coordinate (helsinki modification)
32   !!       hpg_wdj  : s-coordinate (weighted density jacobian)
33   !!       hpg_djc  : s-coordinate (Density Jacobian with Cubic polynomial)
34   !!       hpg_rot  : s-coordinate (ROTated axes scheme)
35   !!----------------------------------------------------------------------
36   USE par_kind
37   USE par_oce
38   USE oce_tam
39   USE dom_oce
40   USE dynhpg
41   USE phycst
42   USE in_out_manager
43   USE gridrandom
44   USE dotprodfld
45   USE tstool_tam
46   USE lib_mpp
47   USE wrk_nemo
48   USE timing
49
50   IMPLICIT NONE
51   PRIVATE
52
53   PUBLIC   dyn_hpg_tan    ! routine called by step_tam module
54   PUBLIC   dyn_hpg_adj    ! routine called by step_tam module
55   PUBLIC   dyn_hpg_init_tam
56   PUBLIC   dyn_hpg_adj_tst! routine called by test module
57
58   !! * Substitutions
59#  include "domzgr_substitute.h90"
60#  include "vectopt_loop_substitute.h90"
61
62CONTAINS
63
64   SUBROUTINE dyn_hpg_tan( kt )
65      !!---------------------------------------------------------------------
66      !!                  ***  ROUTINE dyn_hpg_tan  ***
67      !!
68      !! ** Method of the direct routine:
69      !!              Call the hydrostatic pressure gradient routine
70      !!              using the scheme defined in the namelist
71      !!
72      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
73      !!             - Save the trend (l_trddyn=T)
74      !!----------------------------------------------------------------------
75      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
76      !!
77      !!----------------------------------------------------------------------
78      !
79      IF( nn_timing == 1 )  CALL timing_start('dyn_hpg_tan')
80      !
81      SELECT CASE ( nhpg )      ! Hydrastatic pressure gradient computation
82      CASE (  0 )   ;   CALL hpg_zco_tan    ( kt )      ! z-coordinate
83      CASE (  1 )   ;   CALL hpg_zps_tan    ( kt )      ! z-coordinate plus partial steps (interpolation)
84      CASE (  2 )   ;   CALL hpg_sco_tan    ( kt )      ! s-coordinate (standard jacobian formulation)
85      CASE (  3 )   ;   CALL hpg_djc_tan    ( kt )      ! s-coordinate (helsinki modification)
86      CASE (  4 )   ;   CALL hpg_prj_tan    ( kt )      ! s-coordinate (weighted density jacobian)
87      END SELECT
88      !
89      IF( nn_timing == 1 )  CALL timing_stop('dyn_hpg_tan')
90      !
91   END SUBROUTINE dyn_hpg_tan
92   SUBROUTINE dyn_hpg_adj( kt )
93      !!---------------------------------------------------------------------
94      !!                  ***  ROUTINE dyn_hpg_adj  ***
95      !!
96      !! ** Method of the direct routine:
97      !!              call the hydrostatic pressure gradient routine
98      !!              using the scheme defined in the namelist
99      !!
100      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
101      !!             - Save the trend (l_trddyn=T)
102      !!----------------------------------------------------------------------
103      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
104      !!
105      !!----------------------------------------------------------------------
106      !
107      IF( nn_timing == 1 )  CALL timing_start('dyn_hpg_adj')
108      !
109      SELECT CASE ( nhpg )      ! Hydrastatic pressure gradient computation
110      CASE (  0 )   ;   CALL hpg_zco_adj    ( kt )      ! z-coordinate
111      CASE (  1 )   ;   CALL hpg_zps_adj    ( kt )      ! z-coordinate plus partial steps (interpolation)
112      CASE (  2 )   ;   CALL hpg_sco_adj    ( kt )      ! s-coordinate (standard jacobian formulation)
113      CASE (  3 )   ;   CALL hpg_djc_adj    ( kt )      ! s-coordinate (helsinki modification)
114      CASE (  4 )   ;   CALL hpg_prj_adj    ( kt )      ! s-coordinate (weighted density jacobian)
115      END SELECT
116      !
117      IF( nn_timing == 1 )  CALL timing_stop('dyn_hpg_adj')
118      !
119   END SUBROUTINE dyn_hpg_adj
120
121   SUBROUTINE dyn_hpg_init_tam
122      !!----------------------------------------------------------------------
123      !!                 ***  ROUTINE hpg_ctl_tam  ***
124      !!
125      !! ** Purpose :   initializations for the hydrostatic pressure gradient
126      !!              computation and consistency control
127      !!
128      !! ** Action  :   Read the namelist namdyn_hpg and check the consistency
129      !!      with the type of vertical coordinate used (zco, zps, sco)
130      !!----------------------------------------------------------------------
131      INTEGER ::   ioptio = 0      ! temporary integer
132
133!      Namelist read in opa_flg
134!      NAMELIST/nam_dynhpg/ ln_hpg_zco, ln_hpg_zps, ln_hpg_sco, ln_hpg_hel,   &
135!         &                 ln_hpg_wdj, ln_hpg_djc, ln_hpg_rot, gamm
136      !!----------------------------------------------------------------------
137
138!      REWIND ( numnam )               ! Read Namelist nam_dynhpg : pressure gradient calculation options
139!      READ   ( numnam, nam_dynhpg )
140
141      IF(lwp) THEN                    ! Control print
142         WRITE(numout,*)
143         WRITE(numout,*) 'dyn_ctl_tam : hydrostatic pressure gradient'
144         WRITE(numout,*) '~~~~~~~~~~~~~~~'
145         WRITE(numout,*) '   Namelist namdyn_hpg : choice of hpg scheme'
146         WRITE(numout,*) '      z-coord. - full steps                             ln_hpg_zco    = ', ln_hpg_zco
147         WRITE(numout,*) '      z-coord. - partial steps (interpolation)          ln_hpg_zps    = ', ln_hpg_zps
148         WRITE(numout,*) '      s-coord. (standard jacobian formulation)          ln_hpg_sco    = ', ln_hpg_sco
149         WRITE(numout,*) '      s-coord. (Density Jacobian: Cubic polynomial)     ln_hpg_djc    = ', ln_hpg_djc
150         WRITE(numout,*) '      time stepping: centered (F) or semi-implicit (T)  ln_dynhpg_imp = ', ln_dynhpg_imp
151      ENDIF
152      !
153      IF( ln_hpg_djc )   &
154         &   CALL ctl_stop('dyn_hpg_init_tam : Density Jacobian: Cubic polynominal method &
155                           & currently disabled (bugs under investigation). Please select &
156                           & either  ln_hpg_sco or  ln_hpg_prj instead')
157      IF( lk_vvl .AND. .NOT. ln_hpg_sco )   THEN
158         CALL ctl_stop( 'dyn_hpg_init_tam : variable volume key_vvl compatible only with the standard jacobian formulation hpg_sco')
159      ENDIF
160      !                               ! Set nhpg from ln_hpg_... flags
161      IF( ln_hpg_zco )   nhpg = 0
162      IF( ln_hpg_zps )   nhpg = 1
163      IF( ln_hpg_sco )   nhpg = 2
164      IF( ln_hpg_djc )   nhpg = 3
165      IF( ln_hpg_prj )   nhpg = 4
166      !                               ! Consitency check
167      ioptio = 0
168      IF( ln_hpg_zco )   ioptio = ioptio + 1
169      IF( ln_hpg_zps )   ioptio = ioptio + 1
170      IF( ln_hpg_sco )   ioptio = ioptio + 1
171      IF( ln_hpg_djc )   ioptio = ioptio + 1
172      IF( ln_hpg_prj )   ioptio = ioptio + 1
173      IF ( ioptio /= 1 )   CALL ctl_stop( ' NO or several hydrostatic pressure gradient options used' )
174      !
175   END SUBROUTINE dyn_hpg_init_tam
176   SUBROUTINE hpg_zco_tan( kt )
177      !!---------------------------------------------------------------------
178      !!                  ***  ROUTINE hpg_zco_tan  ***
179      !!
180      !! ** Method of the direct routine:
181      !!      z-coordinate case, levels are horizontal surfaces.
182      !!      The now hydrostatic pressure gradient at a given level, jk,
183      !!      is computed by taking the vertical integral of the in-situ
184      !!      density gradient along the model level from the suface to that
185      !!      level:    zhpi = grav .....
186      !!                zhpj = grav .....
187      !!      add it to the general momentum trend (ua,va).
188      !!            ua = ua - 1/e1u * zhpi
189      !!            va = va - 1/e2v * zhpj
190      !!
191      !! ** Action : - Update (ua_tl,va_tl) with the now hydrastatic pressure trend
192      !!----------------------------------------------------------------------
193      !!
194      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
195      !!
196      INTEGER  ::   ji, jj, jk       ! dummy loop indices
197      REAL(wp) ::   zcoef0, zcoef1   ! temporary scalars
198      REAL(wp), POINTER, DIMENSION(:,:,:) :: zhpitl, zhpjtl
199      !!----------------------------------------------------------------------
200      !
201      CALL wrk_alloc( jpi,jpj,jpk, zhpitl, zhpjtl )
202      !
203      IF( kt == nit000 ) THEN
204         IF(lwp) WRITE(numout,*)
205         IF(lwp) WRITE(numout,*) 'dyn:hpg_zco_tan : hydrostatic pressure gradient trend'
206         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~   z-coordinate case '
207      ENDIF
208      ! Local constant initialization
209      zcoef0 = - grav * 0.5_wp
210      ! Surface value
211      DO jj = 2, jpjm1
212         DO ji = fs_2, fs_jpim1   ! vector opt.
213            zcoef1 = zcoef0 * fse3w(ji,jj,1)
214            ! hydrostatic pressure gradient
215            zhpitl(ji,jj,1) = zcoef1 * ( rhd_tl(ji+1,jj  ,1) - rhd_tl(ji,jj,1) ) / e1u(ji,jj)
216            zhpjtl(ji,jj,1) = zcoef1 * ( rhd_tl(ji  ,jj+1,1) - rhd_tl(ji,jj,1) ) / e2v(ji,jj)
217            ! add to the general momentum trend
218            ua_tl(ji,jj,1) = ua_tl(ji,jj,1) + zhpitl(ji,jj,1)
219            va_tl(ji,jj,1) = va_tl(ji,jj,1) + zhpjtl(ji,jj,1)
220         END DO
221      END DO
222      !
223      ! interior value (2=<jk=<jpkm1)
224      DO jk = 2, jpkm1
225         DO jj = 2, jpjm1
226            DO ji = fs_2, fs_jpim1   ! vector opt.
227               zcoef1 = zcoef0 * fse3w(ji,jj,jk)
228               ! hydrostatic pressure gradient
229               zhpitl(ji,jj,jk) = zhpitl(ji,jj,jk-1)   &
230                  &           + zcoef1 * (  ( rhd_tl(ji+1,jj,jk)+rhd_tl(ji+1,jj,jk-1) )   &
231                  &                       - ( rhd_tl(ji  ,jj,jk)+rhd_tl(ji  ,jj,jk-1) )  ) / e1u(ji,jj)
232
233               zhpjtl(ji,jj,jk) = zhpjtl(ji,jj,jk-1)   &
234                  &           + zcoef1 * (  ( rhd_tl(ji,jj+1,jk)+rhd_tl(ji,jj+1,jk-1) )   &
235                  &                       - ( rhd_tl(ji,jj,  jk)+rhd_tl(ji,jj  ,jk-1) )  ) / e2v(ji,jj)
236               ! add to the general momentum trend
237               ua_tl(ji,jj,jk) = ua_tl(ji,jj,jk) + zhpitl(ji,jj,jk)
238               va_tl(ji,jj,jk) = va_tl(ji,jj,jk) + zhpjtl(ji,jj,jk)
239            END DO
240         END DO
241      END DO
242      !
243      CALL wrk_dealloc( jpi,jpj,jpk, zhpitl, zhpjtl )
244      !
245   END SUBROUTINE hpg_zco_tan
246   SUBROUTINE hpg_zco_adj( kt )
247      !!---------------------------------------------------------------------
248      !!                  ***  ROUTINE hpg_zco_tan  ***
249      !!
250      !! ** Method of the direct routine:
251      !!      z-coordinate case, levels are horizontal surfaces.
252      !!      The now hydrostatic pressure gradient at a given level, jk,
253      !!      is computed by taking the vertical integral of the in-situ
254      !!      density gradient along the model level from the suface to that
255      !!      level:    zhpi = grav .....
256      !!                zhpj = grav .....
257      !!      add it to the general momentum trend (ua,va).
258      !!            ua = ua - 1/e1u * zhpi
259      !!            va = va - 1/e2v * zhpj
260      !!
261      !! ** Action : - Update (ua_tl,va_tl) with the now hydrastatic pressure trend
262      !!----------------------------------------------------------------------
263      !!
264      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
265      !!
266      INTEGER  ::   ji, jj, jk       ! dummy loop indices
267      REAL(wp) ::   zcoef0, zcoef1   ! temporary scalars
268      REAL(wp), POINTER, DIMENSION(:,:,:) :: zhpiad, zhpjad
269      !!----------------------------------------------------------------------
270      !
271      CALL wrk_alloc( jpi,jpj,jpk, zhpiad, zhpjad )
272      !
273      IF( kt == nitend ) THEN
274         IF(lwp) WRITE(numout,*)
275         IF(lwp) WRITE(numout,*) 'dyn:hpg_zco_adj : hydrostatic pressure gradient trend'
276         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~   z-coordinate case '
277      ENDIF
278      ! adjoint variables initialization
279      zhpiad = 0.0_wp
280      zhpjad = 0.0_wp
281      ! Local constant initialization
282      zcoef0 = - grav * 0.5
283
284      ! interior value (2=<jk=<jpkm1)
285      DO jk = jpkm1, 2, -1
286         DO jj = jpjm1, 2, -1
287            DO ji = fs_jpim1, fs_2, -1   ! vector opt.
288               zcoef1 = zcoef0 * fse3w(ji,jj,jk)
289               ! add to the general momentum trend
290               zhpiad(ji,jj,jk) = zhpiad(ji,jj,jk) + ua_ad(ji,jj,jk)
291               zhpjad(ji,jj,jk) = zhpjad(ji,jj,jk) + va_ad(ji,jj,jk)
292               ! hydrostatic pressure gradient
293               rhd_ad(ji,jj+1,jk  ) = rhd_ad(ji,jj+1,jk  ) + zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
294               rhd_ad(ji,jj+1,jk-1) = rhd_ad(ji,jj+1,jk-1) + zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
295               rhd_ad(ji,jj  ,jk  ) = rhd_ad(ji,jj  ,jk  ) - zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
296               rhd_ad(ji,jj  ,jk-1) = rhd_ad(ji,jj  ,jk-1) - zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
297               zhpjad(ji,jj  ,jk-1) = zhpjad(ji,jj  ,jk-1) + zhpjad(ji,jj,jk)
298               zhpjad(ji,jj  ,jk  ) = 0.0_wp
299               !
300               rhd_ad(ji+1,jj,jk  ) = rhd_ad(ji+1,jj,jk  ) + zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
301               rhd_ad(ji+1,jj,jk-1) = rhd_ad(ji+1,jj,jk-1) + zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
302               rhd_ad(ji  ,jj,jk  ) = rhd_ad(ji  ,jj,jk  ) - zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
303               rhd_ad(ji  ,jj,jk-1) = rhd_ad(ji  ,jj,jk-1) - zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
304               zhpiad(ji  ,jj,jk-1) = zhpiad(ji  ,jj,jk-1) + zhpiad(ji,jj,jk)
305               zhpiad(ji  ,jj,jk  ) = 0.0_wp
306               !
307            END DO
308         END DO
309      END DO
310      ! Surface value
311      DO jj = 2, jpjm1
312         DO ji = fs_2, fs_jpim1   ! vector opt.
313            zcoef1 = zcoef0 * fse3w(ji,jj,1)
314            ! add to the general momentum trend
315            zhpiad(ji,jj,1) = zhpiad(ji,jj,1) + ua_ad(ji,jj,1)
316            zhpjad(ji,jj,1) = zhpjad(ji,jj,1) + va_ad(ji,jj,1)
317            ! hydrostatic pressure gradient
318            rhd_ad(ji,jj+1,1) = rhd_ad(ji,jj+1,1) + zhpjad(ji,jj,1) * zcoef1 / e2v(ji,jj)
319            rhd_ad(ji,jj  ,1) = rhd_ad(ji,jj  ,1) - zhpjad(ji,jj,1) * zcoef1 / e2v(ji,jj)
320            zhpjad(ji,jj,1) = 0.0_wp
321            !
322            rhd_ad(ji+1,jj,1) = rhd_ad(ji+1,jj,1) + zhpiad(ji,jj,1) * zcoef1 / e1u(ji,jj)
323            rhd_ad(ji  ,jj,1) = rhd_ad(ji  ,jj,1) - zhpiad(ji,jj,1) * zcoef1 / e1u(ji,jj)
324            zhpiad(ji,jj,1) = 0.0_wp
325         END DO
326      END DO
327      !
328      CALL wrk_dealloc( jpi,jpj,jpk, zhpiad, zhpjad )
329      !
330   END SUBROUTINE hpg_zco_adj
331   SUBROUTINE hpg_zps_tan( kt )
332      !!---------------------------------------------------------------------
333      !!                 ***  ROUTINE hpg_zps  ***
334      !!
335      !! ** Method of the direct routine:
336      !!              z-coordinate plus partial steps case.  blahblah...
337      !!
338      !! ** Action  : - Update (ua_tl,va_tl) with the now hydrastatic pressure trend
339      !!----------------------------------------------------------------------
340      !!
341      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
342      !!
343      INTEGER  ::   ji, jj, jk                       ! dummy loop indices
344      INTEGER  ::   iku, ikv                         ! temporary integers
345      REAL(wp) ::   zcoef0, zcoef1, zcoef2, zcoef3   ! temporary scalars
346      REAL(wp), POINTER, DIMENSION(:,:,:) :: zhpitl, zhpjtl
347      !!----------------------------------------------------------------------
348      !
349      CALL wrk_alloc( jpi,jpj,jpk, zhpitl, zhpjtl )
350      !
351      IF( kt == nit000 ) THEN
352         IF(lwp) WRITE(numout,*)
353         IF(lwp) WRITE(numout,*) 'dyn:hpg_zps_tan : hydrostatic pressure gradient trend'
354         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~   z-coordinate with partial steps - vector optimization'
355      ENDIF
356
357      ! Local constant initialization
358      zcoef0 = - grav * 0.5_wp
359
360      !  Surface value
361      DO jj = 2, jpjm1
362         DO ji = fs_2, fs_jpim1   ! vector opt.
363            zcoef1 = zcoef0 * fse3w(ji,jj,1)
364            ! hydrostatic pressure gradient
365            zhpitl(ji,jj,1) = zcoef1 * ( rhd_tl(ji+1,jj  ,1) - rhd_tl(ji,jj,1) ) / e1u(ji,jj)
366            zhpjtl(ji,jj,1) = zcoef1 * ( rhd_tl(ji  ,jj+1,1) - rhd_tl(ji,jj,1) ) / e2v(ji,jj)
367            ! add to the general momentum trend
368            ua_tl(ji,jj,1) = ua_tl(ji,jj,1) + zhpitl(ji,jj,1)
369            va_tl(ji,jj,1) = va_tl(ji,jj,1) + zhpjtl(ji,jj,1)
370         END DO
371      END DO
372
373      ! interior value (2=<jk=<jpkm1)
374      DO jk = 2, jpkm1
375         DO jj = 2, jpjm1
376            DO ji = fs_2, fs_jpim1   ! vector opt.
377               zcoef1 = zcoef0 * fse3w(ji,jj,jk)
378               ! hydrostatic pressure gradient
379               zhpitl(ji,jj,jk) = zhpitl(ji,jj,jk-1)   &
380                  &           + zcoef1 * (  ( rhd_tl(ji+1,jj,jk) + rhd_tl(ji+1,jj,jk-1) )   &
381                  &                       - ( rhd_tl(ji  ,jj,jk) + rhd_tl(ji  ,jj,jk-1) )  ) / e1u(ji,jj)
382
383               zhpjtl(ji,jj,jk) = zhpjtl(ji,jj,jk-1)   &
384                  &           + zcoef1 * (  ( rhd_tl(ji,jj+1,jk) + rhd_tl(ji,jj+1,jk-1) )   &
385                  &                       - ( rhd_tl(ji,jj,  jk) + rhd_tl(ji,jj  ,jk-1) )  ) / e2v(ji,jj)
386               ! add to the general momentum trend
387               ua_tl(ji,jj,jk) = ua_tl(ji,jj,jk) + zhpitl(ji,jj,jk)
388               va_tl(ji,jj,jk) = va_tl(ji,jj,jk) + zhpjtl(ji,jj,jk)
389            END DO
390         END DO
391      END DO
392
393      ! partial steps correction at the last level  (new gradient with  intgrd.F)
394# if defined key_vectopt_loop
395         jj = 1
396         DO ji = jpi+2, jpij-jpi-1   ! vector opt. (forced unrolling)
397# else
398      DO jj = 2, jpjm1
399         DO ji = 2, jpim1
400# endif
401            iku = mbku(ji,jj)
402            ikv = mbkv(ji,jj)
403            zcoef2 = zcoef0 * MIN( fse3w(ji,jj,iku), fse3w(ji+1,jj  ,iku) )
404            zcoef3 = zcoef0 * MIN( fse3w(ji,jj,ikv), fse3w(ji  ,jj+1,ikv) )
405            ! on i-direction
406            IF ( iku > 2 ) THEN
407               ! subtract old value
408               ua_tl(ji,jj,iku) = ua_tl(ji,jj,iku) - zhpitl(ji,jj,iku)
409               ! compute the new one
410               zhpitl (ji,jj,iku) = zhpitl(ji,jj,iku-1)   &
411                  + zcoef2 * ( rhd_tl(ji+1,jj,iku-1) - rhd_tl(ji,jj,iku-1) + gru_tl(ji,jj) ) / e1u(ji,jj)
412               ! add the new one to the general momentum trend
413               ua_tl(ji,jj,iku) = ua_tl(ji,jj,iku) + zhpitl(ji,jj,iku)
414            ENDIF
415            ! on j-direction
416            IF ( ikv > 2 ) THEN
417               ! subtract old value
418               va_tl(ji,jj,ikv) = va_tl(ji,jj,ikv) - zhpjtl(ji,jj,ikv)
419               ! compute the new one
420               zhpjtl (ji,jj,ikv) = zhpjtl(ji,jj,ikv-1)   &
421                  + zcoef3 * ( rhd_tl(ji,jj+1,ikv-1) - rhd_tl(ji,jj,ikv-1) + grv_tl(ji,jj) ) / e2v(ji,jj)
422               ! add the new one to the general momentum trend
423               va_tl(ji,jj,ikv) = va_tl(ji,jj,ikv) + zhpjtl(ji,jj,ikv)
424            ENDIF
425# if ! defined key_vectopt_loop
426         END DO
427# endif
428      END DO
429      !
430      CALL wrk_dealloc( jpi,jpj,jpk, zhpitl, zhpjtl )
431      !
432   END SUBROUTINE hpg_zps_tan
433   SUBROUTINE hpg_zps_adj( kt )
434      !!---------------------------------------------------------------------
435      !!                 ***  ROUTINE hpg_zps  ***
436      !!
437      !! ** Method of the direct routine:
438      !!              z-coordinate plus partial steps case.  blahblah...
439      !!
440      !! ** Action  : - Update (ua_tl,va_tl) with the now hydrastatic pressure trend
441      !!----------------------------------------------------------------------
442      !!
443      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
444      !!
445      INTEGER  ::   ji, jj, jk                       ! dummy loop indices
446      INTEGER  ::   iku, ikv                         ! temporary integers
447      REAL(wp) ::   zcoef0, zcoef1, zcoef2, zcoef3   ! temporary scalars
448      REAL(wp), POINTER, DIMENSION(:,:,:):: zhpiad, zhpjad
449      !!----------------------------------------------------------------------
450      !
451      CALL wrk_alloc( jpi,jpj,jpk, zhpiad, zhpjad )
452      !
453      IF( kt == nitend ) THEN
454         IF(lwp) WRITE(numout,*)
455         IF(lwp) WRITE(numout,*) 'dyn:hpg_zps_adj : hydrostatic pressure gradient trend'
456         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~   z-coordinate with partial steps - vector optimization'
457      ENDIF
458      zhpiad(:,:,:) = 0.0_wp
459      zhpjad(:,:,:) = 0.0_wp
460      ! Local constant initialization
461      zcoef0 = - grav * 0.5
462
463      ! partial steps correction at the last level  (new gradient with  intgrd.F)
464# if defined key_vectopt_loop
465         jj = 1
466         DO ji = jpij-jpi-1, jpi+2, -1   ! vector opt. (forced unrolling)
467# else
468      DO jj = jpjm1, 2, -1
469         DO ji = jpim1, 2, -1
470# endif
471            iku = mbku(ji,jj)
472            ikv = mbkv(ji,jj)
473            zcoef2 = zcoef0 * MIN( fse3w(ji,jj,iku), fse3w(ji+1,jj  ,iku) )
474            zcoef3 = zcoef0 * MIN( fse3w(ji,jj,ikv), fse3w(ji  ,jj+1,ikv) )
475            ! on i-direction
476            IF ( iku > 2 ) THEN
477               ! add the new one to the general momentum trend
478               zhpiad(ji,jj,iku) = zhpiad(ji,jj,iku) + ua_ad(ji,jj,iku)
479               ! compute the new one
480               rhd_ad(ji+1,jj,iku-1) = rhd_ad(ji+1,jj,iku-1) + zhpiad (ji,jj,iku) * zcoef2 / e1u(ji,jj)
481               rhd_ad(ji,jj,iku-1) = rhd_ad(ji,jj,iku-1) - zhpiad (ji,jj,iku) * zcoef2 / e1u(ji,jj)
482               gru_ad(ji,jj) = gru_ad(ji,jj) + zhpiad (ji,jj,iku) * zcoef2 / e1u(ji,jj)
483               zhpiad(ji,jj,iku-1) = zhpiad(ji,jj,iku-1) + zhpiad (ji,jj,iku)
484               zhpiad (ji,jj,iku) = 0.0_wp
485               ! subtract old value
486               zhpiad(ji,jj,iku) = zhpiad(ji,jj,iku) - ua_ad(ji,jj,iku)
487            ENDIF
488            ! on j-direction
489            IF ( ikv > 2 ) THEN
490               ! add the new one to the general momentum trend
491               zhpjad(ji,jj,ikv) = zhpjad(ji,jj,ikv) + va_ad(ji,jj,ikv)
492               ! compute the new one
493               rhd_ad(ji,jj+1,ikv-1) = rhd_ad(ji,jj+1,ikv-1) + zhpjad (ji,jj,ikv) * zcoef3 / e2v(ji,jj)
494               rhd_ad(ji,jj,ikv-1) = rhd_ad(ji,jj,ikv-1) -zhpjad (ji,jj,ikv) * zcoef3 / e2v(ji,jj)
495               grv_ad(ji,jj) = grv_ad(ji,jj) +zhpjad (ji,jj,ikv) * zcoef3 / e2v(ji,jj)
496               zhpjad(ji,jj,ikv-1) = zhpjad(ji,jj,ikv-1) + zhpjad(ji,jj,ikv)
497               zhpjad (ji,jj,ikv) = 0.0_wp
498               ! subtract old value
499               zhpjad(ji,jj,ikv) = zhpjad(ji,jj,ikv) - va_ad(ji,jj,ikv)
500            ENDIF
501# if ! defined key_vectopt_loop
502         END DO
503# endif
504      END DO
505      !
506      ! interior value (2=<jk=<jpkm1)
507      DO jk = jpkm1, 2, -1
508         DO jj = jpjm1, 2, -1
509            DO ji = fs_jpim1, fs_2, -1   ! vector opt.
510               zcoef1 = zcoef0 * fse3w(ji,jj,jk)
511               ! add to the general momentum trend
512               zhpiad(ji,jj,jk) = zhpiad(ji,jj,jk) + ua_ad(ji,jj,jk)
513               zhpjad(ji,jj,jk) = zhpjad(ji,jj,jk) + va_ad(ji,jj,jk)
514               ! hydrostatic pressure gradient
515               rhd_ad(ji,jj+1,jk  ) = rhd_ad(ji,jj+1,jk  ) + zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
516               rhd_ad(ji,jj+1,jk-1) = rhd_ad(ji,jj+1,jk-1) + zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
517               rhd_ad(ji,jj  ,jk  ) = rhd_ad(ji,jj  ,jk  ) - zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
518               rhd_ad(ji,jj  ,jk-1) = rhd_ad(ji,jj  ,jk-1) - zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
519               zhpjad(ji,jj  ,jk-1) = zhpjad(ji,jj  ,jk-1) + zhpjad(ji,jj,jk)
520               zhpjad(ji,jj  ,jk  ) = 0.0_wp
521               !
522               rhd_ad(ji+1,jj,jk  ) = rhd_ad(ji+1,jj,jk  ) + zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
523               rhd_ad(ji+1,jj,jk-1) = rhd_ad(ji+1,jj,jk-1) + zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
524               rhd_ad(ji  ,jj,jk  ) = rhd_ad(ji  ,jj,jk  ) - zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
525               rhd_ad(ji  ,jj,jk-1) = rhd_ad(ji  ,jj,jk-1) - zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
526               zhpiad(ji  ,jj,jk-1) = zhpiad(ji  ,jj,jk-1) + zhpiad(ji,jj,jk)
527               zhpiad(ji  ,jj,jk  ) = 0.0_wp
528            END DO
529         END DO
530      END DO
531      !  Surface value
532      DO jj = jpjm1, 2, -1
533         DO ji = fs_jpim1, fs_2, -1   ! vector opt.
534            zcoef1 = zcoef0 * fse3w(ji,jj,1)
535            ! add to the general momentum trend
536            zhpiad(ji,jj,1) = zhpiad(ji,jj,1) + ua_ad(ji,jj,1)
537            zhpjad(ji,jj,1) = zhpjad(ji,jj,1) + va_ad(ji,jj,1)
538            ! hydrostatic pressure gradient
539            rhd_ad(ji+1,jj  ,1) = rhd_ad(ji+1,jj  ,1) + zhpiad(ji,jj,1) * zcoef1 / e1u(ji,jj)
540            rhd_ad(ji  ,jj  ,1) = rhd_ad(ji  ,jj  ,1) - zhpiad(ji,jj,1) * zcoef1 / e1u(ji,jj)
541            rhd_ad(ji  ,jj+1,1) = rhd_ad(ji  ,jj+1,1) + zhpjad(ji,jj,1) * zcoef1 / e2v(ji,jj)
542            rhd_ad(ji  ,jj  ,1) = rhd_ad(ji  ,jj  ,1) - zhpjad(ji,jj,1) * zcoef1 / e2v(ji,jj)
543            zhpiad(ji  ,jj  ,1) = 0.0_wp
544            zhpjad(ji  ,jj  ,1) = 0.0_wp
545         END DO
546      END DO
547      !
548      CALL wrk_dealloc( jpi,jpj,jpk, zhpiad, zhpjad )
549      !
550   END SUBROUTINE hpg_zps_adj
551   SUBROUTINE hpg_sco_tan( kt )
552      !!---------------------------------------------------------------------
553      !!                  ***  ROUTINE hpg_sco_tan  ***
554      !!
555      !! ** Method of the direct routine:   s-coordinate case. Jacobian scheme.
556      !!      The now hydrostatic pressure gradient at a given level, jk,
557      !!      is computed by taking the vertical integral of the in-situ
558      !!      density gradient along the model level from the suface to that
559      !!      level. s-coordinates (ln_sco): a corrective term is added
560      !!      to the horizontal pressure gradient :
561      !!         zhpi = grav .....  + 1/e1u mi(rhd) di[ grav dep3w ]
562      !!         zhpj = grav .....  + 1/e2v mj(rhd) dj[ grav dep3w ]
563      !!      add it to the general momentum trend (ua,va).
564      !!         ua = ua - 1/e1u * zhpi
565      !!         va = va - 1/e2v * zhpj
566      !!
567      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
568      !!----------------------------------------------------------------------
569      !!
570      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
571      CALL ctl_stop( 'hpg_sco_tan not available yet')
572   END SUBROUTINE hpg_sco_tan
573   SUBROUTINE hpg_sco_adj( kt )
574      !!---------------------------------------------------------------------
575      !!                  ***  ROUTINE hpg_sco_adj  ***
576      !!
577      !! ** Method of the direct routine:   s-coordinate case. Jacobian scheme.
578      !!      The now hydrostatic pressure gradient at a given level, jk,
579      !!      is computed by taking the vertical integral of the in-situ
580      !!      density gradient along the model level from the suface to that
581      !!      level. s-coordinates (ln_sco): a corrective term is added
582      !!      to the horizontal pressure gradient :
583      !!         zhpi = grav .....  + 1/e1u mi(rhd) di[ grav dep3w ]
584      !!         zhpj = grav .....  + 1/e2v mj(rhd) dj[ grav dep3w ]
585      !!      add it to the general momentum trend (ua,va).
586      !!         ua = ua - 1/e1u * zhpi
587      !!         va = va - 1/e2v * zhpj
588      !!
589      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
590      !!----------------------------------------------------------------------
591      !!
592      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
593      CALL ctl_stop( 'hpg_sco_adj not available yet')
594   END SUBROUTINE hpg_sco_adj
595   SUBROUTINE hpg_djc_tan( kt )
596      !!---------------------------------------------------------------------
597      !!                  ***  ROUTINE hpg_hel_tan  ***
598      !!
599      !! ** Method of the direct routine:   s-coordinate case.
600      !!      The now hydrostatic pressure gradient at a given level
601      !!      jk is computed by taking the vertical integral of the in-situ
602      !!      density gradient along the model level from the suface to that
603      !!      level. s-coordinates (ln_sco): a corrective term is added
604      !!      to the horizontal pressure gradient :
605      !!         zhpi = grav .....  + 1/e1u mi(rhd) di[ grav dep3w ]
606      !!         zhpj = grav .....  + 1/e2v mj(rhd) dj[ grav dep3w ]
607      !!      add it to the general momentum trend (ua,va).
608      !!         ua = ua - 1/e1u * zhpi
609      !!         va = va - 1/e2v * zhpj
610      !!
611      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
612      !!             - Save the trend (l_trddyn=T)
613      !!----------------------------------------------------------------------
614      !!
615      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
616      CALL ctl_stop( 'hpg_djc_tan not available yet')
617   END SUBROUTINE hpg_djc_tan
618   SUBROUTINE hpg_djc_adj( kt )
619      !!---------------------------------------------------------------------
620      !!                  ***  ROUTINE hpg_hel_adj  ***
621      !!
622      !! ** Method of the direct routine:   s-coordinate case.
623      !!      The now hydrostatic pressure gradient at a given level
624      !!      jk is computed by taking the vertical integral of the in-situ
625      !!      density gradient along the model level from the suface to that
626      !!      level. s-coordinates (ln_sco): a corrective term is added
627      !!      to the horizontal pressure gradient :
628      !!         zhpi = grav .....  + 1/e1u mi(rhd) di[ grav dep3w ]
629      !!         zhpj = grav .....  + 1/e2v mj(rhd) dj[ grav dep3w ]
630      !!      add it to the general momentum trend (ua,va).
631      !!         ua = ua - 1/e1u * zhpi
632      !!         va = va - 1/e2v * zhpj
633      !!
634      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
635      !!             - Save the trend (l_trddyn=T)
636      !!----------------------------------------------------------------------
637      !!
638      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
639      CALL ctl_stop( 'hpg_djc_adj not available yet')
640   END SUBROUTINE hpg_djc_adj
641   SUBROUTINE hpg_prj_tan( kt )
642      !!---------------------------------------------------------------------
643      !!                  ***  ROUTINE hpg_wdj_tan  ***
644      !!
645      !! ** Method of the direct roiutine:
646      !!      Weighted Density Jacobian (wdj) scheme (song 1998)
647      !!      The weighting coefficients from the namelist parameter gamm
648      !!      (alpha=0.5-gamm ; beta=1-alpha=0.5+gamm)
649      !!
650      !! Reference : Song, Mon. Wea. Rev., 126, 3213-3230, 1998.
651      !!----------------------------------------------------------------------
652      !!
653      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
654      CALL ctl_stop( 'hpg_prj_tan not available yet')
655   END SUBROUTINE hpg_prj_tan
656   SUBROUTINE hpg_prj_adj( kt )
657      !!---------------------------------------------------------------------
658      !!                  ***  ROUTINE hpg_wdj_adj  ***
659      !!
660      !! ** Method of the direct roiutine:
661      !!      Weighted Density Jacobian (wdj) scheme (song 1998)
662      !!      The weighting coefficients from the namelist parameter gamm
663      !!      (alpha=0.5-gamm ; beta=1-alpha=0.5+gamm)
664      !!
665      !! Reference : Song, Mon. Wea. Rev., 126, 3213-3230, 1998.
666      !!----------------------------------------------------------------------
667      !!
668      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
669      CALL ctl_stop( 'hpg_prj_adj not available yet')
670   END SUBROUTINE hpg_prj_adj
671
672   SUBROUTINE dyn_hpg_adj_tst( kumadt )
673      !!-----------------------------------------------------------------------
674      !!
675      !!                  ***  ROUTINE dynhpg_adj_tst ***
676      !!
677      !! ** Purpose : Test the adjoint routine.
678      !!
679      !! ** Method  : Verify the scalar product
680      !!
681      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
682      !!
683      !!              where  L   = tangent routine
684      !!                     L^T = adjoint routine
685      !!                     W   = diagonal matrix of scale factors
686      !!                     dx  = input perturbation (random field)
687      !!                     dy  = L dx
688      !!
689      !! ** Action  : Separate tests are applied for the following dx and dy:
690      !!
691      !!              1) dx = ( SSH ) and dy = ( SSH )
692      !!
693      !! History :
694      !!        ! 08-07 (A. Vidard)
695      !!-----------------------------------------------------------------------
696      !! * Modules used
697
698      !! * Arguments
699      INTEGER, INTENT(IN) :: &
700         & kumadt             ! Output unit
701
702      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   &
703         & zrhd_tlin,              &  ! in situ density anomalie
704         & zua_tlin,               &  ! after u- velocity
705         & zva_tlin,               &  ! after v- velocity
706         & zua_tlout,              &  ! after u- velocity
707         & zva_tlout                  ! after v- velocity
708      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   &
709         & zrhd_adout,             &  ! in situ density anomalie
710         & zua_adout,              &  ! after u- velocity
711         & zva_adout,              &  ! after v- velocity
712         & zua_adin,               &  ! after u- velocity
713         & zva_adin                   ! after v- velocity
714      REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   &
715         & zgru_tlin,              &
716         & zgrv_tlin,              &
717         & zgru_adout,             &
718         & zgrv_adout
719
720      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
721         & zrh,          & ! 3D random field for rhd
722         & zau,          & ! 3D random field for u
723         & zav             ! 3D random field for v
724      REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   &
725         & zgru,         & ! 2D random field for gru
726         & zgrv            ! 2D random field for grv
727      REAL(KIND=wp) ::   &
728         & zsp1,         & ! scalar product involving the tangent routine
729         & zsp1_1,       & !   scalar product components
730         & zsp1_2,       &
731         & zsp2,         & ! scalar product involving the adjoint routine
732         & zsp2_1,       & !   scalar product components
733         & zsp2_2,       &
734         & zsp2_3,       &
735         & zsp2_4,       &
736         & zsp2_5
737      INTEGER, DIMENSION(jpi,jpj) :: &
738         & iseed_2d           ! 2D seed for the random number generator
739      INTEGER :: &
740         & iseed, &
741         & ji, &
742         & jj, &
743         & jk
744      CHARACTER(LEN=14) :: cl_name
745
746      ! Allocate memory
747      ALLOCATE( &
748         & zrhd_tlin(jpi,jpj,jpk),  &
749         & zua_tlin(jpi,jpj,jpk),   &
750         & zva_tlin(jpi,jpj,jpk),   &
751         & zgru_tlin(jpi,jpj),      &
752         & zgrv_tlin(jpi,jpj),      &
753         & zua_tlout(jpi,jpj,jpk),  &
754         & zva_tlout(jpi,jpj,jpk),  &
755         & zrhd_adout(jpi,jpj,jpk), &
756         & zua_adout(jpi,jpj,jpk),  &
757         & zva_adout(jpi,jpj,jpk),  &
758         & zgru_adout(jpi,jpj),     &
759         & zgrv_adout(jpi,jpj),     &
760         & zua_adin(jpi,jpj,jpk),   &
761         & zva_adin(jpi,jpj,jpk),   &
762         & zrh(jpi,jpj,jpk),        &
763         & zau(jpi,jpj,jpk),        &
764         & zav(jpi,jpj,jpk),        &
765         & zgru(jpi,jpj),           &
766         & zgrv(jpi,jpj)            &
767         &     )
768
769
770      !==================================================================
771      ! 1) dx = ( un_tl, vn_tl, hdivn_tl ) and
772      !    dy = ( hdivb_tl, hdivn_tl )
773      !==================================================================
774
775      !--------------------------------------------------------------------
776      ! Reset the tangent and adjoint variables
777      !--------------------------------------------------------------------
778      zrhd_tlin(:,:,:)  = 0.0_wp
779      zua_tlin(:,:,:)   = 0.0_wp
780      zva_tlin(:,:,:)   = 0.0_wp
781      zgru_tlin(:,:)    = 0.0_wp
782      zgrv_tlin(:,:)    = 0.0_wp
783      zua_tlout(:,:,:)  = 0.0_wp
784      zva_tlout(:,:,:)  = 0.0_wp
785      zgru_adout(:,:)   = 0.0_wp
786      zgrv_adout(:,:)   = 0.0_wp
787      zrhd_adout(:,:,:) = 0.0_wp
788      zua_adout(:,:,:)  = 0.0_wp
789      zva_adout(:,:,:)  = 0.0_wp
790      zua_adin(:,:,:)   = 0.0_wp
791      zva_adin(:,:,:)   = 0.0_wp
792      zrh(:,:,:)        = 0.0_wp
793      zau(:,:,:)        = 0.0_wp
794      zav(:,:,:)        = 0.0_wp
795      zgru(:,:)         = 0.0_wp
796      zgrv(:,:)         = 0.0_wp
797
798
799      gru_tl(:,:)   = 0.0_wp
800      grv_tl(:,:)   = 0.0_wp
801      gru_ad(:,:)   = 0.0_wp
802      grv_ad(:,:)   = 0.0_wp
803      ua_tl(:,:,:)  = 0.0_wp
804      va_tl(:,:,:)  = 0.0_wp
805      rhd_tl(:,:,:) = 0.0_wp
806      ua_ad(:,:,:)  = 0.0_wp
807      va_ad(:,:,:)  = 0.0_wp
808      rhd_ad(:,:,:) = 0.0_wp
809
810      !--------------------------------------------------------------------
811      ! Initialize the tangent input with random noise: dx
812      !--------------------------------------------------------------------
813
814      CALL grid_random(  zau, 'U', 0.0_wp, stdu )
815      CALL grid_random(  zav, 'V', 0.0_wp, stdv )
816      CALL grid_random(  zrh, 'W', 0.0_wp, stdr )
817      CALL grid_random(  zgru, 'U', 0.0_wp, stdu )
818      CALL grid_random(  zgrv, 'V', 0.0_wp, stdv )
819
820      DO jk = 1, jpk
821         DO jj = nldj, nlej
822            DO ji = nldi, nlei
823               zrhd_tlin(ji,jj,jk) = zrh(ji,jj,jk)
824               zua_tlin(ji,jj,jk)  = zau(ji,jj,jk)
825               zva_tlin(ji,jj,jk)  = zav(ji,jj,jk)
826            END DO
827         END DO
828      END DO
829      DO jj = nldj, nlej
830         DO ji = nldi, nlei
831            zgru_tlin(ji,jj)   = zgru(ji,jj)
832            zgrv_tlin(ji,jj)   = zgrv(ji,jj)
833         END DO
834      END DO
835      ua_tl(:,:,:)  = zua_tlin(:,:,:)
836      va_tl(:,:,:)  = zva_tlin(:,:,:)
837      rhd_tl(:,:,:) = zrhd_tlin(:,:,:)
838      gru_tl(:,:)   = zgru_tlin(:,:)
839      grv_tl(:,:)   = zgrv_tlin(:,:)
840
841      CALL dyn_hpg_tan ( nit000 )
842
843      zua_tlout(:,:,:) = ua_tl(:,:,:)
844      zva_tlout(:,:,:) = va_tl(:,:,:)
845      !--------------------------------------------------------------------
846      ! Initialize the adjoint variables: dy^* = W dy
847      !--------------------------------------------------------------------
848
849      DO jk = 1, jpk
850        DO jj = nldj, nlej
851           DO ji = nldi, nlei
852              zua_adin(ji,jj,jk) = zua_tlout(ji,jj,jk) &
853                 &               * e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) &
854                 &               * umask(ji,jj,jk)
855              zva_adin(ji,jj,jk) = zva_tlout(ji,jj,jk) &
856                 &               * e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk) &
857                 &               * vmask(ji,jj,jk)
858            END DO
859         END DO
860      END DO
861      !--------------------------------------------------------------------
862      ! Compute the scalar product: ( L dx )^T W dy
863      !--------------------------------------------------------------------
864
865      zsp1_1 = DOT_PRODUCT( zua_tlout, zua_adin )
866      zsp1_2 = DOT_PRODUCT( zva_tlout, zva_adin )
867      zsp1   = zsp1_1 + zsp1_2
868
869      !--------------------------------------------------------------------
870      ! Call the adjoint routine: dx^* = L^T dy^*
871      !--------------------------------------------------------------------
872
873      ua_ad(:,:,:) = zua_adin(:,:,:)
874      va_ad(:,:,:) = zva_adin(:,:,:)
875
876      CALL dyn_hpg_adj ( nit000 )
877
878      zgru_adout(:,:)   = gru_ad(:,:)
879      zgrv_adout(:,:)   = grv_ad(:,:)
880      zrhd_adout(:,:,:) = rhd_ad(:,:,:)
881      zua_adout(:,:,:)  = ua_ad(:,:,:)
882      zva_adout(:,:,:)  = va_ad(:,:,:)
883
884      zsp2_1 = DOT_PRODUCT( zgru_tlin, zgru_adout )
885      zsp2_2 = DOT_PRODUCT( zgrv_tlin, zgrv_adout )
886      zsp2_3 = DOT_PRODUCT( zrhd_tlin, zrhd_adout )
887      zsp2_4 = DOT_PRODUCT( zua_tlin, zua_adout )
888      zsp2_5 = DOT_PRODUCT( zva_tlin, zva_adout )
889      zsp2   = zsp2_1 + zsp2_2 + zsp2_3 + zsp2_4 + zsp2_5
890      ! Compare the scalar products
891
892      cl_name = 'dyn_hpg_adj   '
893      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
894
895      DEALLOCATE( &
896         & zrhd_tlin,  &
897         & zua_tlin,   &
898         & zva_tlin,   &
899         & zgru_tlin,  &
900         & zgrv_tlin,  &
901         & zua_tlout,  &
902         & zva_tlout,  &
903         & zrhd_adout, &
904         & zua_adout,  &
905         & zva_adout,  &
906         & zgru_adout, &
907         & zgrv_adout, &
908         & zua_adin,   &
909         & zva_adin,   &
910         & zrh,        &
911         & zau,        &
912         & zav,        &
913         & zgru,       &
914         & zgrv        &
915         &              )
916   END SUBROUTINE dyn_hpg_adj_tst
917#endif
918END MODULE dynhpg_tam
Note: See TracBrowser for help on using the repository browser.