16 #include <deal.II/base/partitioner.h> 18 DEAL_II_NAMESPACE_OPEN
27 local_range_data (
std::pair<
types::global_dof_index,
types::global_dof_index> (0, 0)),
28 n_ghost_indices_data (0),
29 n_import_indices_data (0),
32 communicator (MPI_COMM_SELF),
33 have_ghost_indices (false)
60 const MPI_Comm communicator_in)
77 const MPI_Comm communicator_in)
108 ExcMessage (
"The index set specified in locally_owned_indices " 109 "is not contiguous."));
112 local_range_data = std::pair<types::global_dof_index, types::global_dof_index>
117 static_cast<types::global_dof_index>(std::numeric_limits<unsigned int>::max()),
118 ExcMessage(
"Index overflow: This class supports at most 2^32-1 locally owned vector entries"));
136 ExcDimensionMismatch (ghost_indices_in.
size(),
146 ExcMessage(
"Index overflow: This class supports at most 2^32-1 ghost elements"));
160 #ifdef DEAL_II_WITH_MPI 165 Assert (n_ghost_indices_data == 0, ExcInternalError());
169 std::vector<types::global_dof_index> first_index (
n_procs+1);
173 MPI_Bcast(&first_index[0], 1, DEAL_II_DOF_INDEX_MPI_TYPE,
178 DEAL_II_DOF_INDEX_MPI_TYPE, &first_index[1], 1,
186 unsigned int first_proc_with_nonzero_dofs = 0;
187 for (
unsigned int i=0; i<
n_procs; ++i)
188 if (first_index[i+1]>0)
190 first_proc_with_nonzero_dofs = i;
193 for (
unsigned int i=first_proc_with_nonzero_dofs+1; i<
n_procs; ++i)
194 if (first_index[i] == 0)
195 first_index[i] = first_index[i-1];
207 std::vector<types::global_dof_index> expanded_ghost_indices (n_ghost_indices_data);
208 unsigned int n_ghost_targets = 0;
209 if (n_ghost_indices_data > 0)
216 unsigned int current_proc = 0;
219 while (current_index >= first_index[current_proc+1])
221 std::vector<std::pair<unsigned int, unsigned int> > ghost_targets_temp
222 (1, std::pair<unsigned int, unsigned int>(current_proc, 0));
227 current_index = expanded_ghost_indices[iterator];
228 while (current_index >= first_index[current_proc+1])
231 if ( ghost_targets_temp[n_ghost_targets-1].first < current_proc)
233 ghost_targets_temp[n_ghost_targets-1].second =
234 iterator - ghost_targets_temp[n_ghost_targets-1].second;
235 ghost_targets_temp.push_back(std::pair<
unsigned int,
236 unsigned int>(current_proc,iterator));
240 ghost_targets_temp[n_ghost_targets-1].second =
241 n_ghost_indices_data - ghost_targets_temp[n_ghost_targets-1].second;
246 std::vector<int> send_buffer (
n_procs, 0);
247 std::vector<int> receive_buffer (
n_procs, 0);
248 for (
unsigned int i=0; i<n_ghost_targets; i++)
251 MPI_Alltoall (&send_buffer[0], 1, MPI_INT, &receive_buffer[0], 1,
255 std::vector<std::pair<unsigned int,unsigned int> > import_targets_temp;
257 for (
unsigned int i=0; i<
n_procs; i++)
258 if (receive_buffer[i] > 0)
261 import_targets_temp.push_back(std::pair<
unsigned int,
262 unsigned int> (i, receive_buffer[i]));
271 unsigned int current_index_start = 0;
275 MPI_Irecv (&expanded_import_indices[current_index_start],
277 DEAL_II_DOF_INDEX_MPI_TYPE,
285 current_index_start = 0;
286 for (
unsigned int i=0; i<n_ghost_targets; i++)
288 MPI_Send (&expanded_ghost_indices[current_index_start],
296 if (import_requests.size()>0)
297 MPI_Waitall (import_requests.size(), &import_requests[0],
298 MPI_STATUSES_IGNORE);
304 std::vector<std::pair<unsigned int,unsigned int> > compressed_import_indices;
314 ExcNotImplemented());
315 if (new_index == last_index+1)
316 compressed_import_indices.back().second++;
319 compressed_import_indices.push_back
320 (std::pair<unsigned int,unsigned int>(new_index,new_index+1));
322 last_index = new_index;
349 #ifdef DEAL_II_WITH_MPI 352 int communicators_same = 0;
354 &communicators_same);
355 if (!(communicators_same == MPI_IDENT ||
356 communicators_same == MPI_CONGRUENT))
394 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
size_type nth_index_in_set(const unsigned int local_index) const
IndexSet ghost_indices_data
::ExceptionBase & ExcMessage(std::string arg1)
#define AssertIndexRange(index, range)
unsigned int n_ghost_indices_data
#define AssertThrow(cond, exc)
bool job_supports_mpi() DEAL_II_DEPRECATED
void set_owned_indices(const IndexSet &locally_owned_indices)
T sum(const T &t, const MPI_Comm &mpi_communicator)
unsigned int global_dof_index
void subtract_set(const IndexSet &other)
const MPI_Comm communicator
#define Assert(cond, exc)
const types::global_dof_index global_size
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)
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
types::global_dof_index size() const
std::size_t memory_consumption() const
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)
std::pair< types::global_dof_index, types::global_dof_index > local_range_data
const types::global_dof_index invalid_dof_index
unsigned int n_import_indices_data
size_type n_elements() const
void set_ghost_indices(const IndexSet &ghost_indices)