Reference documentation for deal.II version 8.4.2
index_set.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2009 - 2016 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii__index_set_h
17 #define dealii__index_set_h
18 
19 #include <deal.II/base/config.h>
20 #include <deal.II/base/utilities.h>
21 #include <deal.II/base/exceptions.h>
22 #include <boost/serialization/vector.hpp>
23 #include <vector>
24 #include <algorithm>
25 
26 #ifdef DEAL_II_WITH_TRILINOS
27 # include <Epetra_Map.h>
28 #endif
29 
30 #if defined(DEAL_II_WITH_MPI) || defined(DEAL_II_WITH_PETSC)
31 #include <mpi.h>
32 #else
33 typedef int MPI_Comm;
34 # ifndef MPI_COMM_WORLD
35 # define MPI_COMM_WORLD 0
36 # endif
37 #endif
38 
39 DEAL_II_NAMESPACE_OPEN
40 
65 class IndexSet
66 {
67 public:
68  // forward declarations:
69  class ElementIterator;
71 
77 
95  typedef signed int value_type;
96 
97 
101  IndexSet ();
102 
106  explicit IndexSet (const size_type size);
107 
108 
109 #ifdef DEAL_II_WITH_TRILINOS
110 
113  explicit IndexSet(const Epetra_Map &map);
114 #endif
115 
120  void clear ();
121 
128  void set_size (const size_type size);
129 
137  size_type size () const;
138 
145  void add_range (const size_type begin,
146  const size_type end);
147 
151  void add_index (const size_type index);
152 
162  template <typename ForwardIterator>
163  void add_indices (const ForwardIterator &begin,
164  const ForwardIterator &end);
165 
181  void add_indices(const IndexSet &other,
182  const unsigned int offset = 0);
183 
187  bool is_element (const size_type index) const;
188 
193  bool is_contiguous () const;
194 
198  size_type n_elements () const;
199 
205  size_type nth_index_in_set (const unsigned int local_index) const;
206 
213  size_type index_within_set (const size_type global_index) const;
214 
223  unsigned int n_intervals () const;
224 
229  unsigned int largest_range_starting_index() const;
230 
235  void compress () const;
236 
242  bool operator == (const IndexSet &is) const;
243 
249  bool operator != (const IndexSet &is) const;
250 
257  IndexSet operator & (const IndexSet &is) const;
258 
272  IndexSet get_view (const size_type begin,
273  const size_type end) const;
274 
280  void subtract_set (const IndexSet &other);
281 
285  void fill_index_vector(std::vector<size_type> &indices) const;
286 
299  template <typename VectorType>
300  void fill_binary_vector (VectorType &vector) const;
301 
306  template <class StreamType>
307  void print(StreamType &out) const;
308 
313  void write(std::ostream &out) const;
314 
319  void read(std::istream &in);
320 
325  void block_write(std::ostream &out) const;
326 
331  void block_read(std::istream &in);
332 
333 #ifdef DEAL_II_WITH_TRILINOS
334 
362  Epetra_Map make_trilinos_map (const MPI_Comm &communicator = MPI_COMM_WORLD,
363  const bool overlapping = false) const;
364 #endif
365 
366 
371  std::size_t memory_consumption () const;
372 
373  DeclException1 (ExcIndexNotPresent, size_type,
374  << "The global index " << arg1
375  << " is not an element of this set.");
376 
381  template <class Archive>
382  void serialize (Archive &ar, const unsigned int version);
383 
384 
396  {
397  public:
402  IntervalAccessor(const IndexSet *idxset, const size_type range_idx);
403 
407  explicit IntervalAccessor(const IndexSet *idxset);
408 
412  size_type n_elements() const;
413 
417  bool is_valid() const;
418 
422  ElementIterator begin() const;
423 
428  ElementIterator end() const;
429 
433  size_type last() const;
434 
435  private:
439  IntervalAccessor(const IntervalAccessor &other);
444 
448  bool operator == (const IntervalAccessor &other) const;
452  bool operator < (const IntervalAccessor &other) const;
457  void advance ();
462 
467  size_type range_idx;
468 
469  friend class IntervalIterator;
470  };
471 
477  {
478  public:
483  IntervalIterator(const IndexSet *idxset, const size_type range_idx);
484 
488  explicit IntervalIterator(const IndexSet *idxset);
489 
494 
498  IntervalIterator(const IntervalIterator &other);
499 
504 
508  IntervalIterator &operator++ ();
509 
513  IntervalIterator operator++ (int);
514 
518  const IntervalAccessor &operator* () const;
519 
523  const IntervalAccessor *operator-> () const;
524 
528  bool operator == (const IntervalIterator &) const;
529 
533  bool operator != (const IntervalIterator &) const;
534 
538  bool operator < (const IntervalIterator &) const;
539 
546  int operator - (const IntervalIterator &p) const;
547 
548  private:
553  };
554 
560  {
561  public:
566  ElementIterator(const IndexSet *idxset, const size_type range_idx, const size_type index);
567 
571  explicit ElementIterator(const IndexSet *idxset);
572 
577  size_type operator* () const;
578 
582  bool is_valid () const;
583 
587  ElementIterator &operator++ ();
588 
592  ElementIterator operator++ (int);
593 
597  bool operator == (const ElementIterator &) const;
598 
602  bool operator != (const ElementIterator &) const;
603 
607  bool operator < (const ElementIterator &) const;
608 
617  std::ptrdiff_t operator - (const ElementIterator &p) const;
618 
619  private:
623  void advance ();
624 
632  size_type range_idx;
636  size_type idx;
637  };
638 
643  ElementIterator begin() const;
644 
649  ElementIterator end() const;
650 
655 
661 
666 private:
675  struct Range
676  {
677  size_type begin;
678  size_type end;
679 
680  size_type nth_index_in_set;
681 
690  Range ();
691 
699  Range (const size_type i1,
700  const size_type i2);
701 
702  friend
703  inline bool operator< (const Range &range_1,
704  const Range &range_2)
705  {
706  return ((range_1.begin < range_2.begin)
707  ||
708  ((range_1.begin == range_2.begin)
709  &&
710  (range_1.end < range_2.end)));
711  }
712 
713  static bool end_compare(const IndexSet::Range &x, const IndexSet::Range &y)
714  {
715  return x.end < y.end;
716  }
717 
718  static bool nth_index_compare (const IndexSet::Range &x,
719  const IndexSet::Range &y)
720  {
721  return (x.nth_index_in_set+(x.end-x.begin) <
722  y.nth_index_in_set+(y.end-y.begin));
723  }
724 
725  friend
726  inline bool operator== (const Range &range_1,
727  const Range &range_2)
728  {
729  return ((range_1.begin == range_2.begin)
730  &&
731  (range_1.end == range_2.end));
732  }
733 
734  std::size_t memory_consumption () const
735  {
736  return sizeof(Range);
737  }
738 
743  template <class Archive>
744  void serialize (Archive &ar, const unsigned int version);
745  };
746 
755  mutable std::vector<Range> ranges;
756 
765  mutable bool is_compressed;
766 
771  size_type index_space_size;
772 
782  mutable size_type largest_range;
783 
787  void do_compress() const;
788 };
789 
790 
808 inline
809 IndexSet complete_index_set (const unsigned int N)
810 {
811  IndexSet is (N);
812  is.add_range(0, N);
813  return is;
814 }
815 
816 /* ------------------ inline functions ------------------ */
817 
818 
819 /* IntervalAccessor */
820 
821 inline
823  : index_set(idxset), range_idx(range_idx)
824 {
825  Assert(range_idx < idxset->n_intervals(), ExcInternalError("Invalid range index"));
826 }
827 
828 inline
830  : index_set(idxset), range_idx(numbers::invalid_dof_index)
831 {}
832 
833 inline
835 {
836  Assert(is_valid(), ExcMessage("invalid iterator"));
837  return index_set->ranges[range_idx].end - index_set->ranges[range_idx].begin;
838 }
839 
840 inline
842 {
843  return index_set != NULL && range_idx < index_set->n_intervals();
844 }
845 
846 inline
848 {
849  Assert(is_valid(), ExcMessage("invalid iterator"));
851 }
852 
853 inline
855 {
856  Assert(is_valid(), ExcMessage("invalid iterator"));
857 
858  // point to first index in next interval unless we are the last interval.
859  if (range_idx < index_set->ranges.size()-1)
861  else
862  return index_set->end();
863 }
864 
865 inline
868 {
869  Assert(is_valid(), ExcMessage("invalid iterator"));
870 
871  return index_set->ranges[range_idx].end-1;
872 }
873 
874 inline
876  : index_set (other.index_set), range_idx(other.range_idx)
877 {
878  Assert( range_idx == numbers::invalid_dof_index || is_valid(), ExcMessage("invalid iterator"));
879 }
880 
881 inline
884 {
885  index_set = other.index_set;
886  range_idx = other.range_idx;
887  Assert( range_idx == numbers::invalid_dof_index || is_valid(), ExcMessage("invalid iterator"));
888  return *this;
889 }
890 
891 inline
893 {
894  Assert (index_set == other.index_set, ExcMessage("Can not compare accessors pointing to different IndexSets"));
895  return range_idx == other.range_idx;
896 }
897 
898 inline
900 {
901  Assert (index_set == other.index_set, ExcMessage("Can not compare accessors pointing to different IndexSets"));
902  return range_idx < other.range_idx;
903 }
904 
905 inline
907 {
908  Assert(is_valid(), ExcMessage("Impossible to advance an IndexSet::IntervalIterator that is invalid"));
909  ++range_idx;
910 
911  // set ourselves to invalid if we walk off the end
912  if (range_idx>=index_set->ranges.size())
914 }
915 
916 /* IntervalIterator */
917 
918 inline
920  : accessor(idxset, range_idx)
921 {}
922 
923 inline
925  : accessor(NULL)
926 {}
927 
928 inline
930  : accessor(idxset)
931 {}
932 
933 inline
935  : accessor(other.accessor)
936 {}
937 
938 inline
941 {
942  accessor = other.accessor;
943  return *this;
944 }
945 
946 
947 inline
950 {
951  accessor.advance();
952  return *this;
953 }
954 
955 inline
958 {
959  const IndexSet::IntervalIterator iter = *this;
960  accessor.advance ();
961  return iter;
962 }
963 
964 inline
967 {
968  return accessor;
969 }
970 
971 inline
974 {
975  return &accessor;
976 }
977 
978 inline
980 {
981  return accessor == other.accessor;
982 }
983 
984 inline
986 {
987  return !(*this == other);
988 }
989 
990 inline
992 {
993  return accessor < other.accessor;
994 }
995 
996 inline
998 {
999  Assert (accessor.index_set == other.accessor.index_set, ExcMessage("Can not compare iterators belonging to different IndexSets"));
1000 
1003 
1004  if (lhs > rhs)
1005  return static_cast<int>(lhs - rhs);
1006  else
1007  return -static_cast<int>(rhs - lhs);
1008 }
1009 
1010 
1011 /* ElementIterator */
1012 
1013 inline
1015 {
1016  Assert(
1018  ||
1019  (range_idx < index_set->ranges.size() && idx<index_set->ranges[range_idx].end)
1020  , ExcInternalError("Invalid ElementIterator state."));
1021 
1022  return range_idx < index_set->ranges.size() && idx<index_set->ranges[range_idx].end;
1023 }
1024 
1025 inline
1027  : index_set(idxset), range_idx(range_idx), idx(index)
1028 {
1029  Assert(range_idx < index_set->ranges.size(),
1030  ExcMessage("Invalid range index for IndexSet::ElementIterator constructor."));
1031  Assert(idx >= index_set->ranges[range_idx].begin
1032  &&
1033  idx < index_set->ranges[range_idx].end,
1034  ExcInternalError("Invalid index argument for IndexSet::ElementIterator constructor."));
1035 }
1036 
1037 inline
1039  : index_set(idxset), range_idx(numbers::invalid_dof_index), idx(numbers::invalid_dof_index)
1040 {}
1041 
1042 inline
1045 {
1046  Assert(is_valid(), ExcMessage("Impossible to dereference an IndexSet::ElementIterator that is invalid"));
1047  return idx;
1048 }
1049 
1050 inline
1052 {
1053  Assert (index_set == other.index_set, ExcMessage("Can not compare iterators belonging to different IndexSets"));
1054  return range_idx == other.range_idx && idx==other.idx;
1055 }
1056 
1057 inline
1059 {
1060  Assert(is_valid(), ExcMessage("Impossible to advance an IndexSet::ElementIterator that is invalid"));
1061  if (idx < index_set->ranges[range_idx].end)
1062  ++idx;
1063  // end of this range?
1064  if (idx == index_set->ranges[range_idx].end)
1065  {
1066  // point to first element in next interval if possible
1067  if (range_idx < index_set->ranges.size()-1)
1068  {
1069  ++range_idx;
1070  idx = index_set->ranges[range_idx].begin;
1071  }
1072  else
1073  {
1074  // we just fell off the end, set to invalid:
1077  }
1078  }
1079 }
1080 
1081 inline
1084 {
1085  advance();
1086  return *this;
1087 }
1088 
1089 inline
1092 {
1093  IndexSet::ElementIterator it = *this;
1094  advance();
1095  return it;
1096 }
1097 
1098 inline
1100 {
1101  return !(*this == other);
1102 }
1103 
1104 inline
1106 {
1107  Assert (index_set == other.index_set, ExcMessage("Can not compare iterators belonging to different IndexSets"));
1108  return range_idx < other.range_idx || (range_idx == other.range_idx && idx<other.idx);
1109 }
1110 
1111 inline
1113 {
1114  Assert (index_set == other.index_set, ExcMessage("Can not compare iterators belonging to different IndexSets"));
1115  if (*this == other)
1116  return 0;
1117  if (!(*this < other))
1118  return -(other-*this);
1119 
1120  // only other can be equal to end() because of the checks above.
1121  Assert (is_valid(), ExcInternalError());
1122 
1123  // Note: we now compute how far advance *this in "*this < other" to get other, so we need to return -c at the end.
1124 
1125  // first finish the current range:
1126  std::ptrdiff_t c = index_set->ranges[range_idx].end-idx;
1127 
1128  // now walk in steps of ranges (need to start one behind our current one):
1129  for (size_type range=range_idx+1; range<index_set->ranges.size() && range<=other.range_idx; ++range)
1130  c += index_set->ranges[range].end-index_set->ranges[range].begin;
1131 
1133  ExcMessage("Inconsistent iterator state. Did you invalidate iterators by modifying the IndexSet?"));
1134 
1135  // We might have walked too far because we went until the end of other.range_idx, so walk backwards to other.idx:
1137  c -= index_set->ranges[other.range_idx].end - other.idx;
1138 
1139  return -c;
1140 }
1141 
1142 
1143 /* Range */
1144 
1145 inline
1147  :
1148  begin(numbers::invalid_dof_index),
1149  end(numbers::invalid_dof_index)
1150 {}
1151 
1152 
1153 inline
1155  const size_type i2)
1156  :
1157  begin(i1),
1158  end(i2)
1159 {}
1160 
1161 
1162 /* IndexSet itself */
1163 
1164 inline
1166 {
1167  compress();
1168  if (ranges.size()>0)
1169  return IndexSet::ElementIterator(this, 0, ranges[0].begin);
1170  else
1171  return end();
1172 }
1173 
1174 inline
1176 {
1177  compress();
1178  return IndexSet::ElementIterator(this);
1179 }
1180 
1181 
1182 inline
1184 {
1185  compress();
1186  if (ranges.size()>0)
1187  return IndexSet::IntervalIterator(this, 0);
1188  else
1189  return end_intervals();
1190 }
1191 
1192 inline
1194 {
1195  compress();
1196  return IndexSet::IntervalIterator(this);
1197 }
1198 
1199 
1200 
1201 inline
1203  :
1204  is_compressed (true),
1205  index_space_size (0),
1206  largest_range (numbers::invalid_unsigned_int)
1207 {}
1208 
1209 
1210 
1211 inline
1213  :
1214  is_compressed (true),
1215  index_space_size (size),
1216  largest_range (numbers::invalid_unsigned_int)
1217 {}
1218 
1219 
1220 
1221 inline
1222 void
1224 {
1225  ranges.clear ();
1226  largest_range = 0;
1227  is_compressed = true;
1228 }
1229 
1230 
1231 
1232 inline
1233 void
1235 {
1236  Assert (ranges.empty(),
1237  ExcMessage ("This function can only be called if the current "
1238  "object does not yet contain any elements."));
1239  index_space_size = sz;
1240  is_compressed = true;
1241 }
1242 
1243 
1244 
1245 inline
1248 {
1249  return index_space_size;
1250 }
1251 
1252 
1253 
1254 inline
1255 void
1257 {
1258  if (is_compressed == true)
1259  return;
1260 
1261  do_compress();
1262 }
1263 
1264 
1265 
1266 inline
1267 void
1269 {
1270  Assert (index < index_space_size,
1271  ExcIndexRangeType<size_type> (index, 0, index_space_size));
1272 
1273  const Range new_range(index, index+1);
1274  if (ranges.size() == 0 || index > ranges.back().end)
1275  ranges.push_back(new_range);
1276  else if (index == ranges.back().end)
1277  ranges.back().end++;
1278  else
1279  ranges.insert (Utilities::lower_bound (ranges.begin(),
1280  ranges.end(),
1281  new_range),
1282  new_range);
1283  is_compressed = false;
1284 }
1285 
1286 
1287 
1288 template <typename ForwardIterator>
1289 inline
1290 void
1291 IndexSet::add_indices (const ForwardIterator &begin,
1292  const ForwardIterator &end)
1293 {
1294  // insert each element of the range. if some of them happen to be
1295  // consecutive, merge them to a range
1296  for (ForwardIterator p=begin; p!=end;)
1297  {
1298  const size_type begin_index = *p;
1299  size_type end_index = begin_index + 1;
1300  ForwardIterator q = p;
1301  ++q;
1302  while ((q != end) && (*q == end_index))
1303  {
1304  ++end_index;
1305  ++q;
1306  }
1307 
1308  add_range (begin_index, end_index);
1309  p = q;
1310  }
1311 }
1312 
1313 
1314 
1315 inline
1316 bool
1317 IndexSet::is_element (const size_type index) const
1318 {
1319  if (ranges.empty() == false)
1320  {
1321  compress ();
1322 
1323  // fast check whether the index is in the largest range
1324  Assert (largest_range < ranges.size(), ExcInternalError());
1325  if (index >= ranges[largest_range].begin &&
1326  index < ranges[largest_range].end)
1327  return true;
1328 
1329  // get the element after which we would have to insert a range that
1330  // consists of all elements from this element to the end of the index
1331  // range plus one. after this call we know that if p!=end() then
1332  // p->begin<=index unless there is no such range at all
1333  //
1334  // if the searched for element is an element of this range, then we're
1335  // done. otherwise, the element can't be in one of the following ranges
1336  // because otherwise p would be a different iterator
1337  //
1338  // since we already know the position relative to the largest range (we
1339  // called compress!), we can perform the binary search on ranges with
1340  // lower/higher number compared to the largest range
1341  std::vector<Range>::const_iterator
1342  p = std::upper_bound (ranges.begin() + (index<ranges[largest_range].begin?
1343  0 : largest_range+1),
1344  index<ranges[largest_range].begin ?
1345  ranges.begin() + largest_range:
1346  ranges.end(),
1347  Range (index, size()+1));
1348 
1349  if (p == ranges.begin())
1350  return ((index >= p->begin) && (index < p->end));
1351 
1352  Assert ((p == ranges.end()) || (p->begin > index),
1353  ExcInternalError());
1354 
1355  // now move to that previous range
1356  --p;
1357  Assert (p->begin <= index, ExcInternalError());
1358 
1359  return (p->end > index);
1360  }
1361 
1362  // didn't find this index, so it's not in the set
1363  return false;
1364 }
1365 
1366 
1367 
1368 inline
1369 bool
1371 {
1372  compress ();
1373  return (ranges.size() <= 1);
1374 }
1375 
1376 
1377 
1378 inline
1381 {
1382  // make sure we have non-overlapping ranges
1383  compress ();
1384 
1385  size_type v = 0;
1386  if (!ranges.empty())
1387  {
1388  Range &r = ranges.back();
1389  v = r.nth_index_in_set + r.end - r.begin;
1390  }
1391 
1392 #ifdef DEBUG
1393  size_type s = 0;
1394  for (std::vector<Range>::iterator range = ranges.begin();
1395  range != ranges.end();
1396  ++range)
1397  s += (range->end - range->begin);
1398  Assert(s==v, ExcInternalError());
1399 #endif
1400 
1401  return v;
1402 }
1403 
1404 
1405 
1406 inline
1407 unsigned int
1409 {
1410  compress ();
1411  return ranges.size();
1412 }
1413 
1414 
1415 
1416 inline
1417 unsigned int
1419 {
1420  Assert(ranges.empty()==false, ExcMessage("IndexSet cannot be empty."));
1421 
1422  compress();
1423  const std::vector<Range>::const_iterator main_range=ranges.begin()+largest_range;
1424 
1425  return main_range->nth_index_in_set;
1426 }
1427 
1428 
1429 
1430 inline
1432 IndexSet::nth_index_in_set (const unsigned int n) const
1433 {
1434  // to make this call thread-safe, compress() must not be called through this
1435  // function
1436  Assert (is_compressed == true, ExcMessage ("IndexSet must be compressed."));
1437  Assert (n < n_elements(), ExcIndexRangeType<size_type> (n, 0, n_elements()));
1438 
1439  // first check whether the index is in the largest range
1440  Assert (largest_range < ranges.size(), ExcInternalError());
1441  std::vector<Range>::const_iterator main_range=ranges.begin()+largest_range;
1442  if (n>=main_range->nth_index_in_set &&
1443  n<main_range->nth_index_in_set+(main_range->end-main_range->begin))
1444  return main_range->begin + (n-main_range->nth_index_in_set);
1445 
1446  // find out which chunk the local index n belongs to by using a binary
1447  // search. the comparator is based on the end of the ranges. Use the
1448  // position relative to main_range to subdivide the ranges
1449  Range r (n,n+1);
1450  r.nth_index_in_set = n;
1451  std::vector<Range>::const_iterator range_begin, range_end;
1452  if (n<main_range->nth_index_in_set)
1453  {
1454  range_begin = ranges.begin();
1455  range_end = main_range;
1456  }
1457  else
1458  {
1459  range_begin = main_range + 1;
1460  range_end = ranges.end();
1461  }
1462 
1463  const std::vector<Range>::const_iterator
1464  p = Utilities::lower_bound(range_begin, range_end, r,
1465  Range::nth_index_compare);
1466 
1467  Assert (p != ranges.end(), ExcInternalError());
1468  return p->begin + (n-p->nth_index_in_set);
1469 }
1470 
1471 
1472 
1473 inline
1476 {
1477  // to make this call thread-safe, compress() must not be called through this
1478  // function
1479  Assert (is_compressed == true, ExcMessage ("IndexSet must be compressed."));
1480  Assert (is_element(n) == true, ExcIndexNotPresent (n));
1481  Assert (n < size(), ExcIndexRangeType<size_type> (n, 0, size()));
1482 
1483  // check whether the index is in the largest range. use the result to
1484  // perform a one-sided binary search afterward
1485  Assert (largest_range < ranges.size(), ExcInternalError());
1486  std::vector<Range>::const_iterator main_range=ranges.begin()+largest_range;
1487  if (n >= main_range->begin && n < main_range->end)
1488  return (n-main_range->begin) + main_range->nth_index_in_set;
1489 
1490  Range r(n, n);
1491  std::vector<Range>::const_iterator range_begin, range_end;
1492  if (n<main_range->begin)
1493  {
1494  range_begin = ranges.begin();
1495  range_end = main_range;
1496  }
1497  else
1498  {
1499  range_begin = main_range + 1;
1500  range_end = ranges.end();
1501  }
1502 
1503  std::vector<Range>::const_iterator
1504  p = Utilities::lower_bound(range_begin, range_end, r,
1505  Range::end_compare);
1506 
1507  Assert(p!=ranges.end(), ExcInternalError());
1508  Assert(p->begin<=n, ExcInternalError());
1509  Assert(n<p->end, ExcInternalError());
1510  return (n-p->begin) + p->nth_index_in_set;
1511 }
1512 
1513 
1514 
1515 inline
1516 bool
1518 {
1519  Assert (size() == is.size(),
1520  ExcDimensionMismatch (size(), is.size()));
1521 
1522  compress ();
1523  is.compress ();
1524 
1525  return ranges == is.ranges;
1526 }
1527 
1528 
1529 
1530 inline
1531 bool
1533 {
1534  Assert (size() == is.size(),
1535  ExcDimensionMismatch (size(), is.size()));
1536 
1537  compress ();
1538  is.compress ();
1539 
1540  return ranges != is.ranges;
1541 }
1542 
1543 
1544 
1545 template <typename Vector>
1546 void
1547 IndexSet::fill_binary_vector (Vector &vector) const
1548 {
1549  Assert (vector.size() == size(),
1550  ExcDimensionMismatch (vector.size(), size()));
1551 
1552  compress();
1553  // first fill all elements of the vector with zeroes.
1554  std::fill (vector.begin(), vector.end(), 0);
1555 
1556  // then write ones into the elements whose indices are contained in the
1557  // index set
1558  for (std::vector<Range>::iterator it = ranges.begin();
1559  it != ranges.end();
1560  ++it)
1561  for (size_type i=it->begin; i<it->end; ++i)
1562  vector[i] = 1;
1563 }
1564 
1565 
1566 
1567 template <class StreamType>
1568 inline
1569 void
1570 IndexSet::print (StreamType &out) const
1571 {
1572  compress();
1573  out << "{";
1574  std::vector<Range>::const_iterator p;
1575  for (p = ranges.begin(); p != ranges.end(); ++p)
1576  {
1577  if (p->end-p->begin==1)
1578  out << p->begin;
1579  else
1580  out << "[" << p->begin << "," << p->end-1 << "]";
1581 
1582  if (p !=--ranges.end())
1583  out << ", ";
1584  }
1585  out << "}" << std::endl;
1586 }
1587 
1588 
1589 
1590 template <class Archive>
1591 inline
1592 void
1593 IndexSet::Range::serialize (Archive &ar, const unsigned int)
1594 {
1595  ar &begin &end &nth_index_in_set;
1596 }
1597 
1598 
1599 
1600 template <class Archive>
1601 inline
1602 void
1603 IndexSet::serialize (Archive &ar, const unsigned int)
1604 {
1606 }
1607 
1608 DEAL_II_NAMESPACE_CLOSE
1609 
1610 #endif
Iterator lower_bound(Iterator first, Iterator last, const T &val)
Definition: utilities.h:604
void fill_binary_vector(VectorType &vector) const
ElementIterator end() const
Definition: index_set.h:1175
void add_index(const size_type index)
Definition: index_set.h:1268
IndexSet operator&(const IndexSet &is) const
const IntervalAccessor * operator->() const
Definition: index_set.h:973
const IntervalAccessor & operator*() const
Definition: index_set.h:966
size_type nth_index_in_set(const unsigned int local_index) const
Definition: index_set.h:1432
const IndexSet * index_set
Definition: index_set.h:628
void block_read(std::istream &in)
Definition: index_set.cc:442
signed int value_type
Definition: index_set.h:95
::ExceptionBase & ExcMessage(std::string arg1)
std::ptrdiff_t operator-(const ElementIterator &p) const
Definition: index_set.h:1112
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
Definition: index_set.h:1291
unsigned int largest_range_starting_index() const
Definition: index_set.h:1418
ElementIterator(const IndexSet *idxset, const size_type range_idx, const size_type index)
Definition: index_set.h:1026
bool operator<(const IntervalIterator &) const
Definition: index_set.h:991
iterator end()
std::size_t memory_consumption() const
Definition: index_set.cc:549
size_type n_elements() const
Definition: index_set.h:834
size_type index_space_size
Definition: index_set.h:771
Epetra_Map make_trilinos_map(const MPI_Comm &communicator=MPI_COMM_WORLD, const bool overlapping=false) const
Definition: index_set.cc:484
size_type size() const
Definition: index_set.h:1247
void print(StreamType &out) const
Definition: index_set.h:1570
void serialize(Archive &ar, const unsigned int version)
Definition: index_set.h:1593
IndexSet complete_index_set(const unsigned int N)
Definition: index_set.h:809
void clear()
Definition: index_set.h:1223
void serialize(Archive &ar, const unsigned int version)
Definition: index_set.h:1603
void block_write(std::ostream &out) const
Definition: index_set.cc:427
IntervalIterator & operator=(const IntervalIterator &other)
Definition: index_set.h:940
std::vector< Range > ranges
Definition: index_set.h:755
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:542
unsigned int global_dof_index
Definition: types.h:88
void subtract_set(const IndexSet &other)
Definition: index_set.cc:269
#define Assert(cond, exc)
Definition: exceptions.h:294
bool operator<(const ElementIterator &) const
Definition: index_set.h:1105
size_type index_within_set(const size_type global_index) const
Definition: index_set.h:1475
bool operator==(const IndexSet &is) const
Definition: index_set.h:1517
std::size_t size() const
IntervalAccessor accessor
Definition: index_set.h:552
void do_compress() const
Definition: index_set.cc:118
IntervalAccessor & operator=(const IntervalAccessor &other)
Definition: index_set.h:883
bool operator==(const IntervalIterator &) const
Definition: index_set.h:979
iterator begin()
size_type last() const
Definition: index_set.h:867
const IndexSet * index_set
Definition: index_set.h:461
bool operator==(const IntervalAccessor &other) const
Definition: index_set.h:892
unsigned int n_intervals() const
Definition: index_set.h:1408
int operator-(const IntervalIterator &p) const
Definition: index_set.h:997
bool operator!=(const IndexSet &is) const
Definition: index_set.h:1532
void fill_index_vector(std::vector< size_type > &indices) const
Definition: index_set.cc:461
void add_range(const size_type begin, const size_type end)
Definition: index_set.cc:86
void set_size(const size_type size)
Definition: index_set.h:1234
ElementIterator & operator++()
Definition: index_set.h:1083
IntervalAccessor(const IndexSet *idxset, const size_type range_idx)
Definition: index_set.h:822
IndexSet get_view(const size_type begin, const size_type end) const
Definition: index_set.cc:235
void compress() const
Definition: index_set.h:1256
ElementIterator end() const
Definition: index_set.h:854
IntervalIterator begin_intervals() const
Definition: index_set.h:1183
bool is_contiguous() const
Definition: index_set.h:1370
IntervalIterator end_intervals() const
Definition: index_set.h:1193
bool is_compressed
Definition: index_set.h:765
bool operator<(const IntervalAccessor &other) const
Definition: index_set.h:899
bool operator!=(const ElementIterator &) const
Definition: index_set.h:1099
ElementIterator begin() const
Definition: index_set.h:847
void write(std::ostream &out) const
Definition: index_set.cc:394
bool is_element(const size_type index) const
Definition: index_set.h:1317
bool operator==(const ElementIterator &) const
Definition: index_set.h:1051
const types::global_dof_index invalid_dof_index
Definition: types.h:178
types::global_dof_index size_type
Definition: index_set.h:70
ElementIterator begin() const
Definition: index_set.h:1165
void read(std::istream &in)
Definition: index_set.cc:409
size_type n_elements() const
Definition: index_set.h:1380
size_type largest_range
Definition: index_set.h:782
IntervalIterator & operator++()
Definition: index_set.h:949
size_type operator*() const
Definition: index_set.h:1044
bool operator!=(const IntervalIterator &) const
Definition: index_set.h:985