domain_decomposition Module

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.



Derived Types

type, public ::  decomp_t

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.

Components

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.

Functions

public pure function rank_local_count(n_global, n_ranks, rank_id) result(n_local)

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.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: n_global
integer, intent(in) :: n_ranks
integer, intent(in) :: rank_id

Return Value integer

public pure function rank_first_global(n_global, n_ranks, rank_id) result(i_first)

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).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: n_global
integer, intent(in) :: n_ranks
integer, intent(in) :: rank_id

Return Value integer

public pure function decompose(my_rank, n_ranks, n_global, halo_width, is_periodic) result(d)

Compute this rank's decomposition. Pure: no MPI calls, no global state.

Read more…

Arguments

Type IntentOptional 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

Return Value type(decomp_t)

private pure function required_local(d) result(needed)

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.

Arguments

Type IntentOptional Attributes Name
type(decomp_t), intent(in) :: d

Return Value integer

public pure function is_decomp_feasible(d) result(ok)

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).

Arguments

Type IntentOptional Attributes Name
type(decomp_t), intent(in) :: d

Return Value logical


Subroutines

public subroutine validate_decomp(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.

Arguments

Type IntentOptional Attributes Name
type(decomp_t), intent(in) :: d