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 "ManualPartitioner ranks do not match comm size" );
109 return _ranks_per_dim;
124 const std::array<int, num_space_dim>& global_cells_per_dim,
125 std::array<int, num_space_dim>& owned_num_cell,
126 std::array<int, num_space_dim>& global_cell_offset )
const override
129 std::array<int, num_space_dim> cells_per_dim;
130 std::array<int, num_space_dim> dim_remainder;
131 std::array<int, num_space_dim> cart_rank;
132 averageCellInfo( cart_comm, global_cells_per_dim, cart_rank,
133 cells_per_dim, dim_remainder );
138 globalCellOffsetHelper( cart_rank, cells_per_dim, dim_remainder );
142 ownedCellsHelper( cart_rank, cells_per_dim, dim_remainder );
154 const std::array<int, num_space_dim>& global_cells_per_dim )
const
157 std::array<int, num_space_dim> cells_per_dim;
158 std::array<int, num_space_dim> dim_remainder;
159 std::array<int, num_space_dim> cart_rank;
160 averageCellInfo( cart_comm, global_cells_per_dim, cart_rank,
161 cells_per_dim, dim_remainder );
164 return ownedCellsHelper( cart_rank, cells_per_dim, dim_remainder );
179 averageCellInfo( MPI_Comm cart_comm,
180 const std::array<int, num_space_dim>& global_cells_per_dim,
181 std::array<int, num_space_dim>& cart_rank,
182 std::array<int, num_space_dim>& cells_per_dim,
183 std::array<int, num_space_dim>& dim_remainder )
const
187 MPI_Comm_rank( cart_comm, &linear_rank );
193 cells_per_dim[d] = global_cells_per_dim[d] / _ranks_per_dim[d];
194 dim_remainder[d] = global_cells_per_dim[d] % _ranks_per_dim[d];
207 inline std::array<int, num_space_dim> ownedCellsHelper(
208 const std::array<int, num_space_dim>& cart_rank,
209 const std::array<int, num_space_dim>& cells_per_dim,
210 const std::array<int, num_space_dim>& dim_remainder )
const
212 std::array<int, num_space_dim> owned_num_cell;
216 owned_num_cell[d] = cells_per_dim[d];
217 if ( dim_remainder[d] > cart_rank[d] )
220 return owned_num_cell;
232 inline std::array<int, num_space_dim> globalCellOffsetHelper(
233 const std::array<int, num_space_dim>& cart_rank,
234 const std::array<int, num_space_dim>& cells_per_dim,
235 const std::array<int, num_space_dim>& dim_remainder )
const
237 std::array<int, num_space_dim> global_cell_offset;
242 global_cell_offset[d] = 0;
243 for (
int r = 0; r < cart_rank[d]; ++r )
245 global_cell_offset[d] += cells_per_dim[d];
246 if ( dim_remainder[d] > r )
247 ++global_cell_offset[d];
250 return global_cell_offset;
254 std::array<int, NumSpaceDim> _ranks_per_dim;
269template <std::
size_t NumSpaceDim>
280 initUnpartitionedDims();
289 initUnpartitionedDims();
292 _unpartitioned_dim[dim] = 1;
304 "Cannot partition 2d system with 2 unpartitioned dimensions." );
306 initUnpartitionedDims();
309 _unpartitioned_dim[dim_1] = 1;
310 _unpartitioned_dim[dim_2] = 1;
317 std::array<int, NumSpaceDim>
319 const std::array<int, NumSpaceDim>& )
const override
322 MPI_Comm_size( comm, &comm_size );
323 auto ranks_per_dim = _unpartitioned_dim;
324 MPI_Dims_create( comm_size, NumSpaceDim, ranks_per_dim.data() );
326 return ranks_per_dim;
341 const std::array<int, num_space_dim>& global_cells_per_dim,
342 std::array<int, num_space_dim>& owned_num_cell,
343 std::array<int, num_space_dim>& global_cell_offset )
const override
346 std::array<int, num_space_dim> cells_per_dim;
347 std::array<int, num_space_dim> dim_remainder;
348 std::array<int, num_space_dim> cart_rank;
349 averageCellInfo( cart_comm, global_cells_per_dim, cart_rank,
350 cells_per_dim, dim_remainder );
355 globalCellOffsetHelper( cart_rank, cells_per_dim, dim_remainder );
359 ownedCellsHelper( cart_rank, cells_per_dim, dim_remainder );
372 const std::array<int, num_space_dim>& global_cells_per_dim )
const
375 std::array<int, num_space_dim> cells_per_dim;
376 std::array<int, num_space_dim> dim_remainder;
377 std::array<int, num_space_dim> cart_rank;
378 averageCellInfo( cart_comm, global_cells_per_dim, cart_rank,
379 cells_per_dim, dim_remainder );
382 return ownedCellsHelper( cart_rank, cells_per_dim, dim_remainder );
386 std::array<int, NumSpaceDim> _unpartitioned_dim;
389 void initUnpartitionedDims()
391 for ( std::size_t d = 0; d < NumSpaceDim; ++d )
392 _unpartitioned_dim[d] = 0;
406 averageCellInfo( MPI_Comm cart_comm,
407 const std::array<int, num_space_dim>& global_cells_per_dim,
408 std::array<int, num_space_dim>& cart_rank,
409 std::array<int, num_space_dim>& cells_per_dim,
410 std::array<int, num_space_dim>& dim_remainder )
const
413 std::array<int, num_space_dim> ranks_per_dim;
414 std::array<int, num_space_dim> cart_period;
415 MPI_Cart_get( cart_comm,
num_space_dim, ranks_per_dim.data(),
416 cart_period.data(), cart_rank.data() );
421 cells_per_dim[d] = global_cells_per_dim[d] / ranks_per_dim[d];
422 dim_remainder[d] = global_cells_per_dim[d] % ranks_per_dim[d];
435 inline std::array<int, num_space_dim> ownedCellsHelper(
436 const std::array<int, num_space_dim>& cart_rank,
437 const std::array<int, num_space_dim>& cells_per_dim,
438 const std::array<int, num_space_dim>& dim_remainder )
const
440 std::array<int, num_space_dim> owned_num_cell;
444 owned_num_cell[d] = cells_per_dim[d];
445 if ( dim_remainder[d] > cart_rank[d] )
448 return owned_num_cell;
460 inline std::array<int, num_space_dim> globalCellOffsetHelper(
461 const std::array<int, num_space_dim>& cart_rank,
462 const std::array<int, num_space_dim>& cells_per_dim,
463 const std::array<int, num_space_dim>& dim_remainder )
const
465 std::array<int, num_space_dim> global_cell_offset;
470 global_cell_offset[d] = 0;
471 for (
int r = 0; r < cart_rank[d]; ++r )
473 global_cell_offset[d] += cells_per_dim[d];
474 if ( dim_remainder[d] > r )
475 ++global_cell_offset[d];
478 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:274
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:339
DimBlockPartitioner(const int dim)
Constructor for NumSpaceDim-1 (1d for 2d system).
Definition Cabana_Grid_Partitioner.hpp:287
DimBlockPartitioner()
Default constructor (automatically partitioned in all dimensions).
Definition Cabana_Grid_Partitioner.hpp:277
DimBlockPartitioner(const int dim_1, const int dim_2)
Constructor for 1d decomposition (3d systems only).
Definition Cabana_Grid_Partitioner.hpp:300
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:370
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:318
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:152
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:122
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