vmix_bkgnd_fill_impl Subroutine

public pure subroutine vmix_bkgnd_fill_impl(nx, ny, nzp1, kd_bg, h_layer, kd_sfc, kd_deep, z0, delta)

Fill the per-interface Bryan & Lewis (1979) JGR 84:2503 background tracer-diffusivity profile from the CURRENT column interface depths.

Kd_bg(z) = Kd_sfc + (Kd_deep - Kd_sfc)·[½ + atan((|z| - z0)/Δ)/π]

z is the interface depth below the free surface, accumulated from the current h_layer (surface k=nzp1 → bed k=1) so the profile is correct under any vcoord (z*, sigma, …) and tracks the moving free surface. Boundary interfaces k=1 (bed) and k=nzp1 (surface) are left untouched (the assembly clip only floors k=2..nzp1-1).

There is no Henyey-scaled variant of this fill: Bryan-Lewis and the Henyey latitude factor are mutually exclusive (configure refuses both), matching the reference formulation. The Henyey path scales the SCALAR background instead — see vmix_assemble_clip_henyey_impl.

Explicit-shape args so the do concurrent stays descriptor-walk free.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nzp1
real(kind=wp), intent(inout) :: kd_bg(nx,ny,nzp1)
real(kind=wp), intent(in) :: h_layer(nx,ny,nzp1-1)
real(kind=wp), intent(in) :: kd_sfc

Surface / deep asymptotes (m^2/s), transition centre depth (m), transition half-width (m).

real(kind=wp), intent(in) :: kd_deep

Surface / deep asymptotes (m^2/s), transition centre depth (m), transition half-width (m).

real(kind=wp), intent(in) :: z0

Surface / deep asymptotes (m^2/s), transition centre depth (m), transition half-width (m).

real(kind=wp), intent(in) :: delta

Surface / deep asymptotes (m^2/s), transition centre depth (m), transition half-width (m).


Calls

proc~~vmix_bkgnd_fill_impl~~CallsGraph proc~vmix_bkgnd_fill_impl vmix_bkgnd_fill_impl local local proc~vmix_bkgnd_fill_impl->local

Called by

proc~~vmix_bkgnd_fill_impl~~CalledByGraph proc~vmix_bkgnd_fill_impl vmix_bkgnd_fill_impl proc~vmix_assemble vmix_assemble proc~vmix_assemble->proc~vmix_bkgnd_fill_impl proc~vmix_apply_in_stage vmix_apply_in_stage proc~vmix_apply_in_stage->proc~vmix_assemble 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 :: depth
integer, private :: i
real(kind=wp), private :: inv_pi
integer, private :: j
integer, private :: k

Source Code

   pure subroutine vmix_bkgnd_fill_impl(nx, ny, nzp1, kd_bg, h_layer, &
                                        kd_sfc, kd_deep, z0, delta)
      !! Fill the per-interface Bryan & Lewis (1979) JGR 84:2503 background
      !! tracer-diffusivity profile from the CURRENT column interface depths.
      !!
      !!   Kd_bg(z) = Kd_sfc + (Kd_deep - Kd_sfc)·[½ + atan((|z| - z0)/Δ)/π]
      !!
      !! z is the interface depth below the free surface, accumulated from
      !! the current `h_layer` (surface k=nzp1 → bed k=1) so the profile is
      !! correct under any vcoord (z*, sigma, …) and tracks the moving free
      !! surface.  Boundary interfaces k=1 (bed) and k=nzp1 (surface) are
      !! left untouched (the assembly clip only floors k=2..nzp1-1).
      !!
      !! There is no Henyey-scaled variant of this fill: Bryan-Lewis and the
      !! Henyey latitude factor are mutually exclusive (configure refuses
      !! both), matching the reference formulation.  The Henyey path scales
      !! the SCALAR background instead — see `vmix_assemble_clip_henyey_impl`.
      !!
      !! Explicit-shape args so the do concurrent stays descriptor-walk free.
      integer, intent(in) :: nx, ny, nzp1
      real(wp), intent(inout) :: kd_bg(nx, ny, nzp1)
      real(wp), intent(in) :: h_layer(nx, ny, nzp1 - 1)
      real(wp), intent(in) :: kd_sfc, kd_deep, z0, delta
         !! Surface / deep asymptotes (m^2/s), transition centre depth (m),
         !! transition half-width (m).

      integer :: i, j, k
      real(wp) :: depth, inv_pi

      inv_pi = 1.0_wp/PI

      ! Per column: walk the interfaces top-down (surface → bed),
      ! accumulating depth.  Interface k sits at the bottom of layer k;
      ! its depth below the surface is the sum of the thicknesses of
      ! layers k+1 .. nz (nz = nzp1-1) — i.e. depth grows as k decreases.
      do concurrent(j=1:ny, i=1:nx) local(depth, k)
         depth = 0.0_wp
         ! Interface k is the bottom of layer k; its depth below the
         ! surface is the cumulative thickness of layers k..nz.  Descending
         ! from nz, adding h_layer(k) before evaluating interface k gives
         ! exactly that running sum.
         do k = nzp1 - 1, 2, -1
            depth = depth + h_layer(i, j, k)
            kd_bg(i, j, k) = kd_sfc + (kd_deep - kd_sfc)* &
                             (0.5_wp + atan((depth - z0)/delta)*inv_pi)
         end do
      end do
   end subroutine vmix_bkgnd_fill_impl