vdiff_set_viscous_bbl Subroutine

public subroutine vdiff_set_viscous_bbl(grid, this, ms, eos, f_corner)

MOM6 set_viscous_BBL (the BOTTOMDRAGLAW branch): the per-face bottom-boundary-layer viscosity kv_bbl_u/v and thickness bbl_thick_u/v that the vertical-friction glue reads. Called ONCE per outer step, before the stage loop, from the state at the start of the step — MOM6 calls it once per step, from step_MOM_dynamics, before the predictor. No-op unless bbl_glue .and. bbl_per_face.

Per face (bed up; MOM6 counts from the surface, so its k = nz is our k = 1):

  1. h_at_vel: harmonic mean of the two cells when the flow runs thin -> thick (u·Δh >= 0), else arithmetic; T and S at the face are plain averages of the two cells’ CONCENTRATIONS (I1′ column rule).
  2. u_bbl: the h_at_vel-weighted mean, over the bottom HBBL, of sqrt(u² + v_at_u² + DRAG_BG_VEL²) (v_at_u the masked thickness-weighted average of the four transverse faces, set_v_at_u); u* = sqrt(CDRAG)·u_bbl, or sqrt(CDRAG)·DRAG_BG_VEL for the linear law or an empty average.
  3. h_N: the stratification-limited thickness, integrating the density jump up from the bed until h·Δρ reaches 400·ρ₀·u*²/g (Killworth & Edwards 1999 eq. 2.22), with ∂ρ/∂T, ∂ρ/∂S at the BBL-mean T/S and the bottom pressure ρ₀·g·Σh (no surface-pressure term).
  4. bbl_thick = h_N/(1/2 + sqrt(1/4 + (2f·h_N/u*)²)) (rotation, Killworth & Edwards 1999 eq. 2.20), floored at BBL_THICK_MIN, capped at HBBL/2 under kappa-shear.
  5. kv_bbl = sqrt(CDRAG)·u*·bbl_thick — the viscosity whose stress over bbl_thick is CDRAG·u_bbl².

A dry face gets kv_bbl = 0, bbl_thick = HBBL. Open-boundary faces are NOT given MOM6’s zero-gradient projection: they read their two cells like any interior face.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_vdiff_t), intent(inout) :: this
type(multilayer_state_t), intent(in) :: ms
type(eos_t), intent(in) :: eos

The run’s equation of state, for ∂ρ/∂T and ∂ρ/∂S.

real(kind=wp), intent(in) :: f_corner(grid%nx_total+1,grid%ny_total+1)

Coriolis parameter at cell SW corners (1/s), cor%f_corner.


Calls

proc~~vdiff_set_viscous_bbl~~CallsGraph proc~vdiff_set_viscous_bbl vdiff_set_viscous_bbl proc~bbl_column_conc_impl bbl_column_conc_impl proc~vdiff_set_viscous_bbl->proc~bbl_column_conc_impl proc~bbl_faces_impl bbl_faces_impl proc~vdiff_set_viscous_bbl->proc~bbl_faces_impl local local proc~bbl_column_conc_impl->local rdb_vl_column_conc rdb_vl_column_conc proc~bbl_column_conc_impl->rdb_vl_column_conc proc~bbl_faces_impl->local proc~eos_density_derivs eos_density_derivs proc~bbl_faces_impl->proc~eos_density_derivs proc~eos_buoyancy_coeffs eos_buoyancy_coeffs proc~eos_density_derivs->proc~eos_buoyancy_coeffs proc~roquet_spv_point roquet_spv_point proc~eos_buoyancy_coeffs->proc~roquet_spv_point

Called by

proc~~vdiff_set_viscous_bbl~~CalledByGraph proc~vdiff_set_viscous_bbl vdiff_set_viscous_bbl proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~vdiff_set_viscous_bbl proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~vdiff_set_viscous_bbl proc~engine_step engine_step proc~engine_step->proc~ocean_dyn_step proc~engine_step->proc~ocean_dyn_step_split proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
integer, private :: nx
integer, private :: ny
integer, private :: nz
logical, private :: use_eos

Source Code

   subroutine vdiff_set_viscous_bbl(grid, this, ms, eos, f_corner)
      !! MOM6 `set_viscous_BBL` (the
      !! `BOTTOMDRAGLAW` branch): the per-face bottom-boundary-layer
      !! viscosity `kv_bbl_u/v` and thickness `bbl_thick_u/v` that the
      !! vertical-friction glue reads.  Called ONCE per outer step, before
      !! the stage loop, from the state at the start of the step — MOM6
      !! calls it once per step, from `step_MOM_dynamics`, before the
      !! predictor.  No-op unless `bbl_glue .and. bbl_per_face`.
      !!
      !! Per face (bed up; MOM6 counts from the surface, so its `k = nz`
      !! is our `k = 1`):
      !!
      !!   1. `h_at_vel`: harmonic mean of the two cells when the flow runs
      !!      thin -> thick (`u·Δh >= 0`), else arithmetic;
      !!      T and S at the face are plain averages of the two cells'
      !!      CONCENTRATIONS (I1′ column rule).
      !!   2. `u_bbl`: the `h_at_vel`-weighted mean, over the bottom `HBBL`,
      !!      of `sqrt(u² + v_at_u² + DRAG_BG_VEL²)` (`v_at_u` the masked
      !!      thickness-weighted average of the four transverse faces,
      !!      `set_v_at_u`); `u* = sqrt(CDRAG)·u_bbl`, or
      !!      `sqrt(CDRAG)·DRAG_BG_VEL` for the linear law or an empty
      !!      average.
      !!   3. `h_N`: the stratification-limited thickness, integrating the
      !!      density jump up from the bed until `h·Δρ` reaches
      !!      `400·ρ₀·u*²/g` (Killworth & Edwards 1999 eq. 2.22), with
      !!      `∂ρ/∂T`, `∂ρ/∂S` at the BBL-mean T/S and the
      !!      bottom pressure `ρ₀·g·Σh` (no surface-pressure term).
      !!   4. `bbl_thick = h_N/(1/2 + sqrt(1/4 + (2f·h_N/u*)²))` (rotation,
      !!      Killworth & Edwards 1999 eq. 2.20), floored at `BBL_THICK_MIN`,
      !!      capped at `HBBL/2` under kappa-shear.
      !!   5. `kv_bbl = sqrt(CDRAG)·u*·bbl_thick` — the viscosity whose
      !!      stress over `bbl_thick` is `CDRAG·u_bbl²`.
      !!
      !! A dry face gets `kv_bbl = 0`, `bbl_thick = HBBL`.  Open-boundary
      !! faces are NOT given MOM6's zero-gradient projection: they read
      !! their two cells like any interior face.
      type(hgrid_t), intent(in) :: grid
      type(ocean_vdiff_t), intent(inout) :: this
      type(multilayer_state_t), intent(in) :: ms
      type(eos_t), intent(in) :: eos
         !! The run's equation of state, for `∂ρ/∂T` and `∂ρ/∂S`.
      real(wp), intent(in) :: f_corner(grid%nx_total + 1, grid%ny_total + 1)
         !! Coriolis parameter at cell SW corners (1/s), `cor%f_corner`.

      integer :: nx, ny, nz
      logical :: use_eos

      if (.not. (this%bbl_glue .and. this%bbl_per_face)) return
      nx = grid%nx_total
      ny = grid%ny_total
      nz = ms%nz_ml
      use_eos = ms%idx_temperature > 0 .and. ms%idx_salinity > 0
      if (use_eos) then
         call bbl_column_conc_impl(nx, ny, nz, ms%h_layer, &
                                   ms%tracers(ms%idx_temperature)%hTr, this%bbl_conc_t)
         call bbl_column_conc_impl(nx, ny, nz, ms%h_layer, &
                                   ms%tracers(ms%idx_salinity)%hTr, this%bbl_conc_s)
      end if
      call bbl_faces_impl(nx + 1, ny, nx, ny, nz, .true., &
                          ms%u_face_x_layer, ms%v_face_y_layer, ms%h_layer, ms%wet_mask, &
                          this%bbl_conc_t, this%bbl_conc_s, size(this%bbl_conc_t, 1), &
                          size(this%bbl_conc_t, 2), size(this%bbl_conc_t, 3), &
                          f_corner, use_eos, eos, this%bbl_form, this%bbl_cd, this%bbl_hbbl, &
                          this%bbl_bg_vel, this%bbl_thick_min, this%bbl_rino_cap, &
                          this%bbl_rho0, this%kv_bbl_u, this%bbl_thick_u)
      call bbl_faces_impl(nx, ny + 1, nx, ny, nz, .false., &
                          ms%u_face_x_layer, ms%v_face_y_layer, ms%h_layer, ms%wet_mask, &
                          this%bbl_conc_t, this%bbl_conc_s, size(this%bbl_conc_t, 1), &
                          size(this%bbl_conc_t, 2), size(this%bbl_conc_t, 3), &
                          f_corner, use_eos, eos, this%bbl_form, this%bbl_cd, this%bbl_hbbl, &
                          this%bbl_bg_vel, this%bbl_thick_min, this%bbl_rino_cap, &
                          this%bbl_rho0, this%kv_bbl_v, this%bbl_thick_v)
   end subroutine vdiff_set_viscous_bbl