Initialise topology and allocate persistent device-resident buffers. Idempotent: destroys prior state before re-init on grid change.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(decomp_t), | intent(in) | :: | decomp |
Domain decomposition descriptor |
||
| integer, | intent(in) | :: | nghost |
Ghost cell width |
||
| logical, | intent(in) | :: | periodic_x |
Reentrant periodic in x |
||
| logical, | intent(in) | :: | periodic_y |
Reentrant periodic in y |
||
| integer, | intent(out), | optional | :: | ierr |
Non-zero ( |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | cap_ew | ||||
| integer, | private | :: | cap_ns |
subroutine ocean_halo_init(decomp, nghost, periodic_x, periodic_y, ierr) !! Initialise topology and allocate persistent device-resident buffers. !! Idempotent: destroys prior state before re-init on grid change. type(decomp_t), intent(in) :: decomp !! Domain decomposition descriptor integer, intent(in) :: nghost !! Ghost cell width logical, intent(in) :: periodic_x !! Reentrant periodic in x logical, intent(in) :: periodic_y !! Reentrant periodic in y integer, intent(out), optional :: ierr !! Non-zero (`OCEAN_STATUS_ERR_SETUP`) on the decomposed-run !! nghost<3 seam-stencil guard when present; absent behaves as !! today (`error stop`). (F5 residual, P2.4) integer :: cap_ew, cap_ns if (present(ierr)) ierr = OCEAN_STATUS_OK ! O4 seam-stencil guard (FAIL-LOUD): the ocean dyn-core's ! continuity/tracer PPM reconstruction is 5-point; a seam face's ! ghost-side donor cell needs two neighbours beyond itself, so ! full-order reconstruction at a rank-seam face needs THREE ghost ! columns. With nghost < 3 the PPM local-array-edge fallback fires AT ! the seam and degrades the face to first order, producing a ! seam-inconsistent tracer mass flux: it conserves a UNIFORM tracer ! (Σ flux·C cancels) but LEAKS a STRUCTURED one — measured heat ! closure grew to +5e-11 by day 2 on seamount_bench_full np2 at ! nghost=2 (invisible to the mass/salt gates; the O4 heat-leak ! postmortem). This is an ABORT, not a warning: a silent ! decomposition-dependent conservation leak is a correctness bug. ! `decomp%px/py` are the TRUE runtime decomposition (namelist px/py ! are auto-factored by then), so this gate sees the real seam even ! when the namelist left px=py=1. The default nghost is now 3, so ! this only trips an EXPLICIT decomposed override below 3. The ocean ! halo-primitive tests (test_halo_ocean_mpi) already init at nghost=3. if ((decomp%px > 1 .or. decomp%py > 1) .and. nghost < 3) then call fail("ocean_halo_init: decomposed ocean run (px="// & to_string(decomp%px)//", py="//to_string(decomp%py)// & ") requires nghost >= 3, got nghost = "//to_string(nghost)// & ". The continuity/tracer PPM 5-point stencil degrades to "// & "FIRST ORDER at rank-seam faces, leaking a structured tracer "// & "(heat) while conserving a uniform one (salt). "// & "Set &grid_nml nghost = 3 (the default) or higher.", & ierr, OCEAN_STATUS_ERR_SETUP) return end if if (oh_initialised) call ocean_halo_destroy() oh_decomp = decomp oh_nghost = nghost oh_nx_local = decomp%nx_local oh_ny_local = decomp%ny_local oh_nx_total = decomp%nx_local + 2*nghost oh_ny_total = decomp%ny_local + 2*nghost oh_periodic_x = periodic_x oh_periodic_y = periodic_y oh_initialised = .true. ! Capacity: worst case is face-x send-east = (nghost+1)*ny_total for E/W. ! For face-y x-pass, ng*(ny_total+1) <= (ng+1)*ny_total when ny_total >= ng. cap_ew = (nghost + 1)*oh_ny_total cap_ns = (nghost + 1)*oh_nx_total allocate (oh_buf_send_east(cap_ew), oh_buf_recv_east(cap_ew)) allocate (oh_buf_send_west(cap_ew), oh_buf_recv_west(cap_ew)) allocate (oh_buf_send_north(cap_ns), oh_buf_recv_north(cap_ns)) allocate (oh_buf_send_south(cap_ns), oh_buf_recv_south(cap_ns)) !$acc enter data create(oh_buf_send_east, oh_buf_recv_east, & !$acc& oh_buf_send_west, oh_buf_recv_west, & !$acc& oh_buf_send_north, oh_buf_recv_north, & !$acc& oh_buf_send_south, oh_buf_recv_south) oh_cap_ew = cap_ew oh_cap_ns = cap_ns end subroutine ocean_halo_init