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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | n1 |
Face-array extents ( |
||
| integer, | intent(in) | :: | n2 |
Face-array extents ( |
||
| integer, | intent(in) | :: | nz |
Face-array extents ( |
||
| real(kind=wp), | intent(in) | :: | por(n1,n2,nz) |
Layer-averaged open-area fraction (nondim, |
||
| real(kind=wp), | intent(inout) | :: | arr(n1,n2,nz) |
Face-staggered field to narrow (a mass transport). |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | i | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | k |
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