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_fsc_atsk.F90 in trunk/NEMO/OPA_SRC/DYN – NEMO

source: trunk/NEMO/OPA_SRC/DYN/dynspg_fsc_atsk.F90 @ 314

Last change on this file since 314 was 314, checked in by opalod, 19 years ago

nemo_v1_update_017:RB: added call to sol_sor_e for free surface and rigid lid.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.5 KB
Line 
1MODULE dynspg_fsc_atsk
2   !!======================================================================
3   !!                  ***  MODULE  dynspg_fsc_atsk  ***
4   !! Ocean dynamics:  surface pressure gradient trend
5   !!======================================================================
6#if ( defined key_dynspg_fsc && defined key_autotasking )   ||   defined key_esopa
7   !!----------------------------------------------------------------------
8   !!   'key_dynspg_fsc' & 'key_autotasking'   free surface cst volume
9   !!                                                   j-k-i loop (j-slab)
10   !!----------------------------------------------------------------------
11   !!   dyn_spg_fsc_atsk : Update the momentum trend with the surface pressure
12   !!                      gradient for the free surf. constant volume case
13   !!                      with auto-tasking (j-slab) (no vectior opt.)
14   !!----------------------------------------------------------------------
15   !!   OPA 9.0 , LOCEAN-IPSL (2005)
16   !! $Header$
17   !! This software is governed by the CeCILL licence see modipsl/doc/NEMO_CeCILL.txt
18   !!----------------------------------------------------------------------
19   !! * Modules used
20   USE oce             ! ocean dynamics and tracers
21   USE dom_oce         ! ocean space and time domain
22   USE zdf_oce         ! ocean vertical physics
23   USE trdmod          ! ocean dynamics trends
24   USE trdmod_oce      ! ocean variables trends
25   USE in_out_manager  ! I/O manager
26   USE phycst          ! physical constant
27   USE ocesbc          ! Ocean Surface Boundary condition
28   USE flxrnf          ! ocean runoffs
29   USE sol_oce         ! ocean elliptic solver
30   USE solpcg          ! preconditionned conjugate gradient solver
31   USE solsor          ! Successive Over-relaxation solver
32   USE solfet          ! FETI solver
33   USE solsor_e        ! Successive Over-relaxation solver with MPP optimization
34   USE obc_oce         ! Lateral open boundary condition
35   USE obcdyn          ! ocean open boundary condition (obc_dyn routines)
36   USE obcvol          ! ocean open boundary condition (obc_vol routines)
37   USE lib_mpp         ! distributed memory computing library
38   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
39   USE cla_dynspg      ! cross land advection
40   USE prtctl          ! Print control
41
42   IMPLICIT NONE
43   PRIVATE
44
45   !! * Accessibility
46   PUBLIC dyn_spg_fsc_atsk        ! routine called by step.F90
47
48   !! * Shares module variables
49   LOGICAL, PUBLIC, PARAMETER ::   lk_dynspg_fsc_tsk = .TRUE.    !: free surf. cst vol. flag
50
51   !! * Substitutions
52#  include "domzgr_substitute.h90"
53   !!----------------------------------------------------------------------
54   !!   OPA 9.0 , LOCEAN-IPSL (2005)
55   !! $Header$
56   !! This software is governed by the CeCILL licence see modipsl/doc/NEMO_CeCILL.txt
57   !!----------------------------------------------------------------------
58
59CONTAINS
60
61   SUBROUTINE dyn_spg_fsc_atsk( kt, kindic )
62      !!----------------------------------------------------------------------
63      !!                  ***  routine dyn_spg_fsc_atsk  ***
64      !!
65      !! ** Purpose :   Compute the now trend due to the surface pressure
66      !!      gradient for free surface formulation with a constant ocean
67      !!      volume case, add it to the general trend of momentum equation.
68      !!
69      !! ** Method  :   Free surface formulation. The surface pressure gradient
70      !!      is given by:
71      !!         spgu = 1/rau0 d/dx(ps) =  1/e1u di( etn + rnu btda )
72      !!         spgv = 1/rau0 d/dy(ps) =  1/e2v dj( etn + rnu btda )
73      !!      where etn is the free surface elevation and btda is the after
74      !!      of the free surface elevation
75      !!       -1- compute the after sea surface elevation from the cinematic
76      !!      surface boundary condition:
77      !!              zssha = sshb + 2 rdt ( wn - emp )
78      !!           Time filter applied on now sea surface elevation to avoid
79      !!      the divergence of two consecutive time-steps and swap of free
80      !!      surface arrays to start the next time step:
81      !!              sshb = sshn + atfp * [ sshb + zssha - 2 sshn ]
82      !!              sshn = zssha
83      !!       -2- evaluate the surface presure trend (including the addi-
84      !!      tional force) in three steps:
85      !!        a- compute the right hand side of the elliptic equation:
86      !!            gcb = 1/(e1t e2t) [ di(e2u spgu) + dj(e1v spgv) ]
87      !!         where (spgu,spgv) are given by:
88      !!            spgu = vertical sum[ e3u (ub+ 2 rdt ua ) ]
89      !!                 - grav 2 rdt hu /e1u di[sshn + emp]
90      !!            spgv = vertical sum[ e3v (vb+ 2 rdt va) ]
91      !!                 - grav 2 rdt hv /e2v dj[sshn + emp]
92      !!         and define the first guess from previous computation :
93      !!            zbtd = btda
94      !!            btda = 2 zbtd - btdb
95      !!            btdb = zbtd
96      !!        b- compute the relative accuracy to be reached by the
97      !!         iterative solver
98      !!        c- apply the solver by a call to sol... routine
99      !!       -3- compute and add the free surface pressure gradient inclu-
100      !!      ding the additional force used to stabilize the equation.
101      !!      several slabs used ('key-autotasking')
102      !!
103      !! ** Action : - Update (ua,va) with the surf. pressure gradient trend
104      !!             - Save the trends in (ztdua,ztdva) ('key_trddyn')
105      !!
106      !! References :
107      !!      Roullet and Madec 1999, JGR.
108      !!
109      !! History :
110      !!        !  98-05 (G. Roullet)  Original code
111      !!        !  98-10 (G. Madec, M. Imbard)  release 8.2
112      !!   8.5  !  02-08 (G. Madec)  F90: Free form and module
113      !!        !  02-11 (C. Talandier, A-M Treguier) Open boundaries
114      !!   9.0  !  04-08 (C. Talandier) New trends organization
115      !!---------------------------------------------------------------------
116      !! * Modules used     
117      USE oce, ONLY :    ztdua => ta,      & ! use ta as 3D workspace   
118                         ztdva => sa         ! use sa as 3D workspace   
119
120      !! * Arguments
121      INTEGER, INTENT( in ) ::   kt          ! ocean time-step index
122      INTEGER, INTENT( out ) ::   kindic     ! solver convergence flag
123                                             ! if the solver doesn t converge
124                                             ! the flag is < 0
125      !! * Local declarations
126      INTEGER  ::   ji, jj, jk               ! dummy loop indices
127      REAL(wp) ::   &              ! temporary scalars
128         z2dt, z2dtg, zraur, znugdt, znurau,   &
129         zssha, zspgu, zspgv,                  &
130         zgcb, zbtd, ztdgu, ztdgv, zgwgt
131      !!----------------------------------------------------------------------
132
133      IF( kt == nit000 ) THEN
134         IF(lwp) WRITE(numout,*)
135         IF(lwp) WRITE(numout,*) 'dyn_spg_fsc_atsk : surface pressure gradient trend'
136         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~~~  (free surface constant volume, autotasking case)'
137
138         ! set to zero free surface specific arrays
139         spgu(:,:) = 0.e0      ! surface pressure gradient (i-direction)
140         spgv(:,:) = 0.e0      ! surface pressure gradient (j-direction)
141      ENDIF
142
143      ! 0. Local constant initialization
144      ! --------------------------------
145      ! time step: leap-frog
146      z2dt = 2. * rdt
147      ! time step: Euler if restart from rest
148      IF( neuler == 0 .AND. kt == nit000 ) z2dt = rdt
149      ! coefficients
150      z2dtg  = grav * z2dt
151      zraur  = 1. / rauw
152      znugdt =  rnu * grav * z2dt
153      znurau =  znugdt * zraur
154      IF( lk_mpp ) THEN
155         ! Mpp : export boundary values of to neighboring processors
156         !!bug ???  why only in mpp?  is it really needed???
157         CALL lbc_lnk( ua, 'U' , -1. )
158         CALL lbc_lnk( va, 'V' , -1. )
159      ENDIF
160
161      !                                                ! ===============
162      DO jj = 2, jpjm1                                 !  Vertical slab
163         !                                             ! ===============
164         ! 1. Surface pressure gradient (now)
165         ! ----------------------------
166         DO ji = 2, jpim1
167            zspgu =   - grav * ( sshn(ji+1,jj) - sshn(ji,jj) ) / e1u(ji,jj)
168            zspgv =   - grav * ( sshn(ji,jj+1) - sshn(ji,jj) ) / e2v(ji,jj)
169            spgu(ji,jj) = zspgu
170            spgv(ji,jj) = zspgv
171         END DO 
172
173         ! 2. Add the surface pressure trend to the general trend
174         ! ------------------------------------------------------
175         DO jk = 1, jpkm1
176            DO ji = 2, jpim1
177               ua(ji,jj,jk) = ua(ji,jj,jk) + spgu(ji,jj)
178               va(ji,jj,jk) = va(ji,jj,jk) + spgv(ji,jj)
179            END DO
180         END DO
181         !                                             ! ===============
182      END DO                                           !   End of slab
183      !                                                ! ===============
184
185      ! Save the surface pressure gradient trend for diagnostics
186      IF( l_trddyn )   THEN
187         DO jk = 1, jpkm1
188            ztdua(:,:,jk) = spgu(:,:) 
189            ztdva(:,:,jk) = spgv(:,:) 
190         END DO
191      ENDIF
192
193      !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
194
195      !                                                ! ===============
196      DO jj = 2, jpjm1                                 !  Vertical slab
197         !                                             ! ===============
198
199         ! 1. Evaluate the masked next velocity
200         ! ------------------------------------
201         !     (effect of the additional force not included)
202
203         DO jk = 1, jpkm1
204            DO ji = 2, jpim1
205               ua(ji,jj,jk) = ( ub(ji,jj,jk) + z2dt * ua(ji,jj,jk) ) * umask(ji,jj,jk)
206               va(ji,jj,jk) = ( vb(ji,jj,jk) + z2dt * va(ji,jj,jk) ) * vmask(ji,jj,jk)
207            END DO
208         END DO
209
210         !                                             ! ===============
211      END DO                                           !   End of slab
212      !                                                ! ===============
213
214#if defined key_obc
215         ! Update velocities on each open boundary with the radiation algorithm
216         CALL obc_dyn( kt )
217         ! Correction of the barotropic componant velocity to control the volume of the system
218         CALL obc_vol( kt )
219#endif
220#if defined key_orca_r2
221      IF( n_cla == 1 )   CALL dyn_spg_cla( kt )      ! Cross Land Advection (Update (ua,va))
222#endif
223
224      !                                                ! ===============
225      DO jj = 2, jpjm1                                 !  Vertical slab
226         !                                             ! ===============
227
228         ! 2. compute the next vertically averaged velocity
229         ! ------------------------------------------------
230         !     (effect of the additional force not included)
231         ! initialize to zero
232         DO ji = 2, jpim1
233            spgu(ji,jj) = 0.e0
234            spgv(ji,jj) = 0.e0
235         END DO
236
237         ! vertical sum
238         DO jk = 1, jpk
239            DO ji = 2, jpim1
240               spgu(ji,jj) = spgu(ji,jj) + fse3u(ji,jj,jk) * ua(ji,jj,jk)
241               spgv(ji,jj) = spgv(ji,jj) + fse3v(ji,jj,jk) * va(ji,jj,jk)
242            END DO
243         END DO
244
245         ! transport: multiplied by the horizontal scale factor
246         DO ji = 2, jpim1
247            spgu(ji,jj) = spgu(ji,jj) * e2u(ji,jj)
248            spgv(ji,jj) = spgv(ji,jj) * e1v(ji,jj)
249         END DO
250
251         !                                             ! ===============
252      END DO                                           !   End of slab
253      !                                                ! ===============
254
255      !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
256     
257      ! Boundary conditions on (spgu,spgv)
258      CALL lbc_lnk( spgu, 'U', -1. )
259      CALL lbc_lnk( spgv, 'V', -1. )
260
261      !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
262
263      ! 3. Right hand side of the elliptic equation and first guess
264      ! -----------------------------------------------------------
265      DO jj = 2, jpjm1
266         DO ji = 2, jpim1
267            ! Divergence of the after vertically averaged velocity
268            zgcb =  spgu(ji,jj) - spgu(ji-1,jj)   &
269                  + spgv(ji,jj) - spgv(ji,jj-1)
270            gcb(ji,jj) = gcdprc(ji,jj) * zgcb
271            ! First guess of the after barotropic transport divergence
272            zbtd = gcx(ji,jj)
273            gcx (ji,jj) = 2. * zbtd   - gcxb(ji,jj)
274            gcxb(ji,jj) =      zbtd
275         END DO
276      END DO
277      ! applied the lateral boundary conditions
278      IF( nsolv == 4)   CALL lbc_lnk_e( gcb, c_solver_pt, 1. ) 
279
280      !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
281     
282      ! 4. Relative precision (computation on one processor)
283      ! ---------------------
284      rnorme =0.
285      DO jj = 1, jpj
286         DO ji = 1, jpi
287            zgwgt  = gcdmat(ji,jj) * gcb(ji,jj)
288            rnorme = rnorme + gcb(ji,jj) * zgwgt * bmask(ji,jj)
289         END DO
290      END DO
291      IF( lk_mpp )   CALL mpp_sum( rnorme )   ! sum over the global domain
292
293      epsr = eps * eps * rnorme
294      ncut = 0
295      ! if rnorme is 0, the solution is 0, the solver isn't called
296      IF( rnorme == 0.e0 ) THEN
297         gcx(:,:) = 0.e0
298         res   = 0.e0
299         niter = 0
300         ncut  = 999
301      ENDIF
302     
303      !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
304     
305      ! 5. Evaluate the next transport divergence
306      ! -----------------------------------------
307      !    Iterarive solver for the elliptic equation (except IF sol.=0)
308      !    (output in gcx with boundary conditions applied)
309      kindic = 0
310      IF( ncut == 0 ) THEN
311         IF( nsolv == 1 ) THEN         ! diagonal preconditioned conjuguate gradient
312            CALL sol_pcg( kindic )
313         ELSEIF( nsolv == 2 ) THEN     ! successive-over-relaxation
314            CALL sol_sor( kindic )
315         ELSEIF( nsolv == 3 ) THEN     ! FETI solver
316            CALL sol_fet( kindic )
317         ELSEIF( nsolv == 4 ) THEN     ! successive-over-relaxation with extra outer halo
318            CALL sol_sor_e( kindic )
319         ELSE                          ! e r r o r in nsolv namelist parameter
320            IF(lwp) WRITE(numout,cform_err)
321            IF(lwp) WRITE(numout,*) ' dyn_spg_fsc_atsk : e r r o r, nsolv = 1, 2, 3 or 4'
322            IF(lwp) WRITE(numout,*) ' ~~~~~~~~~~~~~~~~                not = ', nsolv
323            nstop = nstop + 1
324         ENDIF
325      ENDIF
326
327      !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
328
329      !                                                ! ===============
330      DO jj = 2, jpjm1                                 !  Vertical slab
331         !                                             ! ===============
332         
333         ! 6. Transport divergence gradient multiplied by z2dt
334         ! -----------------------------------------------====
335         DO ji = 2, jpim1
336            ! trend of Transport divergence gradient
337            ztdgu = znugdt * (gcx(ji+1,jj  ) - gcx(ji,jj) ) / e1u(ji,jj)
338            ztdgv = znugdt * (gcx(ji  ,jj+1) - gcx(ji,jj) ) / e2v(ji,jj)
339            ! multiplied by z2dt
340#if defined key_obc
341            ! caution : grad D = 0 along open boundaries
342            spgu(ji,jj) = z2dt * ztdgu * obcumask(ji,jj)
343            spgv(ji,jj) = z2dt * ztdgv * obcvmask(ji,jj)
344#else
345            spgu(ji,jj) = z2dt * ztdgu
346            spgv(ji,jj) = z2dt * ztdgv
347#endif
348         END DO
349         
350         ! 7.  Add the trends multiplied by z2dt to the after velocity
351         ! -----------------------------------------------------------
352         !     ( c a u t i o n : (ua,va) here are the after velocity not the
353         !                       trend, the leap-frog time stepping will not
354         !                       be done in dynnxt.F routine)
355         DO jk = 1, jpkm1
356            DO ji = 2, jpim1
357               ua(ji,jj,jk) = (ua(ji,jj,jk) + spgu(ji,jj)) * umask(ji,jj,jk)
358               va(ji,jj,jk) = (va(ji,jj,jk) + spgv(ji,jj)) * vmask(ji,jj,jk)
359            END DO
360         END DO
361
362         IF(ln_ctl) THEN         ! print sum trends (used for debugging)
363            CALL prt_ctl(tab3d_1=ua, clinfo1=' spg  - Ua: ', mask1=umask, &
364               &         tab3d_2=va, clinfo2=' Va: ', mask2=vmask)
365         ENDIF
366
367         ! 8. Sea surface elevation time stepping
368         ! --------------------------------------
369         ! Euler (forward) time stepping, no time filter
370         IF( neuler == 0 .AND. kt == nit000 ) THEN
371            DO ji = 1, jpi
372               ! after free surface elevation
373               zssha = sshb(ji,jj) + rdt * ( wn(ji,jj,1) - emp(ji,jj) * zraur ) * tmask(ji,jj,1)
374               ! swap of arrays
375               sshb(ji,jj) = sshn(ji,jj)
376               sshn(ji,jj) = zssha
377            END DO
378         ELSE
379            ! Leap-frog time stepping and time filter
380            DO ji = 1, jpi
381               ! after free surface elevation
382               zssha = sshb(ji,jj) + z2dt * ( wn(ji,jj,1) - emp(ji,jj) * zraur ) * tmask(ji,jj,1)
383               ! time filter and array swap
384               sshb(ji,jj) = atfp * ( sshb(ji,jj) + zssha ) + atfp1 * sshn(ji,jj)
385               sshn(ji,jj) = zssha
386            END DO
387         ENDIF
388         !                                             ! ===============
389      END DO                                           !   End of slab
390      !                                                ! ===============
391
392      ! save the surface pressure gradient trends for diagnostic
393      ! momentum trends
394      IF( l_trddyn )   THEN
395         DO jk = 1, jpkm1
396            ztdua(:,:,jk) = ztdua(:,:,jk) + spgu(:,:)/z2dt 
397            ztdva(:,:,jk) = ztdva(:,:,jk) + spgv(:,:)/z2dt 
398         END DO
399
400         CALL trd_mod(ztdua, ztdva, jpdtdspg, 'DYN', kt)
401      ENDIF
402     
403      !Boundary conditions on sshn
404      CALL lbc_lnk( sshn, 'T', 1. )
405
406      IF(ln_ctl) THEN         ! print sum trends (used for debugging)
407         CALL prt_ctl(tab2d_1=sshn, clinfo1=' spg  - ssh: ', mask1=tmask)
408      ENDIF
409
410
411   END SUBROUTINE dyn_spg_fsc_atsk
412
413#else
414   !!----------------------------------------------------------------------
415   !!   Default case :                                         Empty module
416   !!----------------------------------------------------------------------
417   LOGICAL, PUBLIC, PARAMETER ::   lk_dynspg_fsc_tsk = .FALSE.   !: free surf. cst vol. flag
418CONTAINS
419   SUBROUTINE dyn_spg_fsc_atsk( kt, kindic )      ! Empty module
420      WRITE(*,*) 'dyn_spg_fsc_atsk: You should not have seen this print! error?', kt, kindic
421   END SUBROUTINE dyn_spg_fsc_atsk
422#endif
423   
424   !!======================================================================
425END MODULE dynspg_fsc_atsk
Note: See TracBrowser for help on using the repository browser.