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)
44 std::pair<
types::global_dof_index,
types::global_dof_index>(0, size))
62 const MPI_Comm communicator_in)
64 static_cast<
types::global_dof_index>(locally_owned_indices.
size()))
80 const MPI_Comm communicator_in)
82 static_cast<
types::global_dof_index>(locally_owned_indices.
size()))
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,
218 unsigned int first_proc_with_nonzero_dofs = 0;
219 for (
unsigned int i = 0; i <
n_procs; ++i)
220 if (first_index[i + 1] > 0)
222 first_proc_with_nonzero_dofs = i;
225 for (
unsigned int i = first_proc_with_nonzero_dofs + 1; i <
n_procs;
227 if (first_index[i] == 0)
228 first_index[i] = first_index[i - 1];
241 std::vector<types::global_dof_index> expanded_ghost_indices(
242 n_ghost_indices_data);
243 unsigned int n_ghost_targets = 0;
244 if (n_ghost_indices_data > 0)
251 unsigned int current_proc = 0;
254 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));
263 current_index = expanded_ghost_indices[iterator];
264 while (current_index >= first_index[current_proc + 1])
267 if (ghost_targets_temp[n_ghost_targets - 1].first < current_proc)
269 ghost_targets_temp[n_ghost_targets - 1].second =
270 iterator - ghost_targets_temp[n_ghost_targets - 1].second;
271 ghost_targets_temp.emplace_back(current_proc, iterator);
275 ghost_targets_temp[n_ghost_targets - 1].second =
276 n_ghost_indices_data -
277 ghost_targets_temp[n_ghost_targets - 1].second;
282 std::vector<int> send_buffer(
n_procs, 0);
283 std::vector<int> receive_buffer(
n_procs, 0);
284 for (
unsigned int i = 0; i < n_ghost_targets; i++)
288 const int ierr = MPI_Alltoall(send_buffer.data(),
291 receive_buffer.data(),
298 std::vector<std::pair<unsigned int, unsigned int>> import_targets_temp;
300 for (
unsigned int i = 0; i <
n_procs; i++)
301 if (receive_buffer[i] > 0)
304 import_targets_temp.emplace_back(i, receive_buffer[i]);
312 std::vector<types::global_dof_index> expanded_import_indices(
315 unsigned int current_index_start = 0;
320 MPI_Irecv(&expanded_import_indices[current_index_start],
322 DEAL_II_DOF_INDEX_MPI_TYPE,
326 &import_requests[i]);
333 current_index_start = 0;
334 for (
unsigned int i = 0; i < n_ghost_targets; i++)
337 MPI_Send(&expanded_ghost_indices[current_index_start],
339 DEAL_II_DOF_INDEX_MPI_TYPE,
348 if (import_requests.size() > 0)
350 const int ierr = MPI_Waitall(import_requests.size(),
351 import_requests.data(),
352 MPI_STATUSES_IGNORE);
362 std::vector<std::pair<unsigned int, unsigned int>>
363 compressed_import_indices;
364 unsigned int shift = 0;
372 const unsigned int i = shift + ii;
382 if (new_index == last_index + 1)
383 compressed_import_indices.back().second++;
385 compressed_import_indices.emplace_back(new_index,
387 last_index = new_index;
391 compressed_import_indices.size();
407 #endif // #ifdef DEAL_II_WITH_MPI 409 if (larger_ghost_index_set.
size() == 0)
424 ExcMessage(
"Ghost index set should not overlap with owned set."));
427 ExcMessage(
"Larger ghost index set must contain the tight " 428 "ghost index set."));
432 std::vector<unsigned int> expanded_numbering;
434 it != ghost_indices_data.end();
438 ExcMessage(
"The given larger ghost index set must contain" 439 "all indices in the actual index set."));
440 expanded_numbering.push_back(
444 std::vector<std::pair<unsigned int, unsigned int>>
445 ghost_indices_subset;
449 unsigned int shift = 0;
455 const unsigned int i = shift + ii;
456 if (expanded_numbering[i] == last_index + 1)
457 ghost_indices_subset.back().second++;
459 ghost_indices_subset.emplace_back(expanded_numbering[i],
460 expanded_numbering[i] +
462 last_index = expanded_numbering[i];
466 ghost_indices_subset.size();
481 #ifdef DEAL_II_WITH_MPI 484 int communicators_same = 0;
487 &communicators_same);
489 if (!(communicators_same == MPI_IDENT ||
490 communicators_same == MPI_CONGRUENT))
514 4 *
sizeof(
unsigned int) +
sizeof(MPI_Comm));
536 #include "partitioner.inst" 538 DEAL_II_NAMESPACE_CLOSE
std::vector< std::pair< unsigned int, unsigned int > > import_indices_data
unsigned int n_ghost_indices() const
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
IndexSet ghost_indices_data
types::global_dof_index size() const
types::global_dof_index global_size
#define AssertIndexRange(index, range)
size_type n_elements() const
unsigned int n_ghost_indices_data
#define AssertThrow(cond, exc)
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
unsigned long long int global_dof_index
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
bool is_contiguous() const
static::ExceptionBase & ExcMessage(std::string arg1)
T sum(const T &t, const MPI_Comm &mpi_communicator)
void subtract_set(const IndexSet &other)
void fill_index_vector(std::vector< size_type > &indices) const
#define Assert(cond, exc)
std::size_t memory_consumption() const
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::vector< std::pair< unsigned int, unsigned int > > ghost_indices_subset_data
bool is_globally_compatible(const Partitioner &part) const
IndexSet locally_owned_range_data
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
void add_range(const size_type begin, const size_type end)
bool is_compatible(const Partitioner &part) const
void set_size(const size_type size)
#define AssertThrowMPI(error_code)
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
size_type index_within_set(const size_type global_index) const
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
bool is_element(const size_type index) const
static::ExceptionBase & ExcNotImplemented()
const types::global_dof_index invalid_dof_index
size_type nth_index_in_set(const unsigned int local_index) const
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
unsigned int local_size() 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())