From 1705c024e02e0a1928de5c8901c9c9bbf19c8d46 Mon Sep 17 00:00:00 2001 From: Luke Van Roekel Date: Wed, 10 Jul 2024 15:32:48 -0500 Subject: [PATCH] Fixes to KPP interface Two portions of the KPP interface had bugs 1. the computation of surface buoyancy forcing and friction velocity were incorrect. The surfaceBuoyancyForcing subtracted the wrong values from the heat fluxes from thickness fluxes. The surfaceFrictionVelocity had incorrect interpolation to centers 2. the KPP interface for matchBoth is fixed and the indexing is fixed for matching interior to boundary layer diffusivities. --- .../src/shared/mpas_ocn_diagnostics.F | 26 +++---------------- .../src/shared/mpas_ocn_vmix_cvmix.F | 13 +++++----- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index 52ef08267fc1..1b5df485a20d 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -3303,8 +3303,7 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & evapTemperatureFlux, & icebergTemperatureFlux, & seaIceTemperatureFlux, & - surfaceStress, & - surfaceStressMagnitude + sfcStressMag, & real (kind=RKIND), dimension(:,:), pointer :: & layerThickness, &! layer thickness @@ -3381,10 +3380,8 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & surfaceThicknessFluxRunoff) call mpas_pool_get_array(forcingPool, 'penetrativeTemperatureFlux', & penetrativeTemperatureFlux) - call mpas_pool_get_array(forcingPool, 'surfaceStress', & - surfaceStress) call mpas_pool_get_array(forcingPool, 'surfaceStressMagnitude', & - surfaceStressMagnitude) + sfcStressMag) call mpas_pool_get_array(forcingPool, 'rainTemperatureFlux', & rainTemperatureFlux) call mpas_pool_get_array(forcingPool, 'evapTemperatureFlux', & @@ -3477,9 +3474,7 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & - fracAbsorbed* (rainTemperatureFlux(iCell) + & evapTemperatureFlux(iCell) + & seaIceTemperatureFlux(iCell) + & - icebergTemperatureFlux(iCell)) & - - fracAbsorbedRunoff* & - activeTracersSurfaceFluxRunoff(indexTempFlux,iCell) + icebergTemperatureFlux(iCell)) nonLocalSurfaceTracerFlux(indexSaltFlux,iCell) = & activeTracersSurfaceFlux(indexSaltFlux,iCell) & @@ -3500,21 +3495,8 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & surfaceBuoyancyForcing(iCell) = surfaceBuoyancyForcing(iCell)* & gravity - ! compute magnitude of surface stress - sumSurfaceStressSquared = 0.0_RKIND - do i = 1, nEdgesOnCell(iCell) - iEdge = edgesOnCell(i, iCell) - sumSurfaceStressSquared = sumSurfaceStressSquared & - + edgeAreaFractionOfCell(i,iCell)* & - surfaceStress(iEdge)**2 - enddo - - ! NOTE that the factor of 2 is from averaging dot products - ! to cell centers on a C-grid - surfaceStressMagnitude(iCell) = & - sqrt(2.0_RKIND * sumSurfaceStressSquared) surfaceFrictionVelocity(iCell) = & - sqrt(surfaceStressMagnitude(iCell) / rho_sw) + sqrt(sfcStressMag(iCell) / rho_sw) enddo !$omp end do diff --git a/components/mpas-ocean/src/shared/mpas_ocn_vmix_cvmix.F b/components/mpas-ocean/src/shared/mpas_ocn_vmix_cvmix.F index fcede65e420c..c9a9f52c6f0a 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_vmix_cvmix.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_vmix_cvmix.F @@ -65,7 +65,7 @@ module ocn_vmix_cvmix type(cvmix_tidal_params_type) :: cvmix_tidal_params logical :: cvmixOn, cvmixConvectionOn, cvmixKPPOn - real (kind=RKIND) :: backgroundVisc, backgroundDiff + real (kind=RKIND) :: multVal, backgroundVisc, backgroundDiff integer :: cvmixBackgroundChoice ! user choice of cvmix background scheme @@ -725,9 +725,9 @@ subroutine ocn_vmix_coefs_cvmix_build(meshPool, statePool, forcingPool, err, tim ! intent out of BoundaryLayerDepth is boundary layer depth measured in meters and vertical index indexBoundaryLayerDepth(iCell) = cvmix_variables % kOBL_depth - do k = minLevelCell(iCell), maxLevelCell(iCell) + 1 - vertViscTopOfCell(k, iCell) = cvmix_variables % Mdiff_iface(k) - vertDiffTopOfCell(k, iCell) = cvmix_variables % Tdiff_iface(k) + do k = minLevelCell(iCell), floor(indexBoundaryLayerDepth(iCell)) + 1 + vertViscTopOfCell(k, iCell) = multVal*vertViscTopOfCell(k,iCell) + cvmix_variables % Mdiff_iface(k) + vertDiffTopOfCell(k, iCell) = multVal*vertDiffTopOfCell(k,iCell) + cvmix_variables % Tdiff_iface(k) end do ! store non-local flux terms @@ -751,7 +751,7 @@ subroutine ocn_vmix_coefs_cvmix_build(meshPool, statePool, forcingPool, err, tim ! add convective mixing to vertical viscosity/diffusivity ! if using KPP, then do not apply convective mixing within the ocean boundary layer if(config_use_cvmix_kpp) then - do k = ceiling(indexBoundaryLayerDepth(iCell)) + 1, maxLevelCell(iCell) + do k = floor(indexBoundaryLayerDepth(iCell)) + 1, maxLevelCell(iCell) vertViscTopOfCell(k,iCell) = vertViscTopOfCell(k,iCell) + cvmix_variables % Mdiff_iface(k) vertDiffTopOfCell(k,iCell) = vertDiffTopOfCell(k,iCell) + cvmix_variables % Tdiff_iface(k) enddo @@ -1081,13 +1081,14 @@ subroutine ocn_vmix_cvmix_init(domain,err)!{{{ call cvmix_init_kpp ( & ri_crit = config_cvmix_kpp_criticalBulkRichardsonNumber, & interp_type = config_cvmix_kpp_interpolationOMLType, & - interp_type2 = config_cvmix_kpp_interpolationOMLType, & + interp_type2 = 'LMD94', & lEkman = config_cvmix_kpp_EkmanOBL, & lMonOb = config_cvmix_kpp_MonObOBL, & MatchTechnique = config_cvmix_kpp_matching, & surf_layer_ext = config_cvmix_kpp_surface_layer_extent, & langmuir_mixing_str = config_cvmix_kpp_langmuir_mixing_opt, & langmuir_entrainment_str = config_cvmix_kpp_langmuir_entrainment_opt, & + lnoDGat1 = .true., & lenhanced_diff = config_cvmix_kpp_use_enhanced_diff) endif