ocean_vcoord_closed_face_masks Subroutine

public pure subroutine ocean_vcoord_closed_face_masks(open_u, open_v, target_h, nx, ny, nz, h_vanished)

Partial-step z-level FACE CLOSURE mask for VCOORD_Z_FIXED (&vcoord_nml zfixed_closed_faces; Adcroft, Hill & Marshall 1997; Losch 2008 §2.1 for the ice-shelf cavity).

Under z_fixed a layer whose nominal geopotential range lies inside the bed — or inside the ice draft — is an inert FILLER of thickness zstar_h_min (<= h_vanished). A velocity face at which layer k is a filler on EITHER side is not a thin passage: geometrically there is no water there on one side, so it is a WALL for that layer — no normal velocity, no mass or tracer flux, free-slip on the tangential component. This marks those faces.

The rule, in one line

open_u(I,j,k) = 1  iff  target_h(I-1,j,k) > h_vanished
                  .and. target_h(I  ,j,k) > h_vanished

and the v-face mirror. The mask is STATIC: the bed and the draft are static, and under z_fixed η is absorbed by the first LIVE layer (the partial cell) — a filler’s target is zstar_h_min whatever η does — so the live/filler pattern does not move. Build it once, from ocean_vcoord_z_fixed_target at η = 0, so there is exactly ONE definition of “live” shared with the ALE regrid and the IC seed.

Composition

The mask is a THIRD, independent factor on the face width, not a replacement for either of the other two:

dy_eff(I,j,k) = dy_cu(I,j) · por_face_area_u(I,j,k) · open_u(I,j,k)
                 land (2-D)     porous (subgrid)       z-level (per layer)

Array-edge faces

I = 1 and I = nx+1 are left fully OPEN (1), exactly as the porous kernel leaves them: their dy_cu is already zero and the continuity wall zeroing owns them. The PHYSICAL seam of a periodic axis is an interior index (nghost+1), so it is covered by the 2:nx sweep — provided the caller built target_h from GHOST-FILLED inputs (bt_H_ref and z_top are periodic-wrapped + halo-exchanged before this runs).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(out) :: open_u(nx+1,ny,nz)

u-face 0/1 open mask.

real(kind=wp), intent(out) :: open_v(nx,ny+1,nz)

v-face 0/1 open mask.

real(kind=wp), intent(in) :: target_h(nx,ny,nz)

The z_fixed target thickness at η = 0.

integer, intent(in) :: nx

i-extent of the CENTRE arrays (total, incl. halos).

integer, intent(in) :: ny

j-extent of the CENTRE arrays (total, incl. halos).

integer, intent(in) :: nz

Number of layers; k = 1 is the bed, k = nz the top.

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

Inert-filler marker (H_VANISHED). A layer is LIVE iff its target thickness is strictly greater than this.


Called by

proc~~ocean_vcoord_closed_face_masks~~CalledByGraph proc~ocean_vcoord_closed_face_masks ocean_vcoord_closed_face_masks proc~configure_ocean_closed_faces configure_ocean_closed_faces proc~configure_ocean_closed_faces->proc~ocean_vcoord_closed_face_masks proc~engine_setup engine_setup proc~engine_setup->proc~configure_ocean_closed_faces proc~complete_ocean_create complete_ocean_create proc~complete_ocean_create->proc~engine_setup proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_setup proc~driver_validate driver_validate proc~driver_validate->proc~engine_setup proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean proc~rdb_ocean_create_finalize rdb_ocean_create_finalize proc~rdb_ocean_create_finalize->proc~complete_ocean_create proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~complete_ocean_create

Variables

Type Visibility Attributes Name Initial
integer, private :: i
integer, private :: j
integer, private :: k

Source Code

   pure subroutine ocean_vcoord_closed_face_masks(open_u, open_v, target_h, &
                                                  nx, ny, nz, h_vanished)
      !! Partial-step z-level FACE CLOSURE mask for `VCOORD_Z_FIXED`
      !! (`&vcoord_nml zfixed_closed_faces`; Adcroft, Hill & Marshall
      !! 1997; Losch 2008 §2.1 for the ice-shelf cavity).
      !!
      !! Under `z_fixed` a layer whose nominal geopotential range lies
      !! inside the bed — or inside the ice draft — is an inert FILLER of
      !! thickness `zstar_h_min` (`<= h_vanished`).  A velocity face at
      !! which layer `k` is a filler on EITHER side is not a thin
      !! passage: geometrically there is no water there on one side, so
      !! it is a **WALL for that layer** — no normal velocity, no mass or
      !! tracer flux, free-slip on the tangential component.  This marks
      !! those faces.
      !!
      !! ### The rule, in one line
      !!
      !! ```
      !! open_u(I,j,k) = 1  iff  target_h(I-1,j,k) > h_vanished
      !!                   .and. target_h(I  ,j,k) > h_vanished
      !! ```
      !! and the v-face mirror.  The mask is **STATIC**: the bed and the
      !! draft are static, and under `z_fixed` `η` is absorbed by the
      !! first LIVE layer (the partial cell) — a filler's target is
      !! `zstar_h_min` whatever `η` does — so the live/filler pattern
      !! does not move.  Build it once, from
      !! `ocean_vcoord_z_fixed_target` at `η = 0`, so there is exactly
      !! ONE definition of "live" shared with the ALE regrid and the IC
      !! seed.
      !!
      !! ### Composition
      !!
      !! The mask is a THIRD, independent factor on the face width, not a
      !! replacement for either of the other two:
      !! ```
      !! dy_eff(I,j,k) = dy_cu(I,j) · por_face_area_u(I,j,k) · open_u(I,j,k)
      !!                  land (2-D)     porous (subgrid)       z-level (per layer)
      !! ```
      !!
      !! ### Array-edge faces
      !!
      !! `I = 1` and `I = nx+1` are left fully OPEN (1), exactly as the
      !! porous kernel leaves them: their `dy_cu` is already zero and the
      !! continuity wall zeroing owns them.  The PHYSICAL seam of a
      !! periodic axis is an interior index (`nghost+1`), so it is
      !! covered by the `2:nx` sweep — provided the caller built
      !! `target_h` from GHOST-FILLED inputs (`bt_H_ref` and `z_top` are
      !! periodic-wrapped + halo-exchanged before this runs).
      integer, intent(in) :: nx
         !! i-extent of the CENTRE arrays (total, incl. halos).
      integer, intent(in) :: ny
         !! j-extent of the CENTRE arrays (total, incl. halos).
      integer, intent(in) :: nz
         !! Number of layers; `k = 1` is the bed, `k = nz` the top.
      real(wp), intent(out) :: open_u(nx + 1, ny, nz)
         !! u-face 0/1 open mask.
      real(wp), intent(out) :: open_v(nx, ny + 1, nz)
         !! v-face 0/1 open mask.
      real(wp), intent(in) :: target_h(nx, ny, nz)
         !! The `z_fixed` target thickness at `η = 0`.
      real(wp), intent(in) :: h_vanished
         !! Inert-filler marker (`H_VANISHED`).  A layer is LIVE iff its
         !! target thickness is strictly greater than this.
      integer :: i, j, k

      do concurrent(k=1:nz, j=1:ny, i=1:nx + 1)
         open_u(i, j, k) = 1.0_wp
      end do
      do concurrent(k=1:nz, j=1:ny + 1, i=1:nx)
         open_v(i, j, k) = 1.0_wp
      end do

      do concurrent(k=1:nz, j=1:ny, i=2:nx)
         if (target_h(i - 1, j, k) > h_vanished .and. &
             target_h(i, j, k) > h_vanished) then
            open_u(i, j, k) = 1.0_wp
         else
            open_u(i, j, k) = 0.0_wp
         end if
      end do

      do concurrent(k=1:nz, j=2:ny, i=1:nx)
         if (target_h(i, j - 1, k) > h_vanished .and. &
             target_h(i, j, k) > h_vanished) then
            open_v(i, j, k) = 1.0_wp
         else
            open_v(i, j, k) = 0.0_wp
         end if
      end do
   end subroutine ocean_vcoord_closed_face_masks