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 @ 4574

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

Cosmetic Changes in dynhpg_tam.F90

  • 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/namdyn_hpg/ ln_hpg_zco, ln_hpg_zps, ln_hpg_sco,     &
134         &                 ln_hpg_djc, ln_hpg_prj, ln_dynhpg_imp
135      !!----------------------------------------------------------------------
136
137      REWIND ( numnam )               ! Read Namelist nam_dynhpg : pressure gradient calculation options
138      READ   ( numnam, namdyn_hpg )
139
140      IF(lwp) THEN                    ! Control print
141         WRITE(numout,*)
142         WRITE(numout,*) 'dyn_ctl_tam : hydrostatic pressure gradient'
143         WRITE(numout,*) '~~~~~~~~~~~~~~~'
144         WRITE(numout,*) '   Namelist namdyn_hpg : choice of hpg scheme'
145         WRITE(numout,*) '      z-coord. - full steps                             ln_hpg_zco    = ', ln_hpg_zco
146         WRITE(numout,*) '      z-coord. - partial steps (interpolation)          ln_hpg_zps    = ', ln_hpg_zps
147         WRITE(numout,*) '      s-coord. (standard jacobian formulation)          ln_hpg_sco    = ', ln_hpg_sco
148         WRITE(numout,*) '      s-coord. (Density Jacobian: Cubic polynomial)     ln_hpg_djc    = ', ln_hpg_djc
149         WRITE(numout,*) '      s-coord. (Pressure Jacobian: Cubic polynomial)    ln_hpg_prj    = ', ln_hpg_prj
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 > 1 ) THEN             ! on i-direction (level 2 or more)
407               ua_tl (ji,jj,iku) = ua_tl(ji,jj,iku) - zhpitl(ji,jj,iku)   ! subtract old value
408               zhpitl(ji,jj,iku) = zhpitl(ji,jj,iku-1)               &    ! compute the new one
409                  &              + zcoef2 * ( rhd_tl(ji+1,jj,iku-1) - rhd_tl(ji,jj,iku-1) + gru_tl(ji,jj) ) / e1u(ji,jj)
410               ua_tl (ji,jj,iku) = ua_tl(ji,jj,iku) + zhpitl(ji,jj,iku)   ! add the new one to the general momentum trend
411            ENDIF
412
413            IF ( ikv > 1 ) THEN            ! on j-direction
414               va_tl(ji,jj,ikv) = va_tl(ji,jj,ikv) - zhpjtl(ji,jj,ikv)    ! subtract old value
415               zhpjtl (ji,jj,ikv) = zhpjtl(ji,jj,ikv-1)   &               ! compute the new one
416                  &               + zcoef3 * ( rhd_tl(ji,jj+1,ikv-1) - rhd_tl(ji,jj,ikv-1) + grv_tl(ji,jj) ) / e2v(ji,jj)
417               va_tl(ji,jj,ikv) = va_tl(ji,jj,ikv) + zhpjtl(ji,jj,ikv)    ! add the new one to the general momentum trend
418            ENDIF
419# if ! defined key_vectopt_loop
420         END DO
421# endif
422      END DO
423      !
424      CALL wrk_dealloc( jpi,jpj,jpk, zhpitl, zhpjtl )
425      !
426   END SUBROUTINE hpg_zps_tan
427   SUBROUTINE hpg_zps_adj( kt )
428      !!---------------------------------------------------------------------
429      !!                 ***  ROUTINE hpg_zps  ***
430      !!
431      !! ** Method of the direct routine:
432      !!              z-coordinate plus partial steps case.  blahblah...
433      !!
434      !! ** Action  : - Update (ua_tl,va_tl) with the now hydrastatic pressure trend
435      !!----------------------------------------------------------------------
436      !!
437      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
438      !!
439      INTEGER  ::   ji, jj, jk                       ! dummy loop indices
440      INTEGER  ::   iku, ikv                         ! temporary integers
441      REAL(wp) ::   zcoef0, zcoef1, zcoef2, zcoef3   ! temporary scalars
442      REAL(wp), POINTER, DIMENSION(:,:,:):: zhpiad, zhpjad
443      !!----------------------------------------------------------------------
444      !
445      CALL wrk_alloc( jpi,jpj,jpk, zhpiad, zhpjad )
446      !
447      IF( kt == nitend ) THEN
448         IF(lwp) WRITE(numout,*)
449         IF(lwp) WRITE(numout,*) 'dyn:hpg_zps_adj : hydrostatic pressure gradient trend'
450         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~   z-coordinate with partial steps - vector optimization'
451      ENDIF
452      zhpiad(:,:,:) = 0.0_wp
453      zhpjad(:,:,:) = 0.0_wp
454      ! Local constant initialization
455      zcoef0 = - grav * 0.5
456
457      ! partial steps correction at the last level  (new gradient with  intgrd.F)
458# if defined key_vectopt_loop
459         jj = 1
460         DO ji = jpij-jpi-1, jpi+2, -1   ! vector opt. (forced unrolling)
461# else
462      DO jj = jpjm1, 2, -1
463         DO ji = jpim1, 2, -1
464# endif
465            iku = mbku(ji,jj)
466            ikv = mbkv(ji,jj)
467            zcoef2 = zcoef0 * MIN( fse3w(ji,jj,iku), fse3w(ji+1,jj  ,iku) )
468            zcoef3 = zcoef0 * MIN( fse3w(ji,jj,ikv), fse3w(ji  ,jj+1,ikv) )
469            ! on i-direction
470            IF ( iku > 2 ) THEN
471               ! add the new one to the general momentum trend
472               zhpiad(ji,jj,iku) = zhpiad(ji,jj,iku) + ua_ad(ji,jj,iku)
473               ! compute the new one
474               rhd_ad(ji+1,jj,iku-1) = rhd_ad(ji+1,jj,iku-1) + zhpiad (ji,jj,iku) * zcoef2 / e1u(ji,jj)
475               rhd_ad(ji,jj,iku-1) = rhd_ad(ji,jj,iku-1) - zhpiad (ji,jj,iku) * zcoef2 / e1u(ji,jj)
476               gru_ad(ji,jj) = gru_ad(ji,jj) + zhpiad (ji,jj,iku) * zcoef2 / e1u(ji,jj)
477               zhpiad(ji,jj,iku-1) = zhpiad(ji,jj,iku-1) + zhpiad (ji,jj,iku)
478               zhpiad (ji,jj,iku) = 0.0_wp
479               ! subtract old value
480               zhpiad(ji,jj,iku) = zhpiad(ji,jj,iku) - ua_ad(ji,jj,iku)
481            ENDIF
482            ! on j-direction
483            IF ( ikv > 2 ) THEN
484               ! add the new one to the general momentum trend
485               zhpjad(ji,jj,ikv) = zhpjad(ji,jj,ikv) + va_ad(ji,jj,ikv)
486               ! compute the new one
487               rhd_ad(ji,jj+1,ikv-1) = rhd_ad(ji,jj+1,ikv-1) + zhpjad (ji,jj,ikv) * zcoef3 / e2v(ji,jj)
488               rhd_ad(ji,jj,ikv-1) = rhd_ad(ji,jj,ikv-1) -zhpjad (ji,jj,ikv) * zcoef3 / e2v(ji,jj)
489               grv_ad(ji,jj) = grv_ad(ji,jj) +zhpjad (ji,jj,ikv) * zcoef3 / e2v(ji,jj)
490               zhpjad(ji,jj,ikv-1) = zhpjad(ji,jj,ikv-1) + zhpjad(ji,jj,ikv)
491               zhpjad (ji,jj,ikv) = 0.0_wp
492               ! subtract old value
493               zhpjad(ji,jj,ikv) = zhpjad(ji,jj,ikv) - va_ad(ji,jj,ikv)
494            ENDIF
495# if ! defined key_vectopt_loop
496         END DO
497# endif
498      END DO
499      !
500      ! interior value (2=<jk=<jpkm1)
501      DO jk = jpkm1, 2, -1
502         DO jj = jpjm1, 2, -1
503            DO ji = fs_jpim1, fs_2, -1   ! vector opt.
504               zcoef1 = zcoef0 * fse3w(ji,jj,jk)
505               ! add to the general momentum trend
506               zhpiad(ji,jj,jk) = zhpiad(ji,jj,jk) + ua_ad(ji,jj,jk)
507               zhpjad(ji,jj,jk) = zhpjad(ji,jj,jk) + va_ad(ji,jj,jk)
508               ! hydrostatic pressure gradient
509               rhd_ad(ji,jj+1,jk  ) = rhd_ad(ji,jj+1,jk  ) + zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
510               rhd_ad(ji,jj+1,jk-1) = rhd_ad(ji,jj+1,jk-1) + zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
511               rhd_ad(ji,jj  ,jk  ) = rhd_ad(ji,jj  ,jk  ) - zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
512               rhd_ad(ji,jj  ,jk-1) = rhd_ad(ji,jj  ,jk-1) - zhpjad(ji,jj,jk) * zcoef1 / e2v(ji,jj)
513               zhpjad(ji,jj  ,jk-1) = zhpjad(ji,jj  ,jk-1) + zhpjad(ji,jj,jk)
514               zhpjad(ji,jj  ,jk  ) = 0.0_wp
515               !
516               rhd_ad(ji+1,jj,jk  ) = rhd_ad(ji+1,jj,jk  ) + zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
517               rhd_ad(ji+1,jj,jk-1) = rhd_ad(ji+1,jj,jk-1) + zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
518               rhd_ad(ji  ,jj,jk  ) = rhd_ad(ji  ,jj,jk  ) - zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
519               rhd_ad(ji  ,jj,jk-1) = rhd_ad(ji  ,jj,jk-1) - zhpiad(ji,jj,jk) * zcoef1 / e1u(ji,jj)
520               zhpiad(ji  ,jj,jk-1) = zhpiad(ji  ,jj,jk-1) + zhpiad(ji,jj,jk)
521               zhpiad(ji  ,jj,jk  ) = 0.0_wp
522            END DO
523         END DO
524      END DO
525      !  Surface value
526      DO jj = jpjm1, 2, -1
527         DO ji = fs_jpim1, fs_2, -1   ! vector opt.
528            zcoef1 = zcoef0 * fse3w(ji,jj,1)
529            ! add to the general momentum trend
530            zhpiad(ji,jj,1) = zhpiad(ji,jj,1) + ua_ad(ji,jj,1)
531            zhpjad(ji,jj,1) = zhpjad(ji,jj,1) + va_ad(ji,jj,1)
532            ! hydrostatic pressure gradient
533            rhd_ad(ji+1,jj  ,1) = rhd_ad(ji+1,jj  ,1) + zhpiad(ji,jj,1) * zcoef1 / e1u(ji,jj)
534            rhd_ad(ji  ,jj  ,1) = rhd_ad(ji  ,jj  ,1) - zhpiad(ji,jj,1) * zcoef1 / e1u(ji,jj)
535            rhd_ad(ji  ,jj+1,1) = rhd_ad(ji  ,jj+1,1) + zhpjad(ji,jj,1) * zcoef1 / e2v(ji,jj)
536            rhd_ad(ji  ,jj  ,1) = rhd_ad(ji  ,jj  ,1) - zhpjad(ji,jj,1) * zcoef1 / e2v(ji,jj)
537            zhpiad(ji  ,jj  ,1) = 0.0_wp
538            zhpjad(ji  ,jj  ,1) = 0.0_wp
539         END DO
540      END DO
541      !
542      CALL wrk_dealloc( jpi,jpj,jpk, zhpiad, zhpjad )
543      !
544   END SUBROUTINE hpg_zps_adj
545   SUBROUTINE hpg_sco_tan( kt )
546      !!---------------------------------------------------------------------
547      !!                  ***  ROUTINE hpg_sco_tan  ***
548      !!
549      !! ** Method of the direct routine:   s-coordinate case. Jacobian scheme.
550      !!      The now hydrostatic pressure gradient at a given level, jk,
551      !!      is computed by taking the vertical integral of the in-situ
552      !!      density gradient along the model level from the suface to that
553      !!      level. s-coordinates (ln_sco): a corrective term is added
554      !!      to the horizontal pressure gradient :
555      !!         zhpi = grav .....  + 1/e1u mi(rhd) di[ grav dep3w ]
556      !!         zhpj = grav .....  + 1/e2v mj(rhd) dj[ grav dep3w ]
557      !!      add it to the general momentum trend (ua,va).
558      !!         ua = ua - 1/e1u * zhpi
559      !!         va = va - 1/e2v * zhpj
560      !!
561      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
562      !!----------------------------------------------------------------------
563      !!
564      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
565      CALL ctl_stop( 'hpg_sco_tan not available yet')
566   END SUBROUTINE hpg_sco_tan
567   SUBROUTINE hpg_sco_adj( kt )
568      !!---------------------------------------------------------------------
569      !!                  ***  ROUTINE hpg_sco_adj  ***
570      !!
571      !! ** Method of the direct routine:   s-coordinate case. Jacobian scheme.
572      !!      The now hydrostatic pressure gradient at a given level, jk,
573      !!      is computed by taking the vertical integral of the in-situ
574      !!      density gradient along the model level from the suface to that
575      !!      level. s-coordinates (ln_sco): a corrective term is added
576      !!      to the horizontal pressure gradient :
577      !!         zhpi = grav .....  + 1/e1u mi(rhd) di[ grav dep3w ]
578      !!         zhpj = grav .....  + 1/e2v mj(rhd) dj[ grav dep3w ]
579      !!      add it to the general momentum trend (ua,va).
580      !!         ua = ua - 1/e1u * zhpi
581      !!         va = va - 1/e2v * zhpj
582      !!
583      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
584      !!----------------------------------------------------------------------
585      !!
586      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
587      CALL ctl_stop( 'hpg_sco_adj not available yet')
588   END SUBROUTINE hpg_sco_adj
589   SUBROUTINE hpg_djc_tan( kt )
590      !!---------------------------------------------------------------------
591      !!                  ***  ROUTINE hpg_hel_tan  ***
592      !!
593      !! ** Method of the direct routine:   s-coordinate case.
594      !!      The now hydrostatic pressure gradient at a given level
595      !!      jk is computed by taking the vertical integral of the in-situ
596      !!      density gradient along the model level from the suface to that
597      !!      level. s-coordinates (ln_sco): a corrective term is added
598      !!      to the horizontal pressure gradient :
599      !!         zhpi = grav .....  + 1/e1u mi(rhd) di[ grav dep3w ]
600      !!         zhpj = grav .....  + 1/e2v mj(rhd) dj[ grav dep3w ]
601      !!      add it to the general momentum trend (ua,va).
602      !!         ua = ua - 1/e1u * zhpi
603      !!         va = va - 1/e2v * zhpj
604      !!
605      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
606      !!             - Save the trend (l_trddyn=T)
607      !!----------------------------------------------------------------------
608      !!
609      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
610      CALL ctl_stop( 'hpg_djc_tan not available yet')
611   END SUBROUTINE hpg_djc_tan
612   SUBROUTINE hpg_djc_adj( kt )
613      !!---------------------------------------------------------------------
614      !!                  ***  ROUTINE hpg_hel_adj  ***
615      !!
616      !! ** Method of the direct routine:   s-coordinate case.
617      !!      The now hydrostatic pressure gradient at a given level
618      !!      jk is computed by taking the vertical integral of the in-situ
619      !!      density gradient along the model level from the suface to that
620      !!      level. s-coordinates (ln_sco): a corrective term is added
621      !!      to the horizontal pressure gradient :
622      !!         zhpi = grav .....  + 1/e1u mi(rhd) di[ grav dep3w ]
623      !!         zhpj = grav .....  + 1/e2v mj(rhd) dj[ grav dep3w ]
624      !!      add it to the general momentum trend (ua,va).
625      !!         ua = ua - 1/e1u * zhpi
626      !!         va = va - 1/e2v * zhpj
627      !!
628      !! ** Action : - Update (ua,va) with the now hydrastatic pressure trend
629      !!             - Save the trend (l_trddyn=T)
630      !!----------------------------------------------------------------------
631      !!
632      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
633      CALL ctl_stop( 'hpg_djc_adj not available yet')
634   END SUBROUTINE hpg_djc_adj
635   SUBROUTINE hpg_prj_tan( kt )
636      !!---------------------------------------------------------------------
637      !!                  ***  ROUTINE hpg_wdj_tan  ***
638      !!
639      !! ** Method of the direct roiutine:
640      !!      Weighted Density Jacobian (wdj) scheme (song 1998)
641      !!      The weighting coefficients from the namelist parameter gamm
642      !!      (alpha=0.5-gamm ; beta=1-alpha=0.5+gamm)
643      !!
644      !! Reference : Song, Mon. Wea. Rev., 126, 3213-3230, 1998.
645      !!----------------------------------------------------------------------
646      !!
647      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
648      CALL ctl_stop( 'hpg_prj_tan not available yet')
649   END SUBROUTINE hpg_prj_tan
650   SUBROUTINE hpg_prj_adj( kt )
651      !!---------------------------------------------------------------------
652      !!                  ***  ROUTINE hpg_wdj_adj  ***
653      !!
654      !! ** Method of the direct roiutine:
655      !!      Weighted Density Jacobian (wdj) scheme (song 1998)
656      !!      The weighting coefficients from the namelist parameter gamm
657      !!      (alpha=0.5-gamm ; beta=1-alpha=0.5+gamm)
658      !!
659      !! Reference : Song, Mon. Wea. Rev., 126, 3213-3230, 1998.
660      !!----------------------------------------------------------------------
661      !!
662      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
663      CALL ctl_stop( 'hpg_prj_adj not available yet')
664   END SUBROUTINE hpg_prj_adj
665
666   SUBROUTINE dyn_hpg_adj_tst( kumadt )
667      !!-----------------------------------------------------------------------
668      !!
669      !!                  ***  ROUTINE dynhpg_adj_tst ***
670      !!
671      !! ** Purpose : Test the adjoint routine.
672      !!
673      !! ** Method  : Verify the scalar product
674      !!
675      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
676      !!
677      !!              where  L   = tangent routine
678      !!                     L^T = adjoint routine
679      !!                     W   = diagonal matrix of scale factors
680      !!                     dx  = input perturbation (random field)
681      !!                     dy  = L dx
682      !!
683      !! ** Action  : Separate tests are applied for the following dx and dy:
684      !!
685      !!              1) dx = ( SSH ) and dy = ( SSH )
686      !!
687      !! History :
688      !!        ! 08-07 (A. Vidard)
689      !!-----------------------------------------------------------------------
690      !! * Modules used
691
692      !! * Arguments
693      INTEGER, INTENT(IN) :: &
694         & kumadt             ! Output unit
695
696      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   &
697         & zrhd_tlin,              &  ! in situ density anomalie
698         & zua_tlin,               &  ! after u- velocity
699         & zva_tlin,               &  ! after v- velocity
700         & zua_tlout,              &  ! after u- velocity
701         & zva_tlout                  ! after v- velocity
702      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   &
703         & zrhd_adout,             &  ! in situ density anomalie
704         & zua_adout,              &  ! after u- velocity
705         & zva_adout,              &  ! after v- velocity
706         & zua_adin,               &  ! after u- velocity
707         & zva_adin                   ! after v- velocity
708      REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   &
709         & zgru_tlin,              &
710         & zgrv_tlin,              &
711         & zgru_adout,             &
712         & zgrv_adout
713
714      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
715         & zrh,          & ! 3D random field for rhd
716         & zau,          & ! 3D random field for u
717         & zav             ! 3D random field for v
718      REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   &
719         & zgru,         & ! 2D random field for gru
720         & zgrv            ! 2D random field for grv
721      REAL(KIND=wp) ::   &
722         & zsp1,         & ! scalar product involving the tangent routine
723         & zsp1_1,       & !   scalar product components
724         & zsp1_2,       &
725         & zsp2,         & ! scalar product involving the adjoint routine
726         & zsp2_1,       & !   scalar product components
727         & zsp2_2,       &
728         & zsp2_3,       &
729         & zsp2_4,       &
730         & zsp2_5
731      INTEGER, DIMENSION(jpi,jpj) :: &
732         & iseed_2d           ! 2D seed for the random number generator
733      INTEGER :: &
734         & iseed, &
735         & ji, &
736         & jj, &
737         & jk
738      CHARACTER(LEN=14) :: cl_name
739
740      ! Allocate memory
741      ALLOCATE( &
742         & zrhd_tlin(jpi,jpj,jpk),  &
743         & zua_tlin(jpi,jpj,jpk),   &
744         & zva_tlin(jpi,jpj,jpk),   &
745         & zgru_tlin(jpi,jpj),      &
746         & zgrv_tlin(jpi,jpj),      &
747         & zua_tlout(jpi,jpj,jpk),  &
748         & zva_tlout(jpi,jpj,jpk),  &
749         & zrhd_adout(jpi,jpj,jpk), &
750         & zua_adout(jpi,jpj,jpk),  &
751         & zva_adout(jpi,jpj,jpk),  &
752         & zgru_adout(jpi,jpj),     &
753         & zgrv_adout(jpi,jpj),     &
754         & zua_adin(jpi,jpj,jpk),   &
755         & zva_adin(jpi,jpj,jpk),   &
756         & zrh(jpi,jpj,jpk),        &
757         & zau(jpi,jpj,jpk),        &
758         & zav(jpi,jpj,jpk),        &
759         & zgru(jpi,jpj),           &
760         & zgrv(jpi,jpj)            &
761         &     )
762
763
764      !==================================================================
765      ! 1) dx = ( un_tl, vn_tl, hdivn_tl ) and
766      !    dy = ( hdivb_tl, hdivn_tl )
767      !==================================================================
768
769      !--------------------------------------------------------------------
770      ! Reset the tangent and adjoint variables
771      !--------------------------------------------------------------------
772      zrhd_tlin(:,:,:)  = 0.0_wp
773      zua_tlin(:,:,:)   = 0.0_wp
774      zva_tlin(:,:,:)   = 0.0_wp
775      zgru_tlin(:,:)    = 0.0_wp
776      zgrv_tlin(:,:)    = 0.0_wp
777      zua_tlout(:,:,:)  = 0.0_wp
778      zva_tlout(:,:,:)  = 0.0_wp
779      zgru_adout(:,:)   = 0.0_wp
780      zgrv_adout(:,:)   = 0.0_wp
781      zrhd_adout(:,:,:) = 0.0_wp
782      zua_adout(:,:,:)  = 0.0_wp
783      zva_adout(:,:,:)  = 0.0_wp
784      zua_adin(:,:,:)   = 0.0_wp
785      zva_adin(:,:,:)   = 0.0_wp
786      zrh(:,:,:)        = 0.0_wp
787      zau(:,:,:)        = 0.0_wp
788      zav(:,:,:)        = 0.0_wp
789      zgru(:,:)         = 0.0_wp
790      zgrv(:,:)         = 0.0_wp
791
792
793      gru_tl(:,:)   = 0.0_wp
794      grv_tl(:,:)   = 0.0_wp
795      gru_ad(:,:)   = 0.0_wp
796      grv_ad(:,:)   = 0.0_wp
797      ua_tl(:,:,:)  = 0.0_wp
798      va_tl(:,:,:)  = 0.0_wp
799      rhd_tl(:,:,:) = 0.0_wp
800      ua_ad(:,:,:)  = 0.0_wp
801      va_ad(:,:,:)  = 0.0_wp
802      rhd_ad(:,:,:) = 0.0_wp
803
804      !--------------------------------------------------------------------
805      ! Initialize the tangent input with random noise: dx
806      !--------------------------------------------------------------------
807
808      CALL grid_random(  zau, 'U', 0.0_wp, stdu )
809      CALL grid_random(  zav, 'V', 0.0_wp, stdv )
810      CALL grid_random(  zrh, 'W', 0.0_wp, stdr )
811      CALL grid_random(  zgru, 'U', 0.0_wp, stdu )
812      CALL grid_random(  zgrv, 'V', 0.0_wp, stdv )
813
814      DO jk = 1, jpk
815         DO jj = nldj, nlej
816            DO ji = nldi, nlei
817               zrhd_tlin(ji,jj,jk) = zrh(ji,jj,jk)
818               zua_tlin(ji,jj,jk)  = zau(ji,jj,jk)
819               zva_tlin(ji,jj,jk)  = zav(ji,jj,jk)
820            END DO
821         END DO
822      END DO
823      DO jj = nldj, nlej
824         DO ji = nldi, nlei
825            zgru_tlin(ji,jj)   = zgru(ji,jj)
826            zgrv_tlin(ji,jj)   = zgrv(ji,jj)
827         END DO
828      END DO
829      ua_tl(:,:,:)  = zua_tlin(:,:,:)
830      va_tl(:,:,:)  = zva_tlin(:,:,:)
831      rhd_tl(:,:,:) = zrhd_tlin(:,:,:)
832      gru_tl(:,:)   = zgru_tlin(:,:)
833      grv_tl(:,:)   = zgrv_tlin(:,:)
834
835      CALL dyn_hpg_tan ( nit000 )
836
837      zua_tlout(:,:,:) = ua_tl(:,:,:)
838      zva_tlout(:,:,:) = va_tl(:,:,:)
839      !--------------------------------------------------------------------
840      ! Initialize the adjoint variables: dy^* = W dy
841      !--------------------------------------------------------------------
842
843      DO jk = 1, jpk
844        DO jj = nldj, nlej
845           DO ji = nldi, nlei
846              zua_adin(ji,jj,jk) = zua_tlout(ji,jj,jk) &
847                 &               * e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) &
848                 &               * umask(ji,jj,jk)
849              zva_adin(ji,jj,jk) = zva_tlout(ji,jj,jk) &
850                 &               * e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk) &
851                 &               * vmask(ji,jj,jk)
852            END DO
853         END DO
854      END DO
855      !--------------------------------------------------------------------
856      ! Compute the scalar product: ( L dx )^T W dy
857      !--------------------------------------------------------------------
858
859      zsp1_1 = DOT_PRODUCT( zua_tlout, zua_adin )
860      zsp1_2 = DOT_PRODUCT( zva_tlout, zva_adin )
861      zsp1   = zsp1_1 + zsp1_2
862
863      !--------------------------------------------------------------------
864      ! Call the adjoint routine: dx^* = L^T dy^*
865      !--------------------------------------------------------------------
866
867      ua_ad(:,:,:) = zua_adin(:,:,:)
868      va_ad(:,:,:) = zva_adin(:,:,:)
869
870      CALL dyn_hpg_adj ( nit000 )
871
872      zgru_adout(:,:)   = gru_ad(:,:)
873      zgrv_adout(:,:)   = grv_ad(:,:)
874      zrhd_adout(:,:,:) = rhd_ad(:,:,:)
875      zua_adout(:,:,:)  = ua_ad(:,:,:)
876      zva_adout(:,:,:)  = va_ad(:,:,:)
877
878      zsp2_1 = DOT_PRODUCT( zgru_tlin, zgru_adout )
879      zsp2_2 = DOT_PRODUCT( zgrv_tlin, zgrv_adout )
880      zsp2_3 = DOT_PRODUCT( zrhd_tlin, zrhd_adout )
881      zsp2_4 = DOT_PRODUCT( zua_tlin, zua_adout )
882      zsp2_5 = DOT_PRODUCT( zva_tlin, zva_adout )
883      zsp2   = zsp2_1 + zsp2_2 + zsp2_3 + zsp2_4 + zsp2_5
884      ! Compare the scalar products
885
886      cl_name = 'dyn_hpg_adj   '
887      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
888
889      DEALLOCATE( &
890         & zrhd_tlin,  &
891         & zua_tlin,   &
892         & zva_tlin,   &
893         & zgru_tlin,  &
894         & zgrv_tlin,  &
895         & zua_tlout,  &
896         & zva_tlout,  &
897         & zrhd_adout, &
898         & zua_adout,  &
899         & zva_adout,  &
900         & zgru_adout, &
901         & zgrv_adout, &
902         & zua_adin,   &
903         & zva_adin,   &
904         & zrh,        &
905         & zau,        &
906         & zav,        &
907         & zgru,       &
908         & zgrv        &
909         &              )
910   END SUBROUTINE dyn_hpg_adj_tst
911#endif
912END MODULE dynhpg_tam
Note: See TracBrowser for help on using the repository browser.