From 3176b17ed7a1324b881ab46a4901b4b78f9ce99b Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Wed, 8 Jan 2025 12:50:22 -0500 Subject: [PATCH] +Rename fluxes%TKE_tidal to fluxes%BBL_tidal_dis Revised the name of fluxes%TKE_tidal to fluxes%BBL_tidal_dis to better reflect what this field holds,and the fact that the efficiency of the conversion from mean kinetic energy loss to turbulent kinetic energy has not been applied yet. The units of fluxes%BBL_tidal_dis are [R Z L2 T-3 ~> W m-2], whereas those of fluxes%TKE_tidal were [R Z3 T-3 ~> W m-2]. The factor rescaling between the units of mean kinetic energy and those of turbulent kinetic energy were already in set_diffusivity_CS%BBL_effic, and these have been cancelled out by this change, but this is offset by the addition of rescaling factors in the term setting this array in the NUOPC and mct convert_IOB_to_fluxes routines. In the FMS_cap version of convert_IOB_to_fluxes, the extra rescaling factor is rolled into the scaling factor used in the get_param call for rho_TKE_tidal. All answers are bitwise identical, but there is a change in the name and rescaled units of an element of a transparent type. --- .../FMS_cap/MOM_surface_forcing_gfdl.F90 | 29 ++++++++++-------- .../STALE_mct_cap/mom_surface_forcing_mct.F90 | 4 +-- .../nuopc_cap/mom_surface_forcing_nuopc.F90 | 4 +-- src/core/MOM_forcing_type.F90 | 30 ++++++++++--------- .../vertical/MOM_set_diffusivity.F90 | 10 +++---- 5 files changed, 42 insertions(+), 35 deletions(-) diff --git a/config_src/drivers/FMS_cap/MOM_surface_forcing_gfdl.F90 b/config_src/drivers/FMS_cap/MOM_surface_forcing_gfdl.F90 index b686c59a1f..f59a7c7fe1 100644 --- a/config_src/drivers/FMS_cap/MOM_surface_forcing_gfdl.F90 +++ b/config_src/drivers/FMS_cap/MOM_surface_forcing_gfdl.F90 @@ -88,8 +88,8 @@ module MOM_surface_forcing_gfdl real :: gust_const !< Constant unresolved background gustiness for ustar [R L Z T-2 ~> Pa] logical :: read_gust_2d !< If true, use a 2-dimensional gustiness supplied from an input file. real, pointer, dimension(:,:) :: & - TKE_tidal => NULL() !< Turbulent kinetic energy introduced to the bottom boundary layer - !! by drag on the tidal flows [R Z3 T-3 ~> W m-2]. + BBL_tidal_dis => NULL() !< Tidal energy dissipation in the bottom boundary layer that can act as a + !! source of energy for bottom boundary layer mixing [R Z L2 T-3 ~> W m-2] real, pointer, dimension(:,:) :: & gust => NULL() !< A spatially varying unresolved background gustiness that !! contributes to ustar [R L Z T-2 ~> Pa]. gust is used when read_gust_2d is true. @@ -302,7 +302,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G, call safe_alloc_ptr(fluxes%salt_flux,isd,ied,jsd,jed) call safe_alloc_ptr(fluxes%salt_flux_in,isd,ied,jsd,jed) - call safe_alloc_ptr(fluxes%TKE_tidal,isd,ied,jsd,jed) + call safe_alloc_ptr(fluxes%BBL_tidal_dis,isd,ied,jsd,jed) call safe_alloc_ptr(fluxes%ustar_tidal,isd,ied,jsd,jed) call safe_alloc_ptr(fluxes%heat_added,isd,ied,jsd,jed) @@ -311,7 +311,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G, if (associated(IOB%excess_salt)) call safe_alloc_ptr(fluxes%salt_left_behind,isd,ied,jsd,jed) do j=js-2,je+2 ; do i=is-2,ie+2 - fluxes%TKE_tidal(i,j) = CS%TKE_tidal(i,j) + fluxes%BBL_tidal_dis(i,j) = CS%BBL_tidal_dis(i,j) fluxes%ustar_tidal(i,j) = CS%ustar_tidal(i,j) enddo ; enddo @@ -1304,11 +1304,15 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger) ! Local variables real :: utide ! The RMS tidal velocity [Z T-1 ~> m s-1]. + real, dimension(SZI_(G),SZJ_(G)) :: & + utide_2d ! A 2d array of RMS tidal velocities [Z T-1 ~> m s-1]. real :: Flux_const_dflt ! A default piston velocity for restoring surface properties [m day-1] logical :: Boussinesq ! If true, this run is fully Boussinesq logical :: semi_Boussinesq ! If true, this run is partially non-Boussinesq - real :: rho_TKE_tidal ! The constant bottom density used to translate tidal amplitudes into the - ! tidal bottom TKE input used with INT_TIDE_DISSIPATION [R ~> kg m-3] + real :: rho_TKE_tidal ! The constant bottom density used to translate tidal amplitudes into + ! the tidal bottom TKE input used with INT_TIDE_DISSIPATION, times the + ! factor rescaling from the units of TKE to those of mean kinetic + ! energy [R L2 Z-2 ~> kg m-3] logical :: new_sim ! False if this simulation was started from a restart file ! or other equivalent files. logical :: iceberg_flux_diags ! If true, diagnostics of fluxes from icebergs are available. @@ -1573,27 +1577,28 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger) call get_param(param_file, mdl, "TKE_TIDAL_RHO", rho_TKE_tidal, & "The constant bottom density used to translate tidal amplitudes into the tidal "//& "bottom TKE input used with INT_TIDE_DISSIPATION.", & - units="kg m-3", default=CS%Rho0*US%R_to_kg_m3, scale=US%kg_m3_to_R, & + units="kg m-3", default=CS%Rho0*US%R_to_kg_m3, scale=US%kg_m3_to_R*US%Z_to_L**2, & do_not_log=.not.(CS%read_TIDEAMP.or.(CS%utide>0.0))) - call safe_alloc_ptr(CS%TKE_tidal,isd,ied,jsd,jed) + call safe_alloc_ptr(CS%BBL_tidal_dis,isd,ied,jsd,jed) call safe_alloc_ptr(CS%ustar_tidal,isd,ied,jsd,jed) if (CS%read_TIDEAMP) then TideAmp_file = trim(CS%inputdir) // trim(TideAmp_file) ! NOTE: There are certain cases where FMS is unable to read this file, so ! we use read_netCDF_data in place of MOM_read_data. - call read_netCDF_data(TideAmp_file, 'tideamp', CS%TKE_tidal, G%Domain, & + utide_2d(:,:) = 0.0 + call read_netCDF_data(TideAmp_file, 'tideamp', utide_2d, G%Domain, & rescale=US%m_to_Z*US%T_to_s) do j=jsd, jed; do i=isd, ied - utide = CS%TKE_tidal(i,j) - CS%TKE_tidal(i,j) = G%mask2dT(i,j)*rho_TKE_tidal*CS%cd_tides*(utide*utide*utide) + utide = utide_2d(i,j) + CS%BBL_tidal_dis(i,j) = G%mask2dT(i,j)*rho_TKE_tidal*CS%cd_tides*(utide*utide*utide) CS%ustar_tidal(i,j) = sqrt(CS%cd_tides)*utide enddo ; enddo else do j=jsd,jed; do i=isd,ied utide = CS%utide - CS%TKE_tidal(i,j) = rho_TKE_tidal*CS%cd_tides*(utide*utide*utide) + CS%BBL_tidal_dis(i,j) = rho_TKE_tidal*CS%cd_tides*(utide*utide*utide) CS%ustar_tidal(i,j) = sqrt(CS%cd_tides)*utide enddo ; enddo endif diff --git a/config_src/drivers/STALE_mct_cap/mom_surface_forcing_mct.F90 b/config_src/drivers/STALE_mct_cap/mom_surface_forcing_mct.F90 index 720046d517..ab3964e626 100644 --- a/config_src/drivers/STALE_mct_cap/mom_surface_forcing_mct.F90 +++ b/config_src/drivers/STALE_mct_cap/mom_surface_forcing_mct.F90 @@ -295,7 +295,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G, call safe_alloc_ptr(fluxes%salt_flux_in,isd,ied,jsd,jed) call safe_alloc_ptr(fluxes%salt_flux_added,isd,ied,jsd,jed) - call safe_alloc_ptr(fluxes%TKE_tidal,isd,ied,jsd,jed) + call safe_alloc_ptr(fluxes%BBL_tidal_dis,isd,ied,jsd,jed) call safe_alloc_ptr(fluxes%ustar_tidal,isd,ied,jsd,jed) if (CS%allow_flux_adjustments) then @@ -304,7 +304,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G, endif do j=js-2,je+2 ; do i=is-2,ie+2 - fluxes%TKE_tidal(i,j) = CS%TKE_tidal(i,j) + fluxes%BBL_tidal_dis(i,j) = US%Z_to_L**2*CS%TKE_tidal(i,j) fluxes%ustar_tidal(i,j) = CS%ustar_tidal(i,j) enddo ; enddo diff --git a/config_src/drivers/nuopc_cap/mom_surface_forcing_nuopc.F90 b/config_src/drivers/nuopc_cap/mom_surface_forcing_nuopc.F90 index 5d09c58917..61afee89ba 100644 --- a/config_src/drivers/nuopc_cap/mom_surface_forcing_nuopc.F90 +++ b/config_src/drivers/nuopc_cap/mom_surface_forcing_nuopc.F90 @@ -317,7 +317,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G, call safe_alloc_ptr(fluxes%salt_flux_in,isd,ied,jsd,jed) call safe_alloc_ptr(fluxes%salt_flux_added,isd,ied,jsd,jed) - call safe_alloc_ptr(fluxes%TKE_tidal,isd,ied,jsd,jed) + call safe_alloc_ptr(fluxes%BBL_tidal_dis,isd,ied,jsd,jed) call safe_alloc_ptr(fluxes%ustar_tidal,isd,ied,jsd,jed) if (CS%allow_flux_adjustments) then @@ -326,7 +326,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G, endif do j=js-2,je+2 ; do i=is-2,ie+2 - fluxes%TKE_tidal(i,j) = CS%TKE_tidal(i,j) + fluxes%BBL_tidal_dis(i,j) = US%Z_to_L**2*CS%TKE_tidal(i,j) fluxes%ustar_tidal(i,j) = CS%ustar_tidal(i,j) enddo ; enddo diff --git a/src/core/MOM_forcing_type.F90 b/src/core/MOM_forcing_type.F90 index 998713d1f1..8572bbee01 100644 --- a/src/core/MOM_forcing_type.F90 +++ b/src/core/MOM_forcing_type.F90 @@ -168,7 +168,8 @@ module MOM_forcing_type ! tide related inputs real, pointer, dimension(:,:) :: & - TKE_tidal => NULL(), & !< tidal energy source driving mixing in bottom boundary layer [R Z3 T-3 ~> W m-2] + BBL_tidal_dis => NULL(), & !< Tidal energy dissipation in the bottom boundary layer that can act + !! as a source of energy for bottom boundary layer mixing [R Z L2 T-3 ~> W m-2] ustar_tidal => NULL() !< tidal contribution to bottom ustar [Z T-1 ~> m s-1] ! iceberg related inputs @@ -1313,8 +1314,9 @@ subroutine MOM_forcing_chksum(mesg, fluxes, G, US, haloshift) call hchksum(fluxes%ice_fraction, mesg//" fluxes%ice_fraction", G%HI, haloshift=hshift) if (associated(fluxes%salt_flux)) & call hchksum(fluxes%salt_flux, mesg//" fluxes%salt_flux", G%HI, haloshift=hshift, unscale=US%RZ_T_to_kg_m2s) - if (associated(fluxes%TKE_tidal)) & - call hchksum(fluxes%TKE_tidal, mesg//" fluxes%TKE_tidal", G%HI, haloshift=hshift, unscale=US%RZ3_T3_to_W_m2) + if (associated(fluxes%BBL_tidal_dis)) & + call hchksum(fluxes%BBL_tidal_dis, mesg//" fluxes%BBL_tidal_dis", G%HI, haloshift=hshift, & + unscale=US%L_to_Z**2*US%RZ3_T3_to_W_m2) if (associated(fluxes%ustar_tidal)) & call hchksum(fluxes%ustar_tidal, mesg//" fluxes%ustar_tidal", G%HI, haloshift=hshift, unscale=US%Z_to_m*US%s_to_T) if (associated(fluxes%lrunoff)) & @@ -1438,7 +1440,7 @@ subroutine forcing_SinglePointPrint(fluxes, G, i, j, mesg) call locMsg(fluxes%seaice_melt_heat,'seaice_melt_heat') call locMsg(fluxes%p_surf,'p_surf') call locMsg(fluxes%salt_flux,'salt_flux') - call locMsg(fluxes%TKE_tidal,'TKE_tidal') + call locMsg(fluxes%BBL_tidal_dis,'BBL_tidal_dis') call locMsg(fluxes%ustar_tidal,'ustar_tidal') call locMsg(fluxes%lrunoff,'lrunoff') call locMsg(fluxes%frunoff,'frunoff') @@ -1546,7 +1548,7 @@ subroutine register_forcing_type_diags(Time, diag, US, use_temperature, handles, cmor_standard_name='sea_water_pressure_at_sea_water_surface') handles%id_TKE_tidal = register_diag_field('ocean_model', 'TKE_tidal', diag%axesT1, Time, & - 'Tidal source of BBL mixing', 'W m-2', conversion=US%RZ3_T3_to_W_m2) + 'Tidal source of BBL mixing', 'W m-2', conversion=US%L_to_Z**2*US%RZ3_T3_to_W_m2) if (.not. use_temperature) then handles%id_buoy = register_diag_field('ocean_model', 'buoy', diag%axesT1, Time, & @@ -3160,8 +3162,8 @@ subroutine forcing_diagnostics(fluxes_in, sfc_state, G_in, US, time_end, diag, h if ((handles%id_psurf > 0) .and. associated(fluxes%p_surf)) & call post_data(handles%id_psurf, fluxes%p_surf, diag) - if ((handles%id_TKE_tidal > 0) .and. associated(fluxes%TKE_tidal)) & - call post_data(handles%id_TKE_tidal, fluxes%TKE_tidal, diag) + if ((handles%id_TKE_tidal > 0) .and. associated(fluxes%BBL_tidal_dis)) & + call post_data(handles%id_TKE_tidal, fluxes%BBL_tidal_dis, diag) if ((handles%id_buoy > 0) .and. associated(fluxes%buoy)) & call post_data(handles%id_buoy, fluxes%buoy, diag) @@ -3348,8 +3350,8 @@ subroutine allocate_forcing_by_ref(fluxes_ref, G, fluxes, turns) call myAlloc(fluxes%buoy, G%isd, G%ied, G%jsd, G%jed, & associated(fluxes_ref%buoy)) - call myAlloc(fluxes%TKE_tidal, G%isd, G%ied, G%jsd, G%jed, & - associated(fluxes_ref%TKE_tidal)) + call myAlloc(fluxes%BBL_tidal_dis, G%isd, G%ied, G%jsd, G%jed, & + associated(fluxes_ref%BBL_tidal_dis)) call myAlloc(fluxes%ustar_tidal, G%isd, G%ied, G%jsd, G%jed, & associated(fluxes_ref%ustar_tidal)) @@ -3566,7 +3568,7 @@ subroutine deallocate_forcing_type(fluxes) if (associated(fluxes%salt_flux)) deallocate(fluxes%salt_flux) if (associated(fluxes%p_surf_full)) deallocate(fluxes%p_surf_full) if (associated(fluxes%p_surf)) deallocate(fluxes%p_surf) - if (associated(fluxes%TKE_tidal)) deallocate(fluxes%TKE_tidal) + if (associated(fluxes%BBL_tidal_dis)) deallocate(fluxes%BBL_tidal_dis) if (associated(fluxes%ustar_tidal)) deallocate(fluxes%ustar_tidal) if (associated(fluxes%ustar_shelf)) deallocate(fluxes%ustar_shelf) if (associated(fluxes%iceshelf_melt)) deallocate(fluxes%iceshelf_melt) @@ -3713,8 +3715,8 @@ subroutine rotate_forcing(fluxes_in, fluxes, turns) if (associated(fluxes_in%buoy)) & call rotate_array(fluxes_in%buoy, turns, fluxes%buoy) - if (associated(fluxes_in%TKE_tidal)) & - call rotate_array(fluxes_in%TKE_tidal, turns, fluxes%TKE_tidal) + if (associated(fluxes_in%BBL_tidal_dis)) & + call rotate_array(fluxes_in%BBL_tidal_dis, turns, fluxes%BBL_tidal_dis) if (associated(fluxes_in%ustar_tidal)) & call rotate_array(fluxes_in%ustar_tidal, turns, fluxes%ustar_tidal) @@ -3985,8 +3987,8 @@ subroutine homogenize_forcing(fluxes, G, GV, US) if (associated(fluxes%buoy)) & call homogenize_field_t(fluxes%buoy, G, tmp_scale=US%L_to_m**2*US%s_to_T**3) - if (associated(fluxes%TKE_tidal)) & - call homogenize_field_t(fluxes%TKE_tidal, G, tmp_scale=US%RZ3_T3_to_W_m2) + if (associated(fluxes%BBL_tidal_dis)) & + call homogenize_field_t(fluxes%BBL_tidal_dis, G, tmp_scale=US%L_to_Z**2*US%RZ3_T3_to_W_m2) if (associated(fluxes%ustar_tidal)) & call homogenize_field_t(fluxes%ustar_tidal, G, tmp_scale=US%Z_to_m*US%s_to_T) diff --git a/src/parameterizations/vertical/MOM_set_diffusivity.F90 b/src/parameterizations/vertical/MOM_set_diffusivity.F90 index 27c8ed7755..056a89a190 100644 --- a/src/parameterizations/vertical/MOM_set_diffusivity.F90 +++ b/src/parameterizations/vertical/MOM_set_diffusivity.F90 @@ -1416,8 +1416,8 @@ subroutine add_drag_diffusivity(h, u, v, tv, fluxes, visc, j, TKE_to_Kd, maxTKE, endif TKE(i) = ((CS%BBL_effic * cdrag_sqrt) * exp(-I2decay(i)*h(i,j,nz)) ) * visc%BBL_meanKE_loss(i,j) - if (associated(fluxes%TKE_tidal)) & - TKE(i) = TKE(i) + US%Z_to_L**2*fluxes%TKE_tidal(i,j) * GV%RZ_to_H * & + if (associated(fluxes%BBL_tidal_dis)) & + TKE(i) = TKE(i) + fluxes%BBL_tidal_dis(i,j) * GV%RZ_to_H * & (CS%BBL_effic * exp(-I2decay(i)*h(i,j,nz))) ! Distribute the work over a BBL of depth 20^2 ustar^2 / g' following @@ -1647,9 +1647,9 @@ subroutine add_LOTW_BBL_diffusivity(h, u, v, tv, fluxes, visc, j, N2_int, Rho_bo !### I am still unsure about sqrt(cdrag) in this expressions - AJA BBL_meanKE_dis = cdrag_sqrt * visc%BBL_meanKE_loss(i,j) ! Add in tidal dissipation energy at the bottom [H Z2 T-3 ~> m3 s-3 or W m-2]. - ! Note that TKE_tidal is in [R Z3 T-3 ~> W m-2]. - if (associated(fluxes%TKE_tidal)) & - BBL_meanKE_dis = BBL_meanKE_dis + US%Z_to_L**2*fluxes%TKE_tidal(i,j) * GV%RZ_to_H + ! Note that BBL_tidal_dis is in [R Z L2 T-3 ~> W m-2]. + if (associated(fluxes%BBL_tidal_dis)) & + BBL_meanKE_dis = BBL_meanKE_dis + fluxes%BBL_tidal_dis(i,j) * GV%RZ_to_H TKE_column = CS%BBL_effic * BBL_meanKE_dis ! Only use a fraction of the mechanical dissipation for mixing. TKE_remaining = TKE_column