Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 83 additions & 14 deletions src/parameterizations/lateral/MOM_internal_tides.F90
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ module MOM_internal_tides
logical :: init_forcing_only !< if True, add TKE forcing only at first step (for debugging)
logical :: force_posit_En !< if True, remove subroundoff negative values (needs enhancement)
logical :: add_tke_forcing = .true. !< Whether to add forcing, used by init_forcing_only
logical :: negative_Kd_bug !< If True, use bug that adds Kd_max to every layer/interface diffusivity
!! when Kd_max < 0.

real, allocatable, dimension(:,:) :: fraction_tidal_input
!< how the energy from one tidal component is distributed
Expand Down Expand Up @@ -1505,13 +1507,16 @@ subroutine get_lowmode_diffusivity(G, GV, h, tv, US, h_bot, k_bot, j, N2_lay, N2
threshold_renorm_N, & ! Maximum allowable error on N profile [H T-1 ~> m s-1 or kg m-2 s-1]
threshold_verif ! Maximum allowable error on verification [nondim]

logical :: apply_Kd_max
logical :: non_Bous ! fully Non-Boussinesq
integer :: i, k, is, ie, nz

is=G%isc ; ie=G%iec ; nz=GV%ke

non_Bous = .not.(GV%Boussinesq .or. GV%semi_Boussinesq)

apply_Kd_max = ((Kd_max >= 0.0) .or. CS%negative_Kd_bug)

h_d = CS%Int_tide_decay_scale
h_s = CS%Int_tide_decay_scale_slope
I_h_d = 1 / h_d
Expand Down Expand Up @@ -1703,7 +1708,13 @@ subroutine get_lowmode_diffusivity(G, GV, h, tv, US, h_bot, k_bot, j, N2_lay, N2
Kd_leak_lay(k) = 0.
endif
! add to total Kd in layer
if (CS%update_Kd) Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_leak_lay(k), Kd_max)
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_leak_lay(k), Kd_max)
else
Kd_lay(i,k) = Kd_lay(i,k) + Kd_leak_lay(k)
endif
endif
enddo
endif

Expand All @@ -1725,7 +1736,13 @@ subroutine get_lowmode_diffusivity(G, GV, h, tv, US, h_bot, k_bot, j, N2_lay, N2
Kd_Froude_lay(k) = 0.
endif
! add to total Kd in layer
if (CS%update_Kd) Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_Froude_lay(k), Kd_max)
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_Froude_lay(k), Kd_max)
else
Kd_lay(i,k) = Kd_lay(i,k) + Kd_Froude_lay(k)
endif
endif
enddo
endif

Expand All @@ -1747,7 +1764,13 @@ subroutine get_lowmode_diffusivity(G, GV, h, tv, US, h_bot, k_bot, j, N2_lay, N2
Kd_itidal_lay(k) = 0.
endif
! add to total Kd in layer
if (CS%update_Kd) Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_itidal_lay(k), Kd_max)
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_itidal_lay(k), Kd_max)
else
Kd_lay(i,k) = Kd_lay(i,k) + Kd_itidal_lay(k)
endif
endif
enddo
endif

Expand All @@ -1769,7 +1792,13 @@ subroutine get_lowmode_diffusivity(G, GV, h, tv, US, h_bot, k_bot, j, N2_lay, N2
Kd_slope_lay(k) = 0.
endif
! add to total Kd in layer
if (CS%update_Kd) Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_slope_lay(k), Kd_max)
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_slope_lay(k), Kd_max)
else
Kd_lay(i,k) = Kd_lay(i,k) + Kd_slope_lay(k)
endif
endif
enddo
endif

Expand All @@ -1791,7 +1820,13 @@ subroutine get_lowmode_diffusivity(G, GV, h, tv, US, h_bot, k_bot, j, N2_lay, N2
Kd_quad_lay(k) = 0.
endif
! add to total Kd in layer
if (CS%update_Kd) Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_quad_lay(k), Kd_max)
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_lay(i,k) = Kd_lay(i,k) + min(Kd_quad_lay(k), Kd_max)
else
Kd_lay(i,k) = Kd_lay(i,k) + Kd_quad_lay(k)
endif
endif
enddo
endif

Expand All @@ -1801,7 +1836,13 @@ subroutine get_lowmode_diffusivity(G, GV, h, tv, US, h_bot, k_bot, j, N2_lay, N2
if (k>1) Kd_leak(i,K) = 0.5*Kd_leak_lay(k-1)
if (k<nz+1) Kd_leak(i,K) = Kd_leak(i,K) + 0.5*Kd_leak_lay(k)
! add to Kd_int
if (CS%update_Kd) Kd_int(i,K) = Kd_int(i,K) + min(Kd_leak(i,K), Kd_max)
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_int(i,K) = Kd_int(i,K) + min(Kd_leak(i,K), Kd_max)
else
Kd_int(i,K) = Kd_int(i,K)
endif
endif
enddo
endif

Expand All @@ -1810,35 +1851,59 @@ subroutine get_lowmode_diffusivity(G, GV, h, tv, US, h_bot, k_bot, j, N2_lay, N2
if (k>1) Kd_itidal(i,K) = 0.5*Kd_itidal_lay(k-1)
if (k<nz+1) Kd_itidal(i,K) = Kd_itidal(i,K) + 0.5*Kd_itidal_lay(k)
! add to Kd_int
if (CS%update_Kd) Kd_int(i,K) = Kd_int(i,K) + min(Kd_itidal(i,K), Kd_max)
enddo
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_int(i,K) = Kd_int(i,K) + min(Kd_itidal(i,K), Kd_max)
else
Kd_int(i,K) = Kd_int(i,K)
endif
endif
enddo
endif

if (CS%apply_Froude_drag) then
do k=1,nz+1
if (k>1) Kd_Froude(i,K) = 0.5*Kd_Froude_lay(k-1)
if (k<nz+1) Kd_Froude(i,K) = Kd_Froude(i,K) + 0.5*Kd_Froude_lay(k)
! add to Kd_int
if (CS%update_Kd) Kd_int(i,K) = Kd_int(i,K) + min(Kd_Froude(i,K), Kd_max)
enddo
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_int(i,K) = Kd_int(i,K) + min(Kd_Froude(i,K), Kd_max)
else
Kd_int(i,K) = Kd_int(i,K)
endif
endif
enddo
endif

if (CS%apply_residual_drag) then
do k=1,nz+1
if (k>1) Kd_slope(i,K) = 0.5*Kd_slope_lay(k-1)
if (k<nz+1) Kd_slope(i,K) = Kd_slope(i,K) + 0.5*Kd_slope_lay(k)
! add to Kd_int
if (CS%update_Kd) Kd_int(i,K) = Kd_int(i,K) + min(Kd_slope(i,K), Kd_max)
enddo
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_int(i,K) = Kd_int(i,K) + min(Kd_slope(i,K), Kd_max)
else
Kd_int(i,K) = Kd_int(i,K)
endif
endif
enddo
endif

if (CS%apply_bottom_drag) then
do k=1,nz+1
if (k>1) Kd_quad(i,K) = 0.5*Kd_quad_lay(k-1)
if (k<nz+1) Kd_quad(i,K) = Kd_quad(i,K) + 0.5*Kd_quad_lay(k)
! add to Kd_int
if (CS%update_Kd) Kd_int(i,K) = Kd_int(i,K) + min(Kd_quad(i,K), Kd_max)
enddo
if (CS%update_Kd) then
if (apply_Kd_max) then
Kd_int(i,K) = Kd_int(i,K) + min(Kd_quad(i,K), Kd_max)
else
Kd_int(i,K) = Kd_int(i,K)
endif
endif
enddo
endif
enddo ! i-loop

Expand Down Expand Up @@ -3567,6 +3632,10 @@ subroutine internal_tides_init(Time, G, GV, US, param_file, diag, CS)
call get_param(param_file, mdl, "INTERNAL_TIDES_FORCE_POS_EN", CS%force_posit_En, &
"If true, force energy to be positive by removing subroundoff negative values.", &
default=.true.)
call get_param(param_file, mdl, "INTERNAL_TIDES_NEGATIVE_KD_BUG", CS%negative_Kd_bug, &
"If true, use bug that results in negative diffusivities at top/bottom "//&
"interfaces/layers and disregarding contributions from internal tides in interior.", &
default=.true.)
call get_param(param_file, mdl, "KD_MIN", CS%Kd_min, &
"The minimum diapycnal diffusivity.", &
units="m2 s-1", default=2e-6, scale=GV%m2_s_to_HZ_T)
Expand Down
49 changes: 34 additions & 15 deletions src/parameterizations/vertical/MOM_set_diffusivity.F90
Original file line number Diff line number Diff line change
Expand Up @@ -634,21 +634,40 @@ subroutine set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, optics, visc, dt, Kd_i
if (CS%id_Kd_slope > 0) then ; do K=1,nz+1 ; do i=is,ie
dd%Kd_slope(i,j,K) = Kd_slope_2d(i,K)
enddo ; enddo ; endif
if (associated (VBF%Kd_leak)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_leak(i,j,K) = min(Kd_leak_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
if (associated (VBF%Kd_quad)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_quad(i,j,K) = min(Kd_quad_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
if (associated (VBF%Kd_itidal)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_itidal(i,j,K) = min(Kd_itidal_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
if (associated (VBF%Kd_Froude)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_Froude(i,j,K) = min(Kd_Froude_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
if (associated (VBF%Kd_slope)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_slope(i,j,K) = min(Kd_slope_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
! Only apply diffusivity cap if Kd_max is positive
if (CS%Kd_max < 0.0) then
if (associated (VBF%Kd_leak)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_leak(i,j,K) = Kd_leak_2d(i,K)
enddo ; enddo ; endif
if (associated (VBF%Kd_quad)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_quad(i,j,K) = Kd_quad_2d(i,K)
enddo ; enddo ; endif
if (associated (VBF%Kd_itidal)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_itidal(i,j,K) = Kd_itidal_2d(i,K)
enddo ; enddo ; endif
if (associated (VBF%Kd_Froude)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_Froude(i,j,K) = Kd_Froude_2d(i,K)
enddo ; enddo ; endif
if (associated (VBF%Kd_slope)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_slope(i,j,K) = Kd_slope_2d(i,K)
enddo ; enddo ; endif
else
if (associated (VBF%Kd_leak)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_leak(i,j,K) = min(Kd_leak_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
if (associated (VBF%Kd_quad)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_quad(i,j,K) = min(Kd_quad_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
if (associated (VBF%Kd_itidal)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_itidal(i,j,K) = min(Kd_itidal_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
if (associated (VBF%Kd_Froude)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_Froude(i,j,K) = min(Kd_Froude_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
if (associated (VBF%Kd_slope)) then ; do K=1,nz+1 ; do i=is,ie
VBF%Kd_slope(i,j,K) = min(Kd_slope_2d(i,K), CS%Kd_max)
enddo ; enddo ; endif
endif

if (CS%id_prof_leak > 0) then ; do k=1,nz; do i=is,ie
dd%prof_leak(i,j,k) = prof_leak_2d(i,k)
Expand Down
Loading