18 implicit none ;
private
20 #include <MOM_memory.h>
22 public dense_water_initialize_topography
23 public dense_water_initialize_ts
24 public dense_water_initialize_sponges
26 character(len=40) :: mdl =
"dense_water_initialization"
28 real,
parameter :: default_sill = 0.2
29 real,
parameter :: default_shelf = 0.4
30 real,
parameter :: default_mld = 0.25
35 subroutine dense_water_initialize_topography(D, G, param_file, max_depth)
37 real,
dimension(G%isd:G%ied,G%jsd:G%jed), &
40 real,
intent(in) :: max_depth
43 real,
dimension(5) :: domain_params
44 real :: sill_frac, shelf_frac
48 call get_param(param_file, mdl,
"DENSE_WATER_DOMAIN_PARAMS", domain_params, &
49 "Fractional widths of all the domain sections for the dense water experiment.\n"//&
50 "As a 5-element vector:\n"//&
51 " - open ocean, the section at maximum depth\n"//&
52 " - downslope, the downward overflow slope\n"//&
53 " - sill separating downslope from upslope\n"//&
54 " - upslope, the upward slope accumulating dense water\n"//&
55 " - the shelf in the dense formation region.", &
56 units=
"nondim", fail_if_missing=.true.)
57 call get_param(param_file, mdl,
"DENSE_WATER_SILL_DEPTH", sill_frac, &
58 "Depth of the sill separating downslope from upslope, as fraction of basin depth.", &
59 units=
"nondim", default=default_sill)
60 call get_param(param_file, mdl,
"DENSE_WATER_SHELF_DEPTH", shelf_frac, &
61 "Depth of the shelf region accumulating dense water for overflow, as fraction of basin depth.", &
62 units=
"nondim", default=default_shelf)
66 domain_params(i) = domain_params(i-1) + domain_params(i)
72 x = (g%geoLonT(i,j) - g%west_lon) / g%len_lon
74 if (x <= domain_params(1))
then
77 elseif (x <= domain_params(2))
then
79 d(i,j) = max_depth - (1.0 - sill_frac) * max_depth * &
80 (x - domain_params(1)) / (domain_params(2) - domain_params(1))
81 elseif (x <= domain_params(3))
then
83 d(i,j) = sill_frac * max_depth
84 elseif (x <= domain_params(4))
then
86 d(i,j) = sill_frac * max_depth + (shelf_frac - sill_frac) * max_depth * &
87 (x - domain_params(3)) / (domain_params(4) - domain_params(3))
90 d(i,j) = shelf_frac * max_depth
95 end subroutine dense_water_initialize_topography
98 subroutine dense_water_initialize_ts(G, GV, param_file, eqn_of_state, T, S, h, just_read_params)
102 type(
eos_type),
pointer :: eqn_of_state
103 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(out) :: t
104 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(out) :: s
105 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h
106 logical,
optional,
intent(in) :: just_read_params
109 real :: mld, s_ref, s_range, t_ref
112 integer :: i, j, k, nz
116 just_read = .false. ;
if (
present(just_read_params)) just_read = just_read_params
118 call get_param(param_file, mdl,
"DENSE_WATER_MLD", mld, &
119 "Depth of unstratified mixed layer as a fraction of the water column.", &
120 units=
"nondim", default=default_mld, do_not_log=just_read)
121 call get_param(param_file, mdl,
"S_REF", s_ref,
'Reference salinity', &
122 default=35.0, units=
'1e-3', do_not_log=just_read)
123 call get_param(param_file, mdl,
"T_REF", t_ref,
'Reference temperature', units=
'degC', &
124 fail_if_missing=.not.just_read, do_not_log=just_read)
125 call get_param(param_file, mdl,
"S_RANGE", s_range,
'Initial salinity range', &
126 units=
'1e-3', default=2.0, do_not_log=just_read)
128 if (just_read)
return
138 zmid = zi + 0.5 * h(i,j,k) / (gv%Z_to_H * g%max_depth)
145 s(i,j,k) = s_ref + s_range * (zmid - mld) / (1.0 - mld)
148 zi = zi + h(i,j,k) / (gv%Z_to_H * g%max_depth)
152 end subroutine dense_water_initialize_ts
155 subroutine dense_water_initialize_sponges(G, GV, US, tv, param_file, use_ALE, CSp, ACSp)
161 logical,
intent(in) :: use_ale
165 real :: west_sponge_time_scale, east_sponge_time_scale
166 real :: west_sponge_width, east_sponge_width
168 real,
dimension(SZI_(G),SZJ_(G)) :: idamp
169 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h
170 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: t
171 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: s
172 real,
dimension(SZK_(GV)+1) :: e0, eta1d
174 integer :: i, j, k, nz
175 real :: x, zi, zmid, dist
176 real :: mld, s_ref, s_range, s_dense, t_ref, sill_height
180 call get_param(param_file, mdl,
"DENSE_WATER_WEST_SPONGE_TIME_SCALE", west_sponge_time_scale, &
181 "The time scale on the west (outflow) of the domain for restoring. If zero, the sponge is disabled.", &
182 units=
"s", default=0., scale=us%s_to_T)
183 call get_param(param_file, mdl,
"DENSE_WATER_WEST_SPONGE_WIDTH", west_sponge_width, &
184 "The fraction of the domain in which the western (outflow) sponge is active.", &
185 units=
"nondim", default=0.1)
186 call get_param(param_file, mdl,
"DENSE_WATER_EAST_SPONGE_TIME_SCALE", east_sponge_time_scale, &
187 "The time scale on the east (outflow) of the domain for restoring. If zero, the sponge is disabled.", &
188 units=
"s", default=0., scale=us%s_to_T)
189 call get_param(param_file, mdl,
"DENSE_WATER_EAST_SPONGE_WIDTH", east_sponge_width, &
190 "The fraction of the domain in which the eastern (outflow) sponge is active.", &
191 units=
"nondim", default=0.1)
193 call get_param(param_file, mdl,
"DENSE_WATER_EAST_SPONGE_SALT", s_dense, &
194 "Salt anomaly of the dense water being formed in the overflow region.", &
195 units=
"1e-3", default=4.0)
197 call get_param(param_file, mdl,
"DENSE_WATER_MLD", mld, default=default_mld, do_not_log=.true.)
198 call get_param(param_file, mdl,
"DENSE_WATER_SILL_HEIGHT", sill_height, default=default_sill, do_not_log=.true.)
200 call get_param(param_file, mdl,
"S_REF", s_ref, default=35.0, do_not_log=.true.)
201 call get_param(param_file, mdl,
"S_RANGE", s_range, do_not_log=.true.)
202 call get_param(param_file, mdl,
"T_REF", t_ref, do_not_log=.true.)
205 if (west_sponge_time_scale <= 0. .and. east_sponge_time_scale <= 0.)
return
212 if (g%mask2dT(i,j) > 0.)
then
214 x = (g%geoLonT(i,j) - g%west_lon) / g%len_lon
216 if (west_sponge_time_scale > 0. .and. x < west_sponge_width)
then
217 dist = 1. - x / west_sponge_width
219 idamp(i,j) = 1. / west_sponge_time_scale * max(0., min(1., dist))
220 elseif (east_sponge_time_scale > 0. .and. x > (1. - east_sponge_width))
then
221 dist = 1. - (1. - x) / east_sponge_width
222 idamp(i,j) = 1. / east_sponge_time_scale * max(0., min(1., dist))
231 e0(k) = -g%max_depth * (real(k - 1) / real(nz))
233 e0(nz+1) = -g%max_depth
237 eta1d(nz+1) = -g%bathyT(i,j)
241 if (eta1d(k) < (eta1d(k+1) + gv%Angstrom_Z))
then
243 eta1d(k) = eta1d(k+1) + gv%Angstrom_Z
244 h(i,j,k) = gv%Angstrom_H
246 h(i,j,k) = gv%Z_to_H * (eta1d(k) - eta1d(k+1))
262 x = (g%geoLonT(i,j) - g%west_lon) / g%len_lon
265 zmid = zi + 0.5 * h(i,j,k) / (gv%Z_to_H * g%max_depth)
267 if (x > (1. - east_sponge_width))
then
269 s(i,j,k) = s_ref + s_dense
273 s(i,j,k) = s_ref + s_range * (zmid - mld) / (1.0 - mld)
276 zi = zi + h(i,j,k) / (gv%Z_to_H * g%max_depth)
284 call mom_error(fatal,
"dense_water_initialize_sponges: trying to use non ALE sponge")
286 end subroutine dense_water_initialize_sponges