6 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
7 use mom_cpu_clock,
only : clock_module_driver, clock_module, clock_routine
23 implicit none ;
private 25 #include <MOM_memory.h> 27 public set_int_tide_input, int_tide_input_init, int_tide_input_end
44 real,
allocatable,
dimension(:,:) :: tke_itidal_coef
46 character(len=200) :: inputdir
48 logical :: int_tide_source_test
50 type(time_type) :: time_max_source
51 real :: int_tide_source_x
53 real :: int_tide_source_y
58 integer :: id_tke_itidal = -1, id_nb = -1, id_n2_bot = -1
64 real,
allocatable,
dimension(:,:) :: &
65 tke_itidal_input, & !< The internal tide TKE input at the bottom of the ocean [R Z3 T-3 ~> W m-2].
66 h2, & !< The squared topographic roughness height [Z2 ~> m2].
67 tideamp, & !< The amplitude of the tidal velocities [Z T-1 ~> m s-1].
74 subroutine set_int_tide_input(u, v, h, tv, fluxes, itide, dt, G, GV, US, CS)
78 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(in) :: u
79 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(in) :: v
80 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
83 type(
forcing),
intent(in) :: fluxes
86 real,
intent(in) :: dt
89 real,
dimension(SZI_(G),SZJ_(G)) :: &
92 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
97 logical :: avg_enabled
98 type(time_type) :: time_end
100 integer :: i, j, k, is, ie, js, je, nz, isd, ied, jsd, jed
102 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
103 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
105 if (.not.
associated(cs))
call mom_error(fatal,
"set_diffusivity: "//&
106 "Module must be initialized before it is used.")
108 use_eos =
associated(tv%eqn_of_state)
112 call vert_fill_ts(h, tv%T, tv%S, cs%kappa_fill*dt, t_f, s_f, g, gv, larger_h_denom=.true.)
115 call find_n2_bottom(h, tv, t_f, s_f, itide%h2, fluxes, g, gv, us, n2_bot)
118 do j=js,je ;
do i=is,ie
119 itide%Nb(i,j) = g%mask2dT(i,j) * sqrt(n2_bot(i,j))
120 itide%TKE_itidal_input(i,j) = min(cs%TKE_itidal_coef(i,j)*itide%Nb(i,j), cs%TKE_itide_max)
123 if (cs%int_tide_source_test)
then 124 itide%TKE_itidal_input(:,:) = 0.0
125 avg_enabled = query_averaging_enabled(cs%diag, time_end=time_end)
126 if (time_end <= cs%time_max_source)
then 127 do j=js,je ;
do i=is,ie
129 if (((g%geoLonCu(i-1,j)-cs%int_tide_source_x) * (g%geoLonBu(i,j)-cs%int_tide_source_x) <= 0.0) .and. &
130 ((g%geoLatCv(i,j-1)-cs%int_tide_source_y) * (g%geoLatCv(i,j)-cs%int_tide_source_y) <= 0.0))
then 131 itide%TKE_itidal_input(i,j) = 1.0*us%kg_m3_to_R*us%m_to_Z**3*us%T_to_s**3
138 call hchksum(n2_bot,
"N2_bot",g%HI,haloshift=0, scale=us%s_to_T**2)
139 call hchksum(itide%TKE_itidal_input,
"TKE_itidal_input",g%HI,haloshift=0, &
140 scale=us%RZ3_T3_to_W_m2)
143 if (cs%id_TKE_itidal > 0)
call post_data(cs%id_TKE_itidal, itide%TKE_itidal_input, cs%diag)
144 if (cs%id_Nb > 0)
call post_data(cs%id_Nb, itide%Nb, cs%diag)
145 if (cs%id_N2_bot > 0 )
call post_data(cs%id_N2_bot, n2_bot, cs%diag)
147 end subroutine set_int_tide_input
150 subroutine find_n2_bottom(h, tv, T_f, S_f, h2, fluxes, G, GV, US, N2_bot)
151 type(ocean_grid_type),
intent(in) :: G
152 type(verticalGrid_type),
intent(in) :: GV
153 type(unit_scale_type),
intent(in) :: US
154 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
155 type(thermo_var_ptrs),
intent(in) :: tv
157 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: T_f
159 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: S_f
161 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: h2
162 type(forcing),
intent(in) :: fluxes
163 type(int_tide_input_CS),
pointer :: CS
164 real,
dimension(SZI_(G),SZJ_(G)),
intent(out) :: N2_bot
167 real,
dimension(SZI_(G),SZK_(G)+1) :: &
169 real,
dimension(SZI_(G)) :: &
183 logical :: do_i(SZI_(G)), do_any
184 integer,
dimension(2) :: EOSdom
185 integer :: i, j, k, is, ie, js, je, nz
187 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
188 g_rho0 = (us%L_to_Z**2*gv%g_Earth) / gv%Rho0
189 eosdom(:) = eos_domain(g%HI)
193 drho_int(i,1) = 0.0 ; drho_int(i,nz+1) = 0.0
202 if (
associated(tv%eqn_of_state))
then 203 if (
associated(fluxes%p_surf))
then 204 do i=is,ie ; pres(i) = fluxes%p_surf(i,j) ;
enddo 206 do i=is,ie ; pres(i) = 0.0 ;
enddo 210 pres(i) = pres(i) + (gv%g_Earth*gv%H_to_RZ)*h(i,j,k-1)
211 temp_int(i) = 0.5 * (t_f(i,j,k) + t_f(i,j,k-1))
212 salin_int(i) = 0.5 * (s_f(i,j,k) + s_f(i,j,k-1))
215 tv%eqn_of_state, eosdom)
217 drho_int(i,k) = max(drho_dt(i)*(t_f(i,j,k) - t_f(i,j,k-1)) + &
218 drho_ds(i)*(s_f(i,j,k) - s_f(i,j,k-1)), 0.0)
222 do k=2,nz ;
do i=is,ie
223 drho_int(i,k) = (gv%Rlay(k) - gv%Rlay(k-1))
229 hb(i) = 0.0 ; drho_bot(i) = 0.0
230 z_from_bot(i) = 0.5*gv%H_to_Z*h(i,j,nz)
231 do_i(i) = (g%mask2dT(i,j) > 0.5)
232 h_amp(i) = sqrt(h2(i,j))
237 do i=is,ie ;
if (do_i(i))
then 238 dz_int = 0.5*gv%H_to_Z*(h(i,j,k) + h(i,j,k-1))
239 z_from_bot(i) = z_from_bot(i) + dz_int
241 hb(i) = hb(i) + dz_int
242 drho_bot(i) = drho_bot(i) + drho_int(i,k)
244 if (z_from_bot(i) > h_amp(i))
then 247 hb(i) = hb(i) + 0.5*gv%H_to_Z*(h(i,j,k-1) + h(i,j,k-2))
248 drho_bot(i) = drho_bot(i) + drho_int(i,k-1)
255 if (.not.do_any)
exit 259 if (hb(i) > 0.0)
then 260 n2_bot(i,j) = (g_rho0 * drho_bot(i)) / hb(i)
261 else ; n2_bot(i,j) = 0.0 ;
endif 265 end subroutine find_n2_bottom
268 subroutine int_tide_input_init(Time, G, GV, US, param_file, diag, CS, itide)
269 type(time_type),
intent(in) :: time
274 type(
diag_ctrl),
target,
intent(inout) :: diag
280 logical :: read_tideamp
282 # include "version_variable.h" 283 character(len=40) :: mdl =
"MOM_int_tide_input" 284 character(len=20) :: tmpstr
285 character(len=200) :: filename, tideamp_file, h2_file
288 real :: max_frac_rough
292 real :: kappa_h2_factor
294 real :: min_zbot_itides
297 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
299 if (
associated(cs))
then 300 call mom_error(warning,
"int_tide_input_init called with an associated "// &
301 "control structure.")
304 if (
associated(itide))
then 305 call mom_error(warning,
"int_tide_input_init called with an associated "// &
306 "internal tide input type.")
312 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
313 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
320 call get_param(param_file, mdl,
"INPUTDIR", cs%inputdir, default=
".")
321 cs%inputdir = slasher(cs%inputdir)
323 call get_param(param_file, mdl,
"DEBUG", cs%debug, default=.false., do_not_log=.true.)
325 call get_param(param_file, mdl,
"MIN_ZBOT_ITIDES", min_zbot_itides, &
326 "Turn off internal tidal dissipation when the total "//&
327 "ocean depth is less than this value.", units=
"m", default=0.0, scale=us%m_to_Z)
328 call get_param(param_file, mdl,
"KD_SMOOTH", cs%kappa_fill, &
329 "A diapycnal diffusivity that is used to interpolate "//&
330 "more sensible values of T & S into thin layers.", &
331 units=
"m2 s-1", default=1.0e-6, scale=us%m2_s_to_Z2_T)
333 call get_param(param_file, mdl,
"UTIDE", utide, &
334 "The constant tidal amplitude used with INT_TIDE_DISSIPATION.", &
335 units=
"m s-1", default=0.0, scale=us%m_s_to_L_T)
337 allocate(itide%Nb(isd:ied,jsd:jed)) ; itide%Nb(:,:) = 0.0
338 allocate(itide%h2(isd:ied,jsd:jed)) ; itide%h2(:,:) = 0.0
339 allocate(itide%TKE_itidal_input(isd:ied,jsd:jed)) ; itide%TKE_itidal_input(:,:) = 0.0
340 allocate(itide%tideamp(isd:ied,jsd:jed)) ; itide%tideamp(:,:) = utide
341 allocate(cs%TKE_itidal_coef(isd:ied,jsd:jed)) ; cs%TKE_itidal_coef(:,:) = 0.0
343 call get_param(param_file, mdl,
"KAPPA_ITIDES", kappa_itides, &
344 "A topographic wavenumber used with INT_TIDE_DISSIPATION. "//&
345 "The default is 2pi/10 km, as in St.Laurent et al. 2002.", &
346 units=
"m-1", default=8.e-4*atan(1.0), scale=us%L_to_m)
348 call get_param(param_file, mdl,
"KAPPA_H2_FACTOR", kappa_h2_factor, &
349 "A scaling factor for the roughness amplitude with n"//&
350 "INT_TIDE_DISSIPATION.", units=
"nondim", default=1.0)
351 call get_param(param_file, mdl,
"TKE_ITIDE_MAX", cs%TKE_itide_max, &
352 "The maximum internal tide energy source available to mix "//&
353 "above the bottom boundary layer with INT_TIDE_DISSIPATION.", &
354 units=
"W m-2", default=1.0e3, scale=us%W_m2_to_RZ3_T3)
356 call get_param(param_file, mdl,
"READ_TIDEAMP", read_tideamp, &
357 "If true, read a file (given by TIDEAMP_FILE) containing "//&
358 "the tidal amplitude with INT_TIDE_DISSIPATION.", default=.false.)
359 if (read_tideamp)
then 360 call get_param(param_file, mdl,
"TIDEAMP_FILE", tideamp_file, &
361 "The path to the file containing the spatially varying "//&
362 "tidal amplitudes with INT_TIDE_DISSIPATION.", default=
"tideamp.nc")
363 filename = trim(cs%inputdir) // trim(tideamp_file)
364 call log_param(param_file, mdl,
"INPUTDIR/TIDEAMP_FILE", filename)
365 call mom_read_data(filename,
'tideamp', itide%tideamp, g%domain, timelevel=1, scale=us%m_s_to_L_T)
368 call get_param(param_file, mdl,
"H2_FILE", h2_file, &
369 "The path to the file containing the sub-grid-scale "//&
370 "topographic roughness amplitude with INT_TIDE_DISSIPATION.", &
371 fail_if_missing=.true.)
372 filename = trim(cs%inputdir) // trim(h2_file)
373 call log_param(param_file, mdl,
"INPUTDIR/H2_FILE", filename)
374 call mom_read_data(filename,
'h2', itide%h2, g%domain, timelevel=1, scale=us%m_to_Z**2)
376 call get_param(param_file, mdl,
"FRACTIONAL_ROUGHNESS_MAX", max_frac_rough, &
377 "The maximum topographic roughness amplitude as a fraction of the mean depth, "//&
378 "or a negative value for no limitations on roughness.", &
379 units=
"nondim", default=0.1)
382 call get_param(param_file, mdl,
"INTERNAL_TIDE_SOURCE_TEST", cs%int_tide_source_test, &
383 "If true, apply an arbitrary generation site for internal tide testing", &
385 if (cs%int_tide_source_test)
then 386 call get_param(param_file, mdl,
"INTERNAL_TIDE_SOURCE_X", cs%int_tide_source_x, &
387 "X Location of generation site for internal tide", default=1.)
388 call get_param(param_file, mdl,
"INTERNAL_TIDE_SOURCE_Y", cs%int_tide_source_y, &
389 "Y Location of generation site for internal tide", default=1.)
390 call get_param(param_file, mdl,
"INTERNAL_TIDE_SOURCE_TLEN_DAYS", tlen_days, &
391 "Time interval from start of experiment for adding wave source", &
392 units=
"days", default=0)
393 cs%time_max_source = time + set_time(0, days=tlen_days)
396 do j=js,je ;
do i=is,ie
398 if (g%bathyT(i,j) < min_zbot_itides) mask_itidal = 0.0
400 itide%tideamp(i,j) = itide%tideamp(i,j) * mask_itidal * g%mask2dT(i,j)
403 if (max_frac_rough >= 0.0) &
404 itide%h2(i,j) = min((max_frac_rough*g%bathyT(i,j))**2, itide%h2(i,j))
407 cs%TKE_itidal_coef(i,j) = 0.5*us%L_to_Z*kappa_h2_factor*gv%Rho0*&
408 kappa_itides * itide%h2(i,j) * itide%tideamp(i,j)**2
412 cs%id_TKE_itidal = register_diag_field(
'ocean_model',
'TKE_itidal_itide',diag%axesT1,time, &
413 'Internal Tide Driven Turbulent Kinetic Energy', &
414 'W m-2', conversion=us%RZ3_T3_to_W_m2)
416 cs%id_Nb = register_diag_field(
'ocean_model',
'Nb_itide',diag%axesT1,time, &
417 'Bottom Buoyancy Frequency',
's-1', conversion=us%s_to_T)
419 cs%id_N2_bot = register_diag_field(
'ocean_model',
'N2_b_itide',diag%axesT1,time, &
420 'Bottom Buoyancy frequency squared',
's-2', conversion=us%s_to_T**2)
422 end subroutine int_tide_input_init
425 subroutine int_tide_input_end(CS)
428 if (
associated(cs))
deallocate(cs)
430 end subroutine int_tide_input_end
Wraps the FMS time manager functions.
This module implements boundary forcing for MOM6.
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.
Vertical viscosities, drag coefficients, and related fields.
Wraps the MPP cpu clock functions.
This module contains I/O framework code.
The MOM6 facility to parse input files for runtime parameters.
An overloaded interface to log the values of various types of parameters.
Make a diagnostic available for averaging or output.
Describes various unit conversion factors.
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Routines for error handling and I/O management.
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
Calculate the derivatives of density with temperature and salinity from T, S, and P...
Provides subroutines for quantities specific to the equation of state.
Type for describing a variable, typically a tracer.
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...
Provides a transparent vertical ocean grid type and supporting routines.
Provides transparent structures with groups of MOM6 variables and supporting routines.
Read a data field from a file.
Calculations of isoneutral slopes and stratification.
An overloaded interface to read and log the values of various types of parameters.
Provides checksumming functions for debugging.
A structure for creating arrays of pointers to 3D arrays.