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/nemo_v3_3_beta/NEMOGCM/NEMO/NST_SRC – NEMO

source: branches/nemo_v3_3_beta/NEMOGCM/NEMO/NST_SRC/agrif_opa_sponge.F90 @ 2342

Last change on this file since 2342 was 2342, checked in by rblod, 13 years ago

Change key_off_tra to key_offline in agrif routines

  • Property svn:keywords set to Id
File size: 13.8 KB
Line 
1#define SPONGE
2
3Module agrif_opa_sponge
4#if defined key_agrif  && ! defined key_offline
5   USE par_oce
6   USE oce
7   USE dom_oce
8   USE in_out_manager
9   USE agrif_oce
10
11   IMPLICIT NONE
12   PRIVATE
13
14   PUBLIC Agrif_Sponge_Tra, Agrif_Sponge_Dyn, interptn, interpsn, interpun, interpvn
15
16   !!----------------------------------------------------------------------
17   !! NEMO/NST 3.3 , NEMO Consortium (2010)
18   !! $Id$
19   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
20   !!----------------------------------------------------------------------
21
22   CONTAINS
23
24   SUBROUTINE Agrif_Sponge_Tra
25      !!---------------------------------------------
26      !!   *** ROUTINE Agrif_Sponge_Tra ***
27      !!---------------------------------------------
28#include "domzgr_substitute.h90"
29
30      INTEGER :: ji,jj,jk
31      INTEGER :: spongearea
32      REAL(wp) :: timecoeff
33      REAL(wp) :: zta, zsa, zabe1, zabe2, zbtr
34      REAL(wp), DIMENSION(jpi,jpj) :: localviscsponge
35      REAL(wp), DIMENSION(jpi,jpj,jpk) :: tbdiff, sbdiff
36      REAL(wp), DIMENSION(jpi,jpj,jpk) :: ztu ,ztv, zsu ,zsv
37      REAL(wp), DIMENSION(jpi,jpj,jpk) ::  ztab
38
39#if defined SPONGE
40
41      timecoeff = REAL(Agrif_NbStepint(),wp)/Agrif_rhot()
42
43      Agrif_SpecialValue=0.
44      Agrif_UseSpecialValue = .TRUE.
45      ztab = 0.e0
46      CALL Agrif_Bc_Variable(ztab, ta,calledweight=timecoeff,procname=interptn)
47      Agrif_UseSpecialValue = .FALSE.
48
49      tbdiff(:,:,:) = tb(:,:,:) - ztab(:,:,:)
50
51      ztab = 0.e0
52      Agrif_SpecialValue=0.
53      Agrif_UseSpecialValue = .TRUE.
54      CALL Agrif_Bc_Variable(ztab, sa,calledweight=timecoeff,procname=interpsn)
55      Agrif_UseSpecialValue = .FALSE.
56
57      sbdiff(:,:,:) = sb(:,:,:) - ztab(:,:,:)
58
59
60      spongearea = 2 + 2 * Agrif_irhox()
61
62      localviscsponge = 0.
63     
64      IF (.NOT. spongedoneT) THEN
65         spe1ur(:,:) = 0.
66         spe2vr(:,:) = 0.
67
68      IF ((nbondi == -1).OR.(nbondi == 2)) THEN
69         DO ji = 2, spongearea
70            localviscsponge(ji,:) = visc_tra * (spongearea-ji)/real(spongearea-2)
71         ENDDO
72   
73    spe1ur(2:spongearea-1,:)=0.5 * (localviscsponge(2:spongearea-1,:) + localviscsponge(3:spongearea,:)) &
74          * e2u(2:spongearea-1,:) / e1u(2:spongearea-1,:)
75
76         spe2vr(2:spongearea,1:jpjm1) = 0.5 * (localviscsponge(2:spongearea,1:jpjm1) + &
77             localviscsponge(2:spongearea,2:jpj)) &
78           * e1v(2:spongearea,1:jpjm1) / e2v(2:spongearea,1:jpjm1)
79      ENDIF
80
81      IF ((nbondi == 1).OR.(nbondi == 2)) THEN
82         DO ji = nlci-spongearea + 1,nlci-1
83            localviscsponge(ji,:) = visc_tra * (ji - (nlci-spongearea+1))/real(spongearea-2)
84         ENDDO
85   
86    spe1ur(nlci-spongearea + 1:nlci-2,:)=0.5 * (localviscsponge(nlci-spongearea + 1:nlci-2,:) + &
87           localviscsponge(nlci-spongearea + 2:nlci-1,:)) &
88          * e2u(nlci-spongearea + 1:nlci-2,:) / e1u(nlci-spongearea + 1:nlci-2,:)
89
90         spe2vr(nlci-spongearea + 1:nlci-1,1:jpjm1) = 0.5 * (localviscsponge(nlci-spongearea + 1:nlci-1,1:jpjm1) &
91              + localviscsponge(nlci-spongearea + 1:nlci-1,2:jpj)) &
92           * e1v(nlci-spongearea + 1:nlci-1,1:jpjm1) / e2v(nlci-spongearea + 1:nlci-1,1:jpjm1)
93      ENDIF
94
95
96      IF ((nbondj == -1).OR.(nbondj == 2)) THEN
97         DO jj = 2, spongearea
98            localviscsponge(:,jj) = visc_tra * (spongearea-jj)/real(spongearea-2)
99         ENDDO
100   
101    spe1ur(1:jpim1,2:spongearea)=0.5 * (localviscsponge(1:jpim1,2:spongearea) + &
102           localviscsponge(2:jpi,2:spongearea)) &
103          * e2u(1:jpim1,2:spongearea) / e1u(1:jpim1,2:spongearea)
104
105         spe2vr(:,2:spongearea-1) = 0.5 * (localviscsponge(:,2:spongearea-1) + &
106             localviscsponge(:,3:spongearea)) &
107           * e1v(:,2:spongearea-1) / e2v(:,2:spongearea-1)
108      ENDIF
109
110      IF ((nbondj == 1).OR.(nbondj == 2)) THEN
111         DO jj = nlcj-spongearea + 1,nlcj-1
112            localviscsponge(:,jj) = visc_tra * (jj - (nlcj-spongearea+1))/real(spongearea-2)
113         ENDDO
114   
115    spe1ur(1:jpim1,nlcj-spongearea + 1:nlcj-1)=0.5 * (localviscsponge(1:jpim1,nlcj-spongearea + 1:nlcj-1) + &
116            localviscsponge(2:jpi,nlcj-spongearea + 1:nlcj-1)) &
117          * e2u(1:jpim1,nlcj-spongearea + 1:nlcj-1) / e1u(1:jpim1,nlcj-spongearea + 1:nlcj-1)
118
119         spe2vr(:,nlcj-spongearea + 1:nlcj-2) = 0.5 * (localviscsponge(:,nlcj-spongearea + 1:nlcj-2) + &
120            localviscsponge(:,nlcj-spongearea + 2:nlcj-1)) &
121           * e1v(:,nlcj-spongearea + 1:nlcj-2) / e2v(:,nlcj-spongearea + 1:nlcj-2)
122      ENDIF
123     
124         spbtr2(:,:) = 1. / ( e1t(:,:) * e2t(:,:))
125
126         spongedoneT = .TRUE.
127      ENDIF
128
129      DO jk = 1, jpkm1
130         DO jj = 1, jpjm1
131            DO ji = 1, jpim1
132               zabe1 = umask(ji,jj,jk) * spe1ur(ji,jj) * fse3u(ji,jj,jk)
133               zabe2 = vmask(ji,jj,jk) * spe2vr(ji,jj) * fse3v(ji,jj,jk)
134               ztu(ji,jj,jk) = zabe1 * ( tbdiff(ji+1,jj  ,jk) - tbdiff(ji,jj,jk) )
135               zsu(ji,jj,jk) = zabe1 * ( sbdiff(ji+1,jj  ,jk) - sbdiff(ji,jj,jk) )
136               ztv(ji,jj,jk) = zabe2 * ( tbdiff(ji  ,jj+1,jk) - tbdiff(ji,jj,jk) )
137               zsv(ji,jj,jk) = zabe2 * ( sbdiff(ji  ,jj+1,jk) - sbdiff(ji,jj,jk) )
138            ENDDO
139         ENDDO
140
141         DO jj = 2,jpjm1
142            DO ji = 2,jpim1
143               zbtr = spbtr2(ji,jj) / fse3t(ji,jj,jk)
144               ! horizontal diffusive trends
145               zta = zbtr * (  ztu(ji,jj,jk) - ztu(ji-1,jj,jk)   &
146                  &          + ztv(ji,jj,jk) - ztv(ji,jj-1,jk)  )
147               zsa = zbtr * (  zsu(ji,jj,jk) - zsu(ji-1,jj,jk)   &
148                  &          + zsv(ji,jj,jk) - zsv(ji,jj-1,jk)  )
149               ! add it to the general tracer trends
150               ta(ji,jj,jk) = (ta(ji,jj,jk) + zta)
151               sa(ji,jj,jk) = (sa(ji,jj,jk) + zsa)
152            END DO
153         END DO
154
155      ENDDO
156
157#endif
158
159   END SUBROUTINE Agrif_Sponge_Tra
160
161   SUBROUTINE Agrif_Sponge_dyn
162      !!---------------------------------------------
163      !!   *** ROUTINE Agrif_Sponge_dyn ***
164      !!---------------------------------------------
165#include "domzgr_substitute.h90"
166
167      INTEGER :: ji,jj,jk
168      INTEGER :: spongearea
169      REAL(wp) :: timecoeff
170      REAL(wp) :: ze2u, ze1v, zua, zva, zbtr
171      REAL(wp), DIMENSION(jpi,jpj) :: localviscsponge
172      REAL(wp), DIMENSION(jpi,jpj,jpk) :: ztab, ubdiff, vbdiff,rotdiff,hdivdiff
173
174#if defined SPONGE
175
176      timecoeff = REAL(Agrif_NbStepint(),wp)/Agrif_rhot()
177
178      Agrif_SpecialValue=0.
179      Agrif_UseSpecialValue = ln_spc_dyn
180      ztab = 0.e0
181      CALL Agrif_Bc_Variable(ztab, ua,calledweight=timecoeff,procname=interpun)
182      Agrif_UseSpecialValue = .FALSE.
183
184      ubdiff(:,:,:) = (ub(:,:,:) - ztab(:,:,:))*umask(:,:,:)
185
186      ztab = 0.e0
187      Agrif_SpecialValue=0.
188      Agrif_UseSpecialValue = ln_spc_dyn
189      CALL Agrif_Bc_Variable(ztab, va,calledweight=timecoeff,procname=interpvn)
190      Agrif_UseSpecialValue = .FALSE.
191
192      vbdiff(:,:,:) = (vb(:,:,:) - ztab(:,:,:))*vmask(:,:,:)
193
194      spongearea = 2 + 2 * Agrif_irhox()
195
196      localviscsponge = 0.
197
198      IF (.NOT. spongedoneU) THEN
199         spe1ur2(:,:) = 0.
200         spe2vr2(:,:) = 0.
201
202      IF ((nbondi == -1).OR.(nbondi == 2)) THEN
203         DO ji = 2, spongearea
204            localviscsponge(ji,:) = visc_dyn * (spongearea-ji)/real(spongearea-2)
205         ENDDO
206   
207    spe1ur2(2:spongearea-1,:)=0.5 * (localviscsponge(2:spongearea-1,:) + localviscsponge(3:spongearea,:))
208
209         spe2vr2(2:spongearea,1:jpjm1) = 0.5 * (localviscsponge(2:spongearea,1:jpjm1) + &
210             localviscsponge(2:spongearea,2:jpj))
211      ENDIF
212
213      IF ((nbondi == 1).OR.(nbondi == 2)) THEN
214         DO ji = nlci-spongearea + 1,nlci-1
215            localviscsponge(ji,:) = visc_dyn * (ji - (nlci-spongearea+1))/real(spongearea-2)
216         ENDDO
217   
218    spe1ur2(nlci-spongearea + 1:nlci-2,:)=0.5 * (localviscsponge(nlci-spongearea + 1:nlci-2,:) + &
219           localviscsponge(nlci-spongearea + 2:nlci-1,:))
220
221         spe2vr2(nlci-spongearea + 1:nlci-1,1:jpjm1) = 0.5 * (localviscsponge(nlci-spongearea + 1:nlci-1,1:jpjm1) &
222              + localviscsponge(nlci-spongearea + 1:nlci-1,2:jpj))
223      ENDIF
224
225
226      IF ((nbondj == -1).OR.(nbondj == 2)) THEN
227         DO jj = 2, spongearea
228            localviscsponge(:,jj) = visc_dyn * (spongearea-jj)/real(spongearea-2)
229         ENDDO
230   
231    spe1ur2(1:jpim1,2:spongearea)=0.5 * (localviscsponge(1:jpim1,2:spongearea) + &
232           localviscsponge(2:jpi,2:spongearea))
233
234         spe2vr2(:,2:spongearea-1) = 0.5 * (localviscsponge(:,2:spongearea-1) + &
235             localviscsponge(:,3:spongearea))
236      ENDIF
237
238      IF ((nbondj == 1).OR.(nbondj == 2)) THEN
239         DO jj = nlcj-spongearea + 1,nlcj-1
240            localviscsponge(:,jj) = visc_dyn * (jj - (nlcj-spongearea+1))/real(spongearea-2)
241         ENDDO
242   
243    spe1ur2(1:jpim1,nlcj-spongearea + 1:nlcj-1)=0.5 * (localviscsponge(1:jpim1,nlcj-spongearea + 1:nlcj-1) + &
244            localviscsponge(2:jpi,nlcj-spongearea + 1:nlcj-1))
245
246         spe2vr2(:,nlcj-spongearea + 1:nlcj-2) = 0.5 * (localviscsponge(:,nlcj-spongearea + 1:nlcj-2) + &
247            localviscsponge(:,nlcj-spongearea + 2:nlcj-1))
248      ENDIF
249
250         spongedoneU = .TRUE.
251   
252    spbtr3(:,:) = 1./( e1f(:,:) * e2f(:,:))
253      ENDIF
254     
255      IF (.NOT. spongedoneT) THEN
256        spbtr2(:,:) = 1. / ( e1t(:,:) * e2t(:,:))     
257      ENDIF
258     
259      DO jk=1,jpkm1
260      ubdiff(:,:,jk) = ubdiff(:,:,jk) * spe1ur2(:,:)
261      vbdiff(:,:,jk) = vbdiff(:,:,jk) * spe2vr2(:,:)
262      ENDDO
263     
264      hdivdiff = 0.
265      rotdiff = 0.
266
267      DO jk = 1, jpkm1                                 ! Horizontal slab
268         !                                             ! ===============
269
270         !                                             ! --------
271         ! Horizontal divergence                       !   div
272         !                                             ! --------
273         DO jj = 2, jpjm1
274            DO ji = 2, jpim1   ! vector opt.
275               zbtr = spbtr2(ji,jj) / fse3t(ji,jj,jk)
276               hdivdiff(ji,jj,jk) =   &
277                  (  e2u(ji,jj)*fse3u(ji,jj,jk) * & 
278                  ubdiff(ji,jj,jk) - e2u(ji-1,jj  )* &
279                  fse3u(ji-1,jj  ,jk)  * ubdiff(ji-1,jj  ,jk)       &
280                  + e1v(ji,jj)*fse3v(ji,jj,jk) * &
281                  vbdiff(ji,jj,jk) - e1v(ji  ,jj-1)* &
282                  fse3v(ji  ,jj-1,jk)  * vbdiff(ji  ,jj-1,jk)  ) * zbtr
283            END DO
284         END DO
285
286         DO jj = 1, jpjm1
287            DO ji = 1, jpim1   ! vector opt.
288               zbtr = spbtr3(ji,jj) * fse3f(ji,jj,jk)
289               rotdiff(ji,jj,jk) = (  e2v(ji+1,jj  ) * vbdiff(ji+1,jj  ,jk) - e2v(ji,jj) * vbdiff(ji,jj,jk)    &
290                  &              - e1u(ji  ,jj+1) * ubdiff(ji  ,jj+1,jk) + e1u(ji,jj) * ubdiff(ji,jj,jk)  ) &
291                  &           * fmask(ji,jj,jk) * zbtr
292            END DO
293         END DO
294
295      ENDDO
296
297      !                                                ! ===============
298      DO jk = 1, jpkm1                                 ! Horizontal slab
299         !                                             ! ===============
300         DO jj = 2, jpjm1
301            DO ji = 2, jpim1   ! vector opt.
302               ze2u = rotdiff (ji,jj,jk)
303               ze1v = hdivdiff(ji,jj,jk)
304               ! horizontal diffusive trends
305               zua = - ( ze2u - rotdiff (ji,jj-1,jk)) / ( e2u(ji,jj) * fse3u(ji,jj,jk) )   &
306                  + ( hdivdiff(ji+1,jj,jk) - ze1v      &
307                  ) / e1u(ji,jj)
308
309               zva = + ( ze2u - rotdiff (ji-1,jj,jk)) / ( e1v(ji,jj) * fse3v(ji,jj,jk) )   &
310                  + ( hdivdiff(ji,jj+1,jk) - ze1v    &
311                  ) / e2v(ji,jj)
312
313               ! add it to the general momentum trends
314               ua(ji,jj,jk) = ua(ji,jj,jk) + zua
315               va(ji,jj,jk) = va(ji,jj,jk) + zva
316            END DO
317         END DO
318         !                                             ! ===============
319      END DO                                           !   End of slab
320      !                                                ! ===============
321
322#endif
323
324   END SUBROUTINE Agrif_Sponge_dyn
325
326   SUBROUTINE interptn(tabres,i1,i2,j1,j2,k1,k2)
327      !!---------------------------------------------
328      !!   *** ROUTINE interptn ***
329      !!---------------------------------------------
330#  include "domzgr_substitute.h90"       
331     
332      INTEGER, INTENT(in) :: i1,i2,j1,j2,k1,k2
333      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2), INTENT(inout) :: tabres
334
335      tabres(i1:i2,j1:j2,k1:k2) = tn(i1:i2,j1:j2,k1:k2)
336
337   END SUBROUTINE interptn
338
339   SUBROUTINE interpsn(tabres,i1,i2,j1,j2,k1,k2)
340      !!---------------------------------------------
341      !!   *** ROUTINE interpsn ***
342      !!---------------------------------------------
343#  include "domzgr_substitute.h90"       
344     
345      INTEGER, INTENT(in) :: i1,i2,j1,j2,k1,k2
346      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2), INTENT(inout) :: tabres
347
348      tabres(i1:i2,j1:j2,k1:k2) = sn(i1:i2,j1:j2,k1:k2)
349
350   END SUBROUTINE interpsn
351
352   SUBROUTINE interpun(tabres,i1,i2,j1,j2,k1,k2)
353      !!---------------------------------------------
354      !!   *** ROUTINE interpun ***
355      !!---------------------------------------------
356#  include "domzgr_substitute.h90"       
357     
358      INTEGER, INTENT(in) :: i1,i2,j1,j2,k1,k2
359      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2), INTENT(inout) :: tabres
360
361      tabres(i1:i2,j1:j2,k1:k2) = un(i1:i2,j1:j2,k1:k2)
362
363   END SUBROUTINE interpun
364
365   SUBROUTINE interpvn(tabres,i1,i2,j1,j2,k1,k2)
366      !!---------------------------------------------
367      !!   *** ROUTINE interpvn ***
368      !!---------------------------------------------
369#  include "domzgr_substitute.h90"       
370     
371      INTEGER, INTENT(in) :: i1,i2,j1,j2,k1,k2
372      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2), INTENT(inout) :: tabres
373
374      tabres(i1:i2,j1:j2,k1:k2) = vn(i1:i2,j1:j2,k1:k2)
375
376   END SUBROUTINE interpvn
377
378#else
379CONTAINS
380
381   SUBROUTINE agrif_opa_sponge_empty
382      !!---------------------------------------------
383      !!   *** ROUTINE agrif_OPA_sponge_empty ***
384      !!---------------------------------------------
385      WRITE(*,*)  'agrif_opa_sponge : You should not have seen this print! error?'
386   END SUBROUTINE agrif_opa_sponge_empty
387#endif
388
389END MODULE agrif_opa_sponge
Note: See TracBrowser for help on using the repository browser.