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.
agrif_opa_sponge.F90 in branches/2017/dev_r7881_HPC09_ZDF/NEMOGCM/NEMO/NST_SRC – NEMO

source: branches/2017/dev_r7881_HPC09_ZDF/NEMOGCM/NEMO/NST_SRC/agrif_opa_sponge.F90 @ 7953

Last change on this file since 7953 was 7953, checked in by gm, 7 years ago

#1880 (HPC-09): add zdfphy (the ZDF manager) + remove all key_...

  • Property svn:keywords set to Id
File size: 18.1 KB
RevLine 
[3680]1#define SPONGE && define SPONGE_TOP
[390]2
[5656]3MODULE agrif_opa_sponge
[6140]4   !!======================================================================
[7953]5   !!                   ***  MODULE  agrif_opa_interp  ***
6   !! AGRIF: interpolation package
[6140]7   !!======================================================================
[7953]8   !! History :  2.0  !  2002-06  (XXX)  Original cade
9   !!             -   !  2005-11  (XXX)
10   !!            3.2  !  2009-04  (R. Benshila)
11   !!            3.6  !  2014-09  (R. Benshila)
[6140]12   !!----------------------------------------------------------------------
[7646]13#if defined key_agrif
[7953]14   !!----------------------------------------------------------------------
15   !!   'key_agrif'                                              AGRIF zoom
16   !!----------------------------------------------------------------------
[636]17   USE par_oce
18   USE oce
19   USE dom_oce
[7953]20   !
[636]21   USE in_out_manager
[782]22   USE agrif_oce
[3294]23   USE wrk_nemo 
[5656]24   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
[390]25
[636]26   IMPLICIT NONE
27   PRIVATE
[390]28
[5656]29   PUBLIC Agrif_Sponge, Agrif_Sponge_Tra, Agrif_Sponge_Dyn
30   PUBLIC interptsn_sponge, interpun_sponge, interpvn_sponge
[390]31
[1156]32   !!----------------------------------------------------------------------
[7953]33   !! NEMO/NST 4.0 , NEMO Consortium (2017)
[1156]34   !! $Id$
[2528]35   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
[1156]36   !!----------------------------------------------------------------------
[5656]37CONTAINS
[636]38
[782]39   SUBROUTINE Agrif_Sponge_Tra
[7953]40      !!----------------------------------------------------------------------
41      !!                 *** ROUTINE Agrif_Sponge_Tra ***
42      !!----------------------------------------------------------------------
43      REAL(wp) ::   timecoeff   ! local scalar
44      !!----------------------------------------------------------------------
[6140]45      !
[390]46#if defined SPONGE
[636]47      timecoeff = REAL(Agrif_NbStepint(),wp)/Agrif_rhot()
[7953]48      !
[5656]49      CALL Agrif_Sponge
[7953]50      Agrif_SpecialValue    = 0._wp
[390]51      Agrif_UseSpecialValue = .TRUE.
[7953]52      tabspongedone_tsn     = .FALSE.
53      !
[5656]54      CALL Agrif_Bc_Variable(tsn_sponge_id,calledweight=timecoeff,procname=interptsn_sponge)
[7953]55      !
[5656]56      Agrif_UseSpecialValue = .FALSE.
[390]57#endif
[6140]58      !
[636]59   END SUBROUTINE Agrif_Sponge_Tra
[390]60
[6140]61
[782]62   SUBROUTINE Agrif_Sponge_dyn
[7953]63      !!----------------------------------------------------------------------
64      !!                 *** ROUTINE Agrif_Sponge_dyn ***
65      !!----------------------------------------------------------------------
66      REAL(wp) ::   timecoeff   ! local scalar
67      !!----------------------------------------------------------------------
68      !
[390]69#if defined SPONGE
[636]70      timecoeff = REAL(Agrif_NbStepint(),wp)/Agrif_rhot()
[7953]71      !
72      Agrif_SpecialValue    = 0._wp
[782]73      Agrif_UseSpecialValue = ln_spc_dyn
[7953]74      !
[5656]75      tabspongedone_u = .FALSE.
76      tabspongedone_v = .FALSE.         
77      CALL Agrif_Bc_Variable(un_sponge_id,calledweight=timecoeff,procname=interpun_sponge)
[7953]78      !
[5656]79      tabspongedone_u = .FALSE.
80      tabspongedone_v = .FALSE.
81      CALL Agrif_Bc_Variable(vn_sponge_id,calledweight=timecoeff,procname=interpvn_sponge)
[7953]82      !
[390]83      Agrif_UseSpecialValue = .FALSE.
84#endif
[6140]85      !
[636]86   END SUBROUTINE Agrif_Sponge_dyn
[390]87
[6140]88
[3680]89   SUBROUTINE Agrif_Sponge
[7953]90      !!----------------------------------------------------------------------
91      !!                 *** ROUTINE  Agrif_Sponge ***
92      !!----------------------------------------------------------------------
[3680]93      INTEGER  :: ji,jj,jk
94      INTEGER  :: ispongearea, ilci, ilcj
[4153]95      LOGICAL  :: ll_spdone
96      REAL(wp) :: z1spongearea, zramp
97      REAL(wp), POINTER, DIMENSION(:,:) :: ztabramp
[7953]98      !!----------------------------------------------------------------------
99      !
[3680]100#if defined SPONGE || defined SPONGE_TOP
[4153]101      ll_spdone=.TRUE.
102      IF (( .NOT. spongedoneT ).OR.( .NOT. spongedoneU )) THEN
103         ! Define ramp from boundaries towards domain interior
104         ! at T-points
105         ! Store it in ztabramp
106         ll_spdone=.FALSE.
[3680]107
[4153]108         CALL wrk_alloc( jpi, jpj, ztabramp )
[3680]109
[5656]110         ispongearea  = 2 + nn_sponge_len * Agrif_irhox()
[4153]111         ilci = nlci - ispongearea
112         ilcj = nlcj - ispongearea 
113         z1spongearea = 1._wp / REAL( ispongearea - 2 )
[3680]114
[5656]115         ztabramp(:,:) = 0._wp
[4153]116
117         IF( (nbondi == -1) .OR. (nbondi == 2) ) THEN
118            DO jj = 1, jpj
119               IF ( umask(2,jj,1) == 1._wp ) THEN
120                 DO ji = 2, ispongearea                 
121                    ztabramp(ji,jj) = ( ispongearea-ji ) * z1spongearea
122                 END DO
123               ENDIF
124            ENDDO
125         ENDIF
126
127         IF( (nbondi == 1) .OR. (nbondi == 2) ) THEN
128            DO jj = 1, jpj
129               IF ( umask(nlci-2,jj,1) == 1._wp ) THEN
130                  DO ji = ilci+1,nlci-1
131                     zramp = (ji - (ilci+1) ) * z1spongearea
132                     ztabramp(ji,jj) = MAX( ztabramp(ji,jj), zramp )
133                  ENDDO
134               ENDIF
135            ENDDO
136         ENDIF
137
138         IF( (nbondj == -1) .OR. (nbondj == 2) ) THEN
139            DO ji = 1, jpi
140               IF ( vmask(ji,2,1) == 1._wp ) THEN
141                  DO jj = 2, ispongearea
142                     zramp = ( ispongearea-jj ) * z1spongearea
143                     ztabramp(ji,jj) = MAX( ztabramp(ji,jj), zramp )
144                  END DO
145               ENDIF
146            ENDDO
147         ENDIF
148
149         IF( (nbondj == 1) .OR. (nbondj == 2) ) THEN
150            DO ji = 1, jpi
151               IF ( vmask(ji,nlcj-2,1) == 1._wp ) THEN
152                  DO jj = ilcj+1,nlcj-1
153                     zramp = (jj - (ilcj+1) ) * z1spongearea
154                     ztabramp(ji,jj) = MAX( ztabramp(ji,jj), zramp )
155                  END DO
156               ENDIF
157            ENDDO
158         ENDIF
159
160      ENDIF
161
[3680]162      ! Tracers
163      IF( .NOT. spongedoneT ) THEN
[5656]164         fsaht_spu(:,:) = 0._wp
165         fsaht_spv(:,:) = 0._wp
166         DO jj = 2, jpjm1
167            DO ji = 2, jpim1   ! vector opt.
168               fsaht_spu(ji,jj) = 0.5_wp * visc_tra * (ztabramp(ji,jj) + ztabramp(ji+1,jj  ))
169               fsaht_spv(ji,jj) = 0.5_wp * visc_tra * (ztabramp(ji,jj) + ztabramp(ji  ,jj+1))
170            END DO
171         END DO
[3680]172
[5656]173         CALL lbc_lnk( fsaht_spu, 'U', 1. )   ! Lateral boundary conditions
174         CALL lbc_lnk( fsaht_spv, 'V', 1. )
[3680]175         spongedoneT = .TRUE.
176      ENDIF
177
178      ! Dynamics
179      IF( .NOT. spongedoneU ) THEN
[5656]180         fsahm_spt(:,:) = 0._wp
181         fsahm_spf(:,:) = 0._wp
182         DO jj = 2, jpjm1
183            DO ji = 2, jpim1   ! vector opt.
184               fsahm_spt(ji,jj) = visc_dyn * ztabramp(ji,jj)
185               fsahm_spf(ji,jj) = 0.25_wp * visc_dyn * ( ztabramp(ji,jj) + ztabramp(ji  ,jj+1) &
[7953]186                  &                                     +ztabramp(ji,jj) + ztabramp(ji+1,jj  ) )
[5656]187            END DO
188         END DO
[7953]189         !
[5656]190         CALL lbc_lnk( fsahm_spt, 'T', 1. )   ! Lateral boundary conditions
191         CALL lbc_lnk( fsahm_spf, 'F', 1. )
[3680]192         spongedoneU = .TRUE.
193      ENDIF
194      !
[4153]195      IF (.NOT.ll_spdone) CALL wrk_dealloc( jpi, jpj, ztabramp )
[3680]196      !
197#endif
[6140]198      !
[3680]199   END SUBROUTINE Agrif_Sponge
200
[6140]201
[7953]202   SUBROUTINE interptsn_sponge( tabres, i1, i2, j1, j2, k1, k2, n1, n2, before )
203      !!----------------------------------------------------------------------
204      !!                 *** ROUTINE interptsn_sponge ***
205      !!----------------------------------------------------------------------
206      INTEGER                                     , INTENT(in   ) ::   i1, i2, j1, j2, k1, k2, n1, n2
207      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2,n1:n2), INTENT(inout) ::   tabres
208      LOGICAL                                     , INTENT(in   ) ::   before
[6140]209      !
[5656]210      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
211      INTEGER  ::   iku, ikv
212      REAL(wp) :: ztsa, zabe1, zabe2, zbtr
213      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2) :: ztu, ztv
214      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2,n1:n2) ::tsbdiff
[7953]215      !!----------------------------------------------------------------------
[5656]216      !
[6140]217      IF( before ) THEN
[5656]218         tabres(i1:i2,j1:j2,k1:k2,n1:n2) = tsn(i1:i2,j1:j2,k1:k2,n1:n2)
219      ELSE   
[6140]220         !
[5656]221         tsbdiff(:,:,:,:) = tsb(i1:i2,j1:j2,:,:) - tabres(:,:,:,:)   
222         DO jn = 1, jpts           
223            DO jk = 1, jpkm1
224               DO jj = j1,j2-1
225                  DO ji = i1,i2-1
[6140]226                     zabe1 = fsaht_spu(ji,jj) * umask(ji,jj,jk) * e2_e1u(ji,jj) * e3u_n(ji,jj,jk)
227                     zabe2 = fsaht_spv(ji,jj) * vmask(ji,jj,jk) * e1_e2v(ji,jj) * e3v_n(ji,jj,jk)
[5656]228                     ztu(ji,jj,jk) = zabe1 * ( tsbdiff(ji+1,jj  ,jk,jn) - tsbdiff(ji,jj,jk,jn) ) 
229                     ztv(ji,jj,jk) = zabe2 * ( tsbdiff(ji  ,jj+1,jk,jn) - tsbdiff(ji,jj,jk,jn) )
[6140]230                  END DO
231               END DO
232               !
[5656]233               IF( ln_zps ) THEN      ! set gradient at partial step level
234                  DO jj = j1,j2-1
235                     DO ji = i1,i2-1
236                        ! last level
237                        iku = mbku(ji,jj)
238                        ikv = mbkv(ji,jj)
[6140]239                        IF( iku == jk )   ztu(ji,jj,jk) = 0._wp
240                        IF( ikv == jk )   ztv(ji,jj,jk) = 0._wp
[5656]241                     END DO
242                  END DO
243               ENDIF
[6140]244            END DO
245            !
[5656]246            DO jk = 1, jpkm1
247               DO jj = j1+1,j2-1
248                  DO ji = i1+1,i2-1
249                     IF (.NOT. tabspongedone_tsn(ji,jj)) THEN
[6140]250                        zbtr = r1_e1e2t(ji,jj) / e3t_n(ji,jj,jk)
[5656]251                        ! horizontal diffusive trends
252                        ztsa = zbtr * (  ztu(ji,jj,jk) - ztu(ji-1,jj,jk) + ztv(ji,jj,jk) - ztv(ji  ,jj-1,jk)  )
253                        ! add it to the general tracer trends
254                        tsa(ji,jj,jk,jn) = tsa(ji,jj,jk,jn) + ztsa
255                     ENDIF
[6140]256                  END DO
257               END DO
258            END DO
259            !
260         END DO
261         !
[5656]262         tabspongedone_tsn(i1+1:i2-1,j1+1:j2-1) = .TRUE.
[6140]263         !
[5656]264      ENDIF
[6140]265      !
[5656]266   END SUBROUTINE interptsn_sponge
267
[6140]268
[7953]269   SUBROUTINE interpun_sponge( tabres, i1, i2, j1, j2, k1, k2, before )
270      !!----------------------------------------------------------------------
271      !!                 *** ROUTINE interpun_sponge ***
272      !!----------------------------------------------------------------------
273      INTEGER                               , INTENT(in   ) ::   i1, i2, j1, j2, k1, k2
274      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2), INTENT(inout) ::   tabres
275      LOGICAL                               , INTENT(in   ) ::   before
276      !!
[5656]277      INTEGER :: ji,jj,jk
[7953]278      INTEGER :: jmax
[5656]279      REAL(wp) :: ze2u, ze1v, zua, zva, zbtr
280      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2) :: ubdiff
281      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2) :: rotdiff, hdivdiff
[7953]282      !!----------------------------------------------------------------------
[5656]283      !
[6140]284      IF( before ) THEN
[5656]285         tabres = un(i1:i2,j1:j2,:)
286      ELSE
287         ubdiff(i1:i2,j1:j2,:) = (ub(i1:i2,j1:j2,:) - tabres(:,:,:))*umask(i1:i2,j1:j2,:)
[6140]288         !
[5656]289         DO jk = 1, jpkm1                                 ! Horizontal slab
290            !                                             ! ===============
291
292            !                                             ! --------
293            ! Horizontal divergence                       !   div
294            !                                             ! --------
295            DO jj = j1,j2
296               DO ji = i1+1,i2   ! vector opt.
[6140]297                  zbtr = r1_e1e2t(ji,jj) / e3t_n(ji,jj,jk) * fsahm_spt(ji,jj)
298                  hdivdiff(ji,jj,jk) = (  e2u(ji  ,jj)*e3u_n(ji  ,jj,jk) * ubdiff(ji  ,jj,jk) &
299                                     &   -e2u(ji-1,jj)*e3u_n(ji-1,jj,jk) * ubdiff(ji-1,jj,jk) ) * zbtr
[5656]300               END DO
301            END DO
302
303            DO jj = j1,j2-1
304               DO ji = i1,i2   ! vector opt.
[6140]305                  zbtr = r1_e1e2f(ji,jj) * e3f_n(ji,jj,jk) * fsahm_spf(ji,jj)
[5656]306                  rotdiff(ji,jj,jk) = (-e1u(ji,jj+1) * ubdiff(ji,jj+1,jk) &
307                                       +e1u(ji,jj  ) * ubdiff(ji,jj  ,jk) & 
308                                    & ) * fmask(ji,jj,jk) * zbtr 
309               END DO
310            END DO
[6140]311         END DO
[5656]312         !
313         DO jj = j1+1, j2-1
314            DO ji = i1+1, i2-1   ! vector opt.
315
316               IF (.NOT. tabspongedone_u(ji,jj)) THEN
317                  DO jk = 1, jpkm1                                 ! Horizontal slab
318                     ze2u = rotdiff (ji,jj,jk)
319                     ze1v = hdivdiff(ji,jj,jk)
320                     ! horizontal diffusive trends
[6140]321                     zua = - ( ze2u - rotdiff (ji,jj-1,jk)) / ( e2u(ji,jj) * e3u_n(ji,jj,jk) )   &
[5656]322                           + ( hdivdiff(ji+1,jj,jk) - ze1v  ) / e1u(ji,jj)
323
324                     ! add it to the general momentum trends
325                     ua(ji,jj,jk) = ua(ji,jj,jk) + zua
326
327                  END DO
328               ENDIF
329
330            END DO
331         END DO
332
333         tabspongedone_u(i1+1:i2-1,j1+1:j2-1) = .TRUE.
334
335         jmax = j2-1
336         IF ((nbondj == 1).OR.(nbondj == 2)) jmax = MIN(jmax,nlcj-3)
337
338         DO jj = j1+1, jmax
339            DO ji = i1+1, i2   ! vector opt.
340
341               IF (.NOT. tabspongedone_v(ji,jj)) THEN
342                  DO jk = 1, jpkm1                                 ! Horizontal slab
343                     ze2u = rotdiff (ji,jj,jk)
344                     ze1v = hdivdiff(ji,jj,jk)
345
346                     ! horizontal diffusive trends
[6140]347                     zva = + ( ze2u - rotdiff (ji-1,jj,jk)) / ( e1v(ji,jj) * e3v_n(ji,jj,jk) )   &
[5656]348                           + ( hdivdiff(ji,jj+1,jk) - ze1v  ) / e2v(ji,jj)
349
350                     ! add it to the general momentum trends
351                     va(ji,jj,jk) = va(ji,jj,jk) + zva
352                  END DO
353               ENDIF
[6140]354               !
[5656]355            END DO
356         END DO
[6140]357         !
[5656]358         tabspongedone_v(i1+1:i2,j1+1:jmax) = .TRUE.
[6140]359         !
[5656]360      ENDIF
[6140]361      !
[5656]362   END SUBROUTINE interpun_sponge
363
364
[7953]365   SUBROUTINE interpvn_sponge( tabres, i1, i2, j1, j2, k1, k2, before, nb, ndir )
366      !!----------------------------------------------------------------------
367      !!                 *** ROUTINE interpvn_sponge ***
368      !!----------------------------------------------------------------------
369      INTEGER                               , INTENT(in   ) ::   i1, i2, j1, j2, k1, k2
370      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2), INTENT(inout) ::   tabres
371      LOGICAL                               , INTENT(in   ) ::   before
372      INTEGER                               , INTENT(in   ) ::   nb , ndir
[6140]373      !
[7953]374      INTEGER ::   ji, jj, jk
375      INTEGER ::   imax
376      REAL(wp)::   ze2u, ze1v, zua, zva, zbtr
377      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2) ::   vbdiff, rotdiff, hdivdiff
378      !!----------------------------------------------------------------------
[5656]379
[6140]380      IF( before ) THEN
[5656]381         tabres = vn(i1:i2,j1:j2,:)
382      ELSE
[6140]383         !
[5656]384         vbdiff(i1:i2,j1:j2,:) = (vb(i1:i2,j1:j2,:) - tabres(:,:,:))*vmask(i1:i2,j1:j2,:)
[6140]385         !
[5656]386         DO jk = 1, jpkm1                                 ! Horizontal slab
387            !                                             ! ===============
388
389            !                                             ! --------
390            ! Horizontal divergence                       !   div
391            !                                             ! --------
392            DO jj = j1+1,j2
393               DO ji = i1,i2   ! vector opt.
[6140]394                  zbtr = r1_e1e2t(ji,jj) / e3t_n(ji,jj,jk) * fsahm_spt(ji,jj)
395                  hdivdiff(ji,jj,jk) = ( e1v(ji,jj  ) * e3v_n(ji,jj  ,jk) * vbdiff(ji,jj  ,jk)  &
396                                     &  -e1v(ji,jj-1) * e3v_n(ji,jj-1,jk) * vbdiff(ji,jj-1,jk)  ) * zbtr
[5656]397               END DO
398            END DO
399            DO jj = j1,j2
400               DO ji = i1,i2-1   ! vector opt.
[6140]401                  zbtr = r1_e1e2f(ji,jj) * e3f_n(ji,jj,jk) * fsahm_spf(ji,jj)
[5656]402                  rotdiff(ji,jj,jk) = ( e2v(ji+1,jj) * vbdiff(ji+1,jj,jk) & 
[6140]403                                    &  -e2v(ji  ,jj) * vbdiff(ji  ,jj,jk)  ) * fmask(ji,jj,jk) * zbtr
[5656]404               END DO
405            END DO
[6140]406         END DO
[5656]407
408         !                                                ! ===============
409         !                                               
410
[7953]411         imax = i2 - 1
[6140]412         IF ((nbondi == 1).OR.(nbondi == 2))   imax = MIN(imax,nlci-3)
[5656]413
414         DO jj = j1+1, j2
415            DO ji = i1+1, imax   ! vector opt.
[6140]416               IF( .NOT. tabspongedone_u(ji,jj) ) THEN
417                  DO jk = 1, jpkm1
418                     ua(ji,jj,jk) = ua(ji,jj,jk)                                                               &
419                        & - ( rotdiff (ji  ,jj,jk) - rotdiff (ji,jj-1,jk)) / ( e2u(ji,jj) * e3u_n(ji,jj,jk) )  &
420                        & + ( hdivdiff(ji+1,jj,jk) - hdivdiff(ji,jj  ,jk)) * r1_e1u(ji,jj)
[5656]421                  END DO
422               ENDIF
423            END DO
424         END DO
[6140]425         !
[5656]426         tabspongedone_u(i1+1:imax,j1+1:j2) = .TRUE.
[6140]427         !
[5656]428         DO jj = j1+1, j2-1
429            DO ji = i1+1, i2-1   ! vector opt.
[6140]430               IF( .NOT. tabspongedone_v(ji,jj) ) THEN
431                  DO jk = 1, jpkm1
432                     va(ji,jj,jk) = va(ji,jj,jk)                                                                  &
433                        &  + ( rotdiff (ji,jj  ,jk) - rotdiff (ji-1,jj,jk) ) / ( e1v(ji,jj) * e3v_n(ji,jj,jk) )   &
434                        &  + ( hdivdiff(ji,jj+1,jk) - hdivdiff(ji  ,jj,jk) ) * r1_e2v(ji,jj)
[5656]435                  END DO
436               ENDIF
437            END DO
438         END DO
439         tabspongedone_v(i1+1:i2-1,j1+1:j2-1) = .TRUE.
440      ENDIF
[6140]441      !
[5656]442   END SUBROUTINE interpvn_sponge
443
[390]444#else
[7953]445   !!----------------------------------------------------------------------
446   !!   Empty module                                          no AGRIF zoom
447   !!----------------------------------------------------------------------
[636]448CONTAINS
449   SUBROUTINE agrif_opa_sponge_empty
[7953]450      !!----------------------------------------------------------------------
451      !!                 *** ROUTINE agrif_OPA_sponge_empty ***
452      !!----------------------------------------------------------------------
[636]453      WRITE(*,*)  'agrif_opa_sponge : You should not have seen this print! error?'
454   END SUBROUTINE agrif_opa_sponge_empty
[390]455#endif
[636]456
[6140]457   !!======================================================================
[636]458END MODULE agrif_opa_sponge
Note: See TracBrowser for help on using the repository browser.