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

source: branches/TAM_V3_0/NEMOTAM/OPATAM_SRC/DYN/dynspg_tam.F90 @ 2587

Last change on this file since 2587 was 2587, checked in by vidard, 13 years ago

refer to ticket #798

File size: 12.9 KB
RevLine 
[1885]1MODULE dynspg_tam
2   !!----------------------------------------------------------------------
3   !!    This software is governed by the CeCILL licence (Version 2)
4   !!----------------------------------------------------------------------
5#if defined key_tam
6   !!======================================================================
7   !!                       ***  MODULE  dynspg_tam  ***
8   !! Ocean dynamics:  surface pressure gradient control
9   !!                  Tangent and Adjoint Module
10   !!======================================================================
11   !! History of the direct module:
12   !!            9.0  !  05-12  (C. Talandier, G. Madec)  Original code
13   !!            9.0  !  05-12  (V. Garnier)  dyn_spg_ctl: Original code
14   !! History of the T&A module:
15   !!            9.0  !  08-06  (A. Vidard) Skeleton
16   !!                 !  08-11  (A. Vidard) nemo v3
17   !!                 !  09-03  (A. Weaver) dynspg_flt_tam
18   !!----------------------------------------------------------------------
19   !!   dyn_spg_tan     : update the dynamics trend with the surface pressure
20   !!                     gradient (tangent routine)
21   !!   dyn_spg_adj     : update the dynamics trend with the surface pressure
22   !!                     gradient (adjoint routine)
23   !!   dyn_spg_adj_tst : Test of the adjoint routine
24   !!----------------------------------------------------------------------
25   USE par_kind      , ONLY: & ! Precision variables
26      & wp
27   USE par_oce       , ONLY: & ! Ocean space and time domain variables
28      & lk_esopa
29#if defined key_obc
30   USE obc_oce       , ONLY: & ! ocean open boundary conditions
31      & ln_vol_cst, &
32      & ln_obc_fla
33#endif
34   USE dynspg_oce    , ONLY: & ! surface pressure gradient variables
35      & lk_dynspg_flt,       &
36      & lk_dynspg_ts,        &
37      & lk_dynspg_exp,       &
38      & lk_dynspg_rl
39   USE in_out_manager, ONLY: & ! I/O manager
40      & lwp,                 &
41      & numout,              & 
42      & nit000,              &
43      & nitend,              &
44      & ctl_stop
45   USE dom_oce       , ONLY: & ! Ocean space and time domain
46      & rdt,                 &
47      & rdtbt 
48
49!   USE dynspg_exp_tam ! surface pressure gradient     (dyn_spg_exp routine)
50!   USE dynspg_ts_tam  ! surface pressure gradient     (dyn_spg_ts  routine)
51!   USE dynspg_rl_tam  ! surface pressure gradient     (dyn_spg_rl  routine)
52   USE dynspg_flt_tam  ! surface pressure gradient     (dyn_spg_flt routine)
53
54   IMPLICIT NONE
55   PRIVATE
56
57   !! * Accessibility
58   PUBLIC dyn_spg_tan,     &   ! routine called by steptan module
59      &   dyn_spg_adj,     &   ! routine called by stepadj module
[2587]60      &   dyn_spg_adj_tst      ! routine controlling adjoint tests
61#if defined key_tst_tlm
62   PUBLIC dyn_spg_tlm_tst
63#endif 
[1885]64
65   !! * module variables
66   INTEGER ::   nspg = 0   ! type of surface pressure gradient scheme defined from lk_dynspg_...
67
68   !! * Substitutions
69#  include "domzgr_substitute.h90"
70#  include "vectopt_loop_substitute.h90"
71
72CONTAINS
73
74   SUBROUTINE dyn_spg_tan( kt, kindic )
75      !!----------------------------------------------------------------------
76      !!                  ***  ROUTINE dyn_spg_tan  ***
77      !!
78      !! ** Purpose of the direct routine:
79      !!            compute the lateral ocean dynamics physics.
80      !!----------------------------------------------------------------------
81      INTEGER, INTENT( IN  ) :: &
82         & kt      ! ocean time-step index
83      INTEGER, INTENT( OUT ) :: &
84         & kindic  ! solver flag
85      !!----------------------------------------------------------------------
86
87      IF( kt == nit000 )   CALL dyn_spg_ctl_tam  ! initialisation & control of options
88
89      SELECT CASE ( nspg )                       ! compute surf. pressure gradient
90                                                 ! trend and add it to the general trend
91      CASE (  0 ) 
92         CALL ctl_stop ( 'dyn_spg_exp_tan not available yet' )
93!!!      CALL dyn_spg_exp_tan( kt )              ! explicit
94      CASE (  1 )   
95         CALL ctl_stop ( 'dyn_spg_ts_tan not available yet' )
96!!!      CALL dyn_spg_ts_tan ( kt )              ! time-splitting
97      CASE (  2 ) 
98         CALL dyn_spg_flt_tan( kt, kindic )      ! filtered
99      CASE (  3 ) 
100         CALL ctl_stop ( 'dyn_spg_rl_tan  not available yet' )
101!!!      CALL dyn_spg_rl_tan ( kt, kindic )      ! rigid lid
102      !
103      END SELECT
104      !                   
105   END SUBROUTINE dyn_spg_tan
106
107   SUBROUTINE dyn_spg_adj( kt, kindic )
108      !!----------------------------------------------------------------------
109      !!                  ***  ROUTINE dyn_spg_adj  ***
110      !!
111      !! ** Purpose of the direct routine:
112      !!            compute the lateral ocean dynamics physics.
113      !!----------------------------------------------------------------------
114      INTEGER, INTENT( IN  ) :: &
115         & kt      ! ocean time-step index
116      INTEGER, INTENT( OUT ) :: &
117         & kindic  ! solver flag
118      !!----------------------------------------------------------------------
119
120      IF( kt == nitend )   CALL dyn_spg_ctl_tam  ! initialisation & control of options
121
122      SELECT CASE ( nspg )                       ! compute surf. pressure gradient
123                                                 ! trend and add it to the general trend
124      CASE (  0 ) 
125         CALL ctl_stop ( 'dyn_spg_exp_adj  not available yet' )
126!!!      CALL dyn_spg_exp_adj( kt )              ! explicit
127      CASE (  1 )   
128         CALL ctl_stop ( 'dyn_spg_ts_adj not available yet' )
129!!!      CALL dyn_spg_ts_adj ( kt )              ! time-splitting
130      CASE (  2 ) 
131         CALL dyn_spg_flt_adj( kt, kindic )      ! filtered
132      CASE (  3 ) 
133         CALL ctl_stop ( 'dyn_spg_rl_adj  not available yet' )
134!!!      CALL dyn_spg_rl_adj ( kt, kindic )      ! rigid lid
135      !
136      END SELECT
137      !
138   END SUBROUTINE dyn_spg_adj
139
140   SUBROUTINE dyn_spg_adj_tst( kumadt )
141      !!-----------------------------------------------------------------------
142      !!
143      !!                  ***  ROUTINE dyn_spg_flt_adj_tst ***
144      !!
145      !! ** Purpose : Test the adjoint routine.
146      !!
147      !! ** Method  : Verify the scalar product
148      !!           
149      !!                 ( L dx )^T W dy  =  dx^T L^T W dy
150      !!
151      !!              where  L   = tangent routine
152      !!                     L^T = adjoint routine
153      !!                     W   = diagonal matrix of scale factors
154      !!                     dx  = input perturbation (random field)
155      !!                     dy  = L dx
156      !!
157      !! ** Action  : Call the appropriate test routine depending on the
158      !!              choice of free surface.
159      !!               
160      !! History :
161      !!        ! 09-01 (A. Weaver)
162      !!-----------------------------------------------------------------------
163      !! * Modules used
164
165      !! * Arguments
166      INTEGER, INTENT(IN) :: &
167         & kumadt        ! Output unit
168
169      CALL dyn_spg_ctl_tam                        ! initialisation & control of options
170
171      SELECT CASE ( nspg )                     
172      CASE (  0 ) 
173         CALL ctl_stop ( 'dyn_spg_exp_adj_tst not available yet' )
174!!!      CALL dyn_spg_exp_adj_tst( kumadt )      ! explicit
175      CASE (  1 )   
176         CALL ctl_stop ( 'dyn_spg_ts_adj_tst not available yet' )
177!!!      CALL dyn_spg_ts_adj_tst ( kumadt )      ! time-splitting
178      CASE (  2 ) 
179         CALL dyn_spg_flt_adj_tst( kumadt )      ! filtered
180      CASE (  3 ) 
181         CALL ctl_stop ( 'dyn_spg_rl_adj_tst  not available yet' )
182!!!      CALL dyn_spg_rl_adj_tst ( kumadt )      ! rigid lid
183      !
184      END SELECT
185      !                   
186   END SUBROUTINE dyn_spg_adj_tst
187
188   SUBROUTINE dyn_spg_ctl_tam
189      !!---------------------------------------------------------------------
190      !!                  ***  ROUTINE dyn_spg_ctl_tam  ***
191      !!               
192      !! ** Purpose :  Control the consistency between cpp options for
193      !!               surface pressure gradient schemes
194      !!----------------------------------------------------------------------
195      !! * Local declarations
196      INTEGER :: &
197        & ioptio
198
199      !!----------------------------------------------------------------------
200
201      ! Parameter control and print
202      ! ---------------------------
203      ! Control print
204      IF(lwp) THEN
205         WRITE(numout,*)
206         WRITE(numout,*) 'dyn_spg_ctl_tam : choice of the surface pressure gradient scheme'
207         WRITE(numout,*) '~~~~~~~~~~~~~~~'
208         WRITE(numout,*) '     Explicit free surface                  lk_dynspg_exp = ', lk_dynspg_exp
209         WRITE(numout,*) '     Free surface with time splitting       lk_dynspg_ts  = ', lk_dynspg_ts
210         WRITE(numout,*) '     Filtered free surface cst volume       lk_dynspg_flt = ', lk_dynspg_flt
211         WRITE(numout,*) '     Rigid-lid case                         lk_dynspg_rl  = ', lk_dynspg_rl
212      ENDIF
213
214      ! Control of surface pressure gradient scheme options
215      ! ---------------------------------------------------
216      ioptio = 0
217      IF(lk_dynspg_exp)   ioptio = ioptio + 1
218      IF(lk_dynspg_ts )   ioptio = ioptio + 1
219      IF(lk_dynspg_flt)   ioptio = ioptio + 1
220      IF(lk_dynspg_rl )   ioptio = ioptio + 1
221
222      IF( ( ioptio > 1 .AND. .NOT. lk_esopa ) .OR. ioptio == 0 )   &
223           &   CALL ctl_stop( ' Choose only one surface pressure gradient scheme with a key cpp' )
224
225      IF( lk_esopa     )   nspg = -1
226      IF( lk_dynspg_exp)   nspg =  0
227      IF( lk_dynspg_ts )   nspg =  1
228      IF( lk_dynspg_flt)   nspg =  2
229      IF( lk_dynspg_rl )   nspg =  3
230      IF( nspg == 13   )   nspg =  3
231
232      IF( lk_esopa     )   nspg = -1
233
234     IF(lwp) THEN
235         WRITE(numout,*)
236         IF( nspg == -1 )   WRITE(numout,*) '     ESOPA test All scheme used except rigid-lid'
237         IF( nspg ==  0 )   WRITE(numout,*) '     explicit free surface'
238         IF( nspg ==  1 )   WRITE(numout,*) '     free surface with time splitting scheme'
239         IF( nspg ==  2 )   WRITE(numout,*) '     filtered free surface'
240         IF( nspg ==  3 )   WRITE(numout,*) '     rigid-lid'
241         IF( nspg == 10 )   WRITE(numout,*) '     explicit free surface with j-k-i loop'
242         IF( nspg == 11 )   WRITE(numout,*) '     time splitting free surface with j-k-i loop'
243         IF( nspg == 12 )   WRITE(numout,*) '     filtered free surface with j-k-i loop'
244      ENDIF
245
246      ! Control of timestep choice
247      ! --------------------------
248      IF( lk_dynspg_ts ) THEN
249         IF( MOD( rdt , rdtbt ) /= 0. )   &
250           &   CALL ctl_stop( ' The barotropic timestep must be an integer divisor of the baroclinic timestep' )
251      ENDIF
252
253#if defined key_obc
254      ! Conservation of ocean volume (key_dynspg_flt)
255      ! ---------------------------------------------
256      IF( lk_dynspg_flt ) ln_vol_cst = .true.
257
258      ! Application of Flather's algorithm at open boundaries
259      ! -----------------------------------------------------
260      IF( lk_dynspg_flt ) ln_obc_fla = .false.
261      IF( lk_dynspg_exp ) ln_obc_fla = .true.
262      IF( lk_dynspg_ts  ) ln_obc_fla = .true.
263#endif
264
265   END SUBROUTINE dyn_spg_ctl_tam
[2587]266#if defined key_tst_tlm
[1885]267   SUBROUTINE dyn_spg_tlm_tst( kumadt )
268      !!-----------------------------------------------------------------------
269      !!
270      !!                  ***  ROUTINE dyn_spg_tlm_tst ***
271      !!
272      !! ** Purpose : Test the tangent linear routine.
273      !!
274      !! ** Method  : Verify the relative error Er of the linear model 
275      !!           
276      !!              Er = 100  norm( En ) / norm( L(t0,tn) gamma dx0 )
277      !!                                              --> zero when gamma --> zero
278      !!
279      !!              where  En   = Nn( gamma dx0 ) - L(t0, tn ) gamma dx0
280      !!                     L  =   Linear routine
281      !!                     Nn   = Perturbation evolution ( M( x0 + gamma dx0 ) - M( x0 ) )
282      !!                     gamma dx0  = input perturbation (random field)
283      !!                   
284      !! History :
285      !!        ! 09-06 (F. Vigilant)
286      !!-----------------------------------------------------------------------
287      !! * Modules used
288
289      !! * Arguments
290      INTEGER, INTENT(IN) :: &
291         & kumadt        ! Output unit
292
293      CALL dyn_spg_ctl_tam                        ! initialisation & control of options
294
295      SELECT CASE ( nspg )                     
296      CASE (  0 ) 
297         CALL ctl_stop ( 'dyn_spg_exp_adj_tst not available yet' )
298!!!      CALL dyn_spg_exp_adj_tst( kumadt )      ! explicit
299      CASE (  1 )   
300         CALL ctl_stop ( 'dyn_spg_ts_adj_tst not available yet' )
301!!!      CALL dyn_spg_ts_adj_tst ( kumadt )      ! time-splitting
302      CASE (  2 ) 
303         CALL dyn_spg_flt_tlm_tst( kumadt )      ! filtered
304      CASE (  3 ) 
305         CALL ctl_stop ( 'dyn_spg_rl_adj_tst  not available yet' )
306!!!      CALL dyn_spg_rl_adj_tst ( kumadt )      ! rigid lid
307      !
308      END SELECT
309      !                   
310   END SUBROUTINE dyn_spg_tlm_tst
311
312  !!======================================================================
313#endif
[2587]314#endif
[1885]315END MODULE dynspg_tam
Note: See TracBrowser for help on using the repository browser.