ocean_lateral_mix_compute_vel_scale Subroutine

public pure subroutine ocean_lateral_mix_compute_vel_scale(grid, metrics, this, ms, seed_bg)

Public only for the unit-test suite; ignore in production code. Live velocity-scale viscosity (MOM6 KH_VEL_SCALE, Kh = U·Δ): per face A_vel = kh_vel_scale_live · L_grid · |u_face| (L_grid = sqrt(dxT·dyT)), max-combined into ah_face_* so it floors — never reduces — the active closure. seed_bg = .true. first fills every face with ah_bg (used when no closure ran); .false. only raises faces where A_vel exceeds the closure. No-op when kh_vel_scale_live <= 0.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_lateral_mix_t), intent(inout) :: this
type(multilayer_state_t), intent(in) :: ms
logical, intent(in) :: seed_bg

Calls

proc~~ocean_lateral_mix_compute_vel_scale~~CallsGraph proc~ocean_lateral_mix_compute_vel_scale ocean_lateral_mix_compute_vel_scale local local proc~ocean_lateral_mix_compute_vel_scale->local

Called by

proc~~ocean_lateral_mix_compute_vel_scale~~CalledByGraph proc~ocean_lateral_mix_compute_vel_scale ocean_lateral_mix_compute_vel_scale proc~ocean_lateral_mix_compute ocean_lateral_mix_compute proc~ocean_lateral_mix_compute->proc~ocean_lateral_mix_compute_vel_scale proc~run_stage run_stage proc~run_stage->proc~ocean_lateral_mix_compute proc~run_stage_split run_stage_split proc~run_stage_split->proc~ocean_lateral_mix_compute proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~run_stage proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~run_stage_split 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

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: a_vel
real(kind=wp), private :: ah_bg_local
real(kind=wp), private :: ah_max_local
integer, private :: i
integer, private :: j
integer, private :: k
real(kind=wp), private :: l_grid
integer, private :: nx
integer, private :: ny
integer, private :: nz
real(kind=wp), private :: vel_scale_local

Source Code

   pure subroutine ocean_lateral_mix_compute_vel_scale(grid, metrics, this, ms, seed_bg)
      !! Public only for the unit-test suite; ignore in production code.
      !! Live velocity-scale viscosity (MOM6 `KH_VEL_SCALE`, Kh = U·Δ):
      !! per face `A_vel = kh_vel_scale_live · L_grid · |u_face|`
      !! (`L_grid = sqrt(dxT·dyT)`), `max`-combined into `ah_face_*` so it
      !! floors — never reduces — the active closure.  `seed_bg = .true.`
      !! first fills every face with `ah_bg` (used when no closure ran);
      !! `.false.` only raises faces where `A_vel` exceeds the closure.
      !! No-op when `kh_vel_scale_live <= 0`.
      type(hgrid_t), intent(in) :: grid
      type(ocean_metrics_t), intent(in) :: metrics
      type(ocean_lateral_mix_t), intent(inout) :: this
      type(multilayer_state_t), intent(in) :: ms
      logical, intent(in) :: seed_bg

      integer :: i, j, k, nx, ny, nz
      real(wp) :: vel_scale_local, ah_bg_local, ah_max_local
      real(wp) :: a_vel, l_grid

      if (.not. this%is_init) return
      if (this%kh_vel_scale_live <= 0.0_wp) return
      if (.not. allocated(ms%u_face_x_layer)) return
      if (.not. allocated(ms%v_face_y_layer)) return

      nx = grid%nx_total
      ny = grid%ny_total
      nz = ms%nz_ml
      vel_scale_local = this%kh_vel_scale_live
      ah_bg_local = this%ah_bg
      ah_max_local = this%ah_max

      ! ---- u-faces (i-1/2, j): A_vel from |u_face_x| ----
      ! Interior faces i=2:nx (the closures' range); L_grid taken at
      ! the west-adjacent T cell (i-1).  Cap and floor as the closures
      ! do.  Wall faces (i=1, i=nx+1) get the background under seeding.
      do concurrent(k=1:nz, j=1:ny, i=2:nx) local(a_vel, l_grid)
         l_grid = sqrt(metrics%dxT(i - 1, j)*metrics%dyT(i - 1, j))
         a_vel = min(ah_max_local, vel_scale_local*l_grid*abs(ms%u_face_x_layer(i, j, k)))
         if (seed_bg) then
            this%ah_face_x(i, j, k) = max(ah_bg_local, a_vel)
         else
            this%ah_face_x(i, j, k) = max(this%ah_face_x(i, j, k), a_vel)
         end if
      end do
      do concurrent(k=1:nz, j=1:ny)
         if (seed_bg) then
            this%ah_face_x(1, j, k) = ah_bg_local
            this%ah_face_x(nx + 1, j, k) = ah_bg_local
         end if
      end do

      ! ---- v-faces (i, j-1/2): A_vel from |v_face_y| ----
      ! Interior faces j=2:ny; L_grid at the south-adjacent T cell.
      do concurrent(k=1:nz, j=2:ny, i=1:nx) local(a_vel, l_grid)
         l_grid = sqrt(metrics%dxT(i, j - 1)*metrics%dyT(i, j - 1))
         a_vel = min(ah_max_local, vel_scale_local*l_grid*abs(ms%v_face_y_layer(i, j, k)))
         if (seed_bg) then
            this%ah_face_y(i, j, k) = max(ah_bg_local, a_vel)
         else
            this%ah_face_y(i, j, k) = max(this%ah_face_y(i, j, k), a_vel)
         end if
      end do
      do concurrent(k=1:nz, i=1:nx)
         if (seed_bg) then
            this%ah_face_y(i, 1, k) = ah_bg_local
            this%ah_face_y(i, ny + 1, k) = ah_bg_local
         end if
      end do
   end subroutine ocean_lateral_mix_compute_vel_scale