kappa_shear_vertex_scatter Subroutine

public pure subroutine kappa_shear_vertex_scatter(nx, ny, nzp1, geometric, kdmin, wet_t, kd_corner, kd_int, tke_int)

Corner -> tracer-point averaging (MOM6 vertex form, Pass C). Cell (i,j) reads its four corners SW=(i,j), SE=(i+1,j), NW=(i,j+1), NE=(i+1,j+1) — a read-only corner stencil into an own-cell write, safe as its own do concurrent but NEVER fusable with the corner solve (kd_corner is the required snapshot). Two modes: arithmetic (default): 0.25 * ((SW+NE) + (NW+SE)) geometric: 4th root of the product of the four corner values, each floored at kdmin first — a geometric mean is 0 if ANY factor is 0, which would otherwise blank Kd along every shear-zone edge. The floor applies to the CORNER values only, never the output: a land cell still gets exactly 0 via the wet_t multiply. Endpoints (bed K=1, surface K=nzp1) are forced to exactly 0. tke_int is zeroed — the vertex form does not carry a cell-centred TKE (corner TKE deliberately not materialised). Bracketing is reproducible-sum ordering; keep literal.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nzp1
logical, intent(in) :: geometric
real(kind=wp), intent(in) :: kdmin
real(kind=wp), intent(in) :: wet_t(nx,ny)
real(kind=wp), intent(in) :: kd_corner(nx+1,ny+1,nzp1)
real(kind=wp), intent(out) :: kd_int(nx,ny,nzp1)
real(kind=wp), intent(out) :: tke_int(nx,ny,nzp1)

Calls

proc~~kappa_shear_vertex_scatter~~CallsGraph proc~kappa_shear_vertex_scatter kappa_shear_vertex_scatter local local proc~kappa_shear_vertex_scatter->local

Called by

proc~~kappa_shear_vertex_scatter~~CalledByGraph proc~kappa_shear_vertex_scatter kappa_shear_vertex_scatter proc~kappa_shear_compute kappa_shear_compute proc~kappa_shear_compute->proc~kappa_shear_vertex_scatter proc~vmix_apply_in_stage vmix_apply_in_stage proc~vmix_apply_in_stage->proc~kappa_shear_compute proc~run_stage run_stage proc~run_stage->proc~vmix_apply_in_stage proc~run_stage_split run_stage_split proc~run_stage_split->proc~vmix_apply_in_stage 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

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: c_ne
real(kind=wp), private :: c_nw
real(kind=wp), private :: c_se
real(kind=wp), private :: c_sw
integer, private :: i
integer, private :: j
integer, private :: k

Source Code

   pure subroutine kappa_shear_vertex_scatter(nx, ny, nzp1, geometric, kdmin, &
                                              wet_t, kd_corner, kd_int, tke_int)
      !! Corner -> tracer-point averaging (MOM6 vertex form, Pass C).
      !! Cell (i,j) reads its four corners SW=(i,j), SE=(i+1,j),
      !! NW=(i,j+1), NE=(i+1,j+1) — a read-only corner stencil into an
      !! own-cell write, safe as its own `do concurrent` but NEVER
      !! fusable with the corner solve (`kd_corner` is the required
      !! snapshot).  Two modes:
      !!   arithmetic (default): 0.25 * ((SW+NE) + (NW+SE))
      !!   geometric:  4th root of the product of the four corner
      !!     values, each floored at `kdmin` first — a geometric mean is
      !!     0 if ANY factor is 0, which would otherwise blank Kd along
      !!     every shear-zone edge.  The floor applies to the CORNER
      !!     values only, never the output: a land cell still gets
      !!     exactly 0 via the wet_t multiply.
      !! Endpoints (bed K=1, surface K=nzp1) are forced to exactly 0.
      !! `tke_int` is zeroed — the vertex form does not carry a
      !! cell-centred TKE (corner TKE deliberately not materialised).
      !! Bracketing is reproducible-sum ordering; keep literal.
      integer, intent(in) :: nx, ny, nzp1
      logical, intent(in) :: geometric
      real(wp), intent(in) :: kdmin
      real(wp), intent(in) :: wet_t(nx, ny)
      real(wp), intent(in) :: kd_corner(nx + 1, ny + 1, nzp1)
      real(wp), intent(out) :: kd_int(nx, ny, nzp1)
      real(wp), intent(out) :: tke_int(nx, ny, nzp1)

      integer :: i, j, k
      real(wp) :: c_sw, c_se, c_nw, c_ne

      do concurrent(k=1:nzp1, j=1:ny, i=1:nx) local(c_sw, c_se, c_nw, c_ne)
         if (k == 1 .or. k == nzp1) then
            kd_int(i, j, k) = 0.0_wp
         else
            c_sw = kd_corner(i, j, k)
            c_se = kd_corner(i + 1, j, k)
            c_nw = kd_corner(i, j + 1, k)
            c_ne = kd_corner(i + 1, j + 1, k)
            if (geometric) then
               kd_int(i, j, k) = wet_t(i, j)*sqrt(sqrt( &
                                                  (max(c_sw, kdmin)*max(c_ne, kdmin))* &
                                                  (max(c_nw, kdmin)*max(c_se, kdmin))))
            else
               kd_int(i, j, k) = wet_t(i, j)*0.25_wp* &
                                 ((c_sw + c_ne) + (c_nw + c_se))
            end if
         end if
         tke_int(i, j, k) = 0.0_wp
      end do
   end subroutine kappa_shear_vertex_scatter