Reference documentation for deal.II version Git a0b41b6d0f 2020-02-26 20:08:13 -0600
\(\newcommand{\vcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\vcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
filtered_iterator.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2002 - 2019 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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_filtered_iterator_h
17 # define dealii_filtered_iterator_h
18 
19 
20 # include <deal.II/base/config.h>
21 
22 # include <deal.II/base/exceptions.h>
23 # include <deal.II/base/iterator_range.h>
24 # include <deal.II/base/std_cxx14/memory.h>
25 
26 # include <deal.II/grid/tria_iterator_base.h>
27 
28 # include <set>
29 # include <tuple>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
33 
50 namespace IteratorFilters
51 {
58  class Active
59  {
60  public:
65  template <class Iterator>
66  bool
67  operator()(const Iterator &i) const;
68  };
69 
79  {
80  public:
85  template <class Iterator>
86  bool
87  operator()(const Iterator &i) const;
88  };
89 
90 
99  {
100  public:
105  template <class Iterator>
106  bool
107  operator()(const Iterator &i) const;
108  };
109 
110 
119  {
120  public:
125  LevelEqualTo(const unsigned int level);
126 
132  template <class Iterator>
133  bool
134  operator()(const Iterator &i) const;
135 
136  protected:
140  const unsigned int level;
141  };
142 
143 
144 
154  {
155  public:
160  SubdomainEqualTo(const types::subdomain_id subdomain_id);
161 
167  template <class Iterator>
168  bool
169  operator()(const Iterator &i) const;
170 
171  protected:
176  };
177 
178 
179 
192  {
193  public:
197  template <class Iterator>
198  bool
199  operator()(const Iterator &i) const;
200  };
201 
202 
203 
211  {
212  public:
217  template <class Iterator>
218  bool
219  operator()(const Iterator &i) const;
220  };
221 
222 
233  {
234  public:
239  MaterialIdEqualTo(const types::material_id material_id,
240  const bool only_locally_owned = false);
241 
247  MaterialIdEqualTo(const std::set<types::material_id> &material_ids,
248  const bool only_locally_owned = false);
249 
255  template <class Iterator>
256  bool
257  operator()(const Iterator &i) const;
258 
259  protected:
263  const std::set<types::material_id> material_ids;
267  const bool only_locally_owned;
268  };
269 
280  {
281  public:
286  ActiveFEIndexEqualTo(const unsigned int active_fe_index,
287  const bool only_locally_owned = false);
288 
294  ActiveFEIndexEqualTo(const std::set<unsigned int> &active_fe_indices,
295  const bool only_locally_owned = false);
296 
302  template <class Iterator>
303  bool
304  operator()(const Iterator &i) const;
305 
306  protected:
310  const std::set<unsigned int> active_fe_indices;
314  const bool only_locally_owned;
315  };
316 
326  {
327  public:
331  template <class Iterator>
332  bool
333  operator()(const Iterator &i) const;
334  };
335 } // namespace IteratorFilters
336 
337 
528 template <typename BaseIterator>
529 class FilteredIterator : public BaseIterator
530 {
531 public:
535  using AccessorType = typename BaseIterator::AccessorType;
536 
541  template <typename Predicate>
542  FilteredIterator(Predicate p);
543 
561  template <typename Predicate>
562  FilteredIterator(Predicate p, const BaseIterator &bi);
563 
569 
577  operator=(const FilteredIterator &fi);
578 
585  operator=(const BaseIterator &fi);
586 
596  set_to_next_positive(const BaseIterator &bi);
597 
607  set_to_previous_positive(const BaseIterator &bi);
608 
615  bool
616  operator==(const FilteredIterator &fi) const;
617 
624  bool
625  operator==(const BaseIterator &fi) const;
626 
633  bool
634  operator!=(const FilteredIterator &fi) const;
635 
642  bool
643  operator!=(const BaseIterator &fi) const;
644 
651  bool
652  operator<(const FilteredIterator &fi) const;
653 
660  bool
661  operator<(const BaseIterator &fi) const;
662 
668  operator++();
669 
675  operator++(int);
676 
682  operator--();
683 
689  operator--(int);
690 
695  ExcInvalidElement,
696  BaseIterator,
697  << "The element " << arg1
698  << " with which you want to compare or which you want to"
699  << " assign from is invalid since it does not satisfy the predicate.");
700 
701 private:
712  {
713  public:
718  virtual ~PredicateBase() = default;
719 
724  virtual bool
725  operator()(const BaseIterator &bi) const = 0;
726 
731  virtual std::unique_ptr<PredicateBase>
732  clone() const = 0;
733  };
734 
735 
744  template <typename Predicate>
746  {
747  public:
751  PredicateTemplate(const Predicate &predicate);
752 
756  virtual bool
757  operator()(const BaseIterator &bi) const override;
758 
763  virtual std::unique_ptr<PredicateBase>
764  clone() const override;
765 
766  private:
770  const Predicate predicate;
771  };
772 
777  std::unique_ptr<const PredicateBase> predicate;
778 };
779 
780 
781 
792 template <typename BaseIterator, typename Predicate>
794 make_filtered_iterator(const BaseIterator &i, const Predicate &p)
795 {
797  fi.set_to_next_positive(i);
798  return fi;
799 }
800 
801 
802 
803 namespace internal
804 {
805  namespace FilteredIteratorImplementation
806  {
807  // The following classes create a nested sequence of
808  // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
809  // levels of FilteredIterator classes as there are elements in the TypeList
810  // if the latter is given as a std::tuple<Args...>.
811  template <typename BaseIterator, typename TypeList>
812  struct NestFilteredIterators;
813 
814  template <typename BaseIterator, typename Predicate>
815  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate>>
816  {
818  };
819 
820  template <typename BaseIterator, typename Predicate, typename... Targs>
821  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>
822  {
823  using type = ::FilteredIterator<
824  typename NestFilteredIterators<BaseIterator,
825  std::tuple<Targs...>>::type>;
826  };
827  } // namespace FilteredIteratorImplementation
828 } // namespace internal
829 
830 
831 
865 template <typename BaseIterator, typename Predicate>
868 {
870  FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
871 
873 }
874 
875 
876 
914 template <typename BaseIterator, typename Predicate, typename... Targs>
916  typename internal::FilteredIteratorImplementation::
917  NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>::type>
919  const Predicate & p,
920  const Targs... args)
921 {
922  // Recursively create filtered iterators, one predicate at a time
923  auto fi = filter_iterators(i, p);
924  return filter_iterators(fi, args...);
925 }
926 
927 
928 /* ------------------ Inline functions and templates ------------ */
929 
930 
931 template <typename BaseIterator>
932 template <typename Predicate>
934  : predicate(new PredicateTemplate<Predicate>(p))
935 {}
936 
937 
938 
939 template <typename BaseIterator>
940 template <typename Predicate>
942  const BaseIterator &bi)
943  : BaseIterator(bi)
944  , predicate(new PredicateTemplate<Predicate>(p))
945 {
946  if ((this->state() == IteratorState::valid) && !(*predicate)(*this))
948 }
949 
950 
951 
952 template <typename BaseIterator>
954  const FilteredIterator &fi)
955  : // this construction looks strange, but without going through the
956  // address of fi, GCC would not cast fi to the base class of type
957  // BaseIterator but tries to go through constructing a new
958  // BaseIterator with an Accessor.
959  BaseIterator(*static_cast<const BaseIterator *>(&fi))
960  , predicate(fi.predicate->clone())
961 {}
962 
963 
964 
965 template <typename BaseIterator>
968 {
969  // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
970  // below, some compiler would not cast fi to the base class of type
971  // BaseIterator but try to go through constructing a new Accessor from fi
972  // which fails. Hence, we just use an explicit upcast and call the above-
973  // mentioned method.
974  const BaseIterator &bi = fi;
975  return operator=(bi);
976 }
977 
978 
979 
980 template <typename BaseIterator>
983 {
984  Assert((bi.state() != IteratorState::valid) || (*predicate)(bi),
985  ExcInvalidElement(bi));
986  BaseIterator::operator=(bi);
987  return *this;
988 }
989 
990 
991 
992 template <typename BaseIterator>
995 {
996  BaseIterator::operator=(bi);
997  while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
998  BaseIterator::operator++();
999 
1000  return *this;
1001 }
1002 
1003 
1004 
1005 template <typename BaseIterator>
1008 {
1009  BaseIterator::operator=(bi);
1010  while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1011  BaseIterator::operator--();
1012 
1013  return *this;
1014 }
1015 
1016 
1017 
1018 template <typename BaseIterator>
1019 inline bool
1021 {
1022  return (static_cast<const BaseIterator &>(*this) ==
1023  static_cast<const BaseIterator &>(fi));
1024 }
1025 
1026 
1027 
1028 template <typename BaseIterator>
1029 inline bool
1031 {
1032  return (static_cast<const BaseIterator &>(*this) !=
1033  static_cast<const BaseIterator &>(fi));
1034 }
1035 
1036 
1037 
1038 template <typename BaseIterator>
1039 inline bool
1041 {
1042  return (static_cast<const BaseIterator &>(*this) <
1043  static_cast<const BaseIterator &>(fi));
1044 }
1045 
1046 
1047 
1048 template <typename BaseIterator>
1049 inline bool
1050 FilteredIterator<BaseIterator>::operator==(const BaseIterator &bi) const
1051 {
1052  return (static_cast<const BaseIterator &>(*this) == bi);
1053 }
1054 
1055 
1056 
1057 template <typename BaseIterator>
1058 inline bool
1059 FilteredIterator<BaseIterator>::operator!=(const BaseIterator &bi) const
1060 {
1061  return (static_cast<const BaseIterator &>(*this) != bi);
1062 }
1063 
1064 
1065 
1066 template <typename BaseIterator>
1067 inline bool
1068 FilteredIterator<BaseIterator>::operator<(const BaseIterator &bi) const
1069 {
1070  return (static_cast<const BaseIterator &>(*this) < bi);
1071 }
1072 
1073 
1074 template <typename BaseIterator>
1077 {
1078  if (this->state() == IteratorState::valid)
1079  do
1080  BaseIterator::operator++();
1081  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1082  return *this;
1083 }
1084 
1085 
1086 
1087 template <typename BaseIterator>
1090 {
1091  const FilteredIterator old_state = *this;
1092 
1093  if (this->state() == IteratorState::valid)
1094  do
1095  BaseIterator::operator++();
1096  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1097  return old_state;
1098 }
1099 
1100 
1101 
1102 template <typename BaseIterator>
1105 {
1106  if (this->state() == IteratorState::valid)
1107  do
1108  BaseIterator::operator--();
1109  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1110  return *this;
1111 }
1112 
1113 
1114 
1115 template <typename BaseIterator>
1118 {
1119  const FilteredIterator old_state = *this;
1120 
1121  if (this->state() == IteratorState::valid)
1122  do
1123  BaseIterator::operator--();
1124  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1125  return old_state;
1126 }
1127 
1128 
1129 
1130 template <typename BaseIterator>
1131 template <typename Predicate>
1133  Predicate>::PredicateTemplate(const Predicate &predicate)
1134  : predicate(predicate)
1135 {}
1136 
1137 
1138 
1139 template <typename BaseIterator>
1140 template <typename Predicate>
1141 bool
1143 operator()(const BaseIterator &bi) const
1144 {
1145  return predicate(bi);
1146 }
1147 
1148 
1149 
1150 template <typename BaseIterator>
1151 template <typename Predicate>
1152 std::unique_ptr<typename FilteredIterator<BaseIterator>::PredicateBase>
1154 {
1155  return std_cxx14::make_unique<PredicateTemplate>(predicate);
1156 }
1157 
1158 
1159 
1160 namespace IteratorFilters
1161 {
1162  // ---------------- IteratorFilters::Active ---------
1163 
1164  template <class Iterator>
1165  inline bool
1166  Active::operator()(const Iterator &i) const
1167  {
1168  return i->is_active();
1169  }
1170 
1171 
1172  // ---------------- IteratorFilters::UserFlagSet ---------
1173 
1174  template <class Iterator>
1175  inline bool
1176  UserFlagSet::operator()(const Iterator &i) const
1177  {
1178  return (i->user_flag_set());
1179  }
1180 
1181 
1182  // ---------------- IteratorFilters::UserFlagNotSet ---------
1183 
1184  template <class Iterator>
1185  inline bool
1186  UserFlagNotSet::operator()(const Iterator &i) const
1187  {
1188  return (!i->user_flag_set());
1189  }
1190 
1191 
1192  // ---------------- IteratorFilters::LevelEqualTo ---------
1193  inline LevelEqualTo::LevelEqualTo(const unsigned int level)
1194  : level(level)
1195  {}
1196 
1197 
1198 
1199  template <class Iterator>
1200  inline bool
1201  LevelEqualTo::operator()(const Iterator &i) const
1202  {
1203  return (static_cast<unsigned int>(i->level()) == level);
1204  }
1205 
1206 
1207 
1208  // ---------------- IteratorFilters::SubdomainEqualTo ---------
1210  const types::subdomain_id subdomain_id)
1211  : subdomain_id(subdomain_id)
1212  {}
1213 
1214 
1215 
1216  template <class Iterator>
1217  inline bool
1218  SubdomainEqualTo::operator()(const Iterator &i) const
1219  {
1220  return (i->subdomain_id() == subdomain_id);
1221  }
1222 
1223 
1224 
1225  // ---------------- IteratorFilters::LocallyOwnedCell ---------
1226 
1227  template <class Iterator>
1228  inline bool
1229  LocallyOwnedCell::operator()(const Iterator &i) const
1230  {
1231  return (i->is_locally_owned());
1232  }
1233 
1234 
1235  // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1236 
1237  template <class Iterator>
1238  inline bool
1239  LocallyOwnedLevelCell::operator()(const Iterator &i) const
1240  {
1241  return (i->is_locally_owned_on_level());
1242  }
1243 
1244 
1245 
1246  // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1248  const types::material_id material_id,
1249  const bool only_locally_owned)
1250  : material_ids{material_id}
1252  {}
1253 
1254 
1255 
1257  const std::set<types::material_id> &material_ids,
1258  const bool only_locally_owned)
1259  : material_ids(material_ids)
1260  , only_locally_owned(only_locally_owned)
1261  {}
1262 
1263 
1264 
1265  template <class Iterator>
1266  inline bool
1267  MaterialIdEqualTo::operator()(const Iterator &i) const
1268  {
1269  return only_locally_owned == true ?
1270  (material_ids.find(i->material_id()) != material_ids.end() &&
1271  i->is_locally_owned()) :
1272  material_ids.find(i->material_id()) != material_ids.end();
1273  }
1274 
1275 
1276 
1277  // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1279  const unsigned int active_fe_index,
1280  const bool only_locally_owned)
1281  : active_fe_indices{active_fe_index}
1283  {}
1284 
1285 
1286 
1288  const std::set<unsigned int> &active_fe_indices,
1289  const bool only_locally_owned)
1290  : active_fe_indices(active_fe_indices)
1291  , only_locally_owned(only_locally_owned)
1292  {}
1293 
1294 
1295 
1296  template <class Iterator>
1297  inline bool
1298  ActiveFEIndexEqualTo::operator()(const Iterator &i) const
1299  {
1300  return only_locally_owned == true ?
1301  (active_fe_indices.find(i->active_fe_index()) !=
1302  active_fe_indices.end() &&
1303  i->is_locally_owned()) :
1304  active_fe_indices.find(i->active_fe_index()) !=
1305  active_fe_indices.end();
1306  }
1307 
1308 
1309 
1310  // ---------------- IteratorFilters::AtBoundary ---------
1311 
1312  template <class Iterator>
1313  inline bool
1314  AtBoundary::operator()(const Iterator &i) const
1315  {
1316  return (i->at_boundary());
1317  }
1318 } // namespace IteratorFilters
1319 
1320 
1321 DEAL_II_NAMESPACE_CLOSE
1322 
1323 /*------------------------- filtered_iterator.h ------------------------*/
1324 #endif
1325 /*------------------------- filtered_iterator.h ------------------------*/
bool operator()(const Iterator &i) const
FilteredIterator & operator++()
IteratorOverIterators begin()
const types::subdomain_id subdomain_id
FilteredIterator(Predicate p)
bool operator()(const Iterator &i) const
bool operator==(const FilteredIterator &fi) const
bool operator()(const Iterator &i) const
unsigned int material_id
Definition: types.h:148
IteratorRange< FilteredIterator< BaseIterator > > filter_iterators(IteratorRange< BaseIterator > i, const Predicate &p)
FilteredIterator & operator--()
const std::set< types::material_id > material_ids
bool operator()(const Iterator &i) const
unsigned int subdomain_id
Definition: types.h:43
FilteredIterator & operator=(const FilteredIterator &fi)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
#define Assert(cond, exc)
Definition: exceptions.h:1411
bool operator()(const Iterator &i) const
std::unique_ptr< const PredicateBase > predicate
bool operator!=(const FilteredIterator &fi) const
MaterialIdEqualTo(const types::material_id material_id, const bool only_locally_owned=false)
bool operator()(const Iterator &i) const
const std::set< unsigned int > active_fe_indices
FilteredIterator & set_to_next_positive(const BaseIterator &bi)
SubdomainEqualTo(const types::subdomain_id subdomain_id)
static ::ExceptionBase & ExcInvalidElement(BaseIterator arg1)
bool operator()(const Iterator &i) const
ActiveFEIndexEqualTo(const unsigned int active_fe_index, const bool only_locally_owned=false)
Iterator points to a valid object.
FilteredIterator & set_to_previous_positive(const BaseIterator &bi)
bool operator<(const FilteredIterator &fi) const
FilteredIterator< BaseIterator > make_filtered_iterator(const BaseIterator &i, const Predicate &p)
typename BaseIterator::AccessorType AccessorType
bool operator()(const Iterator &i) const
IteratorOverIterators end() const