pure subroutine build_target_field(nx, ny, nz, h_old, h_floor, mask, h_new)
!! Flat-impl: per grounded (i,j) column build the floor-only conservative
!! target. Non-grounded columns are SKIPPED — their h_new is never read
!! downstream (every consumer falls back to h_old via the mask).
integer, intent(in) :: nx, ny, nz
real(wp), intent(in) :: h_old(nx, ny, nz)
real(wp), intent(in) :: h_floor
real(wp), intent(in) :: mask(nx, ny, 1)
real(wp), intent(out) :: h_new(nx, ny, nz)
integer :: i, j, k
real(wp) :: h_old_col(NZ_STACK_MAX), h_new_col(NZ_STACK_MAX)
logical :: grounded
do concurrent(j=1:ny, i=1:nx) local(k, h_old_col, h_new_col, grounded)
if (mask(i, j, 1) > 0.5_wp) then
do k = 1, nz
h_old_col(k) = h_old(i, j, k)
end do
call min_thickness_target_column(nz, h_old_col(1:nz), h_floor, &
h_new_col(1:nz), grounded)
do k = 1, nz
h_new(i, j, k) = h_new_col(k)
end do
end if
end do
end subroutine build_target_field