22 implicit none ;
private 24 #include <MOM_memory.h> 26 public dome_initialize_topography
27 public dome_initialize_thickness
28 public dome_initialize_sponges
29 public dome_set_obc_data
40 subroutine dome_initialize_topography(D, G, param_file, max_depth, US)
42 real,
dimension(G%isd:G%ied,G%jsd:G%jed), &
45 real,
intent(in) :: max_depth
52 # include "version_variable.h" 53 character(len=40) :: mdl =
"DOME_initialize_topography" 54 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
55 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
56 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
58 call mom_mesg(
" DOME_initialization.F90, DOME_initialize_topography: setting topography", 5)
60 m_to_z = 1.0 ;
if (
present(us)) m_to_z = us%m_to_Z
63 call get_param(param_file, mdl,
"MINIMUM_DEPTH", min_depth, &
64 "The minimum depth of the ocean.", units=
"m", default=0.0, scale=m_to_z)
66 do j=js,je ;
do i=is,ie
67 if (g%geoLatT(i,j) < 600.0)
then 68 if (g%geoLatT(i,j) < 300.0)
then 71 d(i,j) = max_depth - 10.0*m_to_z * (g%geoLatT(i,j)-300.0)
74 if ((g%geoLonT(i,j) > 1000.0) .AND. (g%geoLonT(i,j) < 1100.0))
then 77 d(i,j) = 0.5*min_depth
81 if (d(i,j) > max_depth) d(i,j) = max_depth
82 if (d(i,j) < min_depth) d(i,j) = 0.5*min_depth
85 end subroutine dome_initialize_topography
90 subroutine dome_initialize_thickness(h, G, GV, param_file, just_read_params)
93 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
97 logical,
optional,
intent(in) :: just_read_params
100 real :: e0(szk_(gv)+1)
102 real :: eta1D(szk_(gv)+1)
105 character(len=40) :: mdl =
"DOME_initialize_thickness" 106 integer :: i, j, k, is, ie, js, je, nz
108 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
110 just_read = .false. ;
if (
present(just_read_params)) just_read = just_read_params
112 if (just_read)
return 114 call mom_mesg(
" DOME_initialization.F90, DOME_initialize_thickness: setting thickness", 5)
118 e0(k) = -g%max_depth * (
real(k-1)-0.5)/
real(nz-1)
121 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
127 eta1d(nz+1) = -g%bathyT(i,j)
130 if (eta1d(k) < (eta1d(k+1) + gv%Angstrom_Z))
then 131 eta1d(k) = eta1d(k+1) + gv%Angstrom_Z
132 h(i,j,k) = gv%Angstrom_H
134 h(i,j,k) = gv%Z_to_H * (eta1d(k) - eta1d(k+1))
139 end subroutine dome_initialize_thickness
148 subroutine dome_initialize_sponges(G, GV, US, tv, PF, CSp)
160 real :: eta(szi_(g),szj_(g),szk_(g)+1)
161 real :: temp(szi_(g),szj_(g),szk_(g))
162 real :: Idamp(szi_(g),szj_(g))
166 real :: damp, damp_new
168 character(len=40) :: mdl =
"DOME_initialize_sponges" 169 integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
171 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
172 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
174 eta(:,:,:) = 0.0 ; temp(:,:,:) = 0.0 ; idamp(:,:) = 0.0
182 call get_param(pf, mdl,
"MINIMUM_DEPTH", min_depth, &
183 "The minimum depth of the ocean.", units=
"m", default=0.0, scale=us%m_to_Z)
186 do k=2,nz ; h0(k) = -(
real(k-1)-0.5)*g%max_depth /
real(nz-1) ; enddo
187 do i=is,ie;
do j=js,je
188 if (g%geoLonT(i,j) < 100.0)
then ; damp = 10.0
189 elseif (g%geoLonT(i,j) < 200.0)
then 190 damp = 10.0 * (200.0-g%geoLonT(i,j))/100.0
194 if (g%geoLonT(i,j) > 1400.0)
then ; damp_new = 10.0
195 elseif (g%geoLonT(i,j) > 1300.0)
then 196 damp_new = 10.0 * (g%geoLonT(i,j)-1300.0)/100.0
197 else ; damp_new = 0.0
200 if (damp <= damp_new) damp = damp_new
201 damp = us%T_to_s*damp
208 e_dense = -g%bathyT(i,j)
209 if (e_dense >= h0(k))
then ; eta(i,j,k) = e_dense
210 else ; eta(i,j,k) = h0(k) ;
endif 211 if (eta(i,j,k) < gv%Angstrom_Z*(nz-k+1) - g%bathyT(i,j)) &
212 eta(i,j,k) = gv%Angstrom_Z*(nz-k+1) - g%bathyT(i,j)
214 eta(i,j,nz+1) = -g%bathyT(i,j)
216 if (g%bathyT(i,j) > min_depth)
then 217 idamp(i,j) = damp / 86400.0
218 else ; idamp(i,j) = 0.0 ;
endif 223 call initialize_sponge(idamp, eta, g, pf, csp, gv)
233 if (
associated(tv%T) )
then 234 call mom_error(fatal,
"DOME_initialize_sponges is not set up for use with"//&
235 " a temperatures defined.")
237 call set_up_sponge_field(temp, tv%T, g, nz, csp)
239 call set_up_sponge_field(temp, tv%S, g, nz, csp)
242 end subroutine dome_initialize_sponges
246 subroutine dome_set_obc_data(OBC, tv, G, GV, US, param_file, tr_Reg)
263 real :: T0(szk_(g)), S0(szk_(g))
264 real :: pres(szk_(g))
265 real :: drho_dT(szk_(g))
266 real :: drho_dS(szk_(g))
267 real :: rho_guess(szk_(g))
269 real :: tr_0, y1, y2, tr_k, rst, rsb, rc, v_k, lon_im1
277 character(len=40) :: mdl =
"DOME_set_OBC_data" 278 character(len=32) :: name
279 integer :: i, j, k, itt, is, ie, js, je, isd, ied, jsd, jed, m, nz, NTR
280 integer :: IsdB, IedB, JsdB, JedB
284 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
285 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
286 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
289 d_edge = 300.0*us%m_to_Z
293 if (.not.
associated(obc))
return 295 g_prime_tot = (gv%g_Earth / gv%Rho0) * 2.0*us%kg_m3_to_R
296 def_rad = us%L_to_m*sqrt(d_edge*g_prime_tot) / (1.0e-4*us%T_to_s * 1000.0)
297 tr_0 = (-d_edge*sqrt(d_edge*g_prime_tot)*0.5e3*us%m_to_L*def_rad) * gv%Z_to_H
299 if (obc%number_of_segments /= 1)
then 300 call mom_error(warning,
'Error in DOME OBC segment setup', .true.)
308 if (.not.
associated(obc%tracer_x_reservoirs_used))
then 309 allocate(obc%tracer_x_reservoirs_used(ntr))
310 allocate(obc%tracer_y_reservoirs_used(ntr))
311 obc%tracer_x_reservoirs_used(:) = .false.
312 obc%tracer_y_reservoirs_used(:) = .false.
313 obc%tracer_y_reservoirs_used(1) = .true.
316 segment => obc%segment(1)
317 if (.not. segment%on_pe)
return 319 allocate(segment%field(ntr))
323 if (k>1) rst = -1.0 + (
real(k-1)-0.5)/
real(nz-1)
326 if (k<nz) rsb = -1.0 + (
real(k-1)+0.5)/
real(nz-1)
327 rc = -1.0 +
real(k-1)/
real(nz-1)
330 y1 = (2.0*ri_trans*rst + ri_trans + 2.0)/(2.0 - ri_trans)
331 y2 = (2.0*ri_trans*rsb + ri_trans + 2.0)/(2.0 - ri_trans)
332 tr_k = tr_0 * (2.0/(ri_trans*(2.0-ri_trans))) * &
333 ((log(y1)+1.0)/y1 - (log(y2)+1.0)/y2)
334 v_k = -sqrt(d_edge*g_prime_tot)*log((2.0 + ri_trans*(1.0 + 2.0*rc)) / &
336 if (k == nz) tr_k = tr_k + tr_0 * (2.0/(ri_trans*(2.0+ri_trans))) * &
337 log((2.0+ri_trans)/(2.0-ri_trans))
339 isd = segment%HI%isd ; ied = segment%HI%ied
340 jsdb = segment%HI%JsdB ; jedb = segment%HI%JedB
341 do j=jsdb,jedb ;
do i=isd,ied
342 lon_im1 = 2.0*g%geoLonCv(i,j) - g%geoLonBu(i,j)
343 segment%normal_trans(i,j,k) = tr_k * (exp(-2.0*(lon_im1 - 1000.0)/def_rad) -&
344 exp(-2.0*(g%geoLonBu(i,j) - 1000.0)/def_rad))
345 segment%normal_vel(i,j,k) = v_k * exp(-2.0*(g%geoLonCv(i,j) - 1000.0)/def_rad)
351 if (
associated(tv%S))
then 354 call tracer_name_lookup(tr_reg, tr_ptr, name)
355 call register_segment_tracer(tr_ptr, param_file, gv, segment, obc_scalar=35.0)
357 if (
associated(tv%T))
then 361 pres(:) = tv%P_Ref ; s0(:) = 35.0 ; t0(1) = 25.0
365 do k=1,nz ; t0(k) = t0(1) + (gv%Rlay(k)-rho_guess(1)) / drho_dt(1) ;
enddo 369 do k=1,nz ; t0(k) = t0(k) + (gv%Rlay(k)-rho_guess(k)) / drho_dt(k) ;
enddo 373 allocate(segment%field(1)%buffer_src(segment%HI%isd:segment%HI%ied,segment%HI%JsdB:segment%HI%JedB,nz))
374 do k=1,nz ;
do j=jsdb,jedb ;
do i=isd,ied
375 segment%field(1)%buffer_src(i,j,k) = t0(k)
376 enddo ;
enddo ;
enddo 378 call tracer_name_lookup(tr_reg, tr_ptr, name)
379 call register_segment_tracer(tr_ptr, param_file, gv, segment, obc_array=.true.)
385 allocate(segment%field(1)%buffer_src(segment%HI%isd:segment%HI%ied,segment%HI%JsdB:segment%HI%JedB,nz))
386 do k=1,nz ;
do j=segment%HI%jsd,segment%HI%jed ;
do i=segment%HI%isd,segment%HI%ied
387 if (k < nz/2)
then ; segment%field(1)%buffer_src(i,j,k) = 0.0
388 else ; segment%field(1)%buffer_src(i,j,k) = 1.0 ;
endif 389 enddo ;
enddo ;
enddo 391 call tracer_name_lookup(tr_reg, tr_ptr, name)
392 call register_segment_tracer(tr_ptr, param_file, gv, &
393 obc%segment(1), obc_array=.true.)
398 if (m < 10)
then ;
write(name,
'("tr_D",I1.1)') m
399 else ;
write(name,
'("tr_D",I2.2)') m ;
endif 400 call tracer_name_lookup(tr_reg, tr_ptr, name)
401 call register_segment_tracer(tr_ptr, param_file, gv, &
402 obc%segment(1), obc_scalar=0.0)
405 end subroutine dome_set_obc_data
Ocean grid type. See mom_grid for details.
Calculates density of sea water from T, S and P.
A structure that can be parsed to read and document run-time parameters.
Provides the ocean grid type.
Open boundary segment data structure.
Describes the horizontal ocean grid with only dynamic memory arrays.
The MOM6 facility to parse input files for runtime parameters.
Describes various unit conversion factors.
This module contains the tracer_registry_type and the subroutines that handle registration of tracers...
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Type to carry basic tracer information.
Routines for error handling and I/O management.
This control structure holds memory and parameters for the MOM_sponge module.
Implements sponge regions in isopycnal mode.
Calculate the derivatives of density with temperature and salinity from T, S, and P...
Provides subroutines for quantities specific to the equation of state.
An overloaded interface to log version information about modules.
Describes the vertical ocean grid, including unit conversion factors.
Pointers to an assortment of thermodynamic fields that may be available, including potential temperat...
Contains a shareable dynamic type for describing horizontal grids and metric data and utilty routines...
Controls where open boundary conditions are applied.
Provides a transparent vertical ocean grid type and supporting routines.
Provides transparent structures with groups of MOM6 variables and supporting routines.
Configures the model for the "DOME" experiment. DOME = Dynamics of Overflows and Mixing Experiment...
An overloaded interface to read and log the values of various types of parameters.
A control structure for the equation of state.