porous_narrow_3d Subroutine

public pure subroutine porous_narrow_3d(n1, n2, nz, por, arr)

Multiply a face-staggered per-layer field by the open-area fraction: arr <- arr * por.

Deliberately a SEPARATE pass rather than a factor folded into the transport loops. Folding it in would put metrics%por_face_area_u(i,j,k) inside a do concurrent whose implicit data clause is generated from the LOOP bounds, so the (1,1,1) placeholder a knob-off run carries would be reported partially present and abort under mem:separate. With the multiply hoisted behind a host-side if (metrics%use_porous) there is no kernel launch at all when the knob is off — which also leaves the transport loops textually untouched, so bit-identity is by construction rather than by argument. The extra pass is bandwidth-bound and only runs when the (opt-in) scheme is active.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: n1

Face-array extents (nx+1, ny, nz for u; nx, ny+1, nz for v).

integer, intent(in) :: n2

Face-array extents (nx+1, ny, nz for u; nx, ny+1, nz for v).

integer, intent(in) :: nz

Face-array extents (nx+1, ny, nz for u; nx, ny+1, nz for v).

real(kind=wp), intent(in) :: por(n1,n2,nz)

Layer-averaged open-area fraction (nondim, [0,1]).

real(kind=wp), intent(inout) :: arr(n1,n2,nz)

Face-staggered field to narrow (a mass transport).


Called by

proc~~porous_narrow_3d~~CalledByGraph proc~porous_narrow_3d porous_narrow_3d proc~coriolis_adv_compute_tendencies_hk coriolis_adv_compute_tendencies_hk proc~coriolis_adv_compute_tendencies_hk->proc~porous_narrow_3d proc~coriolis_adv_compute_tendencies_sadourny_energy coriolis_adv_compute_tendencies_sadourny_energy proc~coriolis_adv_compute_tendencies_sadourny_energy->proc~porous_narrow_3d proc~coriolis_adv_compute_tendencies coriolis_adv_compute_tendencies proc~coriolis_adv_compute_tendencies->proc~coriolis_adv_compute_tendencies_hk proc~coriolis_adv_compute_tendencies->proc~coriolis_adv_compute_tendencies_sadourny_energy proc~run_stage run_stage proc~run_stage->proc~coriolis_adv_compute_tendencies proc~run_stage_split run_stage_split proc~run_stage_split->proc~coriolis_adv_compute_tendencies 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
integer, private :: i
integer, private :: j
integer, private :: k

Source Code

   pure subroutine porous_narrow_3d(n1, n2, nz, por, arr)
      !! Multiply a face-staggered per-layer field by the open-area
      !! fraction: `arr <- arr * por`.
      !!
      !! Deliberately a SEPARATE pass rather than a factor folded into the
      !! transport loops.  Folding it in would put
      !! `metrics%por_face_area_u(i,j,k)` inside a `do concurrent` whose
      !! implicit data clause is generated from the LOOP bounds, so the
      !! `(1,1,1)` placeholder a knob-off run carries would be reported
      !! partially present and abort under `mem:separate`.  With the
      !! multiply hoisted behind a host-side `if (metrics%use_porous)`
      !! there is no kernel launch at all when the knob is off — which
      !! also leaves the transport loops textually untouched, so
      !! bit-identity is by construction rather than by argument.  The
      !! extra pass is bandwidth-bound and only runs when the (opt-in)
      !! scheme is active.
      integer, intent(in) :: n1, n2, nz
         !! Face-array extents (`nx+1, ny, nz` for u; `nx, ny+1, nz` for v).
      real(wp), intent(in) :: por(n1, n2, nz)
         !! Layer-averaged open-area fraction (nondim, `[0,1]`).
      real(wp), intent(inout) :: arr(n1, n2, nz)
         !! Face-staggered field to narrow (a mass transport).
      integer :: i, j, k

      do concurrent(k=1:nz, j=1:n2, i=1:n1)
         arr(i, j, k) = arr(i, j, k)*por(i, j, k)
      end do
   end subroutine porous_narrow_3d