18 use regrid_consts,
only : coordinatemode, default_coordinate_mode
23 implicit none ;
private
25 #include <MOM_memory.h>
27 character(len=40) :: mdl =
"dumbbell_initialization"
29 public dumbbell_initialize_topography
30 public dumbbell_initialize_thickness
31 public dumbbell_initialize_temperature_salinity
32 public dumbbell_initialize_sponges
42 subroutine dumbbell_initialize_topography( D, G, param_file, max_depth )
44 real,
dimension(G%isd:G%ied,G%jsd:G%jed), &
47 real,
intent(in) :: max_depth
51 real :: x, y, delta, dblen, dbfrac
54 call get_param(param_file, mdl,
"DUMBBELL_LEN",dblen, &
55 'Lateral Length scale for dumbbell.',&
56 units=
'k', default=600., do_not_log=.false.)
57 call get_param(param_file, mdl,
"DUMBBELL_FRACTION",dbfrac, &
58 'Meridional fraction for narrow part of dumbbell.',&
59 units=
'nondim', default=0.5, do_not_log=.false.)
60 call get_param(param_file, mdl,
"DUMBBELL_ROTATION", dbrotate, &
61 'Logical for rotation of dumbbell domain.',&
62 units=
'nondim', default=.false., do_not_log=.false.)
64 if (g%x_axis_units ==
'm')
then
69 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
71 x = ( g%geoLonT(i,j) ) / g%len_lon
72 y = ( g%geoLatT(i,j) ) / dblen
74 if ((y>=-0.25 .and. y<=0.25) .and. (x <= -0.5*dbfrac .or. x >= 0.5*dbfrac))
then
79 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
81 x = ( g%geoLonT(i,j) ) / dblen
82 y = ( g%geoLatT(i,j) ) / g%len_lat
84 if ((x>=-0.25 .and. x<=0.25) .and. (y <= -0.5*dbfrac .or. y >= 0.5*dbfrac))
then
90 end subroutine dumbbell_initialize_topography
93 subroutine dumbbell_initialize_thickness ( h, G, GV, US, param_file, just_read_params)
97 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
101 logical,
optional,
intent(in) :: just_read_params
104 real :: e0(szk_(g)+1)
106 real :: eta1d(szk_(g)+1)
108 real :: min_thickness
109 real :: s_surf, s_range, s_ref, s_light, s_dense
110 real :: eta_ic_quanta
112 # include "version_variable.h"
113 character(len=20) :: verticalcoordinate
115 integer :: i, j, k, is, ie, js, je, nz
117 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
119 just_read = .false. ;
if (
present(just_read_params)) just_read = just_read_params
121 if (.not.just_read) &
122 call mom_mesg(
"MOM_initialization.F90, initialize_thickness_uniform: setting thickness")
124 if (.not.just_read)
call log_version(param_file, mdl, version,
"")
125 call get_param(param_file, mdl,
"MIN_THICKNESS", min_thickness, &
126 'Minimum thickness for layer',&
127 units=
'm', default=1.0e-3, do_not_log=just_read, scale=us%m_to_Z)
128 call get_param(param_file, mdl,
"REGRIDDING_COORDINATE_MODE", verticalcoordinate, &
129 default=default_coordinate_mode, do_not_log=just_read)
142 select case ( coordinatemode(verticalcoordinate) )
144 case ( regridding_layer, regridding_rho )
145 call get_param(param_file, mdl,
"INITIAL_SSS", s_surf, default=34., do_not_log=.true.)
146 call get_param(param_file, mdl,
"INITIAL_S_RANGE", s_range, default=2., do_not_log=.true.)
147 call get_param(param_file, mdl,
"S_REF", s_ref, default=35.0, do_not_log=.true.)
148 call get_param(param_file, mdl,
"TS_RANGE_S_LIGHT", s_light, default = s_ref, do_not_log=.true.)
149 call get_param(param_file, mdl,
"TS_RANGE_S_DENSE", s_dense, default = s_ref, do_not_log=.true.)
150 call get_param(param_file, mdl,
"INTERFACE_IC_QUANTA", eta_ic_quanta, &
151 "The granularity of initial interface height values "//&
152 "per meter, to avoid sensivity to order-of-arithmetic changes.", &
153 default=2048.0, units=
"m-1", scale=us%Z_to_m, do_not_log=just_read)
154 if (just_read)
return
163 e0(k) = - g%max_depth * ( ( s_light - s_surf ) + ( s_dense - s_light ) * &
164 ( (real(k)-1.5) / real(nz-1) ) ) / s_range
166 if (eta_ic_quanta > 0.0) &
167 e0(k) = nint(eta_ic_quanta*e0(k)) / eta_ic_quanta
168 e0(k) = min(real(1-k)*gv%Angstrom_Z, e0(k))
169 e0(k) = max(-g%max_depth, e0(k))
171 do j=js,je ;
do i=is,ie
172 eta1d(nz+1) = -g%bathyT(i,j)
175 if (eta1d(k) < (eta1d(k+1) + gv%Angstrom_Z))
then
176 eta1d(k) = eta1d(k+1) + gv%Angstrom_Z
177 h(i,j,k) = gv%Angstrom_H
179 h(i,j,k) = gv%Z_to_H * (eta1d(k) - eta1d(k+1))
184 case ( regridding_zstar )
185 if (just_read)
return
186 do j=js,je ;
do i=is,ie
187 eta1d(nz+1) = -g%bathyT(i,j)
189 eta1d(k) = -g%max_depth * real(k-1) / real(nz)
190 if (eta1d(k) < (eta1d(k+1) + min_thickness))
then
191 eta1d(k) = eta1d(k+1) + min_thickness
192 h(i,j,k) = gv%Z_to_H * min_thickness
194 h(i,j,k) = gv%Z_to_H * (eta1d(k) - eta1d(k+1))
199 case ( regridding_sigma )
200 if (just_read)
return
201 do j=js,je ;
do i=is,ie
202 h(i,j,:) = gv%Z_to_H * g%bathyT(i,j) / dfloat(nz)
207 end subroutine dumbbell_initialize_thickness
210 subroutine dumbbell_initialize_temperature_salinity ( T, S, h, G, GV, param_file, &
211 eqn_of_state, just_read_params)
214 real,
dimension(SZI_(G),SZJ_(G), SZK_(G)),
intent(out) :: t
215 real,
dimension(SZI_(G),SZJ_(G), SZK_(G)),
intent(out) :: s
216 real,
dimension(SZI_(G),SZJ_(G), SZK_(G)),
intent(in) :: h
218 type(
eos_type),
pointer :: eqn_of_state
219 logical,
optional,
intent(in) :: just_read_params
223 integer :: i, j, k, is, ie, js, je, nz, k_light
224 real :: xi0, xi1, dxi, r, s_surf, t_surf, s_range, t_range
226 real :: t_ref, t_light, t_dense, s_ref, s_light, s_dense, a1, frac_dense, k_frac, res_rat
229 character(len=20) :: verticalcoordinate, density_profile
231 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
233 just_read = .false. ;
if (
present(just_read_params)) just_read = just_read_params
237 call get_param(param_file, mdl,
"REGRIDDING_COORDINATE_MODE", verticalcoordinate, &
238 default=default_coordinate_mode, do_not_log=just_read)
239 call get_param(param_file, mdl,
"INITIAL_DENSITY_PROFILE", density_profile, &
240 'Initial profile shape. Valid values are "linear", "parabolic" '// &
241 'and "exponential".', default=
'linear', do_not_log=just_read)
242 call get_param(param_file, mdl,
"DUMBBELL_SREF", s_surf, &
243 'DUMBBELL REFERENCE SALINITY', units=
'1e-3', default=34., do_not_log=just_read)
244 call get_param(param_file, mdl,
"DUMBBELL_S_RANGE", s_range, &
245 'DUMBBELL salinity range (right-left)', units=
'1e-3', &
246 default=2., do_not_log=just_read)
247 call get_param(param_file, mdl,
"DUMBBELL_LEN",dblen, &
248 'Lateral Length scale for dumbbell ',&
249 units=
'k', default=600., do_not_log=just_read)
250 call get_param(param_file, mdl,
"DUMBBELL_ROTATION", dbrotate, &
251 'Logical for rotation of dumbbell domain.',&
252 units=
'nondim', default=.false., do_not_log=just_read)
254 if (g%x_axis_units ==
'm')
then
263 x = ( g%geoLatT(i,j) ) / dblen
265 x = ( g%geoLonT(i,j) ) / dblen
272 s(i,j,k)=s_surf + 0.5*s_range
277 s(i,j,k)=s_surf - 0.5*s_range
284 end subroutine dumbbell_initialize_temperature_salinity
287 subroutine dumbbell_initialize_sponges(G, GV, US, tv, param_file, use_ALE, CSp, ACSp)
293 logical,
intent(in) :: use_ale
297 real :: sponge_time_scale
299 real,
dimension(SZI_(G),SZJ_(G)) :: idamp
300 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h, t, s
301 real,
dimension(SZK_(GV)+1) :: e0, eta1d
303 integer :: i, j, k, nz
304 real :: x, zi, zmid, dist, min_thickness, dblen
305 real :: mld, s_ref, s_range, s_dense, t_ref, sill_height
308 call get_param(param_file, mdl,
"DUMBBELL_LEN",dblen, &
309 'Lateral Length scale for dumbbell ',&
310 units=
'k', default=600., do_not_log=.true.)
311 call get_param(param_file, mdl,
"DUMBBELL_ROTATION", dbrotate, &
312 'Logical for rotation of dumbbell domain.',&
313 units=
'nondim', default=.false., do_not_log=.true.)
315 if (g%x_axis_units ==
'm')
then
321 call get_param(param_file, mdl,
"DUMBBELL_SPONGE_TIME_SCALE", sponge_time_scale, &
322 "The time scale in the reservoir for restoring. If zero, the sponge is disabled.", &
323 units=
"s", default=0., scale=us%s_to_T)
324 call get_param(param_file, mdl,
"DUMBBELL_SREF", s_ref, do_not_log=.true.)
325 call get_param(param_file, mdl,
"DUMBBELL_S_RANGE", s_range, do_not_log=.true.)
326 call get_param(param_file, mdl,
"MIN_THICKNESS", min_thickness, &
327 'Minimum thickness for layer',&
328 units=
'm', default=1.0e-3, do_not_log=.true., scale=us%m_to_Z)
331 if (sponge_time_scale <= 0.)
return
338 if (g%mask2dT(i,j) > 0.)
then
342 x = ( g%geoLatT(i,j) ) / dblen
344 x = ( g%geoLonT(i,j) ) / dblen
346 if (x > 0.25 .or. x < -0.25)
then
348 idamp(i,j) = 1. / sponge_time_scale
356 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
357 eta1d(nz+1) = -g%bathyT(i,j)
359 eta1d(k) = -g%max_depth * real(k-1) / real(nz)
360 if (eta1d(k) < (eta1d(k+1) + min_thickness))
then
361 eta1d(k) = eta1d(k+1) + min_thickness
362 h(i,j,k) = gv%Z_to_H * min_thickness
364 h(i,j,k) = gv%Z_to_H * (eta1d(k) - eta1d(k+1))
375 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
379 x = ( g%geoLatT(i,j) ) / dblen
381 x = ( g%geoLonT(i,j) ) / dblen
385 s(i,j,k)=s_ref + 0.5*s_range
390 s(i,j,k)=s_ref - 0.5*s_range
398 end subroutine dumbbell_initialize_sponges