16 #include <deal.II/base/partitioner.h> 17 #include <deal.II/base/partitioner.templates.h> 19 DEAL_II_NAMESPACE_OPEN
28 std::pair<
types::global_dof_index,
types::global_dof_index>(0, 0))
29 , n_ghost_indices_data(0)
30 , n_import_indices_data(0)
31 , n_ghost_indices_in_larger_set(0)
34 , communicator(MPI_COMM_SELF)
35 , have_ghost_indices(false)
42 , locally_owned_range_data(size)
44 std::pair<
types::global_dof_index,
types::global_dof_index>(0, size))
45 , n_ghost_indices_data(0)
46 , n_import_indices_data(0)
47 , n_ghost_indices_in_larger_set(0)
50 , communicator(MPI_COMM_SELF)
51 , have_ghost_indices(false)
62 const MPI_Comm communicator_in)
64 static_cast<
types::global_dof_index>(locally_owned_indices.size()))
65 , n_ghost_indices_data(0)
66 , n_import_indices_data(0)
67 , n_ghost_indices_in_larger_set(0)
70 , communicator(communicator_in)
71 , have_ghost_indices(false)
80 const MPI_Comm communicator_in)
82 static_cast<
types::global_dof_index>(locally_owned_indices.size()))
83 , n_ghost_indices_data(0)
84 , n_import_indices_data(0)
85 , n_ghost_indices_in_larger_set(0)
88 , communicator(communicator_in)
89 , have_ghost_indices(false)
98 const IndexSet &read_write_vector_index_set,
99 const MPI_Comm &communicator_in)
125 ExcMessage(
"The index set specified in locally_owned_indices " 126 "is not contiguous."));
130 std::pair<types::global_dof_index, types::global_dof_index>(
136 static_cast<types::global_dof_index>(
137 std::numeric_limits<unsigned int>::max()),
139 "Index overflow: This class supports at most 2^32-1 locally owned vector entries"));
152 const IndexSet &larger_ghost_index_set)
170 std::numeric_limits<unsigned int>::max()),
172 "Index overflow: This class supports at most 2^32-1 ghost elements"));
186 #ifdef DEAL_II_WITH_MPI 195 std::vector<types::global_dof_index> first_index(
n_procs + 1);
199 int ierr = MPI_Bcast(
200 first_index.data(), 1, DEAL_II_DOF_INDEX_MPI_TYPE, 0,
communicator);
206 DEAL_II_DOF_INDEX_MPI_TYPE,
209 DEAL_II_DOF_INDEX_MPI_TYPE,
222 for (
unsigned int i = 1; i <
n_procs; ++i)
223 if (first_index[i] == 0)
224 first_index[i] = first_index[i - 1];
237 std::vector<types::global_dof_index> expanded_ghost_indices(
239 unsigned int n_ghost_targets = 0;
247 unsigned int current_proc = 0;
250 while (current_index >= first_index[current_proc + 1])
256 std::vector<std::pair<unsigned int, unsigned int>> ghost_targets_temp(
257 1, std::pair<unsigned int, unsigned int>(current_proc, 0));
264 current_index = expanded_ghost_indices[iterator];
265 while (current_index >= first_index[current_proc + 1])
271 if (ghost_targets_temp[n_ghost_targets - 1].first < current_proc)
273 ghost_targets_temp[n_ghost_targets - 1].second =
274 iterator - ghost_targets_temp[n_ghost_targets - 1].second;
275 ghost_targets_temp.emplace_back(current_proc, iterator);
281 ghost_targets_temp[n_ghost_targets - 1].second =
283 ghost_targets_temp[n_ghost_targets - 1].second;
288 std::vector<int> send_buffer(
n_procs, 0);
289 std::vector<int> receive_buffer(
n_procs, 0);
290 for (
unsigned int i = 0; i < n_ghost_targets; i++)
294 const int ierr = MPI_Alltoall(send_buffer.data(),
297 receive_buffer.data(),
304 std::vector<std::pair<unsigned int, unsigned int>> import_targets_temp;
306 for (
unsigned int i = 0; i <
n_procs; i++)
307 if (receive_buffer[i] > 0)
310 import_targets_temp.emplace_back(i, receive_buffer[i]);
319 std::vector<types::global_dof_index> expanded_import_indices(
322 unsigned int current_index_start = 0;
328 MPI_Irecv(&expanded_import_indices[current_index_start],
330 DEAL_II_DOF_INDEX_MPI_TYPE,
334 &import_requests[i]);
342 current_index_start = 0;
343 for (
unsigned int i = 0; i < n_ghost_targets; i++)
346 MPI_Isend(&expanded_ghost_indices[current_index_start],
348 DEAL_II_DOF_INDEX_MPI_TYPE,
359 if (import_requests.size() > 0)
361 const int ierr = MPI_Waitall(import_requests.size(),
362 import_requests.data(),
363 MPI_STATUSES_IGNORE);
374 std::vector<std::pair<unsigned int, unsigned int>>
375 compressed_import_indices;
376 unsigned int shift = 0;
385 const unsigned int i = shift + ii;
397 if (new_index == last_index + 1)
399 compressed_import_indices.back().second++;
402 compressed_import_indices.emplace_back(new_index,
404 last_index = new_index;
408 compressed_import_indices.size();
424 #endif // #ifdef DEAL_II_WITH_MPI 426 if (larger_ghost_index_set.
size() == 0)
441 ExcMessage(
"Ghost index set should not overlap with owned set."));
444 ExcMessage(
"Larger ghost index set must contain the tight " 445 "ghost index set."));
451 std::vector<unsigned int> expanded_numbering;
455 ExcMessage(
"The given larger ghost index set must contain" 456 "all indices in the actual index set."));
460 std::numeric_limits<unsigned int>::max()),
462 "Index overflow: This class supports at most 2^32-1 ghost elements"));
463 expanded_numbering.push_back(
468 std::vector<std::pair<unsigned int, unsigned int>>
469 ghost_indices_subset;
474 unsigned int shift = 0;
480 const unsigned int i = shift + ii;
481 if (expanded_numbering[i] == last_index + 1)
483 ghost_indices_subset.back().second++;
486 ghost_indices_subset.emplace_back(expanded_numbering[i],
487 expanded_numbering[i] +
489 last_index = expanded_numbering[i];
493 ghost_indices_subset.size();
508 #ifdef DEAL_II_WITH_MPI 511 int communicators_same = 0;
514 &communicators_same);
516 if (!(communicators_same == MPI_IDENT ||
517 communicators_same == MPI_CONGRUENT))
541 4 *
sizeof(
unsigned int) +
sizeof(MPI_Comm));
563 #include "partitioner.inst" 565 DEAL_II_NAMESPACE_CLOSE
std::vector< std::pair< unsigned int, unsigned int > > import_indices_data
bool is_globally_compatible(const Partitioner &part) const
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
bool is_compatible(const Partitioner &part) const
unsigned int local_size() const
size_type nth_index_in_set(const unsigned int local_index) const
IndexSet ghost_indices_data
types::global_dof_index global_size
#define AssertIndexRange(index, range)
unsigned int n_ghost_indices_data
#define AssertThrow(cond, exc)
types::global_dof_index size_type
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
void set_owned_indices(const IndexSet &locally_owned_indices)
std::vector< unsigned int > ghost_indices_subset_chunks_by_rank_data
std::vector< unsigned int > import_indices_chunks_by_rank_data
static ::ExceptionBase & ExcMessage(std::string arg1)
unsigned int n_ghost_indices() const
T sum(const T &t, const MPI_Comm &mpi_communicator)
void subtract_set(const IndexSet &other)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
size_type index_within_set(const size_type global_index) const
std::vector< std::pair< unsigned int, unsigned int > > ghost_indices_subset_data
IndexSet locally_owned_range_data
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
void fill_index_vector(std::vector< size_type > &indices) const
void add_range(const size_type begin, const size_type end)
void set_size(const size_type size)
unsigned int global_dof_index
types::global_dof_index size() const
std::size_t memory_consumption() const
#define AssertThrowMPI(error_code)
bool is_contiguous() const
T min(const T &t, const MPI_Comm &mpi_communicator)
std::vector< std::pair< unsigned int, unsigned int > > import_targets_data
std::pair< types::global_dof_index, types::global_dof_index > local_range_data
std::vector< std::pair< unsigned int, unsigned int > > ghost_targets_data
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
static ::ExceptionBase & ExcNotImplemented()
bool is_element(const size_type index) const
const types::global_dof_index invalid_dof_index
unsigned int n_import_indices_data
virtual void reinit(const IndexSet &vector_space_vector_index_set, const IndexSet &read_write_vector_index_set, const MPI_Comm &communicator) override
size_type n_elements() const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
unsigned int n_ghost_indices_in_larger_set
static ::ExceptionBase & ExcInternalError()
void set_ghost_indices(const IndexSet &ghost_indices, const IndexSet &larger_ghost_index_set=IndexSet())