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.
cla_div_tam.F90 in branches/TAM_V3_2_2/NEMOTAM/OPATAM_SRC – NEMO

source: branches/TAM_V3_2_2/NEMOTAM/OPATAM_SRC/cla_div_tam.F90 @ 3317

Last change on this file since 3317 was 2578, checked in by rblod, 13 years ago

first import of NEMOTAM 3.2.2

File size: 35.4 KB
Line 
1MODULE cla_div_tam
2#ifdef key_tam
3   !!==============================================================================
4   !!                    ***  MODULE  cla_div_tam  ***
5   !! Ocean diagnostic variable : specific update of the horizontal divergence
6   !!                             CAUTION: Specific to ORCA_R2
7   !!                             Tangent and adjoint module
8   !!==============================================================================
9#  if defined key_orca_r2
10   !!----------------------------------------------------------------------
11   !!   'key_orca_r2'                                 global ocean model R2
12   !!----------------------------------------------------------------------
13   !!   div_cla      :
14   !!   div_bab_el_mandeb
15   !!   div_gibraltar
16   !!   div_hormuz
17   !!   div_cla_init :
18   !!----------------------------------------------------------------------
19   !! * Modules used
20   USE par_kind,       ONLY: & ! Precision variables
21      & wp
22   USE par_oce,        ONLY: & ! Ocean space and time domain variables
23      & jpi,                 &
24      & jpj,                 & 
25      & jpk,                 & 
26      & jpiglo
27   USE oce_tam,        ONLY: & ! ocean dynamics and tracers
28      & hdivn_tl,            &
29      & hdivn_ad
30   USE sbc_oce_tam,    ONLY: & ! surface variables
31      & emp_tl,              &
32      & emp_ad
33   USE dom_oce,        ONLY: & ! ocean space and time domain
34      & mi0,                 &
35      & mi1,                 &
36      & mj0,                 &
37      & mj1,                 &
38      & nldi,                &
39      & nldj,                &
40      & nlei,                &
41      & nlej,                &
42      & rdt,                 &
43      & tmask,               &
44      & mig,                 &
45      & mjg,                 &
46      & e2u,                 &
47      & e1v,                 &
48      & e1t,                 &
49      & e2t,                 &
50# if defined key_vvl
51      & e3t_1,               &
52# else
53#  if defined key_zco
54      & e3t_0,               &
55#  else
56      & e3t,                 &
57#  endif
58# endif
59# if defined key_zco
60      & e3t_0,               &
61# else
62      & e3u,                 &
63      & e3v
64# endif
65   USE in_out_manager, ONLY: & ! I/O manager
66      & nit000
67   USE phycst,         ONLY: & ! Physical constants
68      & rau0
69   USE lib_mpp,        ONLY: & ! distributed memory computing library
70      & lk_mpp,              &
71      & mpp_sum
72   USE lbclnk,         ONLY: & ! ocean lateral boundary conditions (or mpp link)
73      & lbc_lnk
74   USE lbclnk_tam,     ONLY: & ! ocean lateral boundary conditions (or mpp link)
75      & lbc_lnk_adj
76   USE dotprodfld,     ONLY: & ! Computes dot product for 3D and 2D fields
77      & dot_product
78   USE gridrandom,     ONLY: & ! Random Gaussian noise on grids
79      & grid_random
80   USE tstool_tam,     ONLY: &
81      & prntst_adj,          & !
82      & stdemp,              & ! stdev for evaporation minus precip
83      & stdh                   !           hdiv
84
85   IMPLICIT NONE
86   PRIVATE
87
88   !! * Module variables
89   REAL(wp) :: zempmed_tl, zempred_tl       ! EMP of Mediterranean and Red Sea
90   REAL(wp) :: zempmed_ad, zempred_ad       ! EMP of Mediterranean and Red Sea
91   !! * Routine accessibility
92   PUBLIC div_cla_tan     ! routine called by step_tam.F90
93   PUBLIC div_cla_adj     ! routine called by step_tam.F90
94   PUBLIC div_cla_adj_tst ! routine called by tst.F90
95
96   !! * Substitutions
97#  include "domzgr_substitute.h90"
98
99CONTAINS
100
101   SUBROUTINE div_cla_tan ( kt )
102      !!----------------------------------------------------------------------
103      !!                 ***  ROUTINE div_cla_tan  ***
104      !!
105      !! ** Purpose of the direct routine:
106      !!      update the horizontal divergence of the velocity field
107      !!      for at some straits ( Gibraltar, Bab el Mandeb and Hormuz ).
108      !!
109      !! ** Method  :   With imposed transport at each strait, we compute
110      !!      corresponding velocities and update horizontal divergence.
111      !!        Apply lateral boundary conditions on hdivn through a call
112      !!      to routine lbc_lnk.
113      !!
114      !! ** Action  :   update hdivn array : the now horizontal divergence
115      !!
116      !! History of the direct routine:
117      !!   8.5  !  02-11 (A. Bozec)  Free form, F90
118      !! History of the TAM routine:
119      !!   9.0  !  08-06 (A. Vidard) Skeleton
120      !!   9.0  !  08-09 (A. Vidard) tangent of the 02-11 version
121      !!   9.0  !  09-02 (A. Vidard) cosmetic changes
122      !!----------------------------------------------------------------------
123      !! * Arguments
124      INTEGER, INTENT( in ) ::   kt      ! ocean time-step index
125      !!----------------------------------------------------------------------
126      ! Correction of the Divergence at some straits
127           
128      CALL div_bab_el_mandeb_tan                    ! New divergence at Bab el Mandeb
129
130      CALL div_gibraltar_tan                        ! New divergence at Gibraltar
131
132      CALL div_hormuz_tan                           ! Hormuz Strait ( persian Gulf)
133
134      ! Lateral boundary conditions on hdivn
135      CALL lbc_lnk( hdivn_tl, 'T', 1.0_wp )
136
137
138   END SUBROUTINE div_cla_tan
139
140   SUBROUTINE div_cla_adj ( kt )
141      !!----------------------------------------------------------------------
142      !!                 ***  ROUTINE div_cla_adj  ***
143      !!
144      !! ** Purpose of the direct routine:
145      !!      update the horizontal divergence of the velocity field
146      !!      for at some straits ( Gibraltar, Bab el Mandeb and Hormuz ).
147      !!
148      !! ** Method  :   With imposed transport at each strait, we compute
149      !!      corresponding velocities and update horizontal divergence.
150      !!        Apply lateral boundary conditions on hdivn through a call
151      !!      to routine lbc_lnk.
152      !!
153      !! ** Action  :   update hdivn array : the now horizontal divergence
154      !!
155      !! History of the direct routine:
156      !!   8.5  !  02-11 (A. Bozec)  Free form, F90
157      !! History of the TAM routine:
158      !!   9.0  !  08-06 (A. Vidard) Skeleton
159      !!   9.0  !  08-09 (A. Vidard) adjoint of the 02-11 version
160      !!   9.0  !  09-02 (A. Vidard) cosmetic changes
161     !!----------------------------------------------------------------------
162      !! * Arguments
163      INTEGER, INTENT( in ) ::   kt      ! ocean time-step index
164      !!----------------------------------------------------------------------
165      ! Correction of the Divergence at some straits
166
167      ! Lateral boundary conditions on hdivn
168      CALL lbc_lnk_adj( hdivn_ad, 'T', 1.0_wp )
169
170      CALL div_hormuz_adj                           ! Hormuz Strait ( persian Gulf)
171
172      CALL div_gibraltar_adj                        ! New divergence at Gibraltar
173
174      CALL div_bab_el_mandeb_adj                    ! New divergence at Bab el Mandeb
175
176   END SUBROUTINE div_cla_adj
177
178   SUBROUTINE div_bab_el_mandeb_tan
179      !!----------------------------------------------------------------------
180      !!                ***  ROUTINE div_bab_el_mandeb_tan  ***
181      !!       
182      !! ** Purpose of the direct routine:
183      !!     Update  the now horizontal divergence of the velocity
184      !!     field in Bab el Mandeb ( Red Sea strait ).
185      !!
186      !! ** Method of the direct routine:
187      !!     Set the velocity field at each side of the strait :
188      !!                                          |
189      !!            |/ \|            N          |\ /|
190      !!            |_|_|______      |          |___|______
191      !!        88  |   |<-       W - - E    88 |   |<-
192      !!        87  |___|______      |       87 |___|->____
193      !!             160 161         S           160 161
194      !!       horizontal view                horizontal view
195      !!          surface                        depth
196      !!      The now divergence is given by :
197      !!         hdivn = 1/(e1t*e2t) [ di(e2u  un) + dj(e1v  vn) ]
198      !!
199      !! ** History of the direct routine:
200      !!           !         (A. Bozec) Original code
201      !!      8.5  !  02-11  (A. Bozec) F90: Free form and module
202      !! ** History of the tangent routine:
203      !!           !  08-09  (A. Vidard) Tangent linear of the 02-11 version
204      !!      9.0  !  09-02 (A. Vidard) cosmetic changes
205      !!----------------------------------------------------------------------
206      !! * Local declarations
207      INTEGER  :: ji, jj, jk   ! dummy loop indices
208      REAL(wp) :: zsu, zvt, zwei   ! temporary scalar
209      REAL(wp), DIMENSION (jpk) ::  zu1_rs_tl, zu2_rs_tl, zu3_rs_tl
210      !!---------------------------------------------------------------------
211     
212      ! EMP on the Red Sea
213      ! ------------------
214
215      zempred_tl = 0.e0
216      zwei = 0.e0
217      DO jj = mj0(87), mj1(96)
218         DO ji = mi0(148), mi1(160) 
219            zwei    = tmask(ji,jj,1) * e1t(ji,jj) * e2t(ji,jj)
220            zempred_tl = zempred_tl + emp_tl(ji,jj) * zwei
221         END DO
222      END DO
223      IF( lk_mpp )   CALL mpp_sum( zempred_tl )      ! sum with other processors value
224
225
226      ! convert in m3
227      zempred_tl = zempred_tl * 1.e-3         
228
229      ! Velocity profile at each point
230      ! ------------------------------
231
232      zu1_rs_tl(:) = 0.0_wp
233      zu2_rs_tl(:) = 0.0_wp
234      zu3_rs_tl(:) = 0.0_wp
235
236      ! velocity profile at 161,88 North point
237      ! we imposed zisw_rs + EMP above the Red Sea
238      DO jk = 1,  8                                     
239         DO jj = mj0(88), mj1(88) 
240            DO ji = mi0(160), mi1(160) 
241               zu1_rs_tl(jk) = zu1_rs_tl(jk) - ( zempred_tl / 8. ) / ( e2u(ji, jj) * fse3u(ji, jj,jk) )
242            END DO
243         END DO
244      END DO
245
246      ! velocity profile at 160,88 North  point
247      ! we imposed zisw_rs + EMP above the Red Sea
248      DO jk = 1,  10                                     
249         DO jj = mj0(88), mj1(88) 
250            DO ji = mi0(160), mi1(160) 
251               zu3_rs_tl(jk) = zu3_rs_tl(jk) + ( zempred_tl / 10. ) / ( e1v(ji, jj) * fse3v(ji, jj,jk) )
252            END DO
253         END DO
254      END DO
255       
256      ! Divergence at each point of the straits
257      ! ---------------------------------------
258
259      ! compute the new divergence at 161,88
260      DO jk = 1, 21
261         DO jj = mj0(88), mj1(88) 
262            DO ji = mi0(161), mi1(161) 
263               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
264               zsu = e2u(ji-1, jj) * fse3u(ji-1, jj,jk)
265               hdivn_tl(ji, jj  ,jk) = hdivn_tl(ji, jj  ,jk) - ( 1. / zvt ) * zsu * zu1_rs_tl(jk)
266            END DO
267         END DO
268      END DO
269
270      ! compute the new divergence at 161,87
271      DO jk = 1, 21
272         DO jj = mj0(87), mj1(87) 
273            DO ji = mi0(161), mi1(161) 
274               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
275               zsu = e2u(ji-1, jj) * fse3u(ji-1, jj,jk)
276               hdivn_tl(ji, jj,jk) = hdivn_tl(ji, jj,jk) - ( 1. / zvt ) * zsu * zu2_rs_tl(jk)
277            END DO
278         END DO
279      END DO
280
281      ! compute the divergence at 160,89
282      DO jk = 1, 18
283         DO jj = mj0(89), mj1(89) 
284            DO ji = mi0(160), mi1(160) 
285               zvt = e1t(ji, jj) * e2t(ji,jj) * fse3t(ji,jj,jk)
286               zsu = e1v(ji, jj-1) * fse3v(ji, jj-1,jk)
287               hdivn_tl(ji, jj,jk) = hdivn_tl(ji, jj,jk) - ( 1. / zvt ) * zsu * zu3_rs_tl(jk)
288            END DO
289         END DO
290      END DO
291
292   END SUBROUTINE div_bab_el_mandeb_tan
293
294
295   SUBROUTINE div_bab_el_mandeb_adj
296      !!----------------------------------------------------------------------
297      !!                ***  ROUTINE div_bab_el_mandeb_adj  ***
298      !!       
299      !! ** Purpose of the direct routine:
300      !!     Update  the now horizontal divergence of the velocity
301      !!     field in Bab el Mandeb ( Red Sea strait ).
302      !!
303      !! ** Method of the direct routine:
304      !!     Set the velocity field at each side of the strait :
305      !!                                          |
306      !!            |/ \|            N          |\ /|
307      !!            |_|_|______      |          |___|______
308      !!        88  |   |<-       W - - E    88 |   |<-
309      !!        87  |___|______      |       87 |___|->____
310      !!             160 161         S           160 161
311      !!       horizontal view                horizontal view
312      !!          surface                        depth
313      !!      The now divergence is given by :
314      !!         hdivn = 1/(e1t*e2t) [ di(e2u  un) + dj(e1v  vn) ]
315      !!
316      !! ** History of the direct routine:
317      !!           !         (A. Bozec) Original code
318      !!      8.5  !  02-11  (A. Bozec) F90: Free form and module
319      !! ** History of the adjoint routine:
320      !!           !  08-09  (A. Vidard) Adjoint of the 02-11 version
321      !!      9.0  !  09-02 (A. Vidard) cosmetic changes
322      !!----------------------------------------------------------------------
323      !! * Local declarations
324      INTEGER  :: ji, jj, jk   ! dummy loop indices
325      REAL(wp) :: zsu, zvt, zwei   ! temporary scalar
326      REAL(wp), DIMENSION (jpk) ::  zu1_rs_ad, zu2_rs_ad, zu3_rs_ad
327      !!---------------------------------------------------------------------
328     
329      zempred_ad = 0.e0
330      zu1_rs_ad(:) = 0.0_wp
331      zu2_rs_ad(:) = 0.0_wp
332      zu3_rs_ad(:) = 0.0_wp
333      zwei = 0.e0
334       
335      ! Divergence at each point of the straits
336      ! ---------------------------------------
337
338      ! compute the divergence at 160,89
339      DO jk = 18, 1, -1
340         DO jj = mj0(89), mj1(89) 
341            DO ji = mi0(160), mi1(160) 
342               zvt = e1t(ji, jj) * e2t(ji,jj) * fse3t(ji,jj,jk)
343               zsu = e1v(ji, jj-1) * fse3v(ji, jj-1,jk)
344               zu3_rs_ad(jk) = zu3_rs_ad(jk) - hdivn_ad(ji, jj,jk) * ( 1. / zvt ) * zsu 
345            END DO
346         END DO
347      END DO
348
349      ! compute the new divergence at 161,87
350      DO jk = 21, 1, -1
351         DO jj = mj0(87), mj1(87) 
352            DO ji = mi0(161), mi1(161) 
353               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
354               zsu = e2u(ji-1, jj) * fse3u(ji-1, jj,jk)
355               zu2_rs_ad(jk) = zu2_rs_ad(jk) - hdivn_ad(ji, jj,jk) * ( 1. / zvt ) * zsu
356            END DO
357         END DO
358      END DO
359
360      ! compute the new divergence at 161,88
361      DO jk = 21, 1, -1
362         DO jj = mj0(88), mj1(88) 
363            DO ji = mi0(161), mi1(161) 
364               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
365               zsu = e2u(ji-1, jj) * fse3u(ji-1, jj,jk)
366               zu1_rs_ad(jk) = zu1_rs_ad(jk) - hdivn_ad(ji, jj  ,jk) * ( 1. / zvt ) * zsu
367            END DO
368         END DO
369      END DO
370
371      ! Velocity profile at each point
372      ! ------------------------------
373
374      ! velocity profile at 160,88 North  point
375      ! we imposed zisw_rs + EMP above the Red Sea
376      DO jk = 10, 1, -1                                     
377         DO jj = mj0(88), mj1(88) 
378            DO ji = mi0(160), mi1(160)
379               zempred_ad = zempred_ad + ( zu3_rs_ad(jk) / 10. ) / ( e1v(ji, jj) * fse3v(ji, jj,jk) )
380            END DO
381         END DO
382      END DO
383
384      ! velocity profile at 161,88 North point
385      ! we imposed zisw_rs + EMP above the Red Sea
386      DO jk = 8, 1, -1     
387         DO jj = mj0(88), mj1(88) 
388            DO ji = mi0(160), mi1(160) 
389               zempred_ad = zempred_ad - ( zu1_rs_ad(jk) / 8. ) / ( e2u(ji, jj) * fse3u(ji, jj,jk) )
390            END DO
391         END DO
392      END DO
393
394      zu1_rs_ad(:) = 0.0_wp
395      zu2_rs_ad(:) = 0.0_wp
396      zu3_rs_ad(:) = 0.0_wp
397
398      ! EMP on the Red Sea
399      ! ------------------
400
401      ! convert in m3
402      zempred_ad = zempred_ad * 1.e-3         
403
404      IF( lk_mpp )   CALL mpp_sum( zempred_ad )      ! sum with other processors value
405
406      DO jj = mj1(96), mj0(87), -1
407         DO ji = mi1(160),  mi0(148), -1
408            zwei    = tmask(ji,jj,1) * e1t(ji,jj) * e2t(ji,jj)
409            emp_ad(ji,jj) = emp_ad(ji,jj) + zempred_ad * zwei
410         END DO
411      END DO
412      zempred_ad = 0.e0
413
414   END SUBROUTINE div_bab_el_mandeb_adj
415
416   SUBROUTINE div_gibraltar_tan
417      !! -------------------------------------------------------------------
418      !!                 ***  ROUTINE div_gibraltar_tan  ***
419      !!       
420      !! ** Purpose of the direct routine:
421      !!     update the now horizontal divergence of the velocity
422      !!     field in Gibraltar.
423      !!
424      !! ** Method of the direct routine:
425      !!          ________________      N        ________________
426      !! 102           |    |->         |           <-|    |<-
427      !! 101      ___->|____|_____   W - - E     ___->|____|_____
428      !!           139   140  141       |         139   140  141
429      !!          horizontal view       S        horizontal view
430      !!            surface                          depth
431      !!      The now divergence is given by :
432      !!         hdivn = 1/(e1t*e2t) [ di(e2u  un) + dj(e1v  vn) ]
433      !!
434      !! ** History of the direct routine:
435      !!           !         (A. Bozec) Original code
436      !!      8.5  !  02-10  (A. Bozec) F90: Free form and module
437      !! ** History of the tangent routine:
438      !!           !  08-09  (A. Vidard) Tangent linear of the 02-10 version
439      !!      9.0  !  09-02 (A. Vidard) cosmetic changes
440      !!---------------------------------------------------------------------
441      !! * Local declarations
442      INTEGER  :: ji, jj, jk   ! dummy loop indices
443      REAL(wp) :: zsu, zvt
444      REAL(wp) :: zwei
445      REAL(wp), DIMENSION (jpk) ::  zu1_ms_tl, zu2_ms_tl, zu3_ms_tl
446      !!---------------------------------------------------------------------
447     
448      ! EMP on the Mediterranean Sea
449      ! ----------------------------
450
451      zempmed_tl = 0.e0
452      zwei = 0.e0
453      DO jj = mj0(96), mj1(110)
454         DO ji = mi0(141),mi1(181)
455            zwei    = tmask(ji,jj,1) * e1t(ji,jj) * e2t(ji,jj)
456            zempmed_tl = zempmed_tl + emp_tl(ji,jj) * zwei
457         END DO
458      END DO
459      IF( lk_mpp )   CALL mpp_sum( zempmed_tl )      ! sum with other processors value
460
461      ! minus 2 points in Red Sea and 3 in Atlantic
462      DO jj = mj0(96), mj1(96)
463         DO ji = mi0(148),mi1(148)
464            zempmed_tl = zempmed_tl -  emp_tl(ji  , jj) * tmask(ji  , jj,1) * e1t(ji  , jj) * e2t(ji  , jj)   &
465                              -  emp_tl(ji+1, jj) * tmask(ji+1, jj,1) * e1t(ji+1, jj) * e2t(ji+1, jj)   
466         END DO
467      END DO
468
469      ! convert in m3
470      zempmed_tl = zempmed_tl * 1.e-3
471
472      ! Velocity profile at each point
473      ! ------------------------------
474
475      zu1_ms_tl(:) = 0.0_wp
476      zu2_ms_tl(:) = 0.0_wp
477      zu3_ms_tl(:) = 0.0_wp
478
479      ! velocity profile at 139,101 South point
480      ! we imposed zisw + EMP above the Mediterranean Sea
481      DO jk = 1, 14                     
482         DO jj = mj0(102), mj1(102) 
483            DO ji = mi0(140), mi1(140) 
484               zu1_ms_tl(jk) =  zu1_ms_tl(jk) + ( zempmed_tl / 14. ) / ( e2u(ji-1, jj-1) * fse3u(ji-1, jj-1,jk) ) 
485            END DO
486         END DO
487      END DO
488     
489      ! velocity profile at 141,102  East point
490      ! flux in surface inflow of the Atlantic ocean + EMP   
491      DO  jk = 1, 14                     
492         DO jj = mj0(102), mj1(102) 
493            DO ji = mi0(140), mi1(140) 
494               zu3_ms_tl(jk) = zu3_ms_tl(jk) +  ( zempmed_tl / 14. ) / ( e2u(ji, jj) * fse3u(ji, jj,jk) ) 
495            END DO
496         END DO
497      END DO
498     
499      ! Divergence at each point of the straits
500      ! ---------------------------------------
501
502      ! compute the new divergence at 139,101 South point 
503      DO jk = 1, jpk
504         DO jj = mj0(101), mj1(101) 
505            DO ji = mi0(139), mi1(139) 
506               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
507               zsu = e2u(ji, jj) * fse3u(ji, jj,jk)
508               hdivn_tl(ji, jj,jk) = hdivn_tl(ji, jj,jk) + ( 1. / zvt ) * zsu * zu1_ms_tl(jk) 
509            END DO
510         END DO
511      END DO
512
513      ! compute the new divergence at 139,102 deep North point
514      DO jk = 1, jpk
515         DO jj = mj0(102), mj1(102) 
516            DO ji = mi0(139), mi1(139) 
517               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
518               zsu = e2u(ji, jj) * fse3u(ji, jj,jk)
519               hdivn_tl(ji, jj,jk) = hdivn_tl(ji, jj,jk) + ( 1. / zvt ) * zsu * zu2_ms_tl(jk) 
520            END DO
521         END DO
522      END DO
523
524      ! compute the divergence at 141,102 East point
525      DO jk = 1, jpk
526         DO jj = mj0(102), mj1(102) 
527            DO ji = mi0(141), mi1(141) 
528               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
529               zsu = e2u(ji-1, jj) * fse3u(ji-1, jj,jk)
530               hdivn_tl(ji, jj,jk) = hdivn_tl(ji, jj,jk) - ( 1. / zvt ) * zsu * zu3_ms_tl(jk)
531            END DO
532         END DO
533      END DO
534
535   END SUBROUTINE div_gibraltar_tan
536
537   SUBROUTINE div_gibraltar_adj
538      !! -------------------------------------------------------------------
539      !!                 ***  ROUTINE div_gibraltar_adj  ***
540      !!       
541      !! ** Purpose of the direct routine:
542      !!     update the now horizontal divergence of the velocity
543      !!     field in Gibraltar.
544      !!
545      !! ** Method of the direct routine:
546      !!          ________________      N        ________________
547      !! 102           |    |->         |           <-|    |<-
548      !! 101      ___->|____|_____   W - - E     ___->|____|_____
549      !!           139   140  141       |         139   140  141
550      !!          horizontal view       S        horizontal view
551      !!            surface                          depth
552      !!      The now divergence is given by :
553      !!         hdivn = 1/(e1t*e2t) [ di(e2u  un) + dj(e1v  vn) ]
554      !!
555      !! ** History of the direct routine:
556      !!           !         (A. Bozec) Original code
557      !!      8.5  !  02-10  (A. Bozec) F90: Free form and module
558      !! ** History of the adjoint routine:
559      !!           !  08-09  (A. Vidard) Adjoint of the 02-10 version
560      !!      9.0  !  09-02 (A. Vidard) cosmetic changes
561      !!---------------------------------------------------------------------
562      !! * Local declarations
563      INTEGER  :: ji, jj, jk   ! dummy loop indices
564      REAL(wp) :: zsu, zvt
565      REAL(wp) :: zwei
566      REAL(wp), DIMENSION (jpk) ::  zu1_ms_ad, zu2_ms_ad, zu3_ms_ad
567      !!---------------------------------------------------------------------
568     
569      zu1_ms_ad = 0.0_wp
570      zu2_ms_ad = 0.0_wp
571      zu3_ms_ad = 0.0_wp
572      zempmed_ad = 0.e0
573      zwei = 0.e0
574
575      ! Divergence at each point of the straits
576      ! ---------------------------------------
577
578      ! compute the divergence at 141,102 East point
579      DO jk = jpk, 1, -1
580         DO jj = mj0(102), mj1(102) 
581            DO ji = mi0(141), mi1(141) 
582               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
583               zsu = e2u(ji-1, jj) * fse3u(ji-1, jj,jk)
584               zu3_ms_ad(jk) = zu3_ms_ad(jk) - hdivn_ad(ji, jj,jk) * ( 1. / zvt ) * zsu
585            END DO
586         END DO
587      END DO
588
589      ! compute the new divergence at 139,102 deep North point
590      DO jk = jpk, 1, -1
591         DO jj = mj0(102), mj1(102) 
592            DO ji = mi0(139), mi1(139) 
593               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
594               zsu = e2u(ji, jj) * fse3u(ji, jj,jk)
595               zu2_ms_ad(jk) =  zu2_ms_ad(jk) + hdivn_ad(ji, jj,jk) * ( 1. / zvt ) * zsu 
596            END DO
597         END DO
598      END DO
599
600      ! compute the new divergence at 139,101 South point 
601      DO jk = jpk, 1, -1
602         DO jj = mj0(101), mj1(101) 
603            DO ji = mi0(139), mi1(139) 
604               zvt = e1t(ji, jj) * e2t(ji, jj) * fse3t(ji, jj,jk)
605               zsu = e2u(ji, jj) * fse3u(ji, jj,jk)
606               zu1_ms_ad(jk) = zu1_ms_ad(jk) + hdivn_ad(ji, jj,jk) * ( 1. / zvt ) * zsu 
607            END DO
608         END DO
609      END DO
610
611      ! Velocity profile at each point
612      ! ------------------------------
613     
614      ! velocity profile at 141,102  East point
615      ! flux in surface inflow of the Aadantic ocean + EMP   
616      DO  jk = 14, 1, -1                     
617         DO jj = mj0(102), mj1(102) 
618            DO ji = mi0(140), mi1(140) 
619               zempmed_ad = zempmed_ad + ( zu3_ms_ad(jk) / 14. ) / ( e2u(ji, jj) * fse3u(ji, jj,jk) ) 
620            END DO
621         END DO
622      END DO
623
624      ! velocity profile at 139,101 South point
625      ! we imposed zisw + EMP above the Mediterranean Sea
626      DO jk = 14, 1, -1                     
627         DO jj = mj0(102), mj1(102) 
628            DO ji = mi0(140), mi1(140) 
629               zempmed_ad = zempmed_ad + ( zu1_ms_ad(jk) / 14. ) / ( e2u(ji-1, jj-1) * fse3u(ji-1, jj-1,jk) ) 
630            END DO
631         END DO
632      END DO
633      zu1_ms_ad(:) = 0.0_wp
634      zu2_ms_ad(:) = 0.0_wp
635      zu3_ms_ad(:) = 0.0_wp
636
637      ! EMP on the Mediterranean Sea
638      ! ----------------------------
639
640      ! convert in m3
641      zempmed_ad = zempmed_ad * 1.e-3
642
643      ! minus 2 points in Red Sea and 3 in Aadantic
644      DO jj = mj0(96), mj1(96)
645         DO ji = mi0(148),mi1(148)
646            emp_ad(ji  , jj) = emp_ad(ji  , jj) - zempmed_ad * tmask(ji  , jj,1) * e1t(ji  , jj) * e2t(ji  , jj)
647            emp_ad(ji+1, jj) = emp_ad(ji+1, jj) - zempmed_ad * tmask(ji+1, jj,1) * e1t(ji+1, jj) * e2t(ji+1, jj)   
648         END DO
649      END DO
650      IF( lk_mpp )   CALL mpp_sum( zempmed_ad )      ! sum with other processors value
651
652      DO jj = mj1(110), mj0(96), -1
653         DO ji = mi1(181), mi0(141), -1
654            zwei    = tmask(ji,jj,1) * e1t(ji,jj) * e2t(ji,jj)
655            emp_ad(ji,jj) = emp_ad(ji,jj) + zempmed_ad * zwei
656         END DO
657      END DO
658      zempmed_ad = 0.e0
659
660   END SUBROUTINE div_gibraltar_adj
661
662
663
664   SUBROUTINE div_hormuz_tan
665      !! -------------------------------------------------------------------
666      !!                   ***  ROUTINE div_hormuz_tan  ***
667      !!             
668      !! ** Purpose of the direct routine:
669      !!     update the now horizontal divergence of the velocity
670      !!     field in Hormuz ( Persic Gulf strait ) .
671      !!
672      !! ** Method  of the direct routine:
673      !!      The now divergence is given by :
674      !!         hdivn = 1/(e1t*e2t) [ di(e2u  un) + dj(e1v  vn) ]
675      !!
676      !! ** History of the direct routine 
677      !!           !         (A. Bozec) Original code
678      !!      8.5  !  02-10  (A. Bozec) F90: Free form and module
679      !! ** History of the tangent routine:
680      !!           !  08-09  (A. Vidard) Tangent linear of the 02-10 version
681      !!      9.0  !  09-02 (A. Vidard) cosmetic changes
682      !!---------------------------------------------------------------------
683      !! * Local declarations
684      !... nothing
685
686   END SUBROUTINE div_hormuz_tan
687   SUBROUTINE div_hormuz_adj
688      !! -------------------------------------------------------------------
689      !!                   ***  ROUTINE div_hormuz_adj  ***
690      !!             
691      !! ** Purpose of the direct routine:
692      !!     update the now horizontal divergence of the velocity
693      !!     field in Hormuz ( Persic Gulf strait ) .
694      !!
695      !! ** Method  of the direct routine:
696      !!      The now divergence is given by :
697      !!         hdivn = 1/(e1t*e2t) [ di(e2u  un) + dj(e1v  vn) ]
698      !!
699      !! ** History of the direct routine 
700      !!           !         (A. Bozec) Original code
701      !!      8.5  !  02-10  (A. Bozec) F90: Free form and module
702      !! ** History of the Adjoint routine:
703      !!           !  08-09  (A. Vidard) Adjoint of the 02-10 version
704      !!   9.0     !  09-02 (A. Vidard) cosmetic changes
705      !!---------------------------------------------------------------------
706      !! * Local declarations
707      !... nothing
708
709   END SUBROUTINE div_hormuz_adj
710
711   SUBROUTINE div_cla_adj_tst( kumadt )
712      !!-----------------------------------------------------------------------
713      !!
714      !!                  ***  ROUTINE dyn_adv_adj_tst ***
715      !!
716      !! ** Purpose : Test the adjoint routine.
717      !!
718      !! ** Method  : Verify the scalar product
719      !!           
720      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
721      !!
722      !!              where  L   = tangent routine
723      !!                     L^T = adjoint routine
724      !!                     W   = diagonal matrix of scale factors
725      !!                     dx  = input perturbation (random field)
726      !!                     dy  = L dx
727      !!
728      !! ** Action  : Separate tests are applied for the following dx and dy:
729      !!               
730      !!              1) dx = ( SSH ) and dy = ( SSH )
731      !!                   
732      !! History :
733      !!        ! 08-08 (A. Vidard)
734      !!-----------------------------------------------------------------------
735      !! * Modules used
736
737      !! * Arguments
738      INTEGER, INTENT(IN) :: &
739         & kumadt             ! Output unit
740 
741      INTEGER :: &
742         & ji,    &        ! dummy loop indices
743         & jj,    &       
744         & jk,    &
745         & jt,   &       
746         & jii,  &       
747         & jis,  &       
748         & jji,  &       
749         & jjs     
750      INTEGER, DIMENSION(jpi,jpj) :: &
751         & iseed_2d        ! 2D seed for the random number generator
752
753      !! * Local declarations
754      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
755         & zhdivn_tlin,   &
756         & zhdivn_tlout,  &
757         & zhdivn_adin,   &
758         & zhdivn_adout,  &
759         & zhdiv
760      REAL(KIND=wp), DIMENSION(:,:), ALLOCATABLE :: &
761         & zemp_tlin,     &
762         & zemp_adout,    &
763         & zemp
764     REAL(KIND=wp) :: &
765         & zsp1,         & ! scalar product involving the tangent routine
766         & zsp2,         & ! scalar product involving the adjoint routine
767         & zsp2_1,       & !   scalar product components
768         & zsp2_2,       & 
769         & z2dt,         & ! temporary scalars
770         & zraur
771      CHARACTER(LEN=14) :: cl_name
772
773      ! Allocate memory
774
775      ALLOCATE( &
776         & zhdivn_tlin(jpi,jpj,jpk),   &
777         & zhdivn_tlout(jpi,jpj,jpk),  &
778         & zhdivn_adin(jpi,jpj,jpk),   &
779         & zhdivn_adout(jpi,jpj,jpk),  &
780         & zhdiv(jpi,jpj,jpk),         &
781         & zemp_tlin(jpi,jpj),         &
782         & zemp_adout(jpi,jpj),        &
783         & zemp (jpi,jpj)              &
784         & )
785      ! Initialize constants
786
787      z2dt  = 2.0_wp * rdt       ! time step: leap-frog
788      zraur = 1.0_wp / rau0      ! inverse density of pure water (m3/kg)
789      !==================================================================
790      ! 1) dx = ( un_tl, vn_tl, hdivn_tl ) and
791      !    dy = ( hdivb_tl, hdivn_tl )
792      !==================================================================
793
794      DO jt = 2, 1, -1
795      !--------------------------------------------------------------------
796      ! Reset the tangent and adjoint variables
797      !--------------------------------------------------------------------
798      zhdivn_tlin(:,:,:)  = 0.0_wp   
799      zhdivn_tlout(:,:,:) = 0.0_wp
800      zhdivn_adin(:,:,:)  = 0.0_wp 
801      zhdivn_adout(:,:,:) = 0.0_wp
802      zemp_tlin(:,:)      = 0.0_wp
803      zemp_adout(:,:)     = 0.0_wp
804
805      emp_tl(:,:)      = 0.0_wp
806      emp_ad(:,:)      = 0.0_wp
807      hdivn_tl(:,:,:)  = 0.0_wp
808      hdivn_ad(:,:,:)  = 0.0_wp
809
810         SELECT CASE (jt)
811         CASE(1) ! Bab el Madeb
812            jji = mj0(86)
813            jjs = mj1(97)
814            jii = mi0(147)
815            jis = mi1(162)
816         CASE(2) ! Gibraltar
817            jji = mj0(95)
818            jjs = mj1(111)
819            jii = mi0(138)
820            jis = mi1(182)
821         END SELECT
822         
823      !--------------------------------------------------------------------
824      ! Initialize the tangent input with random noise: dx
825      !--------------------------------------------------------------------
826
827      DO jj = 1, jpj
828         DO ji = 1, jpi
829            iseed_2d(ji,jj) = - ( 596035 + &
830               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
831         END DO
832      END DO
833      CALL grid_random( iseed_2d, zemp, 'T', 0.0_wp, stdemp )
834
835      DO jj = 1, jpj
836         DO ji = 1, jpi
837            iseed_2d(ji,jj) = - ( 523432 + &
838               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
839         END DO
840      END DO
841      CALL grid_random( iseed_2d, zhdiv, 'T', 0.0_wp, stdh )
842
843      DO jk = 1, jpk
844         DO jj = nldj, nlej
845            DO ji = nldi, nlei
846               zhdivn_tlin(ji,jj,jk)  = zhdiv(ji,jj,jk)
847            END DO
848         END DO
849      END DO
850      DO jj = nldj, nlej
851         DO ji = nldi, nlei
852            zemp_tlin(ji,jj)      = zemp(ji,jj) / ( z2dt * zraur )
853         END DO
854      END DO 
855!      hdivn_tl(:,:,:)  = zhdivn_tlin(:,:,:)
856!      emp_tl(:,:)      = zemp_tlin(:,:)
857
858         DO jk = 1, jpk
859            DO jj = jji, jjs
860               DO ji = jii, jis
861                  hdivn_tl(ji,jj,jk)  = zhdivn_tlin(ji,jj,jk)
862                  emp_tl(ji,jj)  = zemp_tlin(ji,jj)
863               END DO
864            END DO
865         END DO
866
867      CALL div_cla_tan( nit000 )
868
869      zhdivn_tlout(:,:,:) = hdivn_tl(:,:,:)
870
871      !--------------------------------------------------------------------
872      ! Initialize the adjoint variables: dy^* = W dy
873      !--------------------------------------------------------------------
874
875      DO jk = 1, jpk
876        DO jj = nldj, nlej
877           DO ji = nldi, nlei
878              zhdivn_adin(ji,jj,jk) = zhdivn_tlout(ji,jj,jk) &
879                 &               * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) &
880                 &               * tmask(ji,jj,jk)
881             
882            END DO
883         END DO
884      END DO
885      !--------------------------------------------------------------------
886      ! Compute the scalar product: ( L dx )^T W dy
887      !--------------------------------------------------------------------
888
889      zsp1 = DOT_PRODUCT( zhdivn_tlout, zhdivn_adin )
890
891      !--------------------------------------------------------------------
892      ! Call the adjoint routine: dx^* = L^T dy^*
893      !--------------------------------------------------------------------
894      hdivn_ad(:,:,:) = zhdivn_adin(:,:,:)
895
896      CALL div_cla_adj( nit000 )
897
898         DO jk = 1, jpk
899            DO jj = jji, jjs    ! tlin should be 0 outside these boundaries but is not by construction
900               DO ji = jii, jis ! here it would insure that the dot product does not account for it
901                  zhdivn_adout(ji,jj,jk) = hdivn_ad(ji,jj,jk)
902                  zemp_adout(ji,jj) = emp_ad(ji,jj)
903               END DO
904            END DO
905         END DO
906
907!      zhdivn_adout(:,:,:) = hdivn_ad(:,:,:)
908!      zemp_adout(:,:)     = emp_ad(:,:)
909
910      zsp2_1 = DOT_PRODUCT( zhdivn_tlin, zhdivn_adout )
911      zsp2_2 = DOT_PRODUCT( zemp_tlin,   zemp_adout   )
912      zsp2   = zsp2_1 + zsp2_2 
913
914      ! Compare the scalar products
915
916      ! 14 char:'12345678901234'
917         SELECT CASE (jt)
918         CASE(1) ! Bab el Madeb
919            cl_name = 'div_cla_adj BM'
920         CASE(2) ! Gibraltar
921            cl_name = 'div_cla_adj Gi'
922         END SELECT
923!      cl_name = 'div_cla_adj   '
924      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
925
926      END DO
927      DEALLOCATE( &
928         & zhdivn_tlin,   &
929         & zhdivn_tlout,  &
930         & zhdivn_adin,   &
931         & zhdivn_adout,  &
932         & zhdiv,         &
933         & zemp_tlin,     &
934         & zemp_adout,    &
935         & zemp           &
936         & )
937
938
939   END SUBROUTINE div_cla_adj_tst
940   !!======================================================================
941#  else
942   !!----------------------------------------------------------------------
943   !!   Default key                                            Dummy module
944   !!----------------------------------------------------------------------
945CONTAINS
946   SUBROUTINE div_cla_tan( kt )
947      WRITE(*,*) 'div_cla: You should have not see this print! error?', kt
948   END SUBROUTINE div_cla_tan
949   SUBROUTINE div_cla_adj( kt )
950      WRITE(*,*) 'div_cla_adj: You should have not see this print! error?', kt
951   END SUBROUTINE div_cla_adj
952   SUBROUTINE div_cla_adj_tst( kt )
953      WRITE(*,*) 'div_cla_adj_tst: You should have not see this print! error?', kt
954   END SUBROUTINE div_cla_adj_tst
955#  endif
956#endif
957END MODULE cla_div_tam
Note: See TracBrowser for help on using the repository browser.