43 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
44 use mom_cpu_clock, only : clock_module_driver, clock_module, clock_routine
59 use fms_mod
, only : read_data
61 implicit none ;
private 63 #include <MOM_memory.h> 74 real,
allocatable,
dimension(:,:) :: &
78 integer :: id_tke_itidal = -1, id_nb = -1, id_n2_bot = -1
79 character(len=200) :: inputdir
83 real,
allocatable,
dimension(:,:) :: &
96 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(in) :: u
97 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(in) :: v
98 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
100 type(
forcing),
intent(in) :: fluxes
102 real,
intent(in) :: dt
118 real,
dimension(SZI_(G),SZJ_(G)) :: &
121 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
126 integer :: i, j, k, is, ie, js, je, nz
127 integer :: isd, ied, jsd, jed
132 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
133 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
135 if (.not.
associated(cs))
call mom_error(fatal,
"set_diffusivity: "//&
136 "Module must be initialized before it is used.")
141 use_eos =
associated(tv%eqn_of_state)
145 call vert_fill_ts(h, tv%T, tv%S, kappa_fill, dt_fill, t_f, s_f, g, gv)
148 call find_n2_bottom(h, tv, t_f, s_f, itide%h2, fluxes, g, gv, n2_bot)
151 do j=js,je ;
do i=is,ie
152 itide%Nb(i,j) = g%mask2dT(i,j) * sqrt(n2_bot(i,j))
153 itide%TKE_itidal_input(i,j) = min(cs%TKE_itidal_coef(i,j)*itide%Nb(i,j),cs%TKE_itide_max)
157 call hchksum(n2_bot,
"N2_bot",g%HI,haloshift=0)
158 call hchksum(itide%TKE_itidal_input,
"TKE_itidal_input",g%HI,haloshift=0)
161 if (cs%id_TKE_itidal > 0)
call post_data(cs%id_TKE_itidal, itide%TKE_itidal_input, cs%diag)
162 if (cs%id_Nb > 0)
call post_data(cs%id_Nb, itide%Nb, cs%diag)
163 if (cs%id_N2_bot > 0 )
call post_data(cs%id_N2_bot,n2_bot,cs%diag)
167 subroutine find_n2_bottom(h, tv, T_f, S_f, h2, fluxes, G, GV, N2_bot)
170 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
172 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: T_f, S_f
173 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: h2
174 type(
forcing),
intent(in) :: fluxes
176 real,
dimension(SZI_(G),SZJ_(G)),
intent(out) :: N2_bot
178 real,
dimension(SZI_(G),SZK_(G)+1) :: &
180 real,
dimension(SZI_(G)) :: &
194 logical :: do_i(szi_(g)), do_any
195 integer :: i, j, k, is, ie, js, je, nz
196 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
197 g_rho0 = gv%g_Earth / gv%Rho0
201 drho_int(i,1) = 0.0 ; drho_int(i,nz+1) = 0.0
210 if (
associated(tv%eqn_of_state))
then 211 if (
associated(fluxes%p_surf))
then 212 do i=is,ie ; pres(i) = fluxes%p_surf(i,j) ;
enddo 214 do i=is,ie ; pres(i) = 0.0 ;
enddo 218 pres(i) = pres(i) + gv%H_to_Pa*h(i,j,k-1)
219 temp_int(i) = 0.5 * (t_f(i,j,k) + t_f(i,j,k-1))
220 salin_int(i) = 0.5 * (s_f(i,j,k) + s_f(i,j,k-1))
223 drho_dt(:), drho_ds(:), is, ie-is+1, tv%eqn_of_state)
225 drho_int(i,k) = max(drho_dt(i)*(t_f(i,j,k) - t_f(i,j,k-1)) + &
226 drho_ds(i)*(s_f(i,j,k) - s_f(i,j,k-1)), 0.0)
230 do k=2,nz ;
do i=is,ie
231 drho_int(i,k) = gv%Rlay(k) - gv%Rlay(k-1)
237 hb(i) = 0.0 ; drho_bot(i) = 0.0
238 z_from_bot(i) = 0.5*gv%H_to_m*h(i,j,nz)
239 do_i(i) = (g%mask2dT(i,j) > 0.5)
240 h_amp(i) = sqrt(h2(i,j))
245 do i=is,ie ;
if (do_i(i))
then 246 dz_int = 0.5*gv%H_to_m*(h(i,j,k) + h(i,j,k-1))
247 z_from_bot(i) = z_from_bot(i) + dz_int
249 hb(i) = hb(i) + dz_int
250 drho_bot(i) = drho_bot(i) + drho_int(i,k)
252 if (z_from_bot(i) > h_amp(i))
then 255 hb(i) = hb(i) + 0.5*gv%H_to_m*(h(i,j,k-1) + h(i,j,k-2))
256 drho_bot(i) = drho_bot(i) + drho_int(i,k-1)
263 if (.not.do_any)
exit 267 if (hb(i) > 0.0)
then 268 n2_bot(i,j) = (g_rho0 * drho_bot(i)) / hb(i)
269 else ; n2_bot(i,j) = 0.0 ;
endif 276 type(time_type),
intent(in) :: Time
280 type(
diag_ctrl),
target,
intent(inout) :: diag
293 logical :: read_tideamp
295 #include "version_variable.h" 296 character(len=40) :: mdl =
"MOM_int_tide_input" 297 character(len=20) :: tmpstr
298 character(len=200) :: filename, tideamp_file, h2_file
303 real :: kappa_h2_factor
305 real :: min_zbot_itides
307 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
309 if (
associated(cs))
then 310 call mom_error(warning,
"int_tide_input_init called with an associated "// &
311 "control structure.")
314 if (
associated(itide))
then 315 call mom_error(warning,
"int_tide_input_init called with an associated "// &
316 "internal tide input type.")
322 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
323 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
330 call get_param(param_file, mdl,
"INPUTDIR", cs%inputdir, default=
".")
331 cs%inputdir = slasher(cs%inputdir)
333 call get_param(param_file, mdl,
"DEBUG", cs%debug, default=.false., do_not_log=.true.)
335 call get_param(param_file, mdl,
"MIN_ZBOT_ITIDES", min_zbot_itides, &
336 "Turn off internal tidal dissipation when the total \n"//&
337 "ocean depth is less than this value.", units=
"m", default=0.0)
339 call get_param(param_file, mdl,
"UTIDE", utide, &
340 "The constant tidal amplitude used with INT_TIDE_DISSIPATION.", &
341 units=
"m s-1", default=0.0)
343 allocate(itide%Nb(isd:ied,jsd:jed)) ; itide%Nb(:,:) = 0.0
344 allocate(itide%h2(isd:ied,jsd:jed)) ; itide%h2(:,:) = 0.0
345 allocate(itide%TKE_itidal_input(isd:ied,jsd:jed)) ; itide%TKE_itidal_input(:,:) = 0.0
346 allocate(itide%tideamp(isd:ied,jsd:jed)) ; itide%tideamp(:,:) = utide
347 allocate(cs%TKE_itidal_coef(isd:ied,jsd:jed)) ; cs%TKE_itidal_coef(:,:) = 0.0
349 call get_param(param_file, mdl,
"KAPPA_ITIDES", kappa_itides, &
350 "A topographic wavenumber used with INT_TIDE_DISSIPATION. \n"//&
351 "The default is 2pi/10 km, as in St.Laurent et al. 2002.", &
352 units=
"m-1", default=8.e-4*atan(1.0))
354 call get_param(param_file, mdl,
"KAPPA_H2_FACTOR", kappa_h2_factor, &
355 "A scaling factor for the roughness amplitude with n"//&
356 "INT_TIDE_DISSIPATION.", units=
"nondim", default=1.0)
357 call get_param(param_file, mdl,
"TKE_ITIDE_MAX", cs%TKE_itide_max, &
358 "The maximum internal tide energy source availble to mix \n"//&
359 "above the bottom boundary layer with INT_TIDE_DISSIPATION.", &
360 units=
"W m-2", default=1.0e3)
362 call get_param(param_file, mdl,
"READ_TIDEAMP", read_tideamp, &
363 "If true, read a file (given by TIDEAMP_FILE) containing \n"//&
364 "the tidal amplitude with INT_TIDE_DISSIPATION.", default=.false.)
365 if (read_tideamp)
then 366 call get_param(param_file, mdl,
"TIDEAMP_FILE", tideamp_file, &
367 "The path to the file containing the spatially varying \n"//&
368 "tidal amplitudes with INT_TIDE_DISSIPATION.", default=
"tideamp.nc")
369 filename = trim(cs%inputdir) // trim(tideamp_file)
370 call log_param(param_file, mdl,
"INPUTDIR/TIDEAMP_FILE", filename)
371 call read_data(filename,
'tideamp', itide%tideamp, &
372 domain=g%domain%mpp_domain, timelevel=1)
375 call get_param(param_file, mdl,
"H2_FILE", h2_file, &
376 "The path to the file containing the sub-grid-scale \n"//&
377 "topographic roughness amplitude with INT_TIDE_DISSIPATION.", &
378 fail_if_missing=.true.)
379 filename = trim(cs%inputdir) // trim(h2_file)
380 call log_param(param_file, mdl,
"INPUTDIR/H2_FILE", filename)
381 call read_data(filename,
'h2', itide%h2, domain=g%domain%mpp_domain, &
384 do j=js,je ;
do i=is,ie
386 if (g%bathyT(i,j) < min_zbot_itides) mask_itidal = 0.0
388 itide%tideamp(i,j) = itide%tideamp(i,j) * mask_itidal * g%mask2dT(i,j)
391 itide%h2(i,j) = min(0.01*g%bathyT(i,j)**2, itide%h2(i,j))
394 cs%TKE_itidal_coef(i,j) = 0.5*kappa_h2_factor*gv%Rho0*&
395 kappa_itides * itide%h2(i,j) * itide%tideamp(i,j)**2
399 cs%id_TKE_itidal =
register_diag_field(
'ocean_model',
'TKE_itidal_itide',diag%axesT1,time, &
400 'Internal Tide Driven Turbulent Kinetic Energy',
'Watt meter-2')
403 'Bottom Buoyancy Frequency',
'sec-1')
406 'Bottom Buoyancy frequency squared',
's-2')
413 if (
associated(cs))
deallocate(cs)
This module implements boundary forcing for MOM6.
subroutine, public vert_fill_ts(h, T_in, S_in, kappa, dt, T_f, S_f, G, GV, halo_here)
Fills tracer values in massless layers with sensible values by diffusing vertically with a (small) co...
Ocean grid type. See mom_grid for details.
Calculates density of sea water from T, S and P.
Provides the ocean grid type.
The vertvisc_type structure contains vertical viscosities, drag coefficients, and related fields...
This module contains I/O framework code.
subroutine, public calculate_density_derivs(T, S, pressure, drho_dT, drho_dS, start, npts, EOS)
Calls the appropriate subroutine to calculate density derivatives for 1-D array inputs.
Thickness diffusion (or Gent McWilliams)
logical function, public is_root_pe()
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
Provides subroutines for quantities specific to the equation of state.
Type for describing a variable, typically a tracer.
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
integer function, public register_zint_diag(var_desc, CS, day)
subroutine, public mom_error(level, message, all_print)
subroutine, public calc_zint_diags(h, in_ptrs, ids, num_diags, G, GV, CS)