1 | MODULE dynspg_flt_tam |
---|
2 | !!---------------------------------------------------------------------- |
---|
3 | !! This software is governed by the CeCILL licence (Version 2) |
---|
4 | !!---------------------------------------------------------------------- |
---|
5 | #if defined key_tam |
---|
6 | !!====================================================================== |
---|
7 | !! *** MODULE dynspg_flt_tam : TANGENT/ADJOINT OF MODULE dynspg_flt *** |
---|
8 | !! |
---|
9 | !! Ocean dynamics: surface pressure gradient trend |
---|
10 | !! |
---|
11 | !!====================================================================== |
---|
12 | !! History of the direct module: |
---|
13 | !! History OPA ! 1998-05 (G. Roullet) free surface |
---|
14 | !! ! 1998-10 (G. Madec, M. Imbard) release 8.2 |
---|
15 | !! NEMO O.1 ! 2002-08 (G. Madec) F90: Free form and module |
---|
16 | !! - ! 2002-11 (C. Talandier, A-M Treguier) Open boundaries |
---|
17 | !! 1.0 ! 2004-08 (C. Talandier) New trends organization |
---|
18 | !! - ! 2005-11 (V. Garnier) Surface pressure gradient organization |
---|
19 | !! 2.0 ! 2006-07 (S. Masson) distributed restart using iom |
---|
20 | !! - ! 2006-08 (J.Chanut, A.Sellar) Calls to BDY routines. |
---|
21 | !! 3.2 ! 2009-03 (G. Madec, M. Leclair, R. Benshila) introduce sshwzv module |
---|
22 | !! History of the TAM module: |
---|
23 | !! 9.0 ! 2008-08 (A. Vidard) skeleton |
---|
24 | !! - ! 2008-08 (A. Weaver) original version |
---|
25 | !! NEMO 3.2 ! 2010-04 (F. Vigilant) converison to 3.2 |
---|
26 | !! NEMO 3.4 ! 2012-07 (P.-A. Bouttier) converison to 3.4 |
---|
27 | !!---------------------------------------------------------------------- |
---|
28 | # if defined key_dynspg_flt || defined key_esopa |
---|
29 | !!---------------------------------------------------------------------- |
---|
30 | !! 'key_dynspg_flt' filtered free surface |
---|
31 | !!---------------------------------------------------------------------- |
---|
32 | !!---------------------------------------------------------------------- |
---|
33 | !! dyn_spg_flt_tan : update the momentum trend with the surface pressure |
---|
34 | !! gradient in the filtered free surface case |
---|
35 | !! (tangent routine) |
---|
36 | !! dyn_spg_flt_adj : update the momentum trend with the surface pressure |
---|
37 | !! gradient in the filtered free surface case |
---|
38 | !! (adjoint routine) |
---|
39 | !! dyn_spg_flt_adj_tst : Test of the adjoint routine |
---|
40 | !!---------------------------------------------------------------------- |
---|
41 | USE prtctl ! Print control |
---|
42 | USE par_oce |
---|
43 | USE in_out_manager |
---|
44 | USE phycst |
---|
45 | USE lib_mpp |
---|
46 | USE dom_oce |
---|
47 | USE solver |
---|
48 | USE dynspg_flt |
---|
49 | USE sol_oce |
---|
50 | USE oce_tam |
---|
51 | USE sbc_oce_tam |
---|
52 | USE sol_oce |
---|
53 | USE sol_oce_tam |
---|
54 | USE solsor_tam |
---|
55 | USE lbclnk |
---|
56 | USE lbclnk_tam |
---|
57 | USE gridrandom |
---|
58 | USE dotprodfld |
---|
59 | USE paresp |
---|
60 | USE dynadv |
---|
61 | USE cla_tam |
---|
62 | USE tstool_tam |
---|
63 | USE wrk_nemo ! Memory Allocation |
---|
64 | USE lib_fortran |
---|
65 | USE timing |
---|
66 | USE iom |
---|
67 | |
---|
68 | |
---|
69 | |
---|
70 | IMPLICIT NONE |
---|
71 | PRIVATE |
---|
72 | |
---|
73 | !! * Accessibility |
---|
74 | PUBLIC dyn_spg_flt_tan, & ! routine called by step_tan.F90 |
---|
75 | & dyn_spg_flt_adj, & ! routine called by step_adj.F90 |
---|
76 | & dyn_spg_flt_adj_tst ! routine called by the tst.F90 |
---|
77 | !! * Substitutions |
---|
78 | # include "domzgr_substitute.h90" |
---|
79 | # include "vectopt_loop_substitute.h90" |
---|
80 | !!---------------------------------------------------------------------- |
---|
81 | CONTAINS |
---|
82 | |
---|
83 | SUBROUTINE dyn_spg_flt_tan( kt, kindic ) |
---|
84 | !!--------------------------------------------------------------------- |
---|
85 | !! *** routine dyn_spg_flt_tan *** |
---|
86 | !! |
---|
87 | !! ** Purpose of the direct routine: |
---|
88 | !! Compute the now trend due to the surface pressure |
---|
89 | !! gradient in case of filtered free surface formulation and add |
---|
90 | !! it to the general trend of momentum equation. |
---|
91 | !! |
---|
92 | !! ** Method of the direct routine: |
---|
93 | !! Filtered free surface formulation. The surface |
---|
94 | !! pressure gradient is given by: |
---|
95 | !! spgu = 1/rau0 d/dx(ps) = 1/e1u di( sshn + btda ) |
---|
96 | !! spgv = 1/rau0 d/dy(ps) = 1/e2v dj( sshn + btda ) |
---|
97 | !! where sshn is the free surface elevation and btda is the after |
---|
98 | !! time derivative of the free surface elevation |
---|
99 | !! -1- evaluate the surface presure trend (including the addi- |
---|
100 | !! tional force) in three steps: |
---|
101 | !! a- compute the right hand side of the elliptic equation: |
---|
102 | !! gcb = 1/(e1t e2t) [ di(e2u spgu) + dj(e1v spgv) ] |
---|
103 | !! where (spgu,spgv) are given by: |
---|
104 | !! spgu = vertical sum[ e3u (ub+ 2 rdt ua ) ] |
---|
105 | !! - grav 2 rdt hu /e1u di[sshn + emp] |
---|
106 | !! spgv = vertical sum[ e3v (vb+ 2 rdt va) ] |
---|
107 | !! - grav 2 rdt hv /e2v dj[sshn + emp] |
---|
108 | !! and define the first guess from previous computation : |
---|
109 | !! zbtd = btda |
---|
110 | !! btda = 2 zbtd - btdb |
---|
111 | !! btdb = zbtd |
---|
112 | !! b- compute the relative accuracy to be reached by the |
---|
113 | !! iterative solver |
---|
114 | !! c- apply the solver by a call to sol... routine |
---|
115 | !! -2- compute and add the free surface pressure gradient inclu- |
---|
116 | !! ding the additional force used to stabilize the equation. |
---|
117 | !! |
---|
118 | !! ** Action : - Update (ua,va) with the surf. pressure gradient trend |
---|
119 | !! |
---|
120 | !! References : Roullet and Madec 1999, JGR. |
---|
121 | !!--------------------------------------------------------------------- |
---|
122 | !! * Arguments |
---|
123 | INTEGER, INTENT( IN ) :: & |
---|
124 | & kt ! ocean time-step index |
---|
125 | INTEGER, INTENT( OUT ) :: & |
---|
126 | & kindic ! solver convergence flag (<0 if not converge) |
---|
127 | |
---|
128 | !! * Local declarations |
---|
129 | INTEGER :: & |
---|
130 | & ji, & ! dummy loop indices |
---|
131 | & jj, & |
---|
132 | & jk |
---|
133 | REAL(wp) :: & |
---|
134 | & z2dt, & ! temporary scalars |
---|
135 | & z2dtg, & |
---|
136 | & zgcb, & |
---|
137 | & zbtd, & |
---|
138 | & ztdgu, & |
---|
139 | & ztdgv |
---|
140 | !!---------------------------------------------------------------------- |
---|
141 | ! |
---|
142 | ! |
---|
143 | IF( nn_timing == 1 ) CALL timing_start('dyn_spg_flt_tan') |
---|
144 | ! |
---|
145 | IF( kt == nit000 ) THEN |
---|
146 | |
---|
147 | IF(lwp) WRITE(numout,*) |
---|
148 | IF(lwp) WRITE(numout,*) 'dyn_spg_flt_tan : surface pressure gradient trend' |
---|
149 | IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~ (free surface constant volume case)' |
---|
150 | ! set to zero free surface specific arrays |
---|
151 | spgu_tl(:,:) = 0.0_wp ! surface pressure gradient (i-direction) |
---|
152 | spgv_tl(:,:) = 0.0_wp ! surface pressure gradient (j-direction) |
---|
153 | ! Reinitialize the solver arrays |
---|
154 | gcxb_tl(:,:) = 0.e0 |
---|
155 | gcx_tl (:,:) = 0.e0 |
---|
156 | CALL sol_mat( nit000 ) |
---|
157 | ENDIF |
---|
158 | ! Local constant initialization |
---|
159 | z2dt = 2. * rdt ! time step: leap-frog |
---|
160 | IF( neuler == 0 .AND. kt == nit000 ) z2dt = rdt ! time step: Euler if restart from rest |
---|
161 | IF( neuler == 0 .AND. kt == nit000+1 ) CALL sol_mat( kt ) |
---|
162 | z2dtg = grav * z2dt |
---|
163 | ! Evaluate the masked next velocity (effect of the additional force not included) |
---|
164 | IF( lk_vvl ) THEN ! variable volume (surface pressure gradient already included in dyn_hpg) |
---|
165 | CALL ctl_stop('key_vvl is not implemented in TAM yet') |
---|
166 | ! |
---|
167 | ELSE ! fixed volume (add the surface pressure gradient + unweighted time stepping) |
---|
168 | ! |
---|
169 | CALL lbc_lnk(sshn_tl,'T',1.) |
---|
170 | DO jj = 2, jpjm1 ! Surface pressure gradient (now) |
---|
171 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
172 | spgu_tl(ji,jj) = - grav * ( sshn_tl(ji+1,jj) - sshn_tl(ji,jj) ) / e1u(ji,jj) |
---|
173 | spgv_tl(ji,jj) = - grav * ( sshn_tl(ji,jj+1) - sshn_tl(ji,jj) ) / e2v(ji,jj) |
---|
174 | END DO |
---|
175 | END DO |
---|
176 | |
---|
177 | DO jk = 1, jpkm1 ! unweighted time stepping |
---|
178 | DO jj = 2, jpjm1 |
---|
179 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
180 | ua_tl(ji,jj,jk) = ( ub_tl(ji,jj,jk) + z2dt * ( ua_tl(ji,jj,jk) + spgu_tl(ji,jj) ) ) * umask(ji,jj,jk) |
---|
181 | va_tl(ji,jj,jk) = ( vb_tl(ji,jj,jk) + z2dt * ( va_tl(ji,jj,jk) + spgv_tl(ji,jj) ) ) * vmask(ji,jj,jk) |
---|
182 | END DO |
---|
183 | END DO |
---|
184 | END DO |
---|
185 | ! |
---|
186 | ENDIF |
---|
187 | IF( nn_cla == 1 ) CALL cla_dynspg_tan( kt ) ! Cross Land Advection (update (ua,va)) |
---|
188 | |
---|
189 | ! compute the next vertically averaged velocity (effect of the additional force not included) |
---|
190 | ! --------------------------------------------- |
---|
191 | DO jj = 2, jpjm1 |
---|
192 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
193 | spgu_tl(ji,jj) = 0.0_wp |
---|
194 | spgv_tl(ji,jj) = 0.0_wp |
---|
195 | END DO |
---|
196 | END DO |
---|
197 | |
---|
198 | ! vertical sum |
---|
199 | !CDIR NOLOOPCHG |
---|
200 | IF( lk_vopt_loop ) THEN ! vector opt., forced unroll |
---|
201 | DO jk = 1, jpkm1 |
---|
202 | DO ji = 1, jpij |
---|
203 | spgu_tl(ji,1) = spgu_tl(ji,1) + fse3u(ji,1,jk) * ua_tl(ji,1,jk) |
---|
204 | spgv_tl(ji,1) = spgv_tl(ji,1) + fse3v(ji,1,jk) * va_tl(ji,1,jk) |
---|
205 | END DO |
---|
206 | END DO |
---|
207 | ELSE ! No vector opt. |
---|
208 | DO jk = 1, jpkm1 |
---|
209 | DO jj = 2, jpjm1 |
---|
210 | DO ji = 2, jpim1 |
---|
211 | spgu_tl(ji,jj) = spgu_tl(ji,jj) + fse3u(ji,jj,jk) * ua_tl(ji,jj,jk) |
---|
212 | spgv_tl(ji,jj) = spgv_tl(ji,jj) + fse3v(ji,jj,jk) * va_tl(ji,jj,jk) |
---|
213 | END DO |
---|
214 | END DO |
---|
215 | END DO |
---|
216 | ENDIF |
---|
217 | |
---|
218 | ! transport: multiplied by the horizontal scale factor |
---|
219 | DO jj = 2, jpjm1 |
---|
220 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
221 | spgu_tl(ji,jj) = spgu_tl(ji,jj) * e2u(ji,jj) |
---|
222 | spgv_tl(ji,jj) = spgv_tl(ji,jj) * e1v(ji,jj) |
---|
223 | END DO |
---|
224 | END DO |
---|
225 | |
---|
226 | CALL lbc_lnk( spgu_tl, 'U', -1.0_wp ) ! lateral boundary conditions |
---|
227 | CALL lbc_lnk( spgv_tl, 'V', -1.0_wp ) |
---|
228 | |
---|
229 | IF( lk_vvl ) CALL ctl_stop( 'dyn_spg_flt_tan: lk_vvl is not available' ) |
---|
230 | |
---|
231 | ! Right hand side of the elliptic equation and first guess |
---|
232 | ! ----------------------------------------------------------- |
---|
233 | DO jj = 2, jpjm1 |
---|
234 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
235 | ! Divergence of the after vertically averaged velocity |
---|
236 | zgcb = spgu_tl(ji,jj) - spgu_tl(ji-1,jj) & |
---|
237 | & + spgv_tl(ji,jj) - spgv_tl(ji,jj-1) |
---|
238 | gcb_tl(ji,jj) = gcdprc(ji,jj) * zgcb |
---|
239 | ! First guess of the after barotropic transport divergence |
---|
240 | zbtd = gcx_tl(ji,jj) |
---|
241 | gcx_tl (ji,jj) = 2.0_wp * zbtd - gcxb_tl(ji,jj) |
---|
242 | gcxb_tl(ji,jj) = zbtd |
---|
243 | END DO |
---|
244 | END DO |
---|
245 | |
---|
246 | ! apply the lateral boundary conditions |
---|
247 | IF( nn_solv == 2 .AND. MAX( jpr2di, jpr2dj ) > 0 ) CALL lbc_lnk_e( gcb_tl, c_solver_pt, 1.0_wp ) |
---|
248 | |
---|
249 | ! Relative precision |
---|
250 | ! ------------------ |
---|
251 | |
---|
252 | rnorme = GLOB_SUM( gcb_tl(1:jpi,1:jpj) * gcdmat(1:jpi,1:jpj) * gcb_tl(1:jpi,1:jpj) * bmask(:,:) ) |
---|
253 | |
---|
254 | epsr = eps * eps * rnorme |
---|
255 | ncut = 0 |
---|
256 | ! if rnorme is 0, the solution is 0, the solver is not called |
---|
257 | IF( rnorme == 0.0_wp ) THEN |
---|
258 | gcx_tl(:,:) = 0.0_wp |
---|
259 | res = 0.0_wp |
---|
260 | niter = 0 |
---|
261 | ncut = 999 |
---|
262 | ENDIF |
---|
263 | |
---|
264 | ! Evaluate the next transport divergence |
---|
265 | ! -------------------------------------- |
---|
266 | ! Iterarive solver for the elliptic equation (except IF sol.=0) |
---|
267 | ! (output in gcx with boundary conditions applied) |
---|
268 | kindic = 0 |
---|
269 | IF( ncut == 0 ) THEN |
---|
270 | IF ( nn_solv == 1 ) THEN ; CALL ctl_stop('sol_pcg_tan not available in TAM yet') ! diagonal preconditioned conjuguate gradient |
---|
271 | ELSEIF( nn_solv == 2 ) THEN ; CALL sol_sor_tan( kt, kindic ) ! successive-over-relaxation |
---|
272 | ENDIF |
---|
273 | ENDIF |
---|
274 | |
---|
275 | ! Transport divergence gradient multiplied by z2dt |
---|
276 | ! --------------------------------------------==== |
---|
277 | DO jj = 2, jpjm1 |
---|
278 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
279 | ! trend of Transport divergence gradient |
---|
280 | ztdgu = z2dtg * ( gcx_tl(ji+1,jj ) - gcx_tl(ji,jj) ) / e1u(ji,jj) |
---|
281 | ztdgv = z2dtg * ( gcx_tl(ji ,jj+1) - gcx_tl(ji,jj) ) / e2v(ji,jj) |
---|
282 | ! multiplied by z2dt |
---|
283 | spgu_tl(ji,jj) = z2dt * ztdgu |
---|
284 | spgv_tl(ji,jj) = z2dt * ztdgv |
---|
285 | END DO |
---|
286 | END DO |
---|
287 | |
---|
288 | ! Add the trends multiplied by z2dt to the after velocity |
---|
289 | ! ------------------------------------------------------- |
---|
290 | ! ( c a u t i o n : (ua_tl,va_tl) here are the after velocity not the |
---|
291 | ! trend, the leap-frog time stepping will not |
---|
292 | ! be done in dynnxt_tan.F90 routine) |
---|
293 | DO jk = 1, jpkm1 |
---|
294 | DO jj = 2, jpjm1 |
---|
295 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
296 | ua_tl(ji,jj,jk) = ( ua_tl(ji,jj,jk) + spgu_tl(ji,jj) ) * umask(ji,jj,jk) |
---|
297 | va_tl(ji,jj,jk) = ( va_tl(ji,jj,jk) + spgv_tl(ji,jj) ) * vmask(ji,jj,jk) |
---|
298 | END DO |
---|
299 | END DO |
---|
300 | END DO |
---|
301 | |
---|
302 | ! |
---|
303 | IF( nn_timing == 1 ) CALL timing_stop('dyn_spg_flt_tan') |
---|
304 | ! |
---|
305 | END SUBROUTINE dyn_spg_flt_tan |
---|
306 | |
---|
307 | SUBROUTINE dyn_spg_flt_adj( kt, kindic ) |
---|
308 | !!---------------------------------------------------------------------- |
---|
309 | !! *** routine dyn_spg_flt_adj *** |
---|
310 | !! |
---|
311 | !! ** Purpose of the direct routine: |
---|
312 | !! Compute the now trend due to the surface pressure |
---|
313 | !! gradient in case of filtered free surface formulation and add |
---|
314 | !! it to the general trend of momentum equation. |
---|
315 | !! |
---|
316 | !! ** Method of the direct routine: |
---|
317 | !! Filtered free surface formulation. The surface |
---|
318 | !! pressure gradient is given by: |
---|
319 | !! spgu = 1/rau0 d/dx(ps) = 1/e1u di( sshn + btda ) |
---|
320 | !! spgv = 1/rau0 d/dy(ps) = 1/e2v dj( sshn + btda ) |
---|
321 | !! where sshn is the free surface elevation and btda is the after |
---|
322 | !! time derivative of the free surface elevation |
---|
323 | !! -1- evaluate the surface presure trend (including the addi- |
---|
324 | !! tional force) in three steps: |
---|
325 | !! a- compute the right hand side of the elliptic equation: |
---|
326 | !! gcb = 1/(e1t e2t) [ di(e2u spgu) + dj(e1v spgv) ] |
---|
327 | !! where (spgu,spgv) are given by: |
---|
328 | !! spgu = vertical sum[ e3u (ub+ 2 rdt ua ) ] |
---|
329 | !! - grav 2 rdt hu /e1u di[sshn + emp] |
---|
330 | !! spgv = vertical sum[ e3v (vb+ 2 rdt va) ] |
---|
331 | !! - grav 2 rdt hv /e2v dj[sshn + emp] |
---|
332 | !! and define the first guess from previous computation : |
---|
333 | !! zbtd = btda |
---|
334 | !! btda = 2 zbtd - btdb |
---|
335 | !! btdb = zbtd |
---|
336 | !! b- compute the relative accuracy to be reached by the |
---|
337 | !! iterative solver |
---|
338 | !! c- apply the solver by a call to sol... routine |
---|
339 | !! -2- compute and add the free surface pressure gradient inclu- |
---|
340 | !! ding the additional force used to stabilize the equation. |
---|
341 | !! |
---|
342 | !! ** Action : - Update (ua,va) with the surf. pressure gradient trend |
---|
343 | !! |
---|
344 | !! References : Roullet and Madec 1999, JGR. |
---|
345 | !!--------------------------------------------------------------------- |
---|
346 | !! * Arguments |
---|
347 | INTEGER, INTENT( IN ) :: & |
---|
348 | & kt ! ocean time-step index |
---|
349 | INTEGER, INTENT( OUT ) :: & |
---|
350 | & kindic ! solver convergence flag (<0 if not converge) |
---|
351 | |
---|
352 | !! * Local declarations |
---|
353 | INTEGER :: & |
---|
354 | & ji, & ! dummy loop indices |
---|
355 | & jj, & |
---|
356 | & jk |
---|
357 | REAL(wp) :: & |
---|
358 | & z2dt, & ! temporary scalars |
---|
359 | & z2dtg, & |
---|
360 | & zgcb, & |
---|
361 | & zbtd, & |
---|
362 | & ztdgu, & |
---|
363 | & ztdgv |
---|
364 | !!---------------------------------------------------------------------- |
---|
365 | ! |
---|
366 | ! |
---|
367 | IF( nn_timing == 1 ) CALL timing_start('dyn_spg_flt_adj') |
---|
368 | ! |
---|
369 | IF( kt == nitend ) THEN |
---|
370 | IF(lwp) WRITE(numout,*) |
---|
371 | IF(lwp) WRITE(numout,*) 'dyn_spg_flt_adj : surface pressure gradient trend' |
---|
372 | IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~ (free surface constant volume case)' |
---|
373 | ENDIF |
---|
374 | |
---|
375 | ! Local constant initialization |
---|
376 | IF ( neuler == 0 .AND. kt == nit000 ) THEN |
---|
377 | |
---|
378 | z2dt = rdt ! time step: Euler if restart from rest |
---|
379 | CALL sol_mat(kt) ! initialize matrix |
---|
380 | |
---|
381 | ELSEIF ( kt == nitend ) THEN |
---|
382 | |
---|
383 | z2dt = 2.0_wp * rdt ! time step: leap-frog |
---|
384 | CALL sol_mat(kt) ! reinitialize matrix |
---|
385 | |
---|
386 | ELSE |
---|
387 | |
---|
388 | z2dt = 2.0_wp * rdt ! time step: leap-frog |
---|
389 | |
---|
390 | ENDIF |
---|
391 | |
---|
392 | z2dtg = grav * z2dt |
---|
393 | |
---|
394 | ! set to zero free surface specific arrays (they are actually local variables) |
---|
395 | spgu_ad(:,:) = 0.0_wp ; spgv_ad(:,:) = 0.0_wp |
---|
396 | |
---|
397 | ! Add the trends multiplied by z2dt to the after velocity |
---|
398 | ! ----------------------------------------------------------- |
---|
399 | ! ( c a u t i o n : (ua_ad,va_ad) here are the after velocity not the |
---|
400 | ! trend, the leap-frog time stepping will not |
---|
401 | ! be done in dynnxt_adj.F90 routine) |
---|
402 | DO jk = 1, jpkm1 |
---|
403 | DO jj = 2, jpjm1 |
---|
404 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
405 | ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) * umask(ji,jj,jk) |
---|
406 | va_ad(ji,jj,jk) = va_ad(ji,jj,jk) * vmask(ji,jj,jk) |
---|
407 | spgu_ad(ji,jj) = spgu_ad(ji,jj) + ua_ad(ji,jj,jk) |
---|
408 | spgv_ad(ji,jj) = spgv_ad(ji,jj) + va_ad(ji,jj,jk) |
---|
409 | END DO |
---|
410 | END DO |
---|
411 | END DO |
---|
412 | |
---|
413 | ! Transport divergence gradient multiplied by z2dt |
---|
414 | ! --------------------------------------------==== |
---|
415 | DO jj = 2, jpjm1 |
---|
416 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
417 | ! multiplied by z2dt |
---|
418 | ztdgu = z2dt * spgu_ad(ji,jj) |
---|
419 | ztdgv = z2dt * spgv_ad(ji,jj) |
---|
420 | spgu_ad(ji,jj) = 0.0_wp |
---|
421 | spgv_ad(ji,jj) = 0.0_wp |
---|
422 | ! trend of Transport divergence gradient |
---|
423 | ztdgu = ztdgu * z2dtg / e1u(ji,jj) |
---|
424 | ztdgv = ztdgv * z2dtg / e2v(ji,jj) |
---|
425 | gcx_ad(ji ,jj ) = gcx_ad(ji ,jj ) - ztdgu - ztdgv |
---|
426 | gcx_ad(ji ,jj+1) = gcx_ad(ji ,jj+1) + ztdgv |
---|
427 | gcx_ad(ji+1,jj ) = gcx_ad(ji+1,jj ) + ztdgu |
---|
428 | END DO |
---|
429 | END DO |
---|
430 | |
---|
431 | ! Evaluate the next transport divergence |
---|
432 | ! -------------------------------------- |
---|
433 | ! Iterative solver for the elliptic equation (except IF sol.=0) |
---|
434 | ! (output in gcx_ad with boundary conditions applied) |
---|
435 | |
---|
436 | kindic = 0 |
---|
437 | ncut = 0 ! Force solver |
---|
438 | IF( ncut == 0 ) THEN |
---|
439 | IF ( nn_solv == 1 ) THEN ; CALL ctl_stop('sol_pcg_adj not available in TMA yet') ! diagonal preconditioned conjuguate gradient |
---|
440 | ELSEIF( nn_solv == 2 ) THEN ; CALL sol_sor_adj( kt, kindic ) ! successive-over-relaxation |
---|
441 | ENDIF |
---|
442 | ENDIF |
---|
443 | |
---|
444 | ! Right hand side of the elliptic equation and first guess |
---|
445 | ! -------------------------------------------------------- |
---|
446 | ! apply the lateral boundary conditions |
---|
447 | IF( nn_solv == 2 .AND. MAX( jpr2di, jpr2dj ) > 0 ) & |
---|
448 | & CALL lbc_lnk_e_adj( gcb_ad, c_solver_pt, 1.0_wp ) |
---|
449 | |
---|
450 | DO jj = 2, jpjm1 |
---|
451 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
452 | ! First guess of the after barotropic transport divergence |
---|
453 | zbtd = gcxb_ad(ji,jj) + 2.0_wp * gcx_ad(ji,jj) |
---|
454 | gcxb_ad(ji,jj) = - gcx_ad(ji,jj) |
---|
455 | gcx_ad (ji,jj) = zbtd |
---|
456 | ! Divergence of the after vertically averaged velocity |
---|
457 | zgcb = gcb_ad(ji,jj) * gcdprc(ji,jj) |
---|
458 | gcb_ad(ji,jj) = 0.0_wp |
---|
459 | spgu_ad(ji-1,jj ) = spgu_ad(ji-1,jj ) - zgcb |
---|
460 | spgu_ad(ji ,jj ) = spgu_ad(ji ,jj ) + zgcb |
---|
461 | spgv_ad(ji ,jj-1) = spgv_ad(ji ,jj-1) - zgcb |
---|
462 | spgv_ad(ji ,jj ) = spgv_ad(ji ,jj ) + zgcb |
---|
463 | END DO |
---|
464 | END DO |
---|
465 | |
---|
466 | IF( lk_vvl ) CALL ctl_stop( 'dyn_spg_flt_adj: lk_vvl is not available' ) |
---|
467 | |
---|
468 | ! Boundary conditions on (spgu_ad,spgv_ad) |
---|
469 | CALL lbc_lnk_adj( spgu_ad, 'U', -1.0_wp ) |
---|
470 | CALL lbc_lnk_adj( spgv_ad, 'V', -1.0_wp ) |
---|
471 | |
---|
472 | ! transport: multiplied by the horizontal scale factor |
---|
473 | DO jj = 2,jpjm1 |
---|
474 | DO ji = fs_2,fs_jpim1 ! vector opt. |
---|
475 | spgu_ad(ji,jj) = spgu_ad(ji,jj) * e2u(ji,jj) |
---|
476 | spgv_ad(ji,jj) = spgv_ad(ji,jj) * e1v(ji,jj) |
---|
477 | END DO |
---|
478 | END DO |
---|
479 | |
---|
480 | ! compute the next vertically averaged velocity (effect of the additional force not included) |
---|
481 | ! --------------------------------------------- |
---|
482 | |
---|
483 | ! vertical sum |
---|
484 | !CDIR NOLOOPCHG |
---|
485 | IF( lk_vopt_loop ) THEN ! vector opt., forced unroll |
---|
486 | DO jk = 1, jpkm1 |
---|
487 | DO ji = 1, jpij |
---|
488 | ua_ad(ji,1,jk) = ua_ad(ji,1,jk) + fse3u(ji,1,jk) * spgu_ad(ji,1) |
---|
489 | va_ad(ji,1,jk) = va_ad(ji,1,jk) + fse3v(ji,1,jk) * spgv_ad(ji,1) |
---|
490 | END DO |
---|
491 | END DO |
---|
492 | ELSE ! No vector opt. |
---|
493 | DO jk = 1, jpkm1 |
---|
494 | DO jj = 2, jpjm1 |
---|
495 | DO ji = 2, jpim1 |
---|
496 | ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) + fse3u(ji,jj,jk) * spgu_ad(ji,jj) |
---|
497 | va_ad(ji,jj,jk) = va_ad(ji,jj,jk) + fse3v(ji,jj,jk) * spgv_ad(ji,jj) |
---|
498 | END DO |
---|
499 | END DO |
---|
500 | END DO |
---|
501 | ENDIF |
---|
502 | |
---|
503 | DO jj = 2, jpjm1 |
---|
504 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
505 | spgu_ad(ji,jj) = 0.0_wp |
---|
506 | spgv_ad(ji,jj) = 0.0_wp |
---|
507 | END DO |
---|
508 | END DO |
---|
509 | |
---|
510 | IF( nn_cla == 1 ) CALL cla_dynspg_adj( kt ) ! Cross Land Advection (update (ua,va)) |
---|
511 | |
---|
512 | ! Evaluate the masked next velocity (effect of the additional force not included) |
---|
513 | IF( lk_vvl ) THEN ! variable volume (surface pressure gradient already included in dyn_hpg) |
---|
514 | ! |
---|
515 | IF( ln_dynadv_vec ) THEN ! vector form : applied on velocity |
---|
516 | DO jk = 1, jpkm1 |
---|
517 | DO jj = 2, jpjm1 |
---|
518 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
519 | ub_ad(ji,jj,jk) = ub_ad(ji,jj,jk) + z2dt * ua_ad(ji,jj,jk) * umask(ji,jj,jk) |
---|
520 | ua_ad(ji,jj,jk) = z2dt * ua_ad(ji,jj,jk) * umask(ji,jj,jk) |
---|
521 | vb_ad(ji,jj,jk) = vb_ad(ji,jj,jk) + z2dt * va_ad(ji,jj,jk) * vmask(ji,jj,jk) |
---|
522 | va_ad(ji,jj,jk) = z2dt * va_ad(ji,jj,jk) * vmask(ji,jj,jk) |
---|
523 | END DO |
---|
524 | END DO |
---|
525 | END DO |
---|
526 | ! |
---|
527 | ELSE ! flux form : applied on thickness weighted velocity |
---|
528 | DO jk = 1, jpkm1 |
---|
529 | DO jj = 2, jpjm1 |
---|
530 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
531 | ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) / fse3u_a(ji,jj,jk) * umask(ji,jj,jk) |
---|
532 | ub_ad(ji,jj,jk) = ub_ad(ji,jj,jk) + ua_ad(ji,jj,jk) * fse3u_b(ji,jj,jk) |
---|
533 | ua_ad(ji,jj,jk) = ua_ad(ji,jj,jk) * z2dt * fse3u_n(ji,jj,jk) |
---|
534 | va_ad(ji,jj,jk) = va_ad(ji,jj,jk) / fse3v_a(ji,jj,jk) * vmask(ji,jj,jk) |
---|
535 | vb_ad(ji,jj,jk) = vb_ad(ji,jj,jk) + va_ad(ji,jj,jk) * fse3v_b(ji,jj,jk) |
---|
536 | va_ad(ji,jj,jk) = va_ad(ji,jj,jk) * z2dt * fse3v_n(ji,jj,jk) |
---|
537 | END DO |
---|
538 | END DO |
---|
539 | END DO |
---|
540 | ! |
---|
541 | ENDIF |
---|
542 | ! |
---|
543 | ELSE ! fixed volume (add the surface pressure gradient + unweighted time stepping) |
---|
544 | ! |
---|
545 | DO jk = 1, jpkm1 ! unweighted time stepping |
---|
546 | DO jj = 2, jpjm1 |
---|
547 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
548 | ua_ad( ji,jj,jk) = ua_ad(ji,jj,jk) * umask(ji,jj,jk) |
---|
549 | ub_ad( ji,jj,jk) = ub_ad(ji,jj,jk) + ua_ad(ji,jj,jk) |
---|
550 | ua_ad( ji,jj,jk) = ua_ad(ji,jj,jk) * z2dt |
---|
551 | spgu_ad(ji,jj ) = spgu_ad(ji,jj) + ua_ad(ji,jj,jk) |
---|
552 | va_ad( ji,jj,jk) = va_ad(ji,jj,jk) * vmask(ji,jj,jk) |
---|
553 | vb_ad( ji,jj,jk) = vb_ad(ji,jj,jk) + va_ad(ji,jj,jk) |
---|
554 | va_ad( ji,jj,jk) = va_ad(ji,jj,jk) * z2dt |
---|
555 | spgv_ad(ji,jj ) = spgv_ad(ji,jj) + va_ad(ji,jj,jk) |
---|
556 | END DO |
---|
557 | END DO |
---|
558 | END DO |
---|
559 | DO jj = 2, jpjm1 ! Surface pressure gradient (now) |
---|
560 | DO ji = fs_2, fs_jpim1 ! vector opt. |
---|
561 | spgu_ad(ji ,jj ) = spgu_ad(ji ,jj ) * grav / e1u(ji,jj) |
---|
562 | spgv_ad(ji ,jj ) = spgv_ad(ji ,jj ) * grav / e2v(ji,jj) |
---|
563 | sshn_ad(ji ,jj ) = sshn_ad(ji ,jj ) + spgv_ad(ji,jj) |
---|
564 | sshn_ad(ji ,jj+1) = sshn_ad(ji ,jj+1) - spgv_ad(ji,jj) |
---|
565 | sshn_ad(ji ,jj ) = sshn_ad(ji ,jj ) + spgu_ad(ji,jj) |
---|
566 | sshn_ad(ji+1,jj ) = sshn_ad(ji+1,jj ) - spgu_ad(ji,jj) |
---|
567 | spgu_ad(ji ,jj ) = 0.0_wp |
---|
568 | spgv_ad(ji ,jj ) = 0.0_wp |
---|
569 | END DO |
---|
570 | END DO |
---|
571 | CALL lbc_lnk_adj(sshn_ad,'T',1.) |
---|
572 | ENDIF |
---|
573 | |
---|
574 | IF( kt == nit000 ) THEN |
---|
575 | ! set to zero free surface specific arrays |
---|
576 | spgu_ad(:,:) = 0.0_wp ! surface pressure gradient (i-direction) |
---|
577 | spgv_ad(:,:) = 0.0_wp ! surface pressure gradient (j-direction) |
---|
578 | ! Reinitialize the solver arrays |
---|
579 | gcxb_ad(:,:) = 0.e0 |
---|
580 | gcx_ad (:,:) = 0.e0 |
---|
581 | ENDIF |
---|
582 | ! |
---|
583 | IF( nn_timing == 1 ) CALL timing_stop('dyn_spg_flt_adj') |
---|
584 | ! |
---|
585 | END SUBROUTINE dyn_spg_flt_adj |
---|
586 | |
---|
587 | SUBROUTINE dyn_spg_flt_adj_tst( kumadt ) |
---|
588 | !!----------------------------------------------------------------------- |
---|
589 | !! |
---|
590 | !! *** ROUTINE dyn_spg_flt_adj_tst *** |
---|
591 | !! |
---|
592 | !! ** Purpose : Test the adjoint routine. |
---|
593 | !! |
---|
594 | !! ** Method : Verify the scalar product |
---|
595 | !! |
---|
596 | !! ( L dx )^T W dy = dx^T L^T W dy |
---|
597 | !! |
---|
598 | !! where L = tangent routine |
---|
599 | !! L^T = adjoint routine |
---|
600 | !! W = diagonal matrix of scale factors |
---|
601 | !! dx = input perturbation (random field) |
---|
602 | !! dy = L dx |
---|
603 | !! |
---|
604 | !! ** Action : |
---|
605 | !! |
---|
606 | !! History : |
---|
607 | !! ! 09-01 (A. Weaver) |
---|
608 | !!----------------------------------------------------------------------- |
---|
609 | !! * Modules used |
---|
610 | |
---|
611 | !! * Arguments |
---|
612 | INTEGER, INTENT(IN) :: & |
---|
613 | & kumadt ! Output unit |
---|
614 | |
---|
615 | !! * Local declarations |
---|
616 | REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: & |
---|
617 | & zua_tlin, & ! Tangent input: ua_tl |
---|
618 | & zva_tlin, & ! Tangent input: va_tl |
---|
619 | & zub_tlin, & ! Tangent input: ub_tl |
---|
620 | & zvb_tlin, & ! Tangent input: vb_tl |
---|
621 | & zua_tlout, & ! Tangent output: ua_tl |
---|
622 | & zva_tlout, & ! Tangent output: va_tl |
---|
623 | & zua_adin, & ! Adjoint input: ua_ad |
---|
624 | & zva_adin, & ! Adjoint input: va_ad |
---|
625 | & zua_adout, & ! Adjoint output: ua_ad |
---|
626 | & zva_adout, & ! Adjoint output: va_ad |
---|
627 | & zub_adout, & ! Adjoint oputput: ub_ad |
---|
628 | & zvb_adout, & ! Adjoint output: vb_ad |
---|
629 | & znu ! 3D random field for u |
---|
630 | |
---|
631 | REAL(wp), DIMENSION(:,:), ALLOCATABLE :: & |
---|
632 | & zgcx_tlin, zgcxb_tlin, zgcx_tlout, zgcxb_tlout, & |
---|
633 | & zgcx_adin, zgcxb_adin, zgcx_adout, zgcxb_adout |
---|
634 | |
---|
635 | REAL(KIND=wp), DIMENSION(:,:), ALLOCATABLE :: & |
---|
636 | & zsshn_tlin, & ! Tangent input: sshn_tl |
---|
637 | & zsshn_adout,& ! Adjoint output: sshn_ad |
---|
638 | & znssh ! 2D random field for SSH |
---|
639 | REAL(wp) :: & |
---|
640 | & zsp1, & ! scalar product involving the tangent routine |
---|
641 | & zsp2 ! scalar product involving the adjoint routine |
---|
642 | INTEGER :: & |
---|
643 | & indic, & |
---|
644 | & istp |
---|
645 | INTEGER :: & |
---|
646 | & ji, & |
---|
647 | & jj, & |
---|
648 | & jk, & |
---|
649 | & kmod, & |
---|
650 | & jstp |
---|
651 | CHARACTER (LEN=14) :: & |
---|
652 | & cl_name |
---|
653 | INTEGER :: & |
---|
654 | & jpert |
---|
655 | INTEGER, PARAMETER :: jpertmax = 6 |
---|
656 | |
---|
657 | ! Allocate memory |
---|
658 | |
---|
659 | ALLOCATE( & |
---|
660 | & zua_tlin(jpi,jpj,jpk), & |
---|
661 | & zva_tlin(jpi,jpj,jpk), & |
---|
662 | & zub_tlin(jpi,jpj,jpk), & |
---|
663 | & zvb_tlin(jpi,jpj,jpk), & |
---|
664 | & zua_tlout(jpi,jpj,jpk), & |
---|
665 | & zva_tlout(jpi,jpj,jpk), & |
---|
666 | & zua_adin(jpi,jpj,jpk), & |
---|
667 | & zva_adin(jpi,jpj,jpk), & |
---|
668 | & zua_adout(jpi,jpj,jpk), & |
---|
669 | & zva_adout(jpi,jpj,jpk), & |
---|
670 | & zub_adout(jpi,jpj,jpk), & |
---|
671 | & zvb_adout(jpi,jpj,jpk), & |
---|
672 | & znu(jpi,jpj,jpk) & |
---|
673 | & ) |
---|
674 | ALLOCATE( & |
---|
675 | & zsshn_tlin(jpi,jpj), & |
---|
676 | & zsshn_adout(jpi,jpj),& |
---|
677 | & znssh(jpi,jpj) & |
---|
678 | & ) |
---|
679 | |
---|
680 | ALLOCATE( zgcx_tlin (jpi,jpj), zgcx_tlout (jpi,jpj), zgcx_adin (jpi,jpj), zgcx_adout (jpi,jpj), & |
---|
681 | zgcxb_tlin(jpi,jpj), zgcxb_tlout(jpi,jpj), zgcxb_adin(jpi,jpj), zgcxb_adout(jpi,jpj) ) |
---|
682 | |
---|
683 | !========================================================================= |
---|
684 | ! dx = ( sshb_tl, sshn_tl, ub_tl, ua_tl, vb_tl, va_tl, wn_tl, emp_tl ) |
---|
685 | ! and dy = ( sshb_tl, sshn_tl, ua_tl, va_tl ) |
---|
686 | !========================================================================= |
---|
687 | |
---|
688 | ! Test for time steps nit000 and nit000 + 1 (the matrix changes) |
---|
689 | |
---|
690 | DO jstp = nit000, nitend, nitend-nit000 |
---|
691 | DO jpert = jpertmax, jpertmax |
---|
692 | istp = jstp |
---|
693 | |
---|
694 | !-------------------------------------------------------------------- |
---|
695 | ! Reset the tangent and adjoint variables |
---|
696 | !-------------------------------------------------------------------- |
---|
697 | |
---|
698 | zub_tlin (:,:,:) = 0.0_wp |
---|
699 | zvb_tlin (:,:,:) = 0.0_wp |
---|
700 | zua_tlin (:,:,:) = 0.0_wp |
---|
701 | zva_tlin (:,:,:) = 0.0_wp |
---|
702 | zua_tlout(:,:,:) = 0.0_wp |
---|
703 | zva_tlout(:,:,:) = 0.0_wp |
---|
704 | zua_adin (:,:,:) = 0.0_wp |
---|
705 | zva_adin (:,:,:) = 0.0_wp |
---|
706 | zub_adout(:,:,:) = 0.0_wp |
---|
707 | zvb_adout(:,:,:) = 0.0_wp |
---|
708 | zua_adout(:,:,:) = 0.0_wp |
---|
709 | zva_adout(:,:,:) = 0.0_wp |
---|
710 | |
---|
711 | zsshn_tlin (:,:) = 0.0_wp |
---|
712 | zsshn_adout(:,:) = 0.0_wp |
---|
713 | |
---|
714 | zgcx_tlout (:,:) = 0.0_wp ; zgcx_adin (:,:) = 0.0_wp ; zgcx_adout (:,:) = 0.0_wp |
---|
715 | zgcxb_tlout(:,:) = 0.0_wp ; zgcxb_adin(:,:) = 0.0_wp ; zgcxb_adout(:,:) = 0.0_wp |
---|
716 | |
---|
717 | ub_tl(:,:,:) = 0.0_wp |
---|
718 | vb_tl(:,:,:) = 0.0_wp |
---|
719 | ua_tl(:,:,:) = 0.0_wp |
---|
720 | va_tl(:,:,:) = 0.0_wp |
---|
721 | sshn_tl(:,:) = 0.0_wp |
---|
722 | gcx_tl(:,:) = 0.0_wp |
---|
723 | gcxb_tl(:,:) = 0.0_wp |
---|
724 | spgu_tl(:,:) = 0.0_wp |
---|
725 | spgv_tl(:,:) = 0.0_wp |
---|
726 | ub_ad(:,:,:) = 0.0_wp |
---|
727 | vb_ad(:,:,:) = 0.0_wp |
---|
728 | ua_ad(:,:,:) = 0.0_wp |
---|
729 | va_ad(:,:,:) = 0.0_wp |
---|
730 | sshn_ad(:,:) = 0.0_wp |
---|
731 | gcb_ad(:,:) = 0.0_wp |
---|
732 | gcx_ad(:,:) = 0.0_wp |
---|
733 | gcxb_ad(:,:) = 0.0_wp |
---|
734 | spgu_ad(:,:) = 0.0_wp |
---|
735 | spgv_ad(:,:) = 0.0_wp |
---|
736 | !-------------------------------------------------------------------- |
---|
737 | ! Initialize the tangent input with random noise: dx |
---|
738 | !-------------------------------------------------------------------- |
---|
739 | IF ( (jpert == 1) .OR. (jpert == jpertmax) ) THEN |
---|
740 | |
---|
741 | CALL grid_random( znu, 'U', 0.0_wp, stdu ) |
---|
742 | |
---|
743 | DO jk = 1, jpk |
---|
744 | DO jj = nldj, nlej |
---|
745 | DO ji = nldi, nlei |
---|
746 | zua_tlin(ji,jj,jk) = znu(ji,jj,jk) |
---|
747 | END DO |
---|
748 | END DO |
---|
749 | END DO |
---|
750 | |
---|
751 | ENDIF |
---|
752 | IF ( (jpert == 2) .OR. (jpert == jpertmax) ) THEN |
---|
753 | CALL grid_random( znu, 'V', 0.0_wp, stdv ) |
---|
754 | |
---|
755 | DO jk = 1, jpk |
---|
756 | DO jj = nldj, nlej |
---|
757 | DO ji = nldi, nlei |
---|
758 | zva_tlin(ji,jj,jk) = znu(ji,jj,jk) |
---|
759 | END DO |
---|
760 | END DO |
---|
761 | END DO |
---|
762 | |
---|
763 | ENDIF |
---|
764 | IF ( (jpert == 3) .OR. (jpert == jpertmax) ) THEN |
---|
765 | CALL grid_random( znu, 'U', 0.0_wp, stdu ) |
---|
766 | |
---|
767 | DO jk = 1, jpk |
---|
768 | DO jj = nldj, nlej |
---|
769 | DO ji = nldi, nlei |
---|
770 | zub_tlin(ji,jj,jk) = znu(ji,jj,jk) |
---|
771 | END DO |
---|
772 | END DO |
---|
773 | END DO |
---|
774 | |
---|
775 | ENDIF |
---|
776 | IF ( (jpert == 4) .OR. (jpert == jpertmax) ) THEN |
---|
777 | CALL grid_random( znu, 'V', 0.0_wp, stdv ) |
---|
778 | |
---|
779 | DO jk = 1, jpk |
---|
780 | DO jj = nldj, nlej |
---|
781 | DO ji = nldi, nlei |
---|
782 | zvb_tlin(ji,jj,jk) = znu(ji,jj,jk) |
---|
783 | END DO |
---|
784 | END DO |
---|
785 | END DO |
---|
786 | |
---|
787 | ENDIF |
---|
788 | IF ( (jpert == 5) .OR. (jpert == jpertmax) ) THEN |
---|
789 | |
---|
790 | CALL grid_random( znssh, 'T', 0.0_wp, stdssh ) |
---|
791 | DO jj = nldj, nlej |
---|
792 | DO ji = nldi, nlei |
---|
793 | zsshn_tlin(ji,jj) = znssh(ji,jj) |
---|
794 | END DO |
---|
795 | END DO |
---|
796 | END IF |
---|
797 | zgcx_tlin (:,:) = ( zua_tlin(:,:,1) + zub_tlin(:,:,1) ) / 10. |
---|
798 | zgcxb_tlin (:,:) = ( zua_tlin(:,:,2) + zub_tlin(:,:,2) ) / 10. |
---|
799 | !-------------------------------------------------------------------- |
---|
800 | ! Call the tangent routine: dy = L dx |
---|
801 | !-------------------------------------------------------------------- |
---|
802 | |
---|
803 | ua_tl(:,:,:) = zua_tlin(:,:,:) |
---|
804 | va_tl(:,:,:) = zva_tlin(:,:,:) |
---|
805 | ub_tl(:,:,:) = zub_tlin(:,:,:) |
---|
806 | vb_tl(:,:,:) = zvb_tlin(:,:,:) |
---|
807 | sshn_tl(:,:) = zsshn_tlin(:,:) |
---|
808 | |
---|
809 | gcb_tl (:,:) = 0.e0 |
---|
810 | gcx_tl (:,:) = zgcx_tlin (:,:) ; gcxb_tl(:,:) = zgcxb_tlin(:,:) |
---|
811 | |
---|
812 | CALL sol_mat( istp ) ! for nitend, it is not called in _tan so it is still set to the nit000 case |
---|
813 | CALL dyn_spg_flt_tan( istp, indic ) |
---|
814 | |
---|
815 | zua_tlout(:,:,:) = ua_tl(:,:,:) ; zva_tlout(:,:,:) = va_tl(:,:,:) |
---|
816 | zgcxb_tlout(:,:) = gcxb_tl(:,:) ; zgcx_tlout (:,:) = gcx_tl (:,:) |
---|
817 | |
---|
818 | !-------------------------------------------------------------------- |
---|
819 | ! Initialize the adjoint variables: dy^* = W dy |
---|
820 | !-------------------------------------------------------------------- |
---|
821 | |
---|
822 | DO jk = 1, jpk |
---|
823 | DO jj = nldj, nlej |
---|
824 | DO ji = nldi, nlei |
---|
825 | zua_adin(ji,jj,jk) = zua_tlout(ji,jj,jk) & |
---|
826 | & * e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) & |
---|
827 | & * umask(ji,jj,jk) |
---|
828 | zva_adin(ji,jj,jk) = zva_tlout(ji,jj,jk) & |
---|
829 | & * e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk) & |
---|
830 | & * vmask(ji,jj,jk) |
---|
831 | END DO |
---|
832 | END DO |
---|
833 | END DO |
---|
834 | DO jj = nldj, nlej |
---|
835 | DO ji = nldi, nlei |
---|
836 | zgcx_adin (ji,jj) = zgcx_tlout (ji,jj) & |
---|
837 | & * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,1) * tmask(ji,jj,1) |
---|
838 | zgcxb_adin(ji,jj) = zgcxb_tlout(ji,jj) & |
---|
839 | & * e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,1) * tmask(ji,jj,1) |
---|
840 | END DO |
---|
841 | END DO |
---|
842 | |
---|
843 | !-------------------------------------------------------------------- |
---|
844 | ! Compute the scalar product: ( L dx )^T W dy |
---|
845 | !-------------------------------------------------------------------- |
---|
846 | |
---|
847 | zsp1 = DOT_PRODUCT( zua_tlout , zua_adin ) & |
---|
848 | & + DOT_PRODUCT( zgcx_tlout , zgcx_adin ) & |
---|
849 | & + DOT_PRODUCT( zgcxb_tlout , zgcxb_adin ) & |
---|
850 | & + DOT_PRODUCT( zva_tlout , zva_adin ) |
---|
851 | |
---|
852 | |
---|
853 | !-------------------------------------------------------------------- |
---|
854 | ! Call the adjoint routine: dx^* = L^T dy^* |
---|
855 | !-------------------------------------------------------------------- |
---|
856 | |
---|
857 | ua_ad(:,:,:) = zua_adin(:,:,:) |
---|
858 | va_ad(:,:,:) = zva_adin(:,:,:) |
---|
859 | |
---|
860 | gcx_ad (:,:) = zgcx_adin (:,:) ; gcxb_ad(:,:) = zgcxb_adin (:,:) |
---|
861 | ub_ad (:,:,:) = 0.0_wp ; vb_ad (:,:,:) = 0.0_wp |
---|
862 | |
---|
863 | CALL dyn_spg_flt_adj( istp, indic ) |
---|
864 | |
---|
865 | zua_adout(:,:,:) = ua_ad(:,:,:) |
---|
866 | zva_adout(:,:,:) = va_ad(:,:,:) |
---|
867 | zub_adout(:,:,:) = ub_ad(:,:,:) |
---|
868 | zvb_adout(:,:,:) = vb_ad(:,:,:) |
---|
869 | zsshn_adout(:,:) = sshn_ad(:,:) |
---|
870 | zgcx_adout (:,:) = gcx_ad (:,:) |
---|
871 | zgcxb_adout(:,:) = gcxb_ad(:,:) |
---|
872 | |
---|
873 | !-------------------------------------------------------------------- |
---|
874 | ! Compute the scalar product: dx^T L^T W dy |
---|
875 | !-------------------------------------------------------------------- |
---|
876 | |
---|
877 | zsp2 = DOT_PRODUCT( zua_tlin , zua_adout ) & |
---|
878 | & + DOT_PRODUCT( zva_tlin , zva_adout ) & |
---|
879 | & + DOT_PRODUCT( zub_tlin , zub_adout ) & |
---|
880 | & + DOT_PRODUCT( zvb_tlin , zvb_adout ) & |
---|
881 | & + DOT_PRODUCT( zgcx_tlin , zgcx_adout ) & |
---|
882 | & + DOT_PRODUCT( zgcxb_tlin, zgcxb_adout ) & |
---|
883 | & + DOT_PRODUCT( zsshn_tlin, zsshn_adout ) |
---|
884 | |
---|
885 | ! Compare the scalar products |
---|
886 | |
---|
887 | ! 14 char:'12345678901234' |
---|
888 | IF ( istp == nit000 ) THEN |
---|
889 | SELECT CASE (jpert) |
---|
890 | CASE(1) |
---|
891 | cl_name = 'spg_flt Ua T1' |
---|
892 | CASE(2) |
---|
893 | cl_name = 'spg_flt Va T1' |
---|
894 | CASE(3) |
---|
895 | cl_name = 'spg_flt Ub T1' |
---|
896 | CASE(4) |
---|
897 | cl_name = 'spg_flt Vb T1' |
---|
898 | CASE(5) |
---|
899 | cl_name = 'spg_flt ssh T1' |
---|
900 | CASE(jpertmax) |
---|
901 | cl_name = 'dyn_spg_flt T1' |
---|
902 | END SELECT |
---|
903 | ELSEIF ( istp == nitend ) THEN |
---|
904 | SELECT CASE (jpert) |
---|
905 | CASE(1) |
---|
906 | cl_name = 'spg_flt Ua T2' |
---|
907 | CASE(2) |
---|
908 | cl_name = 'spg_flt Va T2' |
---|
909 | CASE(3) |
---|
910 | cl_name = 'spg_flt Ub T2' |
---|
911 | CASE(4) |
---|
912 | cl_name = 'spg_flt Vb T2' |
---|
913 | CASE(5) |
---|
914 | cl_name = 'spg_flt ssh T2' |
---|
915 | CASE(jpertmax) |
---|
916 | cl_name = 'dyn_spg_flt T2' |
---|
917 | END SELECT |
---|
918 | END IF |
---|
919 | CALL prntst_adj( cl_name, kumadt, zsp1, zsp2 ) |
---|
920 | |
---|
921 | END DO |
---|
922 | END DO |
---|
923 | |
---|
924 | nitsor(:) = jp_it0adj ! restore nitsor to avoid non reproducible results with or without the tests |
---|
925 | |
---|
926 | ! Deallocate memory |
---|
927 | |
---|
928 | DEALLOCATE( & |
---|
929 | & zua_tlin, & |
---|
930 | & zva_tlin, & |
---|
931 | & zub_tlin, & |
---|
932 | & zvb_tlin, & |
---|
933 | & zua_tlout, & |
---|
934 | & zva_tlout, & |
---|
935 | & zua_adin, & |
---|
936 | & zva_adin, & |
---|
937 | & zua_adout, & |
---|
938 | & zva_adout, & |
---|
939 | & zub_adout, & |
---|
940 | & zvb_adout, & |
---|
941 | & znu & |
---|
942 | & ) |
---|
943 | DEALLOCATE( & |
---|
944 | & zsshn_tlin, & |
---|
945 | & zsshn_adout,& |
---|
946 | & znssh & |
---|
947 | & ) |
---|
948 | DEALLOCATE( zgcx_tlin , zgcx_tlout , zgcx_adin , zgcx_adout, & |
---|
949 | & zgcxb_tlin, zgcxb_tlout, zgcxb_adin, zgcxb_adout ) |
---|
950 | END SUBROUTINE dyn_spg_flt_adj_tst |
---|
951 | |
---|
952 | # else |
---|
953 | !!---------------------------------------------------------------------- |
---|
954 | !! Default case : Empty module No standart explicit free surface |
---|
955 | !!---------------------------------------------------------------------- |
---|
956 | CONTAINS |
---|
957 | SUBROUTINE dyn_spg_flt_tan( kt, kindic ) ! Empty routine |
---|
958 | WRITE(*,*) 'dyn_spg_flt: You should not have seen this print! error?', kt |
---|
959 | END SUBROUTINE dyn_spg_flt_tan |
---|
960 | SUBROUTINE dyn_spg_flt_adj( kt, kindic ) ! Empty routine |
---|
961 | WRITE(*,*) 'dyn_spg_flt: You should not have seen this print! error?', kt |
---|
962 | END SUBROUTINE dyn_spg_flt_adj |
---|
963 | SUBROUTINE dyn_spg_flt_adj_tst( kt ) ! Empty routine |
---|
964 | WRITE(*,*) 'dyn_spg_flt: You should not have seen this print! error?', kt |
---|
965 | END SUBROUTINE dyn_spg_flt_adj_tst |
---|
966 | SUBROUTINE dyn_spg_flt_tlm_tst( kt ) ! Empty routine |
---|
967 | WRITE(*,*) 'dyn_spg_flt: You should not have seen this print! error?', kt |
---|
968 | END SUBROUTINE dyn_spg_flt_tlm_tst |
---|
969 | # endif |
---|
970 | #endif |
---|
971 | END MODULE dynspg_flt_tam |
---|