Owns the per-rank decomp_t derived type and the pure decompose()
function that, given (my_rank, n_ranks, n_global, halo_width, is_periodic),
returns a fully-populated decomp_t with neighbour rank ids and the
global-index range owned by this rank. No MPI calls live here — the
function is callable from unit tests with synthetic rank ids.
Validation of the (n_local >= halo_width) feasibility constraint is done
by validate_decomp(), which aborts via parallel_fatal when violated.
Per-rank domain decomposition descriptor. All integer fields are
local to the rank that holds it; only n_ranks, n_global,
halo_width, and is_periodic are constant across ranks.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public | :: | my_rank | = | -1 | ||
| integer, | public | :: | n_ranks | = | -1 | ||
| integer, | public | :: | n_global | = | -1 | ||
| integer, | public | :: | n_local | = | -1 | ||
| integer, | public | :: | i_first_global | = | -1 | ||
| integer, | public | :: | i_last_global | = | -1 | ||
| integer, | public | :: | halo_width | = | -1 | ||
| integer, | public | :: | left_neighbour | = | -1 | ||
| integer, | public | :: | right_neighbour | = | -1 | ||
| logical, | public | :: | is_periodic | = | .false. |
Single source of truth for the slab/block partition: the number of global
cells owned by rank_id (0-based) when n_global cells are split across
n_ranks. floor(n_global/n_ranks) per rank, with the remainder distributed
one extra cell each to the first mod(n_global,n_ranks) ranks. Pure — used
by decompose(), the gather/scatter count builders, and the 2D axis split so
the partition arithmetic exists in exactly one place.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | n_global | |||
| integer, | intent(in) | :: | n_ranks | |||
| integer, | intent(in) | :: | rank_id |
1-based global index of rank_id's first owned cell under the same
partition as rank_local_count. Equals the sum of all lower ranks'
counts, plus 1. Pure — single source of truth (see rank_local_count).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | n_global | |||
| integer, | intent(in) | :: | n_ranks | |||
| integer, | intent(in) | :: | rank_id |
Compute this rank's decomposition. Pure: no MPI calls, no global state.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | my_rank | |||
| integer, | intent(in) | :: | n_ranks | |||
| integer, | intent(in) | :: | n_global | |||
| integer, | intent(in) | :: | halo_width | |||
| logical, | intent(in) | :: | is_periodic |
Minimum interior cell count this rank must hold. A non-periodic rank needs
at least halo_width cells. A periodic decomposition needs one more: the
wrap send skips the duplicated endpoint node (global node n_global == node
1), so the periodic edge ranks send cells [2 .. h+1] / [n_local-h ..
n_local-1], which require n_local >= halo_width + 1. The bound is applied to
every rank (not just the edges) so the feasibility guarantee is uniform.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(decomp_t), | intent(in) | :: | d |
Return .true. iff this rank's n_local is large enough to accommodate the halo (and, for periodic grids, the wrap send's one-cell offset).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(decomp_t), | intent(in) | :: | d |
Abort with a clear message if this rank's n_local is too small to hold the halo cells the chosen reconstruction scheme requires.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(decomp_t), | intent(in) | :: | d |