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

source: branches/TAM_V3_0/NEMOTAM/OPATAM_SRC/tstool_tam.F90 @ 1885

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

add TAM sources

  • Property svn:executable set to *
File size: 8.4 KB
Line 
1MODULE tstool_tam
2   !!==========================================================================
3   !!     ***  MODULE  tstool_tam : TAM testing utilities  ***
4   !!==========================================================================
5   !! History of the NEMOTAM module:
6   !!             3.0  !  08-11  (A. Vidard) initial version
7   USE par_oce,        ONLY: & ! Ocean space and time domain variables
8      & jpi,                 &
9      & jpj,                 &
10      & jpk,                 &
11      & jpiglo,              &
12      & jpjglo
13   USE dom_oce       , ONLY: & ! Ocean space and time domain
14      & e1u,                 &
15      & e2u,                 &
16#if defined key_zco
17      & e3t_0,               &
18#else
19      & e3u,                 &
20#endif
21      & umask,               &
22      & mig,                 &
23      & mjg,                 &
24      & nldi,                &
25      & nldj,                &
26      & nlei,                &
27      & nlej
28   USE par_kind      , ONLY: & ! Precision variables
29      & wp
30   USE in_out_manager, ONLY: & ! I/O manager
31      & lwp
32   USE gridrandom    , ONLY: & ! Random Gaussian noise on grids
33      & grid_random
34   USE dotprodfld    , ONLY: & ! Computes dot product for 3D and 2D fields
35      & dot_product
36   IMPLICIT NONE
37   PRIVATE
38   REAL(KIND=wp), PUBLIC ::  & ! random field standard deviation for:
39      & stdu   =  0.1_wp,    & !   u-velocity
40      & stdv   =  0.1_wp,    & !   v-velocity
41      & stdw   = 0.01_wp,    & !   w-velocity
42#if defined key_obc
43      & stds   = 0.01_wp,    & !   salinity
44      & stdt   = 0.20_wp,    & !   temperature
45      & stdssh = 0.005_wp,   & !   sea surface height
46#else
47      & stds   =  0.1_wp,    & !   salinity
48      & stdt   =  1.0_wp,    & !   temperature
49      & stdssh = 0.01_wp,    & !   sea surface height
50#endif
51      & stdemp = 0.01_wp,    & !   evaporation minus precip 0.1_wp / SQRT( wesp_emp )
52      & stdqns =  1.0_wp,    & !   non solar heat flux
53      & stdqsr =  1.0_wp,    & !   solar heat flux
54      & stdgc  =  0.1_wp,    & !   gcx, gcb
55      & stdr   =  0.1_wp,    & !   rotb, rhd
56      & stdh   =  0.1_wp       !   hdivb
57
58   PUBLIC &
59      & prntst_adj,          &
60      & prntst_tlm
61
62#  include "domzgr_substitute.h90"
63
64CONTAINS
65
66   SUBROUTINE prntst_adj( cd_name, kumadt, psp1, psp2 )
67      CHARACTER(LEN=14), INTENT(in) :: cd_name
68      REAL(wp), INTENT(in) :: psp1, psp2
69      INTEGER, INTENT(in) :: kumadt
70      REAL(KIND=wp) :: &
71         & zspdif,       & ! scalar product difference
72         & ztol            ! accepted tolerance
73      CHARACTER (LEN=47) :: &
74         & FMT
75      CHARACTER (LEN=9)  :: &
76         & cl_stat         ! Accuracy status of adjoint routine (ok or warning)
77
78      ! Compare the scalar products
79
80      zspdif = ABS( psp1 - psp2 )
81      IF ( psp1 /= 0.0_wp ) zspdif = zspdif / ABS( psp1 )
82       
83      ztol = EPSILON( zspdif ) * 10._wp
84
85      IF ( zspdif < ztol ) THEN
86         cl_stat = '   ok    '
87      ELSEIF ( zspdif < ztol*1000._wp ) THEN
88         cl_stat = ' warning '
89      ELSE
90         cl_stat = 'RED ALERT'
91      ENDIF 
92
93      IF (lwp) THEN
94         FMT = "(A14,1X,E20.15,2X,E20.15,2X,E6.1,1X,E6.1,1x,A9)"
95         WRITE(kumadt,FMT) cd_name, psp1, psp2, zspdif, ztol, cl_stat
96         CALL FLUSH( kumadt )
97      ENDIF
98   END SUBROUTINE prntst_adj
99
100   SUBROUTINE prntst_tlm( cd_name, kumadt, psp1, psp2 )
101      CHARACTER(LEN=14), INTENT(in) :: cd_name
102      REAL(wp), INTENT(in) :: psp1, psp2
103      INTEGER, INTENT(in) :: kumadt
104      REAL(KIND=wp) :: &
105         & zspratio       ! scalar product difference
106      CHARACTER (LEN=47) :: &
107         & FMT
108      CHARACTER (LEN=9)  :: &
109         & cl_stat         ! Accuracy status of adjoint routine (ok or warning)
110
111      ! Compare the scalar products
112
113      IF ( psp1 /= 0.0_wp ) zspratio = 100 * psp1 /  psp2 
114
115      IF (lwp) THEN
116         FMT = "(A14,1X,E20.13,2X,E20.15,2X,E6.1,1X)"
117         WRITE(kumadt,FMT) cd_name, psp1, psp2, zspratio
118         CALL FLUSH( kumadt )
119      ENDIF
120   END SUBROUTINE prntst_tlm
121
122   SUBROUTINE example_adj_tst( kumadt )
123      !!-----------------------------------------------------------------------
124      !!
125      !!                  ***  ROUTINE example_adj_tst ***
126      !!
127      !! ** Purpose : Test the adjoint routine.
128      !!
129      !! ** Method  : Verify the scalar product
130      !!           
131      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
132      !!
133      !!              where  L   = tangent routine
134      !!                     L^T = adjoint routine
135      !!                     W   = diagonal matrix of scale factors
136      !!                     dx  = input perturbation (random field)
137      !!                     dy  = L dx
138      !!
139      !!                   
140      !! History :
141      !!        ! 08-08 (A. Vidard)
142      !!-----------------------------------------------------------------------
143      !! * Modules used
144
145      !! * Arguments
146      INTEGER, INTENT(IN) :: &
147         & kumadt             ! Output unit
148 
149      !! * Local declarations
150      INTEGER ::  &
151         & ji,    &        ! dummy loop indices
152         & jj,    &       
153         & jk     
154      INTEGER, DIMENSION(jpi,jpj) :: &
155         & iseed_2d        ! 2D seed for the random number generator
156      REAL(KIND=wp) :: &
157         & zsp1,         & ! scalar product involving the tangent routine
158         & zsp2            ! scalar product involving the adjoint routine
159      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: &
160         & z_tlin ,     & ! Tangent input
161         & z_tlout,     & ! Tangent output
162         & z_adin ,     & ! Adjoint input
163         & z_adout,     & ! Adjoint output
164         & zr             ! 3D random field
165      CHARACTER(LEN=14) :: &
166         & cl_name
167      ! Allocate memory
168
169      ALLOCATE( &
170         & z_tlin( jpi,jpj,jpk),     &
171         & z_tlout(jpi,jpj,jpk),     &
172         & z_adin( jpi,jpj,jpk),     &
173         & z_adout(jpi,jpj,jpk),     &
174         & zr(     jpi,jpj,jpk)      &
175         & )
176      !==================================================================
177      ! 1) dx = ( un_tl, vn_tl, hdivn_tl ) and
178      !    dy = ( hdivb_tl, hdivn_tl )
179      !==================================================================
180
181      !--------------------------------------------------------------------
182      ! Reset the tangent and adjoint variables
183      !--------------------------------------------------------------------
184          z_tlin( :,:,:) = 0.0_wp
185          z_tlout(:,:,:) = 0.0_wp
186          z_adin( :,:,:) = 0.0_wp
187          z_adout(:,:,:) = 0.0_wp
188          zr(     :,:,:) = 0.0_wp
189      !--------------------------------------------------------------------
190      ! Initialize the tangent input with random noise: dx
191      !--------------------------------------------------------------------
192
193      DO jj = 1, jpj
194         DO ji = 1, jpi
195            iseed_2d(ji,jj) = - ( 596035 + &
196               &                  mig(ji) + ( mjg(jj) - 1 ) * jpiglo )
197         END DO
198      END DO
199      CALL grid_random( iseed_2d, zr, 'U', 0.0_wp, stdr )
200      z_tlin(:,:,:) = zr(:,:,:) 
201
202      CALL example_tan 
203      !--------------------------------------------------------------------
204      ! Initialize the adjoint variables: dy^* = W dy
205      !--------------------------------------------------------------------
206
207      DO jk = 1, jpk
208        DO jj = nldj, nlej
209           DO ji = nldi, nlei
210              z_adin(ji,jj,jk) = z_tlout(ji,jj,jk) &
211                 &               * e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) &
212                 &               * umask(ji,jj,jk)
213            END DO
214         END DO
215      END DO
216      !--------------------------------------------------------------------
217      ! Compute the scalar product: ( L dx )^T W dy
218      !--------------------------------------------------------------------
219
220      zsp1 = DOT_PRODUCT( z_tlout, z_adin )
221
222      !--------------------------------------------------------------------
223      ! Call the adjoint routine: dx^* = L^T dy^*
224      !--------------------------------------------------------------------
225
226      CALL example_adj 
227
228      zsp2 = DOT_PRODUCT( z_tlin, z_adout )
229
230      ! 14 char:'12345678901234'
231      cl_name = 'example_adj   '
232      CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 )
233
234      DEALLOCATE(     &
235         & z_tlin,  &
236         & z_tlout, &
237         & z_adin,  &
238         & z_adout, &
239         & zr       &
240         & )
241
242
243
244   END SUBROUTINE example_adj_tst
245
246   SUBROUTINE example_tan
247   END SUBROUTINE example_tan
248   SUBROUTINE example_adj
249   END SUBROUTINE example_adj
250
251END MODULE tstool_tam
Note: See TracBrowser for help on using the repository browser.