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

source: branches/TAM_V3_0/NEMOTAM/OPATAM_SRC/TRA/trasbc_tam.F90 @ 1885

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

add TAM sources

File size: 40.1 KB
Line 
1MODULE trasbc_tam
2#ifdef key_tam
3   !!==============================================================================
4   !!                       ***  MODULE  trasbc_tam  ***
5   !! Ocean active tracers:  surface boundary condition
6   !!                        Tangent and Adjoint Module
7   !!==============================================================================
8   !! History of the direct module:
9   !!            8.2  !  98-10  (G. Madec, G. Roullet, M. Imbard)  Original code
10   !!            8.2  !  01-02  (D. Ludicone)  sea ice and free surface
11   !!            8.5  !  02-06  (G. Madec)  F90: Free form and module
12   !! History of the TAM:
13   !!                 !  08-05  (A. Vidard) Skeleton
14   !!                 !  08-11  (A. Vidard) tam of the 02-06 version
15   !!----------------------------------------------------------------------
16
17   !!----------------------------------------------------------------------
18   !!   tra_sbc      : update the tracer trend at ocean surface
19   !!----------------------------------------------------------------------
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      & jpim1,               &
27      & jpjm1,               &
28      & jpiglo
29   USE oce           , ONLY: & ! ocean dynamics and active tracers
30      & sn
31   USE oce_tam       , ONLY: & ! tangent and adjoint ocean dynamics and active tracers
32      & sn_tl,               &
33      & sa_tl,               &
34      & ta_tl,               &
35      & sn_ad,               &
36      & sa_ad,               &
37      & ta_ad
38   USE sbc_oce_tam   , ONLY: & ! surface thermohaline fluxes
39      & qns_tl,              &
40      & qsr_tl,              &
41      & emps_tl,             &
42      & qns_ad,              &
43      & qsr_ad,              &
44      & emps_ad
45   USE sbc_oce       , ONLY: & ! surface thermohaline fluxes
46      & emps
47   USE dom_oce       , ONLY: & ! ocean space domain variables
48      & rdt,                 &
49      & e1t,                 &
50      & e2t,                 &
51#if defined key_zco
52      & e3t_0,               &
53#else
54      & e3t,                 &
55#endif
56      & tmask,               &
57      & lk_vvl,              &
58      & mig,                 &
59      & mjg,                 &
60      & nldi,                &
61      & nldj,                &
62      & nlei,                &
63      & nlej
64   USE traqsr        , ONLY: & ! solar radiation penetration
65      & ln_traqsr
66   USE phycst        , ONLY: & ! physical constant
67      & rauw,                &
68      & ro0cpr
69   USE in_out_manager, ONLY: & ! I/O manager
70      & ctl_stop,            &
71      & lwp,                 &
72      & numout,              & 
73      & nit000,              &
74      & nitend
75   USE prtctl        , ONLY: & ! Print control
76      & prt_ctl
77   USE gridrandom    , ONLY: & ! Random Gaussian noise on grids
78      & grid_random
79   USE dotprodfld    , ONLY: & ! Computes dot product for 3D and 2D fields
80      & dot_product
81   USE paresp        , ONLY: & ! Weights for an energy-type scalar product
82      & wesp_t,              &
83      & wesp_s
84   USE tstool_tam    , ONLY: &
85      & prntst_adj,          &
86      & prntst_tlm,          & !
87      & stdqns,              &
88      & stdt,                &
89      & stds,                &
90      & stdemp
91
92   IMPLICIT NONE
93   PRIVATE
94
95   PUBLIC   tra_sbc_tan     ! routine called by step_tam.F90
96   PUBLIC   tra_sbc_adj     ! routine called by step_tam.F90
97   PUBLIC   tra_sbc_adj_tst ! routine called by tst.F90
98   PUBLIC   tra_sbc_tlm_tst ! routine calle  by tamtst.F90
99
100   !! * Substitutions
101#  include "domzgr_substitute.h90"
102#  include "vectopt_loop_substitute.h90"
103
104
105CONTAINS
106
107   SUBROUTINE tra_sbc_tan ( kt )
108      !!----------------------------------------------------------------------
109      !!                  ***  ROUTINE tra_sbc_tan  ***
110      !!                   
111      !! ** Purpose of the direct routine:
112      !!      Compute the tracer surface boundary condition trend of
113      !!      (flux through the interface, concentration/dilution effect)
114      !!      and add it to the general trend of tracer equations.
115      !!
116      !! ** Method :
117      !!      Following Roullet and Madec (2000), the air-sea flux can be divided
118      !!      into three effects: (1) Fext, external forcing;
119      !!      (2) Fwi, concentration/dilution effect due to water exchanged
120      !!         at the surface by evaporation, precipitations and runoff (E-P-R);
121      !!      (3) Fwe, tracer carried with the water that is exchanged.
122      !!
123      !!      Fext, flux through the air-sea interface for temperature and salt:
124      !!            - temperature : heat flux q (w/m2). If penetrative solar
125      !!         radiation q is only the non solar part of the heat flux, the
126      !!         solar part is added in traqsr.F routine.
127      !!            ta = ta + q /(rau0 rcp e3t)  for k=1
128      !!            - salinity    : no salt flux
129      !!
130      !!      The formulation for Fwb and Fwi vary according to the free
131      !!      surface formulation (linear or variable volume).
132      !!      * Linear free surface
133      !!            The surface freshwater flux modifies the ocean volume
134      !!         and thus the concentration of a tracer and the temperature.
135      !!         First order of the effect of surface freshwater exchange
136      !!         for salinity, it can be neglected on temperature (especially
137      !!         as the temperature of precipitations and runoffs is usually
138      !!         unknown).
139      !!            - temperature : we assume that the temperature of both
140      !!         precipitations and runoffs is equal to the SST, thus there
141      !!         is no additional flux since in this case, the concentration
142      !!         dilution effect is balanced by the net heat flux associated
143      !!         to the freshwater exchange (Fwe+Fwi=0):
144      !!            (Tp P - Te E) + SST (P-E) = 0 when Tp=Te=SST
145      !!            - salinity    : evaporation, precipitation and runoff
146      !!         water has a zero salinity (Fwe=0), thus only Fwi remains:
147      !!            sa = sa + emp * sn / e3t   for k=1
148      !!         where emp, the surface freshwater budget (evaporation minus
149      !!         precipitation minus runoff) given in kg/m2/s is divided
150      !!         by 1000 kg/m3 (density of plain water) to obtain m/s.   
151      !!         Note: even though Fwe does not appear explicitly for
152      !!         temperature in this routine, the heat carried by the water
153      !!         exchanged through the surface is part of the total heat flux
154      !!         forcing and must be taken into account in the global heat
155      !!         balance).
156      !!      * nonlinear free surface (variable volume, lk_vvl)
157      !!         contrary to the linear free surface case, Fwi is properly
158      !!         taken into account by using the true layer thicknesses to       
159      !!         calculate tracer content and advection. There is no need to
160      !!         deal with it in this routine.
161      !!           - temperature: Fwe=SST (P-E+R) is added to Fext.
162      !!           - salinity:  Fwe = 0, there is no surface flux of salt.
163      !!
164      !! ** Action  : - Update the 1st level of (ta,sa) with the trend associated
165      !!                with the tracer surface boundary condition
166      !!              - save the trend it in ttrd ('key_trdtra')
167      !!----------------------------------------------------------------------
168      !!
169      INTEGER, INTENT(in) ::   kt     ! ocean time-step index
170      !!
171      INTEGER  ::   ji, jj                   ! dummy loop indices
172      REAL(wp) ::   ztatl, zsatl, zsrau, zse3t   ! temporary scalars
173
174      IF( kt == nit000 ) THEN
175         IF(lwp) WRITE(numout,*)
176         IF(lwp) WRITE(numout,*) 'tra_sbc_tan : TRAcer Surface Boundary Condition'
177         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~ '
178      ENDIF
179
180      zsrau = 1.0_wp / rauw             ! initialization
181#if defined key_zco
182      zse3t = 1.0_wp / e3t_0(1)
183#endif
184
185      IF( .NOT.ln_traqsr )   qsr_tl(:,:) = 0.e0_wp   ! no solar radiation penetration
186
187      ! Concentration dillution effect on (t,s)
188      DO jj = 2, jpj
189         DO ji = fs_2, fs_jpim1   ! vector opt.
190#if ! defined key_zco
191            zse3t = 1.0_wp / fse3t(ji,jj,1)
192#endif
193            IF( lk_vvl ) THEN
194               CALL ctl_stop( 'key_vvl  not available in NEMOTAM' )
195            ELSE
196               ! temperature : heat flux
197               ztatl = ro0cpr * zse3t * qns_tl(ji,jj)         
198
199               ! salinity :  concent./dilut. effect
200               zsatl = (   emps_tl(ji,jj) * sn   (ji,jj,1) & 
201                  &      + emps   (ji,jj) * sn_tl(ji,jj,1) ) * zsrau * zse3t     
202            ENDIF
203            ta_tl(ji,jj,1) = ta_tl(ji,jj,1) + ztatl    ! add the trend to the general tracer trend
204            sa_tl(ji,jj,1) = sa_tl(ji,jj,1) + zsatl
205         END DO
206      END DO
207
208   END SUBROUTINE tra_sbc_tan
209
210   SUBROUTINE tra_sbc_adj ( kt )
211      !!----------------------------------------------------------------------
212      !!                  ***  ROUTINE tra_sbc_adj  ***
213      !!                   
214      !! ** Purpose of the direct routine:
215      !!      Compute the tracer surface boundary condition trend of
216      !!      (flux through the interface, concentration/dilution effect)
217      !!      and add it to the general trend of tracer equations.
218      !!
219      !! ** Method :
220      !!      Following Roullet and Madec (2000), the air-sea flux can be divided
221      !!      into three effects: (1) Fext, external forcing;
222      !!      (2) Fwi, concentration/dilution effect due to water exchanged
223      !!         at the surface by evaporation, precipitations and runoff (E-P-R);
224      !!      (3) Fwe, tracer carried with the water that is exchanged.
225      !!
226      !!      Fext, flux through the air-sea interface for temperature and salt:
227      !!            - temperature : heat flux q (w/m2). If penetrative solar
228      !!         radiation q is only the non solar part of the heat flux, the
229      !!         solar part is added in traqsr.F routine.
230      !!            ta = ta + q /(rau0 rcp e3t)  for k=1
231      !!            - salinity    : no salt flux
232      !!
233      !!      The formulation for Fwb and Fwi vary according to the free
234      !!      surface formulation (linear or variable volume).
235      !!      * Linear free surface
236      !!            The surface freshwater flux modifies the ocean volume
237      !!         and thus the concentration of a tracer and the temperature.
238      !!         First order of the effect of surface freshwater exchange
239      !!         for salinity, it can be neglected on temperature (especially
240      !!         as the temperature of precipitations and runoffs is usually
241      !!         unknown).
242      !!            - temperature : we assume that the temperature of both
243      !!         precipitations and runoffs is equal to the SST, thus there
244      !!         is no additional flux since in this case, the concentration
245      !!         dilution effect is balanced by the net heat flux associated
246      !!         to the freshwater exchange (Fwe+Fwi=0):
247      !!            (Tp P - Te E) + SST (P-E) = 0 when Tp=Te=SST
248      !!            - salinity    : evaporation, precipitation and runoff
249      !!         water has a zero salinity (Fwe=0), thus only Fwi remains:
250      !!            sa = sa + emp * sn / e3t   for k=1
251      !!         where emp, the surface freshwater budget (evaporation minus
252      !!         precipitation minus runoff) given in kg/m2/s is divided
253      !!         by 1000 kg/m3 (density of plain water) to obtain m/s.   
254      !!         Note: even though Fwe does not appear explicitly for
255      !!         temperature in this routine, the heat carried by the water
256      !!         exchanged through the surface is part of the total heat flux
257      !!         forcing and must be taken into account in the global heat
258      !!         balance).
259      !!      * nonlinear free surface (variable volume, lk_vvl)
260      !!         contrary to the linear free surface case, Fwi is properly
261      !!         taken into account by using the true layer thicknesses to       
262      !!         calculate tracer content and advection. There is no need to
263      !!         deal with it in this routine.
264      !!           - temperature: Fwe=SST (P-E+R) is added to Fext.
265      !!           - salinity:  Fwe = 0, there is no surface flux of salt.
266      !!
267      !! ** Action  : - Update the 1st level of (ta,sa) with the trend associated
268      !!                with the tracer surface boundary condition
269      !!              - save the trend it in ttrd ('key_trdtra')
270      !!----------------------------------------------------------------------
271      !!
272      INTEGER, INTENT(in) ::   kt     ! ocean time-step index
273      !!
274      INTEGER  ::   ji, jj                   ! dummy loop indices
275      REAL(wp) ::   ztaad, zsaad, zsrau, zse3t   ! temporary scalars
276
277      IF( kt == nitend ) THEN
278         IF(lwp) WRITE(numout,*)
279         IF(lwp) WRITE(numout,*) 'tra_sbc_adj : TRAcer Surface Boundary Condition'
280         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~ '
281      ENDIF
282
283      zsrau = 1.0_wp / rauw             ! initialization
284#if defined key_zco
285      zse3t = 1.0_wp / e3t_0(1)
286#endif
287
288      ! Concentration dillution effect on (t,s)
289      DO jj = jpj, 2, -1
290         DO ji = fs_jpim1, fs_2, -1   ! vector opt.
291#if ! defined key_zco
292            zse3t = 1.0_wp / fse3t(ji,jj,1)
293#endif
294            ztaad = ta_ad(ji,jj,1)          ! add the trend to the general tracer trend
295            zsaad = sa_ad(ji,jj,1) 
296            IF( lk_vvl) THEN
297               CALL ctl_stop( 'key_vvl  not available in NEMOTAM' )
298            ELSE
299               ztaad = ztaad * ro0cpr * zse3t
300               zsaad = zsaad * zsrau  * zse3t
301               qns_ad(ji,jj)  = qns_ad(ji,jj)  + ztaad
302               emps_ad(ji,jj) = emps_ad(ji,jj) + zsaad * sn(ji,jj,1)
303               sn_ad(ji,jj,1) = sn_ad(ji,jj,1) + zsaad * emps(ji,jj)
304            ENDIF
305         END DO
306      END DO
307
308      IF( .NOT.ln_traqsr )   qsr_ad(:,:) = 0.e0_wp   ! no solar radiation penetration
309
310   END SUBROUTINE tra_sbc_adj
311
312   SUBROUTINE tra_sbc_adj_tst ( kumadt ) 
313      !!-----------------------------------------------------------------------
314      !!
315      !!          ***  ROUTINE tra_sbc_adj_tst : TEST OF tra_sbc_adj  ***
316      !!
317      !! ** Purpose : Test the adjoint routine.
318      !!
319      !! ** Method  : Verify the scalar product
320      !!           
321      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
322      !!
323      !!              where  L   = tangent routine
324      !!                     L^T = adjoint routine
325      !!                     W   = diagonal matrix of scale factors
326      !!                     dx  = input perturbation (random field)
327      !!                     dy  = L dx
328      !!
329      !! History :
330      !!        ! 08-08 (A. Vidard)
331      !!-----------------------------------------------------------------------
332      !! * Modules used
333
334      !! * Arguments
335      INTEGER, INTENT(IN) :: &
336         & kumadt             ! Output unit
337 
338      INTEGER :: &
339         & ji,    &        ! dummy loop indices
340         & jj,    &       
341         & jk     
342      INTEGER, DIMENSION(jpi,jpj) :: &
343         & iseed_2d        ! 2D seed for the random number generator
344
345      !! * Local declarations
346      REAL(KIND=wp), DIMENSION(:,:), ALLOCATABLE :: &
347         & zsn_tlin,     &! Tangent input : now salinity
348         & zsa_tlin,     &! Tangent input : after salinity
349         & zta_tlin,     &! Tangent input : after temperature
350         & zqns_tlin,    &! Tangent input : solar radiation (w/m2)
351         & zemps_tlin,   &! Tangent input : evaporation - precipitation (free surface)
352         & zsa_tlout,    &! Tangent output: after salinity
353         & zta_tlout,    &! Tangent output: after temperature
354         & zsa_adin,     &! Adjoint input : after salinity
355         & zta_adin,     &! Adjoint input : after temperature
356         & zsn_adout,    &! Adjoint output: now salinity
357         & zsa_adout,    &! Adjoint output: after salinity
358         & zta_adout,    &! Adjoint output: after temperature
359         & zqns_adout,   &! Adjoint output: solar radiation (w/m2)
360         & zemps_adout,  &! Adjoint output: evaporation - precipitation (free surface)
361         & zsn,          &! temporary now salinity
362         & zsa,          &! temporary after salinity
363         & zta,          &! temporary after temperature
364         & zqns,         &! temporary solar radiation (w/m2)
365         & zemps          ! temporary evaporation - precipitation (free surface)
366      REAL(KIND=wp) ::       &
367         & zsp1,             & ! scalar product involving the tangent routine
368         & zsp1_1,           & ! scalar product involving the tangent routine
369         & zsp1_2,           & ! scalar product involving the tangent routine
370         & zsp2,             & ! scalar product involving the adjoint routine
371         & zsp2_1,           & ! scalar product involving the adjoint routine
372         & zsp2_2,           & ! scalar product involving the adjoint routine
373         & zsp2_3,           & ! scalar product involving the adjoint routine
374         & zsp2_4,           & ! scalar product involving the adjoint routine
375         & zsp2_5,           & ! scalar product involving the adjoint routine
376         & z2dt,             & ! temporary scalars
377         & zraur
378      CHARACTER (LEN=14) :: &
379         & cl_name
380
381      ALLOCATE( & 
382         & zsn_tlin(jpi,jpj),     &
383         & zsa_tlin(jpi,jpj),     &
384         & zta_tlin(jpi,jpj),     &
385         & zsa_tlout(jpi,jpj),    &
386         & zta_tlout(jpi,jpj),    &
387         & zsn_adout(jpi,jpj),    &
388         & zsa_adout(jpi,jpj),    &
389         & zta_adout(jpi,jpj),    &
390         & zsa_adin(jpi,jpj),     &
391         & zta_adin(jpi,jpj),     &
392         & zsn(jpi,jpj),          &
393         & zsa(jpi,jpj),          &
394         & zta(jpi,jpj),          &
395         & zqns_adout(jpi,jpj),   &
396         & zqns_tlin(jpi,jpj),    &
397         & zemps_tlin(jpi,jpj),   &
398         & zemps_adout(jpi,jpj),  &
399         & zqns(jpi,jpj),         &
400         & zemps(jpi,jpj)         &
401         & )
402
403
404      ! Initialize constants
405      z2dt  = 2.0_wp * rdt       ! time step: leap-frog
406      zraur = 1.0_wp / rauw      ! inverse density of pure water (m3/kg)
407
408      ! Initialize the reference state
409
410      !===========================================================================
411      ! 1) dx = ( qns_tl, sn_tl, emps_tl, ta_tl, sa_tl ) and dy = ( ta_tl, sa_tl )
412      !===========================================================================
413
414      !--------------------------------------------------------------------
415      ! Reset the tangent and adjoint variables
416      !--------------------------------------------------------------------
417      zsn_tlin   (:,:) = 0.0_wp     
418      zsa_tlin   (:,:) = 0.0_wp     
419      zta_tlin   (:,:) = 0.0_wp     
420      zsa_tlout  (:,:) = 0.0_wp   
421      zta_tlout  (:,:) = 0.0_wp   
422      zsn_adout  (:,:) = 0.0_wp   
423      zsa_adout  (:,:) = 0.0_wp   
424      zta_adout  (:,:) = 0.0_wp   
425      zsa_adin   (:,:) = 0.0_wp     
426      zta_adin   (:,:) = 0.0_wp     
427      zqns_tlin  (:,:) = 0.0_wp       
428      zqns_adout (:,:) = 0.0_wp       
429      zemps_tlin (:,:) = 0.0_wp       
430      zemps_adout(:,:) = 0.0_wp     
431     
432      DO jj = 1, jpj
433         DO ji = 1, jpi
434            iseed_2d(ji,jj) = - ( 785483 + &
435               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
436         END DO
437      END DO
438      CALL grid_random( iseed_2d, zemps, 'T', 0.0_wp, stdemp )
439
440      DO jj = 1, jpj
441         DO ji = 1, jpi
442            iseed_2d(ji,jj) = - ( 358606 + &
443               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
444         END DO
445      END DO
446      CALL grid_random( iseed_2d, zqns, 'T', 0.0_wp, stdqns )
447
448      DO jj = 1, jpj
449         DO ji = 1, jpi
450            iseed_2d(ji,jj) = - ( 523432 + &
451               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
452         END DO
453      END DO
454      CALL grid_random( iseed_2d, zsn, 'T', 0.0_wp, stds )
455
456      DO jj = 1, jpj
457         DO ji = 1, jpi
458            iseed_2d(ji,jj) = - ( 297563 + &
459               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
460         END DO
461      END DO
462      CALL grid_random( iseed_2d, zsa, 'T', 0.0_wp, stds )
463
464      DO jj = 1, jpj
465         DO ji = 1, jpi
466            iseed_2d(ji,jj) = - ( 232567 + &
467               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
468         END DO
469      END DO
470      CALL grid_random( iseed_2d, zta, 'T', 0.0_wp, stdt )
471
472      DO jj = nldj, nlej
473         DO ji = nldi, nlei
474            zsn_tlin  (ji,jj) = zsn  (ji,jj)
475            zsa_tlin  (ji,jj) = zsa  (ji,jj)
476            zta_tlin  (ji,jj) = zta  (ji,jj)
477            zemps_tlin(ji,jj) = zemps(ji,jj) / ( z2dt * zraur )
478            zqns_tlin (ji,jj) = zqns (ji,jj)
479         END DO
480      END DO 
481
482      !--------------------------------------------------------------------
483      ! Call the tangent routine: dy = L dx
484      !--------------------------------------------------------------------
485
486      sn_tl  (:,:,1) = zsn_tlin  (:,:)
487      sa_tl  (:,:,1) = zsa_tlin  (:,:)
488      ta_tl  (:,:,1) = zta_tlin  (:,:)
489      emps_tl(:,:)   = zemps_tlin(:,:)
490      qns_tl (:,:)   = zqns_tlin (:,:)
491
492      CALL tra_sbc_tan( nit000 )
493
494      zsa_tlout(:,:) = sa_tl(:,:,1) 
495      zta_tlout(:,:) = ta_tl(:,:,1)
496
497      !--------------------------------------------------------------------
498      ! Initialize the adjoint variables: dy^* = W dy
499      !--------------------------------------------------------------------
500
501      DO jj = nldj, nlej
502         DO ji = nldi, nlei
503            zsa_adin(ji,jj) = zsa_tlout(ji,jj) &
504               &               * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,1) &
505               &               * tmask(ji,jj,1) * wesp_s(1)
506            zta_adin(ji,jj) = zta_tlout(ji,jj) &
507               &               * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,1) &
508               &               * tmask(ji,jj,1) * wesp_t(1)
509         END DO
510      END DO
511
512      !--------------------------------------------------------------------
513      ! Compute the scalar product: ( L dx )^T W dy
514      !--------------------------------------------------------------------
515
516      zsp1_1 = DOT_PRODUCT( zsa_tlout, zsa_adin )
517      zsp1_2 = DOT_PRODUCT( zta_tlout, zta_adin )
518      zsp1   = zsp1_1 + zsp1_2
519
520      !--------------------------------------------------------------------
521      ! Call the adjoint routine: dx^* = L^T dy^*
522      !--------------------------------------------------------------------
523
524      sa_ad(:,:,1) = zsa_adin(:,:)
525      ta_ad(:,:,1) = zta_adin(:,:)
526      sn_ad(:,:,1) = 0.0_wp
527      emps_ad(:,:) = 0.0_wp
528      qns_ad(:,:)  = 0.0_wp
529
530      CALL tra_sbc_adj( nitend )
531
532      zsn_adout  (:,:) = sn_ad(:,:,1)
533      zsa_adout  (:,:) = sa_ad(:,:,1)
534      zta_adout  (:,:) = ta_ad(:,:,1)
535      zqns_adout (:,:) = qns_ad(:,: )
536      zemps_adout(:,:) = emps_ad(:,:)     
537
538      !--------------------------------------------------------------------
539      ! Compute the scalar product: dx^T L^T W dy
540      !--------------------------------------------------------------------
541
542      zsp2_1 = DOT_PRODUCT( zsn_tlin  , zsn_adout   )
543      zsp2_2 = DOT_PRODUCT( zsa_tlin  , zsa_adout   )
544      zsp2_3 = DOT_PRODUCT( zta_tlin  , zta_adout   )
545      zsp2_4 = DOT_PRODUCT( zqns_tlin , zqns_adout  )
546      zsp2_5 = DOT_PRODUCT( zemps_tlin, zemps_adout )
547
548      zsp2 = zsp2_1 + zsp2_2 + zsp2_3 + zsp2_4 + zsp2_5
549
550      ! Compare the scalar products
551
552      ! 14 char:'12345678901234'
553      cl_name = 'tra_sbc_adj   '
554      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
555
556
557
558      DEALLOCATE( & 
559         & zsn_tlin,     &
560         & zsa_tlin,     &
561         & zta_tlin,     &
562         & zsa_tlout,    &
563         & zta_tlout,    &
564         & zsn_adout,    &
565         & zsa_adout,    &
566         & zta_adout,    &
567         & zsa_adin,     &
568         & zta_adin,     &
569         & zsn,          &
570         & zsa,          &
571         & zta,          &
572         & zqns_adout,   &
573         & zqns_tlin,    &
574         & zemps_tlin,   &
575         & zemps_adout,  &
576         & zqns,         &
577         & zemps         &
578         & )
579   END SUBROUTINE tra_sbc_adj_tst
580
581
582   SUBROUTINE tra_sbc_tlm_tst ( kumadt ) 
583      !!-----------------------------------------------------------------------
584      !!
585      !!                  ***  ROUTINE dyn_adv_tlm_tst ***
586      !!
587      !! ** Purpose : Test the adjoint routine.
588      !!
589      !! ** Method  : Verify the tangent with Taylor expansion
590      !!           
591      !!                 M(x+hdx) = M(x) + L(hdx) + O(h^2)
592      !!
593      !!              where  L   = tangent routine
594      !!                     M   = direct routine
595      !!                     dx  = input perturbation (random field)
596      !!                     h   = ration on perturbation
597      !!
598      !!    In the tangent test we verify that:
599      !!                M(x+h*dx) - M(x)
600      !!        g(h) = ------------------ --->  1    as  h ---> 0
601      !!                    L(h*dx)
602      !!    and
603      !!                g(h) - 1
604      !!        f(h) = ----------         --->  k (costant) as  h ---> 0
605      !!                    p
606      !!                   
607      !! History :
608      !!        ! 09-08 (A. Vigilant)
609      !!-----------------------------------------------------------------------
610      !! * Modules used
611      USE trasbc
612      USE tamtrj              ! writing out state trajectory
613      USE par_tlm,    ONLY: &
614        & cur_loop,         &
615        & h_ratio
616      USE istate_mod
617      USE divcur             ! horizontal divergence and relative vorticity
618      USE wzvmod             !  vertical velocity
619      USE gridrandom, ONLY: &
620        & grid_rd_sd
621      USE trj_tam
622      USE oce           , ONLY: & ! ocean dynamics and tracers variables
623        & sn, ta, sa
624      USE sbc_oce       , ONLY: & ! ocean boundary condition
625        & qns, emps
626      USE opatam_tst_ini, ONLY: &
627       & tlm_namrd
628      USE tamctl,         ONLY: & ! Control parameters
629       & numtan, numtan_sc
630      !! * Arguments
631      INTEGER, INTENT(IN) :: &
632         & kumadt             ! Output unit
633 
634      INTEGER :: &
635         & ji,    &        ! dummy loop indices
636         & jj,    &       
637         & jk     
638      INTEGER, DIMENSION(jpi,jpj) :: &
639         & iseed_2d        ! 2D seed for the random number generator
640
641      !! * Local declarations
642      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
643         & zsn_tlin,     &! Tangent input : now salinity
644         & zsa_tlin,     &! Tangent input : after salinity
645         & zta_tlin,     &! Tangent input : after temperature
646         & zsa_out,      &! Tangent output: after salinity
647         & zta_out,      &! Tangent output: after temperature
648         & zsa_wop,      &!
649         & zta_wop,      &
650         & z3r            ! 3D field   
651      REAL(KIND=wp), DIMENSION(:,:), ALLOCATABLE :: &
652         & zqns_tlin,    &! Tangent input : solar radiation (w/m2)
653         & zemps_tlin,   &! Tangent input : evaporation - precipitation (free surface)
654         & z2r     
655      REAL(KIND=wp) ::   &
656         & zsp1,         & ! scalar product
657         & zsp1_1,       & ! scalar product
658         & zsp1_2,       & ! scalar product
659         & zsp2,         & ! scalar product
660         & zsp2_1,       & ! scalar product
661         & zsp2_2,       & ! scalar product
662         & zsp3,         & ! scalar product
663         & zsp3_1,       & ! scalar product
664         & zsp3_2,       & ! scalar product
665         & zzsp,         & ! scalar product
666         & zzsp_1,       & ! scalar product
667         & zzsp_2,       & ! scalar product
668         & zraur,        &
669         & gamma,        &
670         & zgsp1,        &
671         & zgsp2,        &
672         & zgsp3,        &
673         & zgsp4,        &
674         & zgsp5,        &
675         & zgsp6,        &
676         & zgsp7 
677      CHARACTER (LEN=14)  :: cl_name
678      CHARACTER (LEN=128) :: file_out, file_wop
679      CHARACTER (LEN=90)  ::  FMT
680      REAL(KIND=wp), DIMENSION(100):: &
681         & zscta, zscsa, &
682         & zscerrta,     &
683         & zscerrsa
684      INTEGER, DIMENSION(100):: &
685         & iiposta, iipossa,    &
686         & ijposta, ijpossa,    & 
687         & ikposta, ikpossa
688      INTEGER::          &
689         & ii,           &
690         & isamp=40,     &
691         & jsamp=40,     &
692         & ksamp=10,     &
693         & numsctlm
694     REAL(KIND=wp), DIMENSION(jpi,jpj,jpk) :: &
695         & zerrta, zerrsa 
696
697      ALLOCATE( & 
698         & zsn_tlin ( jpi,jpj,jpk),     &
699         & zta_tlin ( jpi,jpj,jpk),     &
700         & zsa_tlin ( jpi,jpj,jpk),     &
701         & zta_out  ( jpi,jpj,jpk),     &
702         & zsa_out  ( jpi,jpj,jpk),     &
703         & zta_wop  ( jpi,jpj,jpk),     &
704         & zsa_wop  ( jpi,jpj,jpk),     &
705         & z3r      ( jpi,jpj,jpk),     &
706         & zqns_tlin( jpi,jpj    ),     &
707         & zemps_tlin(jpi,jpj    ),     &
708         & z2r       (jpi,jpj    )      &
709         & )
710
711      !--------------------------------------------------------------------
712      ! Reset variables
713      !--------------------------------------------------------------------
714      zsn_tlin  ( :,:,:) = 0.0_wp
715      zsa_tlin  ( :,:,:) = 0.0_wp
716      zta_tlin  ( :,:,:) = 0.0_wp
717      zqns_tlin ( :,:  ) = 0.0_wp
718      zemps_tlin( :,:  ) = 0.0_wp
719      zta_out   ( :,:,:) = 0.0_wp
720      zsa_out   ( :,:,:) = 0.0_wp
721      zta_wop   ( :,:,:) = 0.0_wp
722      zsa_wop   ( :,:,:) = 0.0_wp
723
724      zscta(:)         = 0.0_wp
725      zscsa(:)         = 0.0_wp
726      zscerrta(:)      = 0.0_wp
727      zscerrsa(:)      = 0.0_wp
728      zerrta(:,:,:)    = 0.0_wp
729      zerrsa(:,:,:)    = 0.0_wp
730      !--------------------------------------------------------------------
731      ! Output filename Xn=F(X0)
732      !--------------------------------------------------------------------
733      file_wop='trj_wop_trasbc'
734      CALL tlm_namrd
735      gamma = h_ratio
736      !--------------------------------------------------------------------
737      ! Initialize the tangent input with random noise: dx
738      !--------------------------------------------------------------------
739      IF (( cur_loop .NE. 0) .OR. ( gamma .NE. 0.0_wp) )THEN
740         CALL grid_rd_sd( 523432, z3r,    'T', 0.0_wp, stds  )
741         DO jk = 1, jpk
742            DO jj = nldj, nlej
743               DO ji = nldi, nlei
744                  zsn_tlin(ji,jj,jk) = z3r(ji,jj,jk)
745               END DO
746            END DO
747         END DO
748         CALL grid_rd_sd( 232567, z3r,    'T', 0.0_wp, stdt  )
749         DO jk = 1, jpk
750            DO jj = nldj, nlej
751               DO ji = nldi, nlei
752                  zta_tlin(ji,jj,jk) = z3r(ji,jj,jk)
753               END DO
754            END DO
755         END DO
756         CALL grid_rd_sd( 297563, z3r,    'T', 0.0_wp, stds  )
757         DO jk = 1, jpk
758            DO jj = nldj, nlej
759               DO ji = nldi, nlei
760                  zsa_tlin(ji,jj,jk) = z3r(ji,jj,jk)
761               END DO
762            END DO
763         END DO
764         CALL grid_rd_sd( 358606, z2r,   'T', 0.0_wp, stdqns) 
765         DO jj = nldj, nlej
766            DO ji = nldi, nlei
767               zqns_tlin(ji,jj) = z2r(ji,jj)
768            END DO
769         END DO
770         CALL grid_rd_sd( 785483, z2r,  'T', 0.0_wp, stdemp)
771         DO jj = nldj, nlej
772            DO ji = nldi, nlei
773               zemps_tlin(ji,jj) = z2r(ji,jj)
774            END DO
775         END DO
776      ENDIF   
777      !--------------------------------------------------------------------
778      ! Complete Init for Direct
779      !-------------------------------------------------------------------
780      CALL istate_p 
781
782      ! *** initialize the reference trajectory
783      ! ------------
784      CALL  trj_rea( nit000-1, 1 )
785      CALL  trj_rea( nit000, 1 )
786
787      IF (( cur_loop .NE. 0) .OR. ( gamma .NE. 0.0_wp) )THEN
788         zsn_tlin(:,:,:) = gamma * zsn_tlin(:,:,:)
789         sn(:,:,:)       = sn(:,:,:) + zsn_tlin(:,:,:)
790
791         zta_tlin(:,:,:) = gamma * zta_tlin(:,:,:)
792         ta(:,:,:)       = ta(:,:,:) + zta_tlin(:,:,:)
793
794         zsa_tlin(:,:,:) = gamma * zsa_tlin(:,:,:)
795         sa(:,:,:)       = sa(:,:,:) + zsa_tlin(:,:,:)
796
797         zqns_tlin(:,:) = gamma * zqns_tlin(:,:)
798         qns(:,:)         = qns(:,:) + zqns_tlin(:,:)
799
800         zemps_tlin(:,:) = gamma * zemps_tlin(:,:)
801         emps(:,:)       = emps(:,:) + zemps_tlin(:,:)
802      ENDIF 
803      !--------------------------------------------------------------------
804      !  Compute the direct model F(X0,t=n) = Xn
805      !--------------------------------------------------------------------
806      CALL tra_sbc(nit000)
807
808      IF ( cur_loop .EQ. 0) CALL trj_wri_spl(file_wop)
809
810      !--------------------------------------------------------------------
811      !  Compute the Tangent
812      !--------------------------------------------------------------------
813      IF ( cur_loop .NE. 0) THEN
814         !--------------------------------------------------------------------
815         !  Storing data
816         !-------------------------------------------------------------------- 
817         zta_out  (:,:,:) = ta   (:,:,:)
818         zsa_out  (:,:,:) = sa   (:,:,:)         
819
820         !--------------------------------------------------------------------
821         ! Initialize the tangent variables: dy^* = W dy 
822         !--------------------------------------------------------------------
823         CALL  trj_rea( nit000-1, 1 ) 
824         CALL  trj_rea( nit000, 1 ) 
825         sn_tl   (:,:,:) = zsn_tlin  (:,:,:)
826         ta_tl   (:,:,:) = zta_tlin  (:,:,:)
827         sa_tl   (:,:,:) = zsa_tlin  (:,:,:)
828         qns_tl  (:,:  ) = zqns_tlin (:,:  )
829         emps_tl (:,:  ) = zemps_tlin(:,:  )
830         !-----------------------------------------------------------------------
831         !  Initialization of the dynamics and tracer fields for the tangent
832         !-----------------------------------------------------------------------
833         CALL tra_sbc_tan(nit000)
834
835         !--------------------------------------------------------------------
836         ! Compute the scalar product: ( L(t0,tn) gamma dx0 ) )
837         !--------------------------------------------------------------------
838
839         zsp2_1    = DOT_PRODUCT( ta_tl, ta_tl  )
840         zsp2_2    = DOT_PRODUCT( sa_tl, sa_tl  )
841
842         zsp2      = zsp2_1 + zsp2_2
843         !--------------------------------------------------------------------
844         !  Storing data
845         !--------------------------------------------------------------------
846         CALL trj_rd_spl(file_wop) 
847         zta_wop  (:,:,:) = ta  (:,:,:)
848         zsa_wop  (:,:,:) = sa  (:,:,:)
849         !--------------------------------------------------------------------
850         ! Compute the Linearization Error
851         ! Nn = M( X0+gamma.dX0, t0,tn) - M(X0, t0,tn)
852         ! and
853         ! Compute the Linearization Error
854         ! En = Nn -TL(gamma.dX0, t0,tn)
855         !--------------------------------------------------------------------
856         ! Warning: Here we re-use local variables z()_out and z()_wop
857         ii=0
858         DO jk = 1, jpk
859            DO jj = 1, jpj
860               DO ji = 1, jpi
861                  zta_out   (ji,jj,jk) = zta_out    (ji,jj,jk) - zta_wop  (ji,jj,jk)
862                  zta_wop   (ji,jj,jk) = zta_out    (ji,jj,jk) - ta_tl    (ji,jj,jk)
863                  IF (  ta_tl(ji,jj,jk) .NE. 0.0_wp ) &
864                     & zerrta(ji,jj,jk) = zta_out(ji,jj,jk)/ta_tl(ji,jj,jk)
865                  IF( (MOD(ji, isamp) .EQ. 0) .AND. &
866                  &   (MOD(jj, jsamp) .EQ. 0) .AND. &
867                  &   (MOD(jk, ksamp) .EQ. 0)     ) THEN
868                      ii = ii+1
869                      iiposta(ii) = ji
870                      ijposta(ii) = jj
871                      ikposta(ii) = jk
872                      IF ( INT(tmask(ji,jj,jk)) .NE. 0)  THEN
873                         zscta (ii) =  zta_wop(ji,jj,jk)
874                         zscerrta (ii) =  ( zerrta(ji,jj,jk) - 1.0_wp ) / gamma
875                      ENDIF
876                  ENDIF
877               END DO
878            END DO
879         END DO
880         ii=0
881         DO jk = 1, jpk
882            DO jj = 1, jpj
883               DO ji = 1, jpi
884                  zsa_out   (ji,jj,jk) = zsa_out    (ji,jj,jk) - zsa_wop  (ji,jj,jk)
885                  zsa_wop   (ji,jj,jk) = zsa_out    (ji,jj,jk) - sa_tl    (ji,jj,jk)
886                  IF (  sa_tl(ji,jj,jk) .NE. 0.0_wp ) &
887                     & zerrsa(ji,jj,jk) = zsa_out(ji,jj,jk)/sa_tl(ji,jj,jk)
888                  IF( (MOD(ji, isamp) .EQ. 0) .AND. &
889                  &   (MOD(jj, jsamp) .EQ. 0) .AND. &
890                  &   (MOD(jk, ksamp) .EQ. 0)     ) THEN
891                      ii = ii+1
892                      iipossa(ii) = ji
893                      ijpossa(ii) = jj
894                      ikpossa(ii) = jk
895                      IF ( INT(tmask(ji,jj,jk)) .NE. 0)  THEN
896                         zscsa (ii) =  zsa_wop(ji,jj,jk)
897                         zscerrsa (ii) =  ( zerrsa(ji,jj,jk) - 1.0_wp ) /gamma
898                      ENDIF
899                  ENDIF
900               END DO
901            END DO
902         END DO
903
904         zsp1_1    = DOT_PRODUCT( zta_out, zta_out )
905         zsp1_2    = DOT_PRODUCT( zsa_out, zsa_out  )
906         zsp1      = zsp1_1 + zsp1_2
907
908         zsp3_1    = DOT_PRODUCT( zta_wop, zta_wop )
909         zsp3_2    = DOT_PRODUCT( zsa_wop, zsa_wop  )
910         zsp3      = zsp3_1 + zsp3_2
911         !--------------------------------------------------------------------
912         ! Print the linearization error En - norme 2
913         !--------------------------------------------------------------------
914         ! 14 char:'12345678901234'
915         cl_name = 'trasbc_tam:En '
916         zzsp    = SQRT(zsp3)
917         zzsp_1  = SQRT(zsp3_1)
918         zzsp_2  = SQRT(zsp3_2)
919         zgsp5   = zzsp
920         CALL prntst_tlm( cl_name, kumadt, zzsp, h_ratio )
921         !--------------------------------------------------------------------
922         ! Compute TLM norm2
923         !--------------------------------------------------------------------
924         zzsp    = SQRT(zsp2)
925         zzsp_1  = SQRT(zsp2_1)
926         zzsp_2  = SQRT(zsp2_2)
927         zgsp4   = zzsp
928         cl_name = 'trasbc_tam:Ln2'
929         CALL prntst_tlm( cl_name, kumadt, zzsp, h_ratio )
930         !--------------------------------------------------------------------
931         ! Print the linearization error Nn - norme 2
932         !--------------------------------------------------------------------
933         zzsp    = SQRT(zsp1)
934         zzsp_1  = SQRT(zsp1_1)
935         zzsp_2  = SQRT(zsp1_2)
936         cl_name = 'trasbc:Mhdx-Mx'
937         CALL prntst_tlm( cl_name, kumadt, zzsp, h_ratio )
938         zgsp3   = SQRT( zsp3/zsp2 )
939         zgsp7   = zgsp3/gamma
940         zgsp1   = zzsp
941         zgsp2   = zgsp1 / zgsp4
942         zgsp6   = (zgsp2 - 1.0_wp)/gamma
943
944         FMT = "(A8,2X,I4.4,2X,E6.1,2X,E20.13,2X,E20.13,2X,E20.13,2X,E20.13,2X,E20.13,2X,E20.13,2X,E20.13)"
945         WRITE(numtan,FMT) 'trasbc  ', cur_loop, h_ratio, zgsp1, zgsp2, zgsp3, zgsp4, zgsp5, zgsp6, zgsp7
946         !--------------------------------------------------------------------
947         ! Unitary calculus
948         !--------------------------------------------------------------------
949         FMT = "(A8,2X,A8,2X,I4.4,2X,E6.1,2X,I4.4,2X,I4.4,2X,I4.4,2X,E20.13,1X)"
950         cl_name = 'trasbc  '
951         IF(lwp) THEN
952            DO ii=1, 100, 1
953               IF ( zscta(ii) .NE. 0.0_wp ) WRITE(numtan_sc,FMT) cl_name, 'zscta     ', &
954                    & cur_loop, h_ratio, ii, iiposta(ii), ijposta(ii), zscta(ii)
955            ENDDO
956            DO ii=1, 100, 1
957               IF ( zscsa(ii) .NE. 0.0_wp ) WRITE(numtan_sc,FMT) cl_name, 'zscsa     ', &
958                    & cur_loop, h_ratio, ii, iipossa(ii), ijpossa(ii), zscsa(ii)
959            ENDDO
960            DO ii=1, 100, 1
961               IF ( zscerrta(ii) .NE. 0.0_wp ) WRITE(numtan_sc,FMT) cl_name, 'zscerrta  ', &
962                    & cur_loop, h_ratio, ii, iiposta(ii), ijposta(ii), zscerrta(ii)
963            ENDDO
964            DO ii=1, 100, 1
965               IF ( zscerrsa(ii) .NE. 0.0_wp ) WRITE(numtan_sc,FMT) cl_name, 'zscerrsa  ', &
966                    & cur_loop, h_ratio, ii, iipossa(ii), ijpossa(ii), zscerrsa(ii)
967            ENDDO
968            ! write separator
969            WRITE(numtan_sc,"(A4)") '===='
970         ENDIF
971      ENDIF
972
973      DEALLOCATE(                           &
974         & zsn_tlin, zta_tlin, zsa_tlin,    & 
975         & zqns_tlin, zemps_tlin,           & 
976         & zta_out, zsa_out,                & 
977         & zta_wop, zsa_wop,                &
978         & z3r, z2r                         &
979         & )
980   END SUBROUTINE tra_sbc_tlm_tst
981!!======================================================================
982#endif
983END MODULE trasbc_tam
Note: See TracBrowser for help on using the repository browser.