16 #include <deal.II/base/partitioner.h> 17 #include <deal.II/base/partitioner.templates.h> 19 DEAL_II_NAMESPACE_OPEN
28 local_range_data (
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 locally_owned_range_data (size),
45 local_range_data (
std::pair<
types::global_dof_index,
types::global_dof_index> (0, size)),
46 n_ghost_indices_data (0),
47 n_import_indices_data (0),
48 n_ghost_indices_in_larger_set(0),
51 communicator (MPI_COMM_SELF),
52 have_ghost_indices (false)
63 const MPI_Comm communicator_in)
65 global_size (static_cast<
types::global_dof_index>(locally_owned_indices.size())),
66 n_ghost_indices_data (0),
67 n_import_indices_data (0),
68 n_ghost_indices_in_larger_set(0),
71 communicator (communicator_in),
72 have_ghost_indices (false)
81 const MPI_Comm communicator_in)
83 global_size (static_cast<
types::global_dof_index>(locally_owned_indices.size())),
84 n_ghost_indices_data (0),
85 n_import_indices_data (0),
86 n_ghost_indices_in_larger_set(0),
89 communicator (communicator_in),
90 have_ghost_indices (false)
99 const IndexSet &read_write_vector_index_set,
100 const MPI_Comm &communicator_in)
126 ExcMessage (
"The index set specified in locally_owned_indices " 127 "is not contiguous."));
130 local_range_data = std::pair<types::global_dof_index, types::global_dof_index>
135 static_cast<types::global_dof_index>(std::numeric_limits<unsigned int>::max()),
136 ExcMessage(
"Index overflow: This class supports at most 2^32-1 locally owned vector entries"));
148 const IndexSet &larger_ghost_index_set)
165 ExcMessage(
"Index overflow: This class supports at most 2^32-1 ghost elements"));
179 #ifdef DEAL_II_WITH_MPI 188 std::vector<types::global_dof_index> first_index (
n_procs+1);
192 int ierr = MPI_Bcast(first_index.data(), 1, DEAL_II_DOF_INDEX_MPI_TYPE,
198 DEAL_II_DOF_INDEX_MPI_TYPE, &first_index[1], 1,
207 unsigned int first_proc_with_nonzero_dofs = 0;
208 for (
unsigned int i=0; i<
n_procs; ++i)
209 if (first_index[i+1]>0)
211 first_proc_with_nonzero_dofs = i;
214 for (
unsigned int i=first_proc_with_nonzero_dofs+1; i<
n_procs; ++i)
215 if (first_index[i] == 0)
216 first_index[i] = first_index[i-1];
229 unsigned int n_ghost_targets = 0;
237 unsigned int current_proc = 0;
240 while (current_index >= first_index[current_proc+1])
242 std::vector<std::pair<unsigned int, unsigned int> > ghost_targets_temp
243 (1, std::pair<unsigned int, unsigned int>(current_proc, 0));
248 current_index = expanded_ghost_indices[iterator];
249 while (current_index >= first_index[current_proc+1])
252 if ( ghost_targets_temp[n_ghost_targets-1].first < current_proc)
254 ghost_targets_temp[n_ghost_targets-1].second =
255 iterator - ghost_targets_temp[n_ghost_targets-1].second;
256 ghost_targets_temp.emplace_back (current_proc, iterator);
260 ghost_targets_temp[n_ghost_targets-1].second =
266 std::vector<int> send_buffer (
n_procs, 0);
267 std::vector<int> receive_buffer (
n_procs, 0);
268 for (
unsigned int i=0; i<n_ghost_targets; i++)
271 const int ierr = MPI_Alltoall (send_buffer.data(), 1, MPI_INT, receive_buffer.data(), 1,
276 std::vector<std::pair<unsigned int,unsigned int> > import_targets_temp;
278 for (
unsigned int i=0; i<
n_procs; i++)
279 if (receive_buffer[i] > 0)
282 import_targets_temp.emplace_back(i, receive_buffer[i]);
292 unsigned int current_index_start = 0;
296 const int ierr = MPI_Irecv (&expanded_import_indices[current_index_start],
298 DEAL_II_DOF_INDEX_MPI_TYPE,
308 current_index_start = 0;
309 for (
unsigned int i=0; i<n_ghost_targets; i++)
311 const int ierr = MPI_Send (&expanded_ghost_indices[current_index_start],
320 if (import_requests.size()>0)
322 const int ierr = MPI_Waitall (import_requests.size(),
323 import_requests.data(),
324 MPI_STATUSES_IGNORE);
333 std::vector<std::pair<unsigned int,unsigned int> > compressed_import_indices;
334 unsigned int shift = 0;
340 const unsigned int i = shift + ii;
349 if (new_index == last_index+1)
350 compressed_import_indices.back().second++;
352 compressed_import_indices.emplace_back (new_index,new_index+1);
353 last_index = new_index;
371 #endif // #ifdef DEAL_II_WITH_MPI 373 if (larger_ghost_index_set.
size() == 0)
384 ExcMessage(
"Ghost index set should not overlap with owned set."));
386 ExcMessage(
"Larger ghost index set must contain the tight " 387 "ghost index set."));
391 std::vector<unsigned int> expanded_numbering;
396 ExcMessage(
"The given larger ghost index set must contain" 397 "all indices in the actual index set."));
401 std::vector<std::pair<unsigned int,unsigned int> > ghost_indices_subset;
404 unsigned int shift = 0;
410 const unsigned int i = shift + ii;
411 if (expanded_numbering[i] == last_index+1)
412 ghost_indices_subset.back().second++;
414 ghost_indices_subset.emplace_back(expanded_numbering[i],
415 expanded_numbering[i]+1);
416 last_index = expanded_numbering[i];
434 #ifdef DEAL_II_WITH_MPI 437 int communicators_same = 0;
439 &communicators_same);
441 if (!(communicators_same == MPI_IDENT ||
442 communicators_same == MPI_CONGRUENT))
485 #include "partitioner.inst" 487 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)
virtual void reinit(const IndexSet &vector_space_vector_index_set, const IndexSet &read_write_vector_index_set, const MPI_Comm &communicator)
ElementIterator end() const
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)
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)
unsigned int global_dof_index
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)
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::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
std::pair< types::global_dof_index, types::global_dof_index > local_range_data
const types::global_dof_index invalid_dof_index
ElementIterator begin() const
unsigned int n_import_indices_data
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())