16 #ifndef dealii_index_set_h 17 #define dealii_index_set_h 19 #include <deal.II/base/config.h> 21 #include <deal.II/base/exceptions.h> 22 #include <deal.II/base/thread_management.h> 23 #include <deal.II/base/utilities.h> 25 #include <boost/serialization/vector.hpp> 32 #ifdef DEAL_II_WITH_TRILINOS 33 # include <Epetra_Map.h> 34 # ifdef DEAL_II_TRILINOS_WITH_TPETRA 35 # include <Tpetra_Map.hpp> 39 #if defined(DEAL_II_WITH_MPI) || defined(DEAL_II_WITH_PETSC) 43 # ifndef MPI_COMM_WORLD 44 # define MPI_COMM_WORLD 0 48 DEAL_II_NAMESPACE_OPEN
141 #ifdef DEAL_II_WITH_TRILINOS 145 explicit IndexSet(
const Epetra_BlockMap &map);
198 template <
typename ForwardIterator>
380 template <
typename VectorType>
388 template <
class StreamType>
390 print(StreamType &out)
const;
397 write(std::ostream &out)
const;
404 read(std::istream &in);
420 #ifdef DEAL_II_WITH_TRILINOS 451 const bool overlapping =
false)
const;
453 # ifdef DEAL_II_TRILINOS_WITH_TPETRA 454 Tpetra::Map<int, types::global_dof_index>
455 make_tpetra_map(
const MPI_Comm &communicator = MPI_COMM_WORLD,
456 const bool overlapping =
false)
const;
470 <<
"The global index " << arg1
471 <<
" is not an element of this set.");
477 template <
class Archive>
479 serialize(Archive &ar,
const unsigned int version);
668 using difference_type = std::ptrdiff_t;
759 using difference_type = std::ptrdiff_t;
868 operator<(
const Range &range_1,
const Range &range_2)
871 (range_1.begin < range_2.begin) ||
872 ((range_1.begin == range_2.begin) && (range_1.end < range_2.end)));
878 return x.end < y.end;
884 return (x.nth_index_in_set + (x.end - x.begin) <
885 y.nth_index_in_set + (y.end - y.begin));
889 operator==(
const Range &range_1,
const Range &range_2)
891 return ((range_1.begin == range_2.begin) && (range_1.end == range_2.end));
897 return sizeof(
Range);
904 template <
class Archive>
906 serialize(Archive &ar,
const unsigned int version);
995 , range_idx(range_idx)
1005 , range_idx(
numbers::invalid_dof_index)
1012 : index_set(other.index_set)
1013 , range_idx(other.range_idx)
1025 return index_set->ranges[range_idx].end - index_set->ranges[range_idx].begin;
1033 return index_set !=
nullptr && range_idx < index_set->n_intervals();
1042 return {index_set, range_idx, index_set->ranges[range_idx].begin};
1053 if (range_idx < index_set->
ranges.size() - 1)
1054 return {index_set, range_idx + 1, index_set->ranges[range_idx + 1].begin};
1056 return index_set->end();
1066 return index_set->ranges[range_idx].end - 1;
1089 "Can not compare accessors pointing to different IndexSets"));
1101 "Can not compare accessors pointing to different IndexSets"));
1113 "Impossible to advance an IndexSet::IntervalIterator that is invalid"));
1117 if (range_idx >= index_set->ranges.size())
1127 : accessor(idxset, range_idx)
1192 return !(*
this == other);
1212 "Can not compare iterators belonging to different IndexSets"));
1215 accessor.index_set->ranges.size() :
1219 accessor.index_set->ranges.size() :
1223 return static_cast<int>(lhs - rhs);
1225 return -
static_cast<int>(rhs - lhs);
1237 , range_idx(range_idx)
1242 "Invalid range index for IndexSet::ElementIterator constructor."));
1247 "Invalid index argument for IndexSet::ElementIterator constructor."));
1254 , range_idx(
numbers::invalid_dof_index)
1255 , idx(
numbers::invalid_dof_index)
1265 (range_idx < index_set->
ranges.size() &&
1266 idx < index_set->ranges[range_idx].end),
1269 return (range_idx < index_set->
ranges.size() &&
1270 idx < index_set->ranges[range_idx].end);
1280 "Impossible to dereference an IndexSet::ElementIterator that is invalid"));
1292 "Can not compare iterators belonging to different IndexSets"));
1293 return range_idx == other.
range_idx && idx == other.
idx;
1304 "Impossible to advance an IndexSet::ElementIterator that is invalid"));
1305 if (idx < index_set->
ranges[range_idx].
end)
1308 if (idx == index_set->ranges[range_idx].end)
1311 if (range_idx < index_set->
ranges.size() - 1)
1314 idx = index_set->ranges[range_idx].begin;
1350 return !(*
this == other);
1361 "Can not compare iterators belonging to different IndexSets"));
1368 inline std::ptrdiff_t
1374 "Can not compare iterators belonging to different IndexSets"));
1377 if (!(*
this < other))
1378 return -(other - *
this);
1387 std::ptrdiff_t c = index_set->ranges[range_idx].end - idx;
1391 range < index_set->ranges.size() && range <= other.
range_idx;
1393 c += index_set->ranges[range].end - index_set->ranges[range].begin;
1396 other.
range_idx < index_set->ranges.size() ||
1399 "Inconsistent iterator state. Did you invalidate iterators by modifying the IndexSet?"));
1404 c -= index_set->ranges[other.
range_idx].end - other.
idx;
1439 : is_compressed(true)
1440 , index_space_size(size)
1441 , largest_range(
numbers::invalid_unsigned_int)
1447 : ranges(std::move(is.ranges))
1448 , is_compressed(is.is_compressed)
1449 , index_space_size(is.index_space_size)
1450 , largest_range(is.largest_range)
1453 is.is_compressed =
true;
1454 is.index_space_size = 0;
1465 ranges = std::move(is.ranges);
1466 is_compressed = is.is_compressed;
1467 index_space_size = is.index_space_size;
1468 largest_range = is.largest_range;
1471 is.is_compressed =
true;
1472 is.index_space_size = 0;
1487 return {
this, 0,
ranges[0].begin};
1499 ExcIndexRangeType<size_type>(global_index, 0,
size()));
1504 std::vector<Range>::const_iterator main_range =
1507 Range r(global_index, global_index + 1);
1510 std::vector<Range>::const_iterator range_begin, range_end;
1511 if (global_index < main_range->
begin)
1513 range_begin =
ranges.begin();
1514 range_end = main_range;
1518 range_begin = main_range;
1519 range_end =
ranges.end();
1524 const std::vector<Range>::const_iterator p =
1537 if (global_index < p->
begin)
1540 return {
this,
static_cast<size_type>(p -
ranges.begin()), global_index};
1591 ExcMessage(
"This function can only be called if the current " 1592 "object does not yet contain any elements."));
1624 const Range new_range(index, index + 1);
1626 ranges.push_back(new_range);
1627 else if (index ==
ranges.back().end)
1639 template <
typename ForwardIterator>
1645 for (ForwardIterator p =
begin; p !=
end;)
1649 ForwardIterator q = p;
1651 while ((q !=
end) && (*q == end_index))
1667 if (
ranges.empty() ==
false)
1689 std::vector<Range>::const_iterator p = std::upper_bound(
1697 return ((index >= p->begin) && (index < p->end));
1705 return (p->end > index);
1718 return (
ranges.size() <= 1);
1741 v = r.nth_index_in_set + r.end - r.begin;
1746 for (
const auto &range :
ranges)
1747 s += (range.end - range.begin);
1771 const std::vector<Range>::const_iterator main_range =
1774 return main_range->nth_index_in_set;
1788 std::vector<Range>::const_iterator main_range =
1790 if (n >= main_range->nth_index_in_set &&
1792 return main_range->begin + (n - main_range->nth_index_in_set);
1798 r.nth_index_in_set = n;
1799 std::vector<Range>::const_iterator range_begin, range_end;
1802 range_begin =
ranges.begin();
1803 range_end = main_range;
1807 range_begin = main_range + 1;
1808 range_end =
ranges.end();
1811 const std::vector<Range>::const_iterator p =
1815 return p->begin + (n - p->nth_index_in_set);
1835 std::vector<Range>::const_iterator main_range =
1837 if (n >= main_range->begin && n < main_range->
end)
1838 return (n - main_range->begin) + main_range->nth_index_in_set;
1841 std::vector<Range>::const_iterator range_begin, range_end;
1842 if (n < main_range->
begin)
1844 range_begin =
ranges.begin();
1845 range_end = main_range;
1849 range_begin = main_range + 1;
1850 range_end =
ranges.end();
1853 std::vector<Range>::const_iterator p =
1857 if (p == range_end || p->end == n || p->begin > n)
1863 return (n - p->begin) + p->nth_index_in_set;
1894 template <
typename Vector>
1902 std::fill(vector.begin(), vector.end(), 0);
1906 for (
const auto &range :
ranges)
1907 for (
size_type i = range.begin; i < range.end; ++i)
1913 template <
class StreamType>
1919 std::vector<Range>::const_iterator p;
1922 if (p->end - p->begin == 1)
1925 out <<
"[" << p->begin <<
"," << p->end - 1 <<
"]";
1930 out <<
"}" << std::endl;
1935 template <
class Archive>
1939 ar &begin &end &nth_index_in_set;
1944 template <
class Archive>
1951 DEAL_II_NAMESPACE_CLOSE
Iterator lower_bound(Iterator first, Iterator last, const T &val)
void fill_binary_vector(VectorType &vector) const
static const unsigned int invalid_unsigned_int
ElementIterator end() const
void add_index(const size_type index)
const IntervalAccessor * operator->() const
const IntervalAccessor & operator*() const
size_type nth_index_in_set(const unsigned int local_index) const
const IndexSet * index_set
IndexSet & operator=(const IndexSet &)=default
void block_read(std::istream &in)
std::ptrdiff_t operator-(const ElementIterator &p) const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
unsigned int largest_range_starting_index() const
types::global_dof_index size_type
ElementIterator(const IndexSet *idxset, const size_type range_idx, const size_type index)
bool operator<(const IntervalIterator &) const
std::forward_iterator_tag iterator_category
std::size_t memory_consumption() const
LinearAlgebra::distributed::Vector< Number > Vector
size_type n_elements() 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
void print(StreamType &out) const
void serialize(Archive &ar, const unsigned int version)
IndexSet complete_index_set(const unsigned int N)
void serialize(Archive &ar, const unsigned int version)
static ::ExceptionBase & ExcMessage(std::string arg1)
void block_write(std::ostream &out) const
std::vector< Range > ranges
static ::ExceptionBase & ExcIndexNotPresent(size_type arg1)
#define DeclException1(Exception1, type1, outsequence)
void subtract_set(const IndexSet &other)
#define Assert(cond, exc)
std::forward_iterator_tag iterator_category
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
bool operator<(const ElementIterator &) const
size_type index_within_set(const size_type global_index) const
bool operator==(const IndexSet &is) const
IntervalAccessor accessor
IntervalAccessor & operator=(const IntervalAccessor &other)
bool operator==(const IntervalIterator &) const
const IndexSet * index_set
bool operator==(const IntervalAccessor &other) const
unsigned int n_intervals() const
int operator-(const IntervalIterator &p) const
bool operator!=(const IndexSet &is) const
void fill_index_vector(std::vector< size_type > &indices) const
void add_range(const size_type begin, const size_type end)
IndexSet operator &(const IndexSet &is) const
IntervalIterator & operator=(const IntervalIterator &other)=default
void set_size(const size_type size)
ElementIterator & operator++()
unsigned int global_dof_index
IntervalAccessor(const IndexSet *idxset, const size_type range_idx)
IndexSet get_view(const size_type begin, const size_type end) const
ElementIterator end() const
IntervalIterator begin_intervals() const
bool is_contiguous() const
Threads::Mutex compress_mutex
IntervalIterator end_intervals() const
bool operator<(const IntervalAccessor &other) const
bool operator!=(const ElementIterator &) const
ElementIterator begin() const
void write(std::ostream &out) const
bool is_element(const size_type index) const
bool operator==(const ElementIterator &) const
ElementIterator at(const size_type global_index) const
const types::global_dof_index invalid_dof_index
ElementIterator begin() const
void read(std::istream &in)
size_type n_elements() const
IntervalIterator & operator++()
static ::ExceptionBase & ExcInternalError()
size_type operator*() const
bool operator!=(const IntervalIterator &) const