diff --git a/src/parameterizations/lateral/MOM_mixed_layer_restrat.F90 b/src/parameterizations/lateral/MOM_mixed_layer_restrat.F90 index 36a83cd43a..90761da1bb 100644 --- a/src/parameterizations/lateral/MOM_mixed_layer_restrat.F90 +++ b/src/parameterizations/lateral/MOM_mixed_layer_restrat.F90 @@ -14,6 +14,7 @@ module MOM_mixed_layer_restrat use MOM_forcing_type, only : mech_forcing, find_ustar use MOM_grid, only : ocean_grid_type use MOM_hor_index, only : hor_index_type +use MOM_intrinsic_functions, only : cuberoot use MOM_lateral_mixing_coeffs, only : VarMix_CS use MOM_restart, only : register_restart_field, query_initialized, MOM_restart_CS use MOM_unit_scaling, only : unit_scale_type @@ -114,6 +115,7 @@ module MOM_mixed_layer_restrat integer :: id_wpup = -1 integer :: id_ustar = -1 integer :: id_bflux = -1 + integer :: id_lfbod = -1 !>@} end type mixedlayer_restrat_CS @@ -801,6 +803,7 @@ subroutine mixedlayer_restrat_Bodner(CS, G, GV, US, h, uhtr, vhtr, tv, forces, d wpup ! Turbulent vertical momentum [L H T-2 ~> m2 s-2 or kg m-1 s-2] real :: uDml_diag(SZIB_(G),SZJ_(G)) ! A 2D copy of uDml for diagnostics [H L2 T-1 ~> m3 s-1 or kg s-1] real :: vDml_diag(SZI_(G),SZJB_(G)) ! A 2D copy of vDml for diagnostics [H L2 T-1 ~> m3 s-1 or kg s-1] + real :: lf_bodner_diag(SZI_(G),SZJ_(G)) ! Front width as in Bodner et al., 2023 (B22), eq 24 [L ~> m] real :: U_star_2d(SZI_(G),SZJ_(G)) ! The wind friction velocity, calculated using the Boussinesq ! reference density or the time-evolving surface density in non-Boussinesq ! mode [Z T-1 ~> m s-1] @@ -823,6 +826,8 @@ subroutine mixedlayer_restrat_Bodner(CS, G, GV, US, h, uhtr, vhtr, tv, forces, d real :: u_star3 ! Cube of surface fruction velocity [m3 s-3] real :: r_wpup ! reciprocal of vertical momentum flux [T2 L-1 H-1 ~> s2 m-2 or m s2 kg-1] real :: absf ! absolute value of f, interpolated to velocity points [T-1 ~> s-1] + real :: f2_h ! Coriolis parameter at h-points squared [T-2 ~> s-2] + real :: absurdly_small_freq2 ! Frequency squared used to avoid division by 0 [T-2 ~> s-2] real :: grid_dsd ! combination of grid scales [L2 ~> m2] real :: h_sml ! "Little h", the active mixing depth with diurnal cycle removed [H ~> m or kg m-2] real :: h_big ! "Big H", the mixed layer depth based on a time filtered "little h" [H ~> m or kg m-2] @@ -852,6 +857,9 @@ subroutine mixedlayer_restrat_Bodner(CS, G, GV, US, h, uhtr, vhtr, tv, forces, d covTS(:) = 0.0 ! Might be in tv% in the future. Not implemented for the time being. varS(:) = 0.0 ! Ditto. + ! This value is roughly (pi / (the age of the universe) )^2. + absurdly_small_freq2 = 1e-34*US%T_to_s**2 + if (.not.associated(tv%eqn_of_state)) call MOM_error(FATAL, "mixedlayer_restrat_Bodner: "// & "An equation of state must be used with this module.") if (.not.CS%MLE_use_PBL_MLD) call MOM_error(FATAL, "mixedlayer_restrat_Bodner: "// & @@ -930,6 +938,21 @@ subroutine mixedlayer_restrat_Bodner(CS, G, GV, US, h, uhtr, vhtr, tv, forces, d wpup(i,j) = rmean2ts(wpup(i,j), CS%wpup_filtered(i,j), & CS%BLD_growing_Tfilt, CS%BLD_decaying_Tfilt, dt) CS%wpup_filtered(i,j) = wpup(i,j) + + if (CS%id_lfbod > 0) then + ! Calculate front length used in B22 formula (eq 24). + + ! Include an absurdly_small_freq2 to prevent division by zero. + f2_h = max( & + (0.25*((G%CoriolisBu(I,J) + G%CoriolisBu(I-1,J-1)) & + + (G%CoriolisBu(I-1,J) + G%CoriolisBu(I,J-1))))**2, & + absurdly_small_freq2) + + lf_bodner_diag(i,j) = & + 0.25 * (cuberoot(CS%mstar * u_star3 + CS%nstar * w_star3)**2 & + * (US%m_to_L * GV%m_to_H * US%T_to_s**2) & + ) / (f2_h * max(little_h(i,j), GV%Angstrom_H)) + endif enddo ; enddo if (CS%debug) then @@ -1117,6 +1140,7 @@ subroutine mixedlayer_restrat_Bodner(CS, G, GV, US, h, uhtr, vhtr, tv, forces, d if (CS%id_vhml > 0) call post_data(CS%id_vhml, vhml, CS%diag) if (CS%id_uDml > 0) call post_data(CS%id_uDml, uDml_diag, CS%diag) if (CS%id_vDml > 0) call post_data(CS%id_vDml, vDml_diag, CS%diag) + if (CS%id_lfbod > 0) call post_data(CS%id_lfbod, lf_bodner_diag, CS%diag) if (CS%id_uml > 0) then do J=js,je ; do i=is-1,ie @@ -1727,14 +1751,17 @@ logical function mixedlayer_restrat_init(Time, G, GV, US, param_file, diag, CS, 'm s-1', conversion=US%L_T_to_m_s) if (CS%use_Bodner) then CS%id_wpup = register_diag_field('ocean_model', 'MLE_wpup', diag%axesT1, Time, & - 'Vertical turbulent momentum flux in Bodner mixed layer restratificiation parameterization', & + 'Vertical turbulent momentum flux in Bodner mixed layer restratification parameterization', & 'm2 s-2', conversion=US%L_to_m*GV%H_to_m*US%s_to_T**2) CS%id_ustar = register_diag_field('ocean_model', 'MLE_ustar', diag%axesT1, Time, & - 'Surface turbulent friction velicity, u*, in Bodner mixed layer restratificiation parameterization', & + 'Surface turbulent friction velocity, u*, in Bodner mixed layer restratification parameterization', & 'm s-1', conversion=(US%Z_to_m*US%s_to_T)) CS%id_bflux = register_diag_field('ocean_model', 'MLE_bflux', diag%axesT1, Time, & - 'Surface buoyancy flux, B0, in Bodner mixed layer restratificiation parameterization', & + 'Surface buoyancy flux, B0, in Bodner mixed layer restratification parameterization', & 'm2 s-3', conversion=(US%Z_to_m**2*US%s_to_T**3)) + CS%id_lfbod = register_diag_field('ocean_model', 'lf_bodner', diag%axesT1, Time, & + 'Front length in Bodner mixed layer restratificiation parameterization', & + 'm', conversion=(US%L_to_m)) endif ! If MLD_filtered is being used, we need to update halo regions after a restart