Zero the per-layer face velocity at any face where BOTH adjacent
centre-cell thicknesses are at or below vanish_tol
(isopycnal_vanish_tol(angstrom_h) = max(angstrom_h, H_VANISHED)).
Both-sided rule (R1/R6): a face is reset only when BOTH
neighbouring centre cells are vanished. A face with one massive
side (h >> vanish_tol) is LEFT UNTOUCHED — that flux is
legitimate (it may be re-wetting the thin layer at a grounding
FRONT) and zeroing it would create a spurious vorticity dipole.
Idempotency (R6): faces zeroed here are already 0 when
Phase-3 CFL truncation runs (apply_velocity_truncation);
the composition is harmless.
Mirroring mask_layer_velocities: plain do concurrent, no
!$acc annotations, pure, explicit dims before arrays.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(multilayer_state_t), | intent(inout) | :: | ms | |||
| real(kind=wp), | intent(in) | :: | vanish_tol |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | i | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | k | ||||
| integer, | private | :: | nx_centre | ||||
| integer, | private | :: | nx_face | ||||
| integer, | private | :: | nx_vface | ||||
| integer, | private | :: | ny_centre | ||||
| integer, | private | :: | ny_face | ||||
| integer, | private | :: | ny_uface | ||||
| integer, | private | :: | nz |
pure subroutine reset_vanished_layer_velocities(ms, vanish_tol) !! Zero the per-layer face velocity at any face where BOTH adjacent !! centre-cell thicknesses are at or below `vanish_tol` !! (`isopycnal_vanish_tol(angstrom_h)` = `max(angstrom_h, H_VANISHED)`). !! !! **Both-sided rule (R1/R6):** a face is reset only when BOTH !! neighbouring centre cells are vanished. A face with one massive !! side (`h >> vanish_tol`) is LEFT UNTOUCHED — that flux is !! legitimate (it may be re-wetting the thin layer at a grounding !! FRONT) and zeroing it would create a spurious vorticity dipole. !! !! **Idempotency (R6):** faces zeroed here are already 0 when !! Phase-3 CFL truncation runs (`apply_velocity_truncation`); !! the composition is harmless. !! !! Mirroring `mask_layer_velocities`: plain `do concurrent`, no !! `!$acc` annotations, pure, explicit dims before arrays. type(multilayer_state_t), intent(inout) :: ms real(wp), intent(in) :: vanish_tol integer :: i, j, k, nz, nx_face, ny_uface, nx_vface, ny_face integer :: nx_centre, ny_centre nz = ms%nz_ml nx_centre = size(ms%h_layer, 1) ny_centre = size(ms%h_layer, 2) nx_face = size(ms%u_face_x_layer, 1) ny_uface = size(ms%u_face_x_layer, 2) nx_vface = size(ms%v_face_y_layer, 1) ny_face = size(ms%v_face_y_layer, 2) ! u-face at (i,j,k) straddles centres (i-1,j,k) and (i,j,k). ! Skip outermost columns (i=1 and i=nx_face) which are ghost/wall ! faces — their adjacent interior index would be out of range. ! Safe inner range: i=2..nx_face-1 (both i-1 and i are in 1..nx_centre). ! Both-sided-vanished test as an inner `if`, not a DC mask — masked ! headers fail tools/dc_audit.py --strict. do concurrent(k=1:nz, j=1:ny_uface, i=2:nx_face - 1) if (max(ms%h_layer(i - 1, j, k), ms%h_layer(i, j, k)) <= vanish_tol) then ms%u_face_x_layer(i, j, k) = 0.0_wp end if end do ! v-face at (i,j,k) straddles centres (i,j-1,k) and (i,j,k). ! Safe inner range: j=2..ny_face-1. do concurrent(k=1:nz, j=2:ny_face - 1, i=1:nx_vface) if (max(ms%h_layer(i, j - 1, k), ms%h_layer(i, j, k)) <= vanish_tol) then ms%v_face_y_layer(i, j, k) = 0.0_wp end if end do end subroutine reset_vanished_layer_velocities