core 0.5.0
Shared MPI block decomposition + asynchronous ghost-layer exchange (header-only C++20)
Loading...
Searching...
No Matches
peclet::core::decomp::BlockDecomposer< Dim > Class Template Reference

#include <block_decomposer.hpp>

Public Member Functions

 BlockDecomposer ()=default
 
 BlockDecomposer (std::size_t numBlocks, IVec< Dim > globalSize)
 
 BlockDecomposer (std::size_t numBlocks, IVec< Dim > globalSize, const std::vector< Real > &weights)
 
 BlockDecomposer (std::size_t numBlocks, IVec< Dim > globalSize, const IVec< Dim > &align)
 Aligned ORB (coarsenable): see the aligned init() below.
 
void init (std::size_t numBlocks, IVec< Dim > globalSize)
 Build the decomposition of a globalSize cell grid into numBlocks blocks (equal cell count).
 
void init (std::size_t numBlocks, IVec< Dim > globalSize, const IVec< Dim > &align)
 Aligned ORB: force every split position (and hence every block origin/size) on axis k to be a multiple of align[k].
 
void init (std::size_t numBlocks, IVec< Dim > globalSize, const IVec< Dim > &align, const IVec< Dim > &cellExtent)
 Anisotropic-cell aligned ORB: cellExtent[k] is how many underlying FINE cells one cell of this grid spans along axis k.
 
void init (std::size_t numBlocks, IVec< Dim > globalSize, const std::vector< Real > &weights)
 Weighted ORB: balance the total weight per block instead of the cell count.
 
std::size_t numBlocks () const
 
const IVec< Dim > & globalSize () const
 
const std::vector< IVec< Dim > > & origins () const
 
const std::vector< IVec< Dim > > & sizes () const
 
Block< Dim > block (std::size_t b) const
 
int ownerOf (const IVec< Dim > &g) const
 Owning block index of a global cell coordinate. Caller must wrap into [0, globalSize) first.
 
void flattenTree (std::vector< int > &splitDim, std::vector< Index > &splitVal) const
 Flatten the implicit ORB tree into two parallel arrays for a device-callable ownerOf: for node i, splitDim[i] is the split axis (−1 ⇒ leaf), splitVal[i] the split coordinate (internal) or the block index (leaf); children sit at 2i+1 / 2i+2.
 
Index linearGlobal (const IVec< Dim > &g) const
 Global multi-index -> global linear index (x-fastest: I = x + y*nx + z*nx*ny).
 
IVec< Dim > multiGlobal (Index lin) const
 Global linear index -> global multi-index (inverse of linearGlobal).
 
BlockDecomposer< Dim > coarsened (const IVec< Dim > &ratio) const
 Derive the NESTED coarse decomposition: each block, split value and the global size divided by ratio per axis (ratio[k] is 1 or the integer coarsening factor).
 
BlockDecomposer< Dim > refined (const IVec< Dim > &ratio) const
 Derive the NESTED fine decomposition: the exact inverse of coarsened() — global size, split values, block origins and block sizes each MULTIPLIED by ratio per axis.
 

Detailed Description

template<int Dim>
class peclet::core::decomp::BlockDecomposer< Dim >

Definition at line 28 of file block_decomposer.hpp.

Constructor & Destructor Documentation

◆ BlockDecomposer() [1/4]

template<int Dim>
peclet::core::decomp::BlockDecomposer< Dim >::BlockDecomposer ( )
default

◆ BlockDecomposer() [2/4]

template<int Dim>
peclet::core::decomp::BlockDecomposer< Dim >::BlockDecomposer ( std::size_t  numBlocks,
IVec< Dim >  globalSize 
)
inline

◆ BlockDecomposer() [3/4]

template<int Dim>
peclet::core::decomp::BlockDecomposer< Dim >::BlockDecomposer ( std::size_t  numBlocks,
IVec< Dim >  globalSize,
const std::vector< Real > &  weights 
)
inline

◆ BlockDecomposer() [4/4]

template<int Dim>
peclet::core::decomp::BlockDecomposer< Dim >::BlockDecomposer ( std::size_t  numBlocks,
IVec< Dim >  globalSize,
const IVec< Dim > &  align 
)
inline

Member Function Documentation

◆ init() [1/4]

◆ init() [2/4]

template<int Dim>
void peclet::core::decomp::BlockDecomposer< Dim >::init ( std::size_t  numBlocks,
IVec< Dim >  globalSize,
const IVec< Dim > &  align 
)
inline

Aligned ORB: force every split position (and hence every block origin/size) on axis k to be a multiple of align[k].

This is what makes a decomposition safely COARSENABLE — a geometric multigrid can then derive each coarse level by coarsened() (halving in place) and every level nests, so restrict/prolong stay purely local. Set align[k] = 2^(levels axis k coarsens). align[k] == 1 is the classic unaligned split. globalSize[k] must be a multiple of align[k].

Definition at line 54 of file block_decomposer.hpp.

References peclet::core::decomp::BlockDecomposer< Dim >::globalSize(), and peclet::core::decomp::BlockDecomposer< Dim >::numBlocks().

◆ init() [3/4]

template<int Dim>
void peclet::core::decomp::BlockDecomposer< Dim >::init ( std::size_t  numBlocks,
IVec< Dim >  globalSize,
const IVec< Dim > &  align,
const IVec< Dim > &  cellExtent 
)
inline

Anisotropic-cell aligned ORB: cellExtent[k] is how many underlying FINE cells one cell of this grid spans along axis k.

It affects ONLY the choice of split axis, which then compares size[k]*cellExtent[k] (the physical extent) instead of the raw cell count. Required when decomposing a grid whose axes were coarsened by DIFFERENT factors — there equal cell counts do not mean equal extents, and comparing counts makes the ORB bisect the wrong axis (which is how a coarse-first partition ends up cutting a direction the fine grid would never have cut). All ones (the default) reproduces the isotropic ORB exactly.

Definition at line 69 of file block_decomposer.hpp.

References peclet::core::decomp::BlockDecomposer< Dim >::globalSize(), peclet::core::decomp::BlockDecomposer< Dim >::init(), and peclet::core::decomp::BlockDecomposer< Dim >::numBlocks().

◆ init() [4/4]

template<int Dim>
void peclet::core::decomp::BlockDecomposer< Dim >::init ( std::size_t  numBlocks,
IVec< Dim >  globalSize,
const std::vector< Real > &  weights 
)
inline

Weighted ORB: balance the total weight per block instead of the cell count.

weights is a per-cell weight array over the global grid (size == product(globalSize), x-fastest). Each split is placed on the integer cell boundary whose cumulative weight is closest to the sub-block's target fraction. Reduces bit-exactly to the unweighted init() when all weights are equal.

Definition at line 80 of file block_decomposer.hpp.

References peclet::core::decomp::BlockDecomposer< Dim >::globalSize(), and peclet::core::decomp::BlockDecomposer< Dim >::numBlocks().

◆ numBlocks()

◆ globalSize()

◆ origins()

template<int Dim>
const std::vector< IVec< Dim > > & peclet::core::decomp::BlockDecomposer< Dim >::origins ( ) const
inline

◆ sizes()

template<int Dim>
const std::vector< IVec< Dim > > & peclet::core::decomp::BlockDecomposer< Dim >::sizes ( ) const
inline

◆ block()

template<int Dim>
Block< Dim > peclet::core::decomp::BlockDecomposer< Dim >::block ( std::size_t  b) const
inline

Definition at line 99 of file block_decomposer.hpp.

Referenced by peclet::core::decomp::redistributeGridFields().

◆ ownerOf()

template<int Dim>
int peclet::core::decomp::BlockDecomposer< Dim >::ownerOf ( const IVec< Dim > &  g) const
inline

Owning block index of a global cell coordinate. Caller must wrap into [0, globalSize) first.

Definition at line 102 of file block_decomposer.hpp.

Referenced by peclet::core::halo::GridHaloTopology< Dim >::buildTopology().

◆ flattenTree()

template<int Dim>
void peclet::core::decomp::BlockDecomposer< Dim >::flattenTree ( std::vector< int > &  splitDim,
std::vector< Index > &  splitVal 
) const
inline

Flatten the implicit ORB tree into two parallel arrays for a device-callable ownerOf: for node i, splitDim[i] is the split axis (−1 ⇒ leaf), splitVal[i] the split coordinate (internal) or the block index (leaf); children sit at 2i+1 / 2i+2.

Uploaded once by ParticleMigratorView so the per-particle owner lookup runs on the device (D1). Mirrors ownerOf exactly.

Definition at line 115 of file block_decomposer.hpp.

Referenced by peclet::core::halo::ParticleMigratorView< Dim >::init().

◆ linearGlobal()

template<int Dim>
Index peclet::core::decomp::BlockDecomposer< Dim >::linearGlobal ( const IVec< Dim > &  g) const
inline

Global multi-index -> global linear index (x-fastest: I = x + y*nx + z*nx*ny).

Definition at line 125 of file block_decomposer.hpp.

Referenced by peclet::core::halo::GridHaloTopology< Dim >::buildTopology(), and peclet::core::halo::rebalanceByParticleCount().

◆ multiGlobal()

template<int Dim>
IVec< Dim > peclet::core::decomp::BlockDecomposer< Dim >::multiGlobal ( Index  lin) const
inline

Global linear index -> global multi-index (inverse of linearGlobal).

Definition at line 135 of file block_decomposer.hpp.

Referenced by peclet::core::halo::GridHaloTopology< Dim >::buildTopology().

◆ coarsened()

template<int Dim>
BlockDecomposer< Dim > peclet::core::decomp::BlockDecomposer< Dim >::coarsened ( const IVec< Dim > &  ratio) const
inline

Derive the NESTED coarse decomposition: each block, split value and the global size divided by ratio per axis (ratio[k] is 1 or the integer coarsening factor).

The tree shape and leaf order are preserved, so rank r's coarse block is exactly rank r's fine block coarsened in place — the invariant a geometric-multigrid restrict/prolong relies on (coarse-local i ↔ fine-local ratio*i). Exact iff this decomposition was built aligned to a multiple of ratio on each coarsened axis (see the aligned init); asserts divisibility in debug builds.

Definition at line 150 of file block_decomposer.hpp.

◆ refined()

template<int Dim>
BlockDecomposer< Dim > peclet::core::decomp::BlockDecomposer< Dim >::refined ( const IVec< Dim > &  ratio) const
inline

Derive the NESTED fine decomposition: the exact inverse of coarsened() — global size, split values, block origins and block sizes each MULTIPLIED by ratio per axis.

This is the "decompose coarse, refine upward" route to a multigrid-safe partition, and it is strictly stronger than building the fine ORB with an alignment. Aligning the fine ORB decides the split and then snaps it, so a balanced split can be rounded into an unbalanced one (the pathological case: 96|96 snapped to 128|64, a 2:1 cascade). Refining upward instead lets the ORB balance on the coarse grid, where one coarse cell IS the alignment quantum — so the fine blocks are multiples of ratio by construction, coarsened() nests exactly for log2(ratio) levels, and the load balance is the best achievable at that granularity.

Caller's responsibility: ratio should be the coarsening the hierarchy will actually perform (2^levels per axis, bounded by that axis's factors of two), and the coarse grid must hold at least numBlocks cells.

Definition at line 191 of file block_decomposer.hpp.


The documentation for this class was generated from the following file: