6#ifndef PECLET_CORE_DECOMP_BLOCK_DECOMPOSER_HPP
7#define PECLET_CORE_DECOMP_BLOCK_DECOMPOSER_HPP
50 for (int i = 0; i < Dim; ++i)
54 "weights array must cover the global grid (x-fastest)");
58 std::size_t
numBlocks()
const {
return origins_.size(); }
60 const std::vector<IVec<Dim>>&
origins()
const {
return origins_; }
61 const std::vector<IVec<Dim>>&
sizes()
const {
return sizes_; }
68 while (tree_[
node].splitDim != -1) {
71 return static_cast<int>(tree_[
node].splitValue);
80 splitDim.resize(tree_.size());
82 for (std::size_t
i = 0;
i < tree_.size(); ++
i) {
83 splitDim[
i] = tree_[
i].splitDim;
90 Index idx = g[Dim - 1];
91 for (
int i = Dim - 2;
i >= 0; --
i) {
92 idx *= globalSize_[
i];
101 for (
int i = 0;
i < Dim; ++
i) {
102 g[
i] =
lin % globalSize_[
i];
103 lin /= globalSize_[
i];
111 Index splitValue = 0;
124 const std::vector<Real>*
weights)
const;
127 std::vector<IVec<Dim>> origins_;
128 std::vector<IVec<Dim>> sizes_;
129 std::vector<TreeNode> tree_;
133void BlockDecomposer<Dim>::initImpl(std::size_t numBlocks,
IVec<Dim> globalSize,
134 const std::vector<Real>*
weights) {
135 globalSize_ = globalSize;
146 std::stack<StackBlock>
stack;
150 while (!
stack.empty()) {
154 if (
static_cast<std::size_t
>(
cur.treeIndx) >= tree_.size()) {
155 tree_.resize(
cur.treeIndx + 1);
158 if (
cur.numSub > 1) {
162 for (
int k = 1; k < Dim; ++k) {
172 left.treeIndx = 2 *
cur.treeIndx + 1;
178 right.treeIndx = 2 *
cur.treeIndx + 2;
185 origins_.push_back(
cur.origin);
186 sizes_.push_back(
cur.size);
194 const std::vector<Real>*
weights)
const {
199 if (
weights ==
nullptr || n <= 1) {
200 return static_cast<Index>(std::round(
static_cast<double>(n) *
static_cast<double>(
numSub) /
206 std::vector<double>
slab(
static_cast<std::size_t
>(n), 0.0);
208 for (
int i = 0;
i < Dim; ++
i)
209 end[
i] = origin[
i] + size[
i];
215 for (
double w :
slab)
222 double bestDist = std::numeric_limits<double>::max();
225 cum +=
slab[
static_cast<std::size_t
>(
s - 1)];
226 const double dist = std::abs(
cum -
target);
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,...
Block< Dim > block(std::size_t b) const
const std::vector< IVec< Dim > > & sizes() const
void init(std::size_t numBlocks, IVec< Dim > globalSize)
Build the decomposition of a globalSize cell grid into numBlocks blocks (equal cell count).
BlockDecomposer(std::size_t numBlocks, IVec< Dim > globalSize, const std::vector< Real > &weights)
const std::vector< IVec< Dim > > & origins() const
const IVec< Dim > & globalSize() const
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
BlockDecomposer()=default
BlockDecomposer(std::size_t numBlocks, IVec< Dim > globalSize)
Index linearGlobal(const IVec< Dim > &g) const
Global multi-index -> global linear index (x-fastest: I = x + y*nx + z*nx*ny).
int ownerOf(const IVec< Dim > &g) const
Owning block index of a global cell coordinate. Caller must wrap into [0, globalSize) first.
IVec< Dim > multiGlobal(Index lin) const
Global linear index -> global multi-index (inverse of linearGlobal).
Kokkos::View< T *, MemSpace > View
1D device array.
std::int64_t Index
Signed index type for grids and particles (supersedes block_decomposer's long int IndxT).
A rank-owned axis-aligned block of the global cell grid.
IVec< Dim > size
extent in cells along each axis
IVec< Dim > origin
inclusive lower corner in global cell coordinates