26 implicit none ;
private 28 #include <MOM_memory.h> 35 real,
dimension(:,:,:),
pointer :: p => null()
38 real,
dimension(:,:),
pointer :: p => null()
45 integer :: isc, iec, jsc, jec
46 integer :: iscb, iecb, jscb, jecb
47 integer :: isd, ied, jsd, jed
49 integer :: num_col, num_col_u, num_col_v
54 integer,
pointer :: col_i(:) => null()
55 integer,
pointer :: col_j(:) => null()
56 integer,
pointer :: col_i_u(:) => null()
57 integer,
pointer :: col_j_u(:) => null()
58 integer,
pointer :: col_i_v(:) => null()
59 integer,
pointer :: col_j_v(:) => null()
61 real,
pointer :: iresttime_col(:) => null()
63 real,
pointer :: iresttime_col_u(:) => null()
64 real,
pointer :: iresttime_col_v(:) => null()
66 type(
p3d) :: var(max_fields_)
67 type(
p2d) :: ref_val(max_fields_)
68 real,
dimension(:,:),
pointer :: ref_val_u => null()
69 real,
dimension(:,:),
pointer :: ref_val_v => null()
70 real,
dimension(:,:,:),
pointer :: var_u => null()
72 real,
dimension(:,:,:),
pointer :: var_v => null()
74 real,
pointer :: ref_h(:,:) => null()
75 real,
pointer :: ref_hu(:,:) => null()
76 real,
pointer :: ref_hv(:,:) => null()
94 integer,
intent(in) :: nz_data
96 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: Iresttime
97 real,
dimension(SZI_(G),SZJ_(G),nz_data),
intent(in) :: data_h
103 #include "version_variable.h" 104 character(len=40) :: mdl =
"MOM_sponge" 105 logical :: use_sponge
106 real,
dimension(SZIB_(G),SZJ_(G),nz_data) :: data_hu
107 real,
dimension(SZI_(G),SZJB_(G),nz_data) :: data_hv
108 real,
dimension(SZIB_(G),SZJ_(G)) :: Iresttime_u
109 real,
dimension(SZI_(G),SZJB_(G)) :: Iresttime_v
110 logical :: bndExtrapolation = .true.
111 integer :: i, j, k, col, total_sponge_cols, total_sponge_cols_u, total_sponge_cols_v
112 character(len=10) :: remapScheme
113 if (
associated(cs))
then 114 call mom_error(warning,
"initialize_sponge called with an associated "// &
115 "control structure.")
121 call get_param(param_file, mdl,
"SPONGE", use_sponge, &
122 "If true, sponges may be applied anywhere in the domain. \n"//&
123 "The exact location and properties of those sponges are \n"//&
124 "specified from MOM_initialization.F90.", default=.false.)
126 if (.not.use_sponge)
return 130 call get_param(param_file, mdl,
"SPONGE_UV", cs%sponge_uv, &
131 "Apply sponges in u and v, in addition to tracers.", &
134 call get_param(param_file, mdl,
"REMAPPING_SCHEME", remapscheme, &
135 "This sets the reconstruction scheme used \n"//&
136 " for vertical remapping for all variables.", &
137 default=
"PLM", do_not_log=.true.)
139 call get_param(param_file, mdl,
"BOUNDARY_EXTRAPOLATION", bndextrapolation, &
140 "When defined, a proper high-order reconstruction \n"//&
141 "scheme is used within boundary cells rather \n"// &
142 "than PCM. E.g., if PPM is used for remapping, a \n" //&
143 "PPM reconstruction will also be used within boundary cells.", &
144 default=.false., do_not_log=.true.)
147 cs%isc = g%isc ; cs%iec = g%iec ; cs%jsc = g%jsc ; cs%jec = g%jec
148 cs%isd = g%isd ; cs%ied = g%ied ; cs%jsd = g%jsd ; cs%jed = g%jed
149 cs%iscB = g%iscB ; cs%iecB = g%iecB; cs%jscB = g%jscB ; cs%jecB = g%jecB
152 cs%num_col = 0 ; cs%fldno = 0
153 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
154 if ((iresttime(i,j)>0.0) .and. (g%mask2dT(i,j)>0)) &
155 cs%num_col = cs%num_col + 1
159 if (cs%num_col > 0)
then 161 allocate(cs%Iresttime_col(cs%num_col)) ; cs%Iresttime_col = 0.0
162 allocate(cs%col_i(cs%num_col)) ; cs%col_i = 0
163 allocate(cs%col_j(cs%num_col)) ; cs%col_j = 0
167 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
168 if ((iresttime(i,j)>0.0) .and. (g%mask2dT(i,j)>0))
then 169 cs%col_i(col) = i ; cs%col_j(col) = j
170 cs%Iresttime_col(col) = iresttime(i,j)
177 allocate(cs%Ref_h(cs%nz_data,cs%num_col))
178 do col=1,cs%num_col ;
do k=1,cs%nz_data
179 cs%Ref_h(k,col) = data_h(cs%col_i(col),cs%col_j(col),k)
184 total_sponge_cols = cs%num_col
185 call sum_across_pes(total_sponge_cols)
190 call log_param(param_file, mdl,
"!Total sponge columns at h points", total_sponge_cols, &
191 "The total number of columns where sponges are applied at h points.")
193 if (cs%sponge_uv)
then 196 do j=cs%jsc,cs%jec;
do i=cs%iscB,cs%iecB
197 data_hu(i,j,:) = 0.5 * (data_h(i,j,:) + data_h(i+1,j,:))
198 iresttime_u(i,j) = 0.5 * (iresttime(i,j) + iresttime(i+1,j))
199 if ((iresttime_u(i,j)>0.0) .and. (g%mask2dCu(i,j)>0)) &
200 cs%num_col_u = cs%num_col_u + 1
203 if (cs%num_col_u > 0)
then 205 allocate(cs%Iresttime_col_u(cs%num_col_u)) ; cs%Iresttime_col_u = 0.0
206 allocate(cs%col_i_u(cs%num_col_u)) ; cs%col_i_u = 0
207 allocate(cs%col_j_u(cs%num_col_u)) ; cs%col_j_u = 0
211 do j=cs%jsc,cs%jec ;
do i=cs%iscB,cs%iecB
212 if ((iresttime_u(i,j)>0.0) .and. (g%mask2dCu(i,j)>0))
then 213 cs%col_i_u(col) = i ; cs%col_j_u(col) = j
214 cs%Iresttime_col_u(col) = iresttime_u(i,j)
220 allocate(cs%Ref_hu(cs%nz_data,cs%num_col_u))
221 do col=1,cs%num_col_u ;
do k=1,cs%nz_data
222 cs%Ref_hu(k,col) = data_hu(cs%col_i_u(col),cs%col_j_u(col),k)
226 total_sponge_cols_u = cs%num_col_u
227 call sum_across_pes(total_sponge_cols_u)
228 call log_param(param_file, mdl,
"!Total sponge columns at u points", total_sponge_cols_u, &
229 "The total number of columns where sponges are applied at u points.")
233 do j=cs%jscB,cs%jecB;
do i=cs%isc,cs%iec
234 data_hu(i,j,:) = 0.5 * (data_h(i,j,:) + data_h(i,j+1,:))
235 iresttime_v(i,j) = 0.5 * (iresttime(i,j) + iresttime(i,j+1))
236 if ((iresttime_v(i,j)>0.0) .and. (g%mask2dCv(i,j)>0)) &
237 cs%num_col_v = cs%num_col_v + 1
240 if (cs%num_col_v > 0)
then 242 allocate(cs%Iresttime_col_v(cs%num_col_v)) ; cs%Iresttime_col_v = 0.0
243 allocate(cs%col_i_v(cs%num_col_v)) ; cs%col_i_v = 0
244 allocate(cs%col_j_v(cs%num_col_v)) ; cs%col_j_v = 0
248 do j=cs%jscB,cs%jecB ;
do i=cs%isc,cs%iec
249 if ((iresttime_v(i,j)>0.0) .and. (g%mask2dCv(i,j)>0))
then 250 cs%col_i_v(col) = i ; cs%col_j_v(col) = j
251 cs%Iresttime_col_v(col) = iresttime_v(i,j)
257 allocate(cs%Ref_hv(cs%nz_data,cs%num_col_v))
258 do col=1,cs%num_col_v ;
do k=1,cs%nz_data
259 cs%Ref_hv(k,col) = data_hv(cs%col_i_v(col),cs%col_j_v(col),k)
263 total_sponge_cols_v = cs%num_col_v
264 call sum_across_pes(total_sponge_cols_v)
265 call log_param(param_file, mdl,
"!Total sponge columns at v points", total_sponge_cols_v, &
266 "The total number of columns where sponges are applied at v points.")
274 type(time_type),
target,
intent(in) :: Time
275 type(ocean_grid_type),
intent(in) :: G
276 type(diag_ctrl),
target,
intent(inout) :: diag
279 if (.not.
associated(cs))
return 288 type(ocean_grid_type),
intent(in) :: G
290 real,
dimension(SZI_(G),SZJ_(G),CS%nz_data),
intent(in) :: sp_val
291 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
target,
intent(in) :: f_ptr
294 character(len=256) :: mesg
296 if (.not.
associated(cs))
return 298 cs%fldno = cs%fldno + 1
300 if (cs%fldno > max_fields_)
then 301 write(mesg,
'("Increase MAX_FIELDS_ to at least ",I3," in MOM_memory.h or decrease & 302 &the number of fields to be damped in the call to & 303 &initialize_sponge." )') cs%fldno
304 call mom_error(fatal,
"set_up_ALE_sponge_field: "//mesg)
308 allocate(cs%Ref_val(cs%fldno)%p(cs%nz_data,cs%num_col))
309 cs%Ref_val(cs%fldno)%p(:,:) = 0.0
312 cs%Ref_val(cs%fldno)%p(k,col) = sp_val(cs%col_i(col),cs%col_j(col),k)
316 cs%var(cs%fldno)%p => f_ptr
323 type(ocean_grid_type),
intent(in) :: G
325 real,
dimension(SZIB_(G),SZJ_(G),CS%nz_data),
intent(in) :: u_val
326 real,
dimension(SZI_(G),SZJB_(G),CS%nz_data),
intent(in) :: v_val
327 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
target,
intent(in) :: u_ptr
328 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
target,
intent(in) :: v_ptr
331 character(len=256) :: mesg
333 if (.not.
associated(cs))
return 336 allocate(cs%Ref_val_u(cs%nz_data,cs%num_col_u))
337 cs%Ref_val_u(:,:) = 0.0
338 do col=1,cs%num_col_u
340 cs%Ref_val_u(k,col) = u_val(cs%col_i_u(col),cs%col_j_u(col),k)
346 allocate(cs%Ref_val_v(cs%nz_data,cs%num_col_v))
347 cs%Ref_val_v(:,:) = 0.0
348 do col=1,cs%num_col_v
350 cs%Ref_val_v(k,col) = v_val(cs%col_i_v(col),cs%col_j_v(col),k)
360 type(ocean_grid_type),
intent(inout) :: G
361 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: h
362 real,
intent(in) :: dt
368 real :: tmp_val1(cs%nz)
369 real :: tmp_val2(cs%nz_data)
370 real :: hu(szib_(g), szj_(g), szk_(g))
371 real :: hv(szi_(g), szjb_(g), szk_(g))
372 integer :: c, m, nkmb, i, j, k, is, ie, js, je, nz
373 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
375 if (.not.
associated(cs))
return 380 i = cs%col_i(c) ; j = cs%col_j(c)
381 damp = dt*cs%Iresttime_col(c)
382 i1pdamp = 1.0 / (1.0 + damp)
384 tmp_val2(1:cs%nz_data) = cs%Ref_val(m)%p(1:cs%nz_data,c)
385 call remapping_core_h(cs%remap_cs, &
386 cs%nz_data, cs%Ref_h(:,c), tmp_val2, &
387 cs%nz, h(i,j,:), tmp_val1)
390 cs%var(m)%p(i,j,:) = i1pdamp * &
391 (cs%var(m)%p(i,j,:) + tmp_val1 * damp)
404 if (cs%sponge_uv)
then 407 do j=cs%jsc,cs%jec;
do i=cs%iscB,cs%iecB;
do k=1,nz
408 hu(i,j,k) = 0.5 * (h(i,j,k) + h(i+1,j,k))
412 i = cs%col_i_u(c) ; j = cs%col_j_u(c)
413 damp = dt*cs%Iresttime_col_u(c)
414 i1pdamp = 1.0 / (1.0 + damp)
415 tmp_val2(1:cs%nz_data) = cs%Ref_val_u(1:cs%nz_data,c)
416 call remapping_core_h(cs%remap_cs, &
417 cs%nz_data, cs%Ref_hu(:,c), tmp_val2, &
418 cs%nz, hu(i,j,:), tmp_val1)
421 cs%var_u(i,j,:) = i1pdamp * (cs%var_u(i,j,:) + tmp_val1 * damp)
425 do j=cs%jscB,cs%jecB;
do i=cs%isc,cs%iec;
do k=1,nz
426 hv(i,j,k) = 0.5 * (h(i,j,k) + h(i,j+1,k))
430 i = cs%col_i_v(c) ; j = cs%col_j_v(c)
431 damp = dt*cs%Iresttime_col_v(c)
432 i1pdamp = 1.0 / (1.0 + damp)
433 tmp_val2(1:cs%nz_data) = cs%Ref_val_v(1:cs%nz_data,c)
434 call remapping_core_h(cs%remap_cs, &
435 cs%nz_data, cs%Ref_hv(:,c), tmp_val2, &
436 cs%nz, hv(i,j,:), tmp_val1)
438 cs%var_v(i,j,:) = i1pdamp * (cs%var_v(i,j,:) + tmp_val1 * damp)
452 if (.not.
associated(cs))
return 454 if (
associated(cs%col_i))
deallocate(cs%col_i)
455 if (
associated(cs%col_i_u))
deallocate(cs%col_i_u)
456 if (
associated(cs%col_i_v))
deallocate(cs%col_i_v)
457 if (
associated(cs%col_j))
deallocate(cs%col_j)
458 if (
associated(cs%col_j_u))
deallocate(cs%col_j_u)
459 if (
associated(cs%col_j_v))
deallocate(cs%col_j_v)
461 if (
associated(cs%Iresttime_col))
deallocate(cs%Iresttime_col)
462 if (
associated(cs%Iresttime_col_u))
deallocate(cs%Iresttime_col_u)
463 if (
associated(cs%Iresttime_col_v))
deallocate(cs%Iresttime_col_v)
466 if (
associated(cs%Ref_val(cs%fldno)%p))
deallocate(cs%Ref_val(cs%fldno)%p)
subroutine, public ale_sponge_end(CS)
GMM: I could not find where sponge_end is being called, but I am keeping.
subroutine, public apply_ale_sponge(h, dt, G, CS)
This subroutine applies damping to the layers thicknesses, temp, salt and a variety of tracers for ev...
Ocean grid type. See mom_grid for details.
Provides the ocean grid type.
Provides column-wise vertical remapping functions.
subroutine, public set_up_ale_sponge_field(sp_val, G, f_ptr, CS)
This subroutine stores the reference profile at h points for the variable.
This module contains the routines used to apply sponge layers when using the ALE mode. Applying sponges requires the following: (1) initialize_ALE_sponge (2) set_up_ALE_sponge_field (tracers) and set_up_ALE_sponge_vel_field (vel) (3) apply_ALE_sponge (4) init_ALE_sponge_diags (not being used for now) (5) ALE_sponge_end (not being used for now)
SPONGE control structure.
Container for remapping parameters.
subroutine, public global_i_mean(array, i_mean, G, mask)
logical function, public is_root_pe()
subroutine, public set_up_ale_sponge_vel_field(u_val, v_val, G, u_ptr, v_ptr, CS)
This subroutine stores the reference profile at uand v points for the variable.
subroutine, public initialize_ale_sponge(Iresttime, data_h, nz_data, G, param_file, CS)
This subroutine determines the number of points which are within.
subroutine, public init_ale_sponge_diags(Time, G, diag, CS)
Initialize diagnostics for the ALE_sponge module.
subroutine, public remapping_core_h(CS, n0, h0, u0, n1, h1, u1)
Remaps column of values u0 on grid h0 to grid h1 assuming the top edge is aligned.
subroutine, public initialize_remapping(CS, remapping_scheme, boundary_extrapolation, check_reconstruction, check_remapping, force_bounds_in_subcell)
Constructor for remapping control structure.
subroutine, public mom_error(level, message, all_print)