16 #include <deal.II/base/memory_consumption.h> 17 #include <deal.II/base/mpi.h> 18 #include <deal.II/base/index_set.h> 22 #ifdef DEAL_II_WITH_TRILINOS 23 # ifdef DEAL_II_WITH_MPI 24 # include <Epetra_MpiComm.h> 26 # include <Epetra_SerialComm.h> 27 # include <Epetra_Map.h> 30 DEAL_II_NAMESPACE_OPEN
34 #ifdef DEAL_II_WITH_TRILINOS 39 #ifdef DEAL_II_WITH_64BIT_INDICES 44 index_space_size (1+map.MaxAllGID64()),
45 largest_range (
numbers::invalid_unsigned_int)
48 map.MinAllGID64() == 0,
49 ExcMessage(
"The Epetra_Map does not contain the global index 0, which " 50 "means some entries are not present on any processor."));
57 const size_type n_indices = map.NumMyElements();
59 add_indices(indices, indices+n_indices);
71 index_space_size (1+map.MaxAllGID()),
72 largest_range (
numbers::invalid_unsigned_int)
76 ExcMessage(
"The Epetra_Map does not contain the global index 0, which " 77 "means some entries are not present on any processor."));
84 const size_type n_indices = map.NumMyElements();
85 unsigned int *indices =
reinterpret_cast<unsigned int *
>(map.MyGlobalElements());
93 #endif // ifdef DEAL_II_WITH_TRILINOS 108 ExcIndexRangeType<size_type> (
begin, 0,
end));
117 ranges.push_back(new_range);
143 std::vector<Range>::iterator store =
ranges.begin();
144 for (std::vector<Range>::iterator i =
ranges.begin();
147 std::vector<Range>::iterator
155 while (next !=
ranges.end() &&
156 (next->begin <= last_index))
158 last_index = std::max (last_index, next->end);
164 *store =
Range(first_index, last_index);
168 if (store !=
ranges.end())
170 std::vector<Range> new_ranges(
ranges.begin(), store);
175 size_type next_index = 0, largest_range_size = 0;
176 for (std::vector<Range>::iterator i =
ranges.begin(); i !=
ranges.end();
181 i->nth_index_in_set = next_index;
182 next_index += (i->end - i->begin);
183 if (i->end - i->begin > largest_range_size)
185 largest_range_size = i->end - i->begin;
207 std::vector<Range>::const_iterator r1 =
ranges.begin(),
211 while ((r1 !=
ranges.end())
217 if (r1->end <= r2->begin)
219 else if (r2->end <= r1->begin)
224 Assert (((r1->begin <= r2->begin) &&
225 (r1->end > r2->begin))
227 ((r2->begin <= r1->begin) &&
228 (r2->end > r1->begin)),
232 result.add_range (std::max (r1->begin,
240 if (r1->end <= r2->end)
258 ExcMessage (
"End index needs to be larger or equal to begin index!"));
260 ExcMessage (
"Given range exceeds index set dimension"));
263 std::vector<Range>::const_iterator r1 =
ranges.begin();
265 while (r1 !=
ranges.end())
267 if ((r1->end >
begin)
275 else if (r1->begin >=
end)
297 std::vector<Range> new_ranges;
299 std::vector<Range>::iterator own_it =
ranges.begin();
300 std::vector<Range>::iterator other_it = other.
ranges.begin();
302 while (own_it !=
ranges.end() && other_it != other.
ranges.end())
305 if (own_it->end <= other_it->begin)
311 if (own_it->begin >= other_it->end)
319 if (own_it->begin < other_it->begin)
321 Range r(own_it->begin, other_it->begin);
322 r.nth_index_in_set = 0;
323 new_ranges.push_back(r);
328 own_it->begin = other_it->end;
329 if (own_it->begin > own_it->end)
331 own_it->begin = own_it->end;
341 for (std::vector<Range>::iterator it =
ranges.begin();
344 if (it->begin >= it->end)
351 const std::vector<Range>::iterator
end = new_ranges.end();
352 for (std::vector<Range>::iterator it = new_ranges.begin();
365 ExcMessage(
"pop_back() failed, because this IndexSet contains no entries."));
382 ExcMessage(
"pop_front() failed, because this IndexSet contains no entries."));
401 const unsigned int offset)
403 if ((
this == &other) && (offset == 0))
408 ExcIndexRangeType<size_type> (other.
ranges.back().end-1,
414 std::vector<Range>::const_iterator r1 =
ranges.begin(),
415 r2 = other.
ranges.begin();
417 std::vector<Range> new_ranges;
424 if (r2 == other.
ranges.end() ||
425 (r1 !=
ranges.end() && r1->end < (r2->begin+offset)))
427 new_ranges.push_back(*r1);
430 else if (r1 ==
ranges.end() || (r2->end+offset) < r1->begin)
432 new_ranges.emplace_back(r2->begin+offset, r2->end+offset);
439 Range next(std::min(r1->begin, r2->begin+offset),
440 std::max(r1->end, r2->end+offset));
441 new_ranges.push_back(next);
458 out <<
size() <<
" ";
459 out <<
ranges.size() << std::endl;
460 std::vector<Range>::const_iterator r =
ranges.begin();
461 for ( ; r!=
ranges.end(); ++r)
463 out << r->begin <<
" " << r->end << std::endl;
475 unsigned int n_ranges;
480 for (
unsigned int i=0; i<n_ranges; ++i)
497 size_t n_ranges =
ranges.size();
498 out.write(reinterpret_cast<const char *>(&n_ranges),
500 if (
ranges.empty() ==
false)
501 out.write (reinterpret_cast<const char *>(&*
ranges.begin()),
511 in.read(reinterpret_cast<char *>(&
size),
sizeof(
size));
512 in.read(reinterpret_cast<char *>(&n_ranges),
sizeof(n_ranges));
518 in.read(reinterpret_cast<char *>(&*
ranges.begin()),
533 for (std::vector<Range>::iterator it =
ranges.begin();
537 indices.push_back (i);
546 #ifdef DEAL_II_WITH_TRILINOS 550 const bool overlapping)
const 561 ExcMessage (
"You are trying to create an Epetra_Map object " 562 "that partitions elements of an index set " 563 "between processors. However, the union of the " 564 "index sets on different processors does not " 565 "contain all indices exactly once: the sum of " 566 "the number of entries the various processors " 567 "want to store locally is " 569 " whereas the total size of the object to be " 572 ". In other words, there are " 573 "either indices that are not spoken for " 574 "by any processor, or there are indices that are " 575 "claimed by multiple processors."));
584 return Epetra_Map (TrilinosWrappers::types::int_type(
size()),
585 TrilinosWrappers::types::int_type(
n_elements()),
587 #ifdef DEAL_II_WITH_MPI
588 Epetra_MpiComm(communicator)
595 std::vector<size_type> indices;
597 return Epetra_Map (TrilinosWrappers::types::int_type(-1),
598 TrilinosWrappers::types::int_type(
n_elements()),
601 reinterpret_cast<TrilinosWrappers::types::int_type *>(indices.data())
605 #ifdef DEAL_II_WITH_MPI 606 Epetra_MpiComm(communicator)
624 if (n_global_elements !=
size())
627 #ifdef DEAL_II_WITH_MPI 633 bool is_globally_ascending =
true;
640 const std::vector<types::global_dof_index> global_dofs =
Utilities::MPI::gather(communicator,first_local_dof,0);
649 for (; index<global_dofs.size(); ++index)
654 if (new_dof <= old_dof)
656 is_globally_ascending =
false;
666 int is_ascending = is_globally_ascending ? 1 : 0;
667 int ierr = MPI_Bcast(&is_ascending, 1, MPI_INT, 0, communicator);
670 return (is_ascending==1);
673 #endif //DEAL_II_WITH_MPI 689 DEAL_II_NAMESPACE_CLOSE
Iterator lower_bound(Iterator first, Iterator last, const T &val)
types::global_dof_index size_type
ElementIterator end() const
IndexSet operator&(const IndexSet &is) const
static ::ExceptionBase & ExcIO()
void block_read(std::istream &in)
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
#define AssertThrow(cond, exc)
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
std::size_t memory_consumption() const
size_type index_space_size
bool is_ascending_and_one_to_one(const MPI_Comm &communicator) const
Epetra_Map make_trilinos_map(const MPI_Comm &communicator=MPI_COMM_WORLD, const bool overlapping=false) const
static ::ExceptionBase & ExcMessage(std::string arg1)
void block_write(std::ostream &out) const
std::vector< Range > ranges
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)
std::vector< T > gather(const MPI_Comm &comm, const T &object_to_send, const unsigned int root_process=0)
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)
IndexSet get_view(const size_type begin, const size_type end) const
IntervalIterator begin_intervals() const
#define AssertThrowMPI(error_code)
bool is_contiguous() const
Threads::Mutex compress_mutex
T min(const T &t, const MPI_Comm &mpi_communicator)
ElementIterator begin() const
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
void write(std::ostream &out) const
const types::global_dof_index invalid_dof_index
types::global_dof_index size_type
ElementIterator begin() const
void read(std::istream &in)
size_type n_elements() const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()