16#ifndef CABANA_GRID_PARTITIONER_HPP
17#define CABANA_GRID_PARTITIONER_HPP
35template <std::
size_t NumSpaceDim>
52 const std::array<int, num_space_dim>& global_cells_per_dim )
const = 0;
66 const std::array<int, num_space_dim>& global_cells_per_dim,
67 std::array<int, num_space_dim>& owned_num_cell,
68 std::array<int, num_space_dim>& global_cell_offset )
const = 0;
77template <std::
size_t NumSpaceDim>
89 : _ranks_per_dim( ranks_per_dim )
97 std::array<int, NumSpaceDim>
99 const std::array<int, NumSpaceDim>& )
const override
102 MPI_Comm_size( comm, &comm_size );
105 nrank *= _ranks_per_dim[d];
106 if ( comm_size != nrank )
107 throw std::runtime_error(
108 "Cabana::Grid::ManualBlockPartitioner::ranksPerDimension: "
109 "ManualBlockPartitioner ranks do not match comm size" );
110 return _ranks_per_dim;
125 const std::array<int, num_space_dim>& global_cells_per_dim,
126 std::array<int, num_space_dim>& owned_num_cell,
127 std::array<int, num_space_dim>& global_cell_offset )
const override
130 std::array<int, num_space_dim> cells_per_dim;
131 std::array<int, num_space_dim> dim_remainder;
132 std::array<int, num_space_dim> cart_rank;
133 averageCellInfo( cart_comm, global_cells_per_dim, cart_rank,
134 cells_per_dim, dim_remainder );
139 globalCellOffsetHelper( cart_rank, cells_per_dim, dim_remainder );
143 ownedCellsHelper( cart_rank, cells_per_dim, dim_remainder );
155 const std::array<int, num_space_dim>& global_cells_per_dim )
const
158 std::array<int, num_space_dim> cells_per_dim;
159 std::array<int, num_space_dim> dim_remainder;
160 std::array<int, num_space_dim> cart_rank;
161 averageCellInfo( cart_comm, global_cells_per_dim, cart_rank,
162 cells_per_dim, dim_remainder );
165 return ownedCellsHelper( cart_rank, cells_per_dim, dim_remainder );
180 averageCellInfo( MPI_Comm cart_comm,
181 const std::array<int, num_space_dim>& global_cells_per_dim,
182 std::array<int, num_space_dim>& cart_rank,
183 std::array<int, num_space_dim>& cells_per_dim,
184 std::array<int, num_space_dim>& dim_remainder )
const
188 MPI_Comm_rank( cart_comm, &linear_rank );
194 cells_per_dim[d] = global_cells_per_dim[d] / _ranks_per_dim[d];
195 dim_remainder[d] = global_cells_per_dim[d] % _ranks_per_dim[d];
208 inline std::array<int, num_space_dim> ownedCellsHelper(
209 const std::array<int, num_space_dim>& cart_rank,
210 const std::array<int, num_space_dim>& cells_per_dim,
211 const std::array<int, num_space_dim>& dim_remainder )
const
213 std::array<int, num_space_dim> owned_num_cell;
217 owned_num_cell[d] = cells_per_dim[d];
218 if ( dim_remainder[d] > cart_rank[d] )
221 return owned_num_cell;
233 inline std::array<int, num_space_dim> globalCellOffsetHelper(
234 const std::array<int, num_space_dim>& cart_rank,
235 const std::array<int, num_space_dim>& cells_per_dim,
236 const std::array<int, num_space_dim>& dim_remainder )
const
238 std::array<int, num_space_dim> global_cell_offset;
243 global_cell_offset[d] = 0;
244 for (
int r = 0; r < cart_rank[d]; ++r )
246 global_cell_offset[d] += cells_per_dim[d];
247 if ( dim_remainder[d] > r )
248 ++global_cell_offset[d];
251 return global_cell_offset;
255 std::array<int, NumSpaceDim> _ranks_per_dim;
270template <std::
size_t NumSpaceDim>
281 initUnpartitionedDims();
290 initUnpartitionedDims();
293 _unpartitioned_dim[dim] = 1;
305 "Cannot partition 2d system with 2 unpartitioned dimensions." );
307 initUnpartitionedDims();
310 _unpartitioned_dim[dim_1] = 1;
311 _unpartitioned_dim[dim_2] = 1;
318 std::array<int, NumSpaceDim>
320 const std::array<int, NumSpaceDim>& )
const override
323 MPI_Comm_size( comm, &comm_size );
324 auto ranks_per_dim = _unpartitioned_dim;
325 MPI_Dims_create( comm_size, NumSpaceDim, ranks_per_dim.data() );
327 return ranks_per_dim;
342 const std::array<int, num_space_dim>& global_cells_per_dim,
343 std::array<int, num_space_dim>& owned_num_cell,
344 std::array<int, num_space_dim>& global_cell_offset )
const override
347 std::array<int, num_space_dim> cells_per_dim;
348 std::array<int, num_space_dim> dim_remainder;
349 std::array<int, num_space_dim> cart_rank;
350 averageCellInfo( cart_comm, global_cells_per_dim, cart_rank,
351 cells_per_dim, dim_remainder );
356 globalCellOffsetHelper( cart_rank, cells_per_dim, dim_remainder );
360 ownedCellsHelper( cart_rank, cells_per_dim, dim_remainder );
373 const std::array<int, num_space_dim>& global_cells_per_dim )
const
376 std::array<int, num_space_dim> cells_per_dim;
377 std::array<int, num_space_dim> dim_remainder;
378 std::array<int, num_space_dim> cart_rank;
379 averageCellInfo( cart_comm, global_cells_per_dim, cart_rank,
380 cells_per_dim, dim_remainder );
383 return ownedCellsHelper( cart_rank, cells_per_dim, dim_remainder );
387 std::array<int, NumSpaceDim> _unpartitioned_dim;
390 void initUnpartitionedDims()
392 for ( std::size_t d = 0; d < NumSpaceDim; ++d )
393 _unpartitioned_dim[d] = 0;
407 averageCellInfo( MPI_Comm cart_comm,
408 const std::array<int, num_space_dim>& global_cells_per_dim,
409 std::array<int, num_space_dim>& cart_rank,
410 std::array<int, num_space_dim>& cells_per_dim,
411 std::array<int, num_space_dim>& dim_remainder )
const
414 std::array<int, num_space_dim> ranks_per_dim;
415 std::array<int, num_space_dim> cart_period;
416 MPI_Cart_get( cart_comm,
num_space_dim, ranks_per_dim.data(),
417 cart_period.data(), cart_rank.data() );
422 cells_per_dim[d] = global_cells_per_dim[d] / ranks_per_dim[d];
423 dim_remainder[d] = global_cells_per_dim[d] % ranks_per_dim[d];
436 inline std::array<int, num_space_dim> ownedCellsHelper(
437 const std::array<int, num_space_dim>& cart_rank,
438 const std::array<int, num_space_dim>& cells_per_dim,
439 const std::array<int, num_space_dim>& dim_remainder )
const
441 std::array<int, num_space_dim> owned_num_cell;
445 owned_num_cell[d] = cells_per_dim[d];
446 if ( dim_remainder[d] > cart_rank[d] )
449 return owned_num_cell;
461 inline std::array<int, num_space_dim> globalCellOffsetHelper(
462 const std::array<int, num_space_dim>& cart_rank,
463 const std::array<int, num_space_dim>& cells_per_dim,
464 const std::array<int, num_space_dim>& dim_remainder )
const
466 std::array<int, num_space_dim> global_cell_offset;
471 global_cell_offset[d] = 0;
472 for (
int r = 0; r < cart_rank[d]; ++r )
474 global_cell_offset[d] += cells_per_dim[d];
475 if ( dim_remainder[d] > r )
476 ++global_cell_offset[d];
479 return global_cell_offset;
Block partitioner base class.
Definition Cabana_Grid_Partitioner.hpp:37
virtual void ownedCellInfo(MPI_Comm cart_comm, const std::array< int, num_space_dim > &global_cells_per_dim, std::array< int, num_space_dim > &owned_num_cell, std::array< int, num_space_dim > &global_cell_offset) const =0
Get the owned number of cells and global cell offset of the current MPI rank.
static constexpr std::size_t num_space_dim
Spatial dimension.
Definition Cabana_Grid_Partitioner.hpp:40
virtual std::array< int, num_space_dim > ranksPerDimension(MPI_Comm comm, const std::array< int, num_space_dim > &global_cells_per_dim) const =0
Get the number of MPI ranks in each dimension of the grid.
static constexpr std::size_t num_space_dim
Spatial dimension.
Definition Cabana_Grid_Partitioner.hpp:275
void ownedCellInfo(MPI_Comm cart_comm, const std::array< int, num_space_dim > &global_cells_per_dim, std::array< int, num_space_dim > &owned_num_cell, std::array< int, num_space_dim > &global_cell_offset) const override
Get the owned number of cells and the global cell offset of the current MPI rank.
Definition Cabana_Grid_Partitioner.hpp:340
DimBlockPartitioner(const int dim)
Constructor for NumSpaceDim-1 (1d for 2d system).
Definition Cabana_Grid_Partitioner.hpp:288
DimBlockPartitioner()
Default constructor (automatically partitioned in all dimensions).
Definition Cabana_Grid_Partitioner.hpp:278
DimBlockPartitioner(const int dim_1, const int dim_2)
Constructor for 1d decomposition (3d systems only).
Definition Cabana_Grid_Partitioner.hpp:301
std::array< int, num_space_dim > ownedCellsPerDimension(MPI_Comm cart_comm, const std::array< int, num_space_dim > &global_cells_per_dim) const
Get the owned number of cells of the current MPI rank.
Definition Cabana_Grid_Partitioner.hpp:371
std::array< int, NumSpaceDim > ranksPerDimension(MPI_Comm comm, const std::array< int, NumSpaceDim > &) const override
Get the MPI ranks per dimension.
Definition Cabana_Grid_Partitioner.hpp:319
ManualBlockPartitioner(const std::array< int, NumSpaceDim > &ranks_per_dim)
Constructor.
Definition Cabana_Grid_Partitioner.hpp:88
static constexpr std::size_t num_space_dim
Spatial dimension.
Definition Cabana_Grid_Partitioner.hpp:82
std::array< int, num_space_dim > ownedCellsPerDimension(MPI_Comm cart_comm, const std::array< int, num_space_dim > &global_cells_per_dim) const
Get the owned number of cells of the current MPI rank.
Definition Cabana_Grid_Partitioner.hpp:153
void ownedCellInfo(MPI_Comm cart_comm, const std::array< int, num_space_dim > &global_cells_per_dim, std::array< int, num_space_dim > &owned_num_cell, std::array< int, num_space_dim > &global_cell_offset) const override
Get the owned number of cells of the current MPI rank.
Definition Cabana_Grid_Partitioner.hpp:123
std::array< int, NumSpaceDim > ranksPerDimension(MPI_Comm comm, const std::array< int, NumSpaceDim > &) const override
Get the MPI ranks per dimension.
Definition Cabana_Grid_Partitioner.hpp:98
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36