ROMS
Loading...
Searching...
No Matches
ana_sponge.h
Go to the documentation of this file.
1!!
2 SUBROUTINE ana_sponge (ng, tile, model)
3!
4!! git $Id$
5!!================================================= Hernan G. Arango ===
6!! Copyright (c) 2002-2025 The ROMS Group !
7!! Licensed under a MIT/X style license !
8!! See License_ROMS.md !
9!=======================================================================
10! !
11! This subroutine computes spatially varying horizontal mixing !
12! coefficients in sponge areas. The horizontal viscosity and/or !
13! diffusion are increased in sponge areas to supress noise due !
14! open boundary conditions or nesting. !
15! !
16! There are two different ways to code the increased viscosity !
17! and/or diffusion in the sponge areas: !
18! !
19! (1) Rescale the horizontal mixing coefficients computed earlier !
20! in routine "ini_hmixcoef.F" with a nondimentional factor: !
21! !
22! visc2_r(i,j) = ABS(factor(i,j)) * visc2_r(i,j) !
23! !
24! visc2_p(i,j) = 0.25_r8 * ABS(factor(i-1,j-1)+ !
25! factor(i ,j-1)+ !
26! factor(i-1,j )+ !
27! factor(i ,j )) * visc2_p(i,j) !
28! !
29! where factor(i,j) is defined at RHO-points and its values !
30! can be ZERO (no mixing), ONE (same values), or linearly !
31! greater than ONE (sponge are with larger mixing). !
32! !
33! (See Adriatic Sea application below) !
34! !
35! (2) Overwrite the horizontal mixing coefficients computed earlier !
36! in routine "ini_hmixcoef.F" with a new distribution: !
37! !
38! visc2_r(i,j) = my_values(i,j) !
39! !
40! visc2_p(i,j) = my_values(i,j) !
41! !
42! (See US West Coast application below) !
43! !
44! However, !
45! !
46! It is HIGHLY recommended to write the nondimentional spatial !
47! distribution arrays "visc_factor(i,j)" and "diff_factor(i,j)" !
48! into the grid NetCDF file instead of using the analytical code !
49! below. It is very easy to introduce parallel bugs. Also, Users !
50! can plot their spatial distribution and fine tune their values !
51! during at the pre-proccessing stage for a particular application. !
52! !
53! The Metadata for these scale factors in the Grid NetCDF file is !
54! as follows (spherical grid case): !
55! !
56! double visc_factor(eta_rho, xi_rho) !
57! visc_factor:long_name = "horizontal viscosity factor" !
58! visc_factor:valid_min = 0. !
59! visc_factor:coordinates = "lon_rho lat_rho" !
60! !
61! double diff_factor(eta_rho, xi_rho) !
62! diff_factor:long_name = "horizontal diffusivity factor" !
63! diff_factor:valid_min = 0. !
64! diff_factor:coordinates = "lon_rho lat_rho" !
65! !
66!=======================================================================
67!
68 USE mod_param
69 USE mod_ncparam
70!
71! Imported variable declarations.
72!
73 integer, intent(in) :: ng, tile, model
74!
75! Local variable declarations.
76!
77 character (len=*), parameter :: MyFile = &
78 & __FILE__
79!
80#include "tile.h"
81
82 CALL ana_sponge_tile (ng, tile, model, &
83 & lbi, ubi, lbj, ubj, &
84 & imins, imaxs, jmins, jmaxs)
85!
86! Set analytical header file name used.
87!
88#ifdef DISTRIBUTE
89 IF (lanafile) THEN
90#else
91 IF (lanafile.and.(tile.eq.0)) THEN
92#endif
93 ananame( 8)=myfile
94 END IF
95!
96 RETURN
97 END SUBROUTINE ana_sponge
98!
99!***********************************************************************
100 SUBROUTINE ana_sponge_tile (ng, tile, model, &
101 & LBi, UBi, LBj, UBj, &
102 & IminS, ImaxS, JminS, JmaxS)
103!***********************************************************************
104!
105 USE mod_param
106 USE mod_grid
107 USE mod_mixing
108 USE mod_scalars
109!
111#ifdef DISTRIBUTE
113# ifdef SOLVE3D
115# endif
116#endif
117!
118! Imported variable declarations.
119!
120 integer, intent(in) :: ng, tile, model
121 integer, intent(in) :: LBi, UBi, LBj, UBj
122 integer, intent(in) :: IminS, ImaxS, JminS, JmaxS
123!
124! Local variable declarations.
125!
126 integer :: i, itrc, j
127!
128 real(r8) :: cff, innerF, outerF, val, width
129!
130 real(r8), dimension(IminS:ImaxS,JminS:JmaxS) :: factor
131
132#include "set_bounds.h"
133!
134!-----------------------------------------------------------------------
135! Increase horizontal mixing in the sponge areas.
136!-----------------------------------------------------------------------
137
138#if defined ADRIA02
139!
140! Adriatic Sea southern sponge areas.
141!
142 cff=4.0_r8 ! quadruple horizontal mixing
143 width=6.0_r8
144!
145! Set horizontal mixing factor over 6 grid points in the southern
146! boundary and increase linearly its values by four. Otherwise, the
147! horizontal mixing is set to zero.
148!
149 factor(imins:imaxs,jmins:jmaxs)=0.0_r8 ! initialize
150
151 DO i=istrt,iendt
152 DO j=jstrt,min(int(width),jendt)
153 factor(i,j)=1.0_r8+(cff-1.0_r8)*(width-real(j,r8))/width
154 END DO
155 END DO
156
157# if defined UV_VIS2
158 IF (luvsponge(ng)) THEN
159 DO i=istrt,iendt
160 DO j=jstrt,jendt
161 mixing(ng) % visc2_r(i,j)=abs(factor(i,j))* &
162 & mixing(ng) % visc2_r(i,j)
163 END DO
164 END DO
165 DO j=jstrp,jendt
166 DO i=istrp,iendt
167 mixing(ng) % visc2_p(i,j)=0.25_r8*abs(factor(i-1,j-1)+ &
168 & factor(i ,j-1)+ &
169 & factor(i-1,j )+ &
170 & factor(i ,j ))* &
171 & mixing(ng) % visc2_p(i,j)
172 END DO
173 END DO
174 END IF
175# endif
176
177# if defined TS_DIF2
178 DO itrc=1,nt(ng)
179 IF (ltracersponge(itrc,ng)) THEN
180 DO i=istrt,iendt
181 DO j=jstrt,jendt
182 mixing(ng) % diff2(i,j,itrc)=abs(factor(i,j)* &
183 & mixing(ng) % diff2(i,j,itrc)
184 END DO
185 END DO
186 END IF
187 END DO
188# endif
189
190#elif defined WC13
191!
192! US West Coast sponge areas.
193!
194 width=user(1) ! sponge width in grid points
195
196# if defined UV_VIS2
197!
198! Momentum sponge regions: sponge viscosities as in Marchesiello
199! et al 2003.
200!
201 IF (luvsponge(ng)) THEN
202 innerf=visc2(ng) ! inner limit match value
203 outerf=100.0_r8 ! outer limit maximum value
204!
205! Southern edge.
206!
207 DO j=jstrt,min(int(width),jendt)
208 val=innerf+(outerf-innerf)*(width-real(j,r8))/width
209 DO i=istrt,iendt
210 mixing(ng)%visc2_r(i,j)=max(min(val,outerf),innerf)
211 mixing(ng)%visc2_p(i,j)=max(min(val,outerf),innerf)
212 END DO
213 END DO
214!
215! Northern edge.
216!
217 DO j=max(jstrt,mm(ng)+1-int(width)),jendt
218 val=outerf+(innerf-outerf)*real(mm(ng)+1-j,r8)/width
219 DO i=istrt,iendt
220 mixing(ng) % visc2_r(i,j)=max(min(val,outerf),innerf)
221 mixing(ng) % visc2_p(i,j)=max(min(val,outerf),innerf)
222 END DO
223 END DO
224!
225! Western edge.
226!
227 DO i=istrt,min(int(width),iendt)
228 DO j=max(jstrt,i),min(mm(ng)+1-i,jendt)
229 val=innerf+(outerf-innerf)*(width-real(i,r8))/width
230 mixing(ng) % visc2_r(i,j)=max(min(val,outerf),innerf)
231 mixing(ng) % visc2_p(i,j)=max(min(val,outerf),innerf)
232 END DO
233 END DO
234 END IF
235# endif
236
237# if defined TS_DIF2
238!
239! Tracer sponge regions: sponge diffusivities as in Marchesiello
240! et al 2003.
241!
242 DO itrc=1,nt(ng)
243 IF (ltracersponge(itrc,ng)) THEN
244 innerf=tnu2(itrc,ng) ! inner limit match value
245 outerf=50.0_r8 ! outer limit maximum value
246!
247! Southern edge.
248!
249 DO j=jstrt,min(int(width),jendt)
250 val=innerf+(outerf-innerf)*(width-real(j,r8))/width
251 DO i=istrt,iendt
252 mixing(ng) % diff2(i,j,itrc)=max(min(val,outerf),innerf)
253 END DO
254 END DO
255!
256! Northern edge.
257!
258 DO j=max(jstrt,mm(ng)+1-int(width)),jendt
259 val=outerf+(innerf-outerf)*real(mm(ng)+1-j,r8)/width
260 DO i=istrt,iendt
261 mixing(ng) % diff2(i,j,itrc)=max(min(val,outerf),innerf)
262 END DO
263 END DO
264!
265! Western edge.
266!
267 DO i=istrt,min(int(width),iendt)
268 DO j=max(jstrt,i),min(mm(ng)+1-i,jendt)
269 val=innerf+(outerf-innerf)*(width-real(i,r8))/width
270 mixing(ng) % diff2(i,j,itrc)=max(min(val,outerf),innerf)
271 END DO
272 END DO
273 END IF
274 END DO
275# endif
276#endif
277!
278!-----------------------------------------------------------------------
279! Exchange boundary data.
280!-----------------------------------------------------------------------
281!
282!! WARNING: This section is generic for all applications. Please do not
283!! change the code below.
284!!
285#ifdef UV_VIS2
286 IF (luvsponge(ng)) THEN
287 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
288 CALL exchange_r2d_tile (ng, tile, &
289 & lbi, ubi, lbj, ubj, &
290 & mixing(ng) % visc2_r)
291 CALL exchange_p2d_tile (ng, tile, &
292 & lbi, ubi, lbj, ubj, &
293 & mixing(ng) % visc2_p)
294 END IF
295 END IF
296#endif
297
298#ifdef UV_VIS4
299 IF (luvsponge(ng)) THEN
300 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
301 CALL exchange_r2d_tile (ng, tile, &
302 & lbi, ubi, lbj, ubj, &
303 & mixing(ng) % visc4_r)
304 CALL exchange_p2d_tile (ng, tile, &
305 & lbi, ubi, lbj, ubj, &
306 & mixing(ng) % visc4_p)
307 END IF
308 END IF
309#endif
310
311#ifdef SOLVE3D
312# ifdef TS_DIF2
313 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
314 DO itrc=1,nt(ng)
315 IF (ltracersponge(itrc,ng)) THEN
316 CALL exchange_r2d_tile (ng, tile, &
317 & lbi, ubi, lbj, ubj, &
318 & mixing(ng) % diff2(:,:,itrc))
319 END IF
320 END DO
321 END IF
322# endif
323
324# ifdef TS_DIF4
325 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
326 DO itrc=1,nt(ng)
327 IF (ltracersponge(itrc,ng)) THEN
328 CALL exchange_r2d_tile (ng, tile, &
329 & lbi, ubi, lbj, ubj, &
330 & mixing(ng) % diff4(:,:,itrc))
331 END IF
332 END DO
333 END IF
334# endif
335#endif
336
337#ifdef DISTRIBUTE
338!
339# ifdef UV_VIS2
340 IF (luvsponge(ng)) THEN
341 CALL mp_exchange2d (ng, tile, model, 2, &
342 & lbi, ubi, lbj, ubj, &
343 & nghostpoints, &
344 & ewperiodic(ng), nsperiodic(ng), &
345 & mixing(ng) % visc2_r, &
346 & mixing(ng) % visc2_p)
347 END IF
348# endif
349
350# ifdef UV_VIS4
351 IF (luvsponge(ng)) THEN
352 CALL mp_exchange2d (ng, tile, model, 2, &
353 & lbi, ubi, lbj, ubj, &
354 & nghostpoints, &
355 & ewperiodic(ng), nsperiodic(ng), &
356 & mixing(ng) % visc4_r, &
357 & mixing(ng) % visc4_p)
358 END IF
359# endif
360
361# ifdef SOLVE3D
362# ifdef TS_DIF2
363 IF (any(ltracersponge(:,ng))) THEN
364 CALL mp_exchange3d (ng, tile, model, 1, &
365 & lbi, ubi, lbj, ubj, 1, nt(ng), &
366 & nghostpoints, &
367 & ewperiodic(ng), nsperiodic(ng), &
368 & mixing(ng) % diff2)
369 END IF
370# endif
371
372# ifdef TS_DIF4
373 IF (any(ltracersponge(:,ng))) THEN
374 CALL mp_exchange3d (ng, tile, model, 1, &
375 & lbi, ubi, lbj, ubj, 1, nt(ng), &
376 & nghostpoints, &
377 & ewperiodic(ng), nsperiodic(ng), &
378 & mixing(ng) % diff4)
379 END IF
380# endif
381# endif
382#endif
383!
384 RETURN
385 END SUBROUTINE ana_sponge_tile
subroutine ana_sponge(ng, tile, model)
Definition ana_hmixcoef.h:3
subroutine ana_sponge_tile(ng, tile, model, lbi, ubi, lbj, ubj, imins, imaxs, jmins, jmaxs)
subroutine exchange_r2d_tile(ng, tile, lbi, ubi, lbj, ubj, a)
subroutine exchange_p2d_tile(ng, tile, lbi, ubi, lbj, ubj, a)
Definition exchange_2d.F:66
type(t_mixing), dimension(:), allocatable mixing
Definition mod_mixing.F:399
logical lanafile
character(len=256), dimension(39) ananame
integer nghostpoints
Definition mod_param.F:710
integer, dimension(:), allocatable nt
Definition mod_param.F:489
integer, dimension(:), allocatable mm
Definition mod_param.F:456
real(r8), dimension(:,:), allocatable tnu2
logical, dimension(:), allocatable luvsponge
logical, dimension(:), allocatable ewperiodic
logical, dimension(:), allocatable nsperiodic
real(r8), dimension(:), allocatable user
logical, dimension(:,:), allocatable ltracersponge
real(r8), dimension(:), allocatable visc2
subroutine mp_exchange2d(ng, tile, model, nvar, lbi, ubi, lbj, ubj, nghost, ew_periodic, ns_periodic, a, b, c, d)
subroutine mp_exchange3d(ng, tile, model, nvar, lbi, ubi, lbj, ubj, lbk, ubk, nghost, ew_periodic, ns_periodic, a, b, c, d)