Reduce the per-column status plane into four counts, ON DEVICE.
do concurrent ... reduce(+:) and not count(...): the array
is device-resident under mem:separate, and a host intrinsic
would silently read the stale host shadow — the same trap
continuity_t%n_limited_step documents.
Only ACTIVE columns are counted. An inactive column always
carries CAVITY_MELT_OK, but gating the count on the mask
keeps that a property of the caller rather than of the kernel.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx |
First dimension. |
||
| integer, | intent(in) | :: | ny |
Second dimension. |
||
| real(kind=wp), | intent(in) | :: | active(nx,ny) |
Composed solve mask. |
||
| integer, | intent(in) | :: | status(nx,ny) |
|
||
| integer, | intent(out) | :: | n_nonfinite |
Count of |
||
| integer, | intent(out) | :: | n_not_converged |
Count of |
||
| integer, | intent(out) | :: | n_no_root |
Count of |
||
| integer, | intent(out) | :: | n_other |
Count of every other non-OK status. |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | c_nc | ||||
| integer, | private | :: | c_nf | ||||
| integer, | private | :: | c_nr | ||||
| integer, | private | :: | c_ot | ||||
| integer, | private | :: | i | ||||
| integer, | private | :: | j |
pure subroutine cavity_status_counts_impl(nx, ny, active, status, n_nonfinite, & n_not_converged, n_no_root, n_other) !! Reduce the per-column status plane into four counts, ON DEVICE. !! !! `do concurrent ... reduce(+:)` and not `count(...)`: the array !! is device-resident under `mem:separate`, and a host intrinsic !! would silently read the stale host shadow — the same trap !! `continuity_t%n_limited_step` documents. !! !! Only ACTIVE columns are counted. An inactive column always !! carries `CAVITY_MELT_OK`, but gating the count on the mask !! keeps that a property of the caller rather than of the kernel. integer, intent(in) :: nx !! First dimension. integer, intent(in) :: ny !! Second dimension. real(wp), intent(in) :: active(nx, ny) !! Composed solve mask. integer, intent(in) :: status(nx, ny) !! `CAVITY_MELT_*` per column. integer, intent(out) :: n_nonfinite !! Count of `NONFINITE_INPUT` + `NONFINITE_STATE`. integer, intent(out) :: n_not_converged !! Count of `NOT_CONVERGED`. integer, intent(out) :: n_no_root !! Count of `NO_PHYSICAL_ROOT`. integer, intent(out) :: n_other !! Count of every other non-OK status. integer :: i, j, c_nf, c_nc, c_nr, c_ot c_nf = 0 c_nc = 0 c_nr = 0 c_ot = 0 do concurrent(j=1:ny, i=1:nx) reduce(+:c_nf, c_nc, c_nr, c_ot) if (active(i, j) > 0.5_wp) then select case (status(i, j)) case (CAVITY_MELT_OK) continue case (CAVITY_MELT_NONFINITE_INPUT, CAVITY_MELT_NONFINITE_STATE) c_nf = c_nf + 1 case (CAVITY_MELT_NOT_CONVERGED) c_nc = c_nc + 1 case (CAVITY_MELT_NO_PHYSICAL_ROOT) c_nr = c_nr + 1 case default c_ot = c_ot + 1 end select end if end do n_nonfinite = c_nf n_not_converged = c_nc n_no_root = c_nr n_other = c_ot end subroutine cavity_status_counts_impl