Apply the conservative minimum-thickness adjustment in place on ms.
h_new is caller-owned device-resident scratch shaped
(nx_total, ny_total, nz_ml) (a scratch_3d_buffer_t%data slot);
grounded_mask is (nx_total, ny_total, 1) scratch (ct%mt_grounded).
On grounded columns h_new receives the floor-only target thickness;
non-grounded columns are never written (their target ≡ h_old).
Order (each step a separate device launch so the h_old reads all complete before h_layer is overwritten): 0. build the 2D grounded mask + global count (ONE coalesced pass); count == 0 ⇒ return — the entire adjustment is a byte-no-op. 1. build the target field h_new on grounded columns, 2. remap every tracer (h_old -> h_new) on grounded columns, 3. remap the face velocities (h_old -> h_new) on active faces, 4. h_layer := h_new on grounded columns.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(multilayer_state_t), | intent(inout) | :: | ms | |||
| real(kind=wp), | intent(inout) | :: | h_new(grid%nx_total,grid%ny_total,ms%nz_ml) | |||
| real(kind=wp), | intent(inout) | :: | grounded_mask(grid%nx_total,grid%ny_total,1) | |||
| real(kind=wp), | intent(in) | :: | h_floor |
Minimum layer thickness (m); the isopycnal |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | n_grounded | ||||
| integer, | private | :: | nx | ||||
| integer, | private | :: | ny | ||||
| integer, | private | :: | nz | ||||
| integer, | private | :: | t |
subroutine ocean_apply_conservative_min_thickness(grid, ms, h_new, grounded_mask, & h_floor) !! Apply the conservative minimum-thickness adjustment in place on `ms`. !! !! `h_new` is caller-owned device-resident scratch shaped !! `(nx_total, ny_total, nz_ml)` (a `scratch_3d_buffer_t%data` slot); !! `grounded_mask` is `(nx_total, ny_total, 1)` scratch (`ct%mt_grounded`). !! On grounded columns `h_new` receives the floor-only target thickness; !! non-grounded columns are never written (their target ≡ h_old). !! !! Order (each step a separate device launch so the h_old reads all !! complete before h_layer is overwritten): !! 0. build the 2D grounded mask + global count (ONE coalesced pass); !! count == 0 ⇒ return — the entire adjustment is a byte-no-op. !! 1. build the target field h_new on grounded columns, !! 2. remap every tracer (h_old -> h_new) on grounded columns, !! 3. remap the face velocities (h_old -> h_new) on active faces, !! 4. h_layer := h_new on grounded columns. type(hgrid_t), intent(in) :: grid type(multilayer_state_t), intent(inout) :: ms real(wp), intent(inout) :: h_new(grid%nx_total, grid%ny_total, ms%nz_ml) real(wp), intent(inout) :: grounded_mask(grid%nx_total, grid%ny_total, 1) real(wp), intent(in) :: h_floor !! Minimum layer thickness (m); the isopycnal `angstrom_h`. integer :: nx, ny, nz, t, n_grounded nx = grid%nx_total ny = grid%ny_total nz = ms%nz_ml call build_grounded_mask(nx, ny, nz, ms%h_layer, h_floor, grounded_mask, & n_grounded) if (n_grounded == 0) return call build_target_field(nx, ny, nz, ms%h_layer, h_floor, grounded_mask, h_new) if (allocated(ms%tracers)) then do t = 1, size(ms%tracers) if (.not. allocated(ms%tracers(t)%hTr)) cycle call remap_tracer_grounded(nx, ny, nz, ms%h_layer, h_new, grounded_mask, & ms%tracers(t)%hTr) end do end if call remap_x_face_grounded(nx, ny, nz, ms%h_layer, h_new, grounded_mask, & ms%u_face_x_layer) call remap_y_face_grounded(nx, ny, nz, ms%h_layer, h_new, grounded_mask, & ms%v_face_y_layer) call assign_h_layer(nx, ny, nz, h_new, grounded_mask, ms%h_layer) end subroutine ocean_apply_conservative_min_thickness