gather_boundary_ghosts_to_root Subroutine

public subroutine gather_boundary_ghosts_to_root(state, lft, rgt, bot, top)

Gather the GLOBAL boundary-ghost frame to cart rank 0: the four width-h ghost bands outside the global interior, corners included — every ghost cell of every rank that is NOT an interior MPI-halo cell. The 2D twin of 1D's gather_edge_ghosts_to_root (checkpoint v6; 1D's is v5/F2): the checkpoint must persist these words because the multi-stage whole-array RK kernels leave a stage-snapshot blend in them that is not reconstructable from the interior (see checkpoint_2d.f90's record-block comment for the full root cause).

Band layout (all 1-based; h = halo width, nx_g/ny_g = global cells): lft/rgt (neq2d, h, ny_g): column k <-> global i = k - h (left) or nx_g + k (right); j = 1..ny_g. bot/top (neq2d, nx_g + 2*h, h): column c <-> global i = c - h (spanning 1-h..nx_g+h, corners included); row k <-> global j = k - h (bottom) or ny_g + k (top).

Edge ownership needs no handshake (mirroring the 1D twin's argument): axis_split delegates to the pure rank_local_count/rank_first_global partition, so rank 0 recomputes every source rank's tile from its cart coordinates (MPI_Cart_coords is a local call) — deterministic, no rank-divergent I/O. At np=1 all four edges are rank 0's and this is a pure local copy — no MPI traffic. Collective discipline: EVERY rank must call, at a fixed position; MPI/allocation failures are parallel_fatal (matching the 1D twin), never silent.

Arguments

Type IntentOptional Attributes Name
type(solver_state_2d_t), intent(in) :: state

This rank's solver state (ub must be allocated/populated).

real(kind=wp), intent(inout) :: lft(:,:,:)
real(kind=wp), intent(inout) :: rgt(:,:,:)
real(kind=wp), intent(inout) :: bot(:,:,:)
real(kind=wp), intent(inout) :: top(:,:,:)