Loading [MathJax]/extensions/TeX/newcommand.js
 Reference documentation for deal.II version 9.3.3
\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}} \newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=} \newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]} \newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
filtered_iterator.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2002 - 2020 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
24
26
27# include <memory>
28# include <set>
29# include <tuple>
30
32
33
50{
57 class Active
58 {
59 public:
64 template <class Iterator>
65 bool
66 operator()(const Iterator &i) const;
67 };
68
78 {
79 public:
84 template <class Iterator>
85 bool
86 operator()(const Iterator &i) const;
87 };
88
89
98 {
99 public:
104 template <class Iterator>
105 bool
106 operator()(const Iterator &i) const;
107 };
108
109
118 {
119 public:
124 LevelEqualTo(const unsigned int level);
125
131 template <class Iterator>
132 bool
133 operator()(const Iterator &i) const;
134
135 protected:
139 const unsigned int level;
140 };
141
142
143
153 {
154 public:
160
166 template <class Iterator>
167 bool
168 operator()(const Iterator &i) const;
169
170 protected:
175 };
176
177
178
191 {
192 public:
196 template <class Iterator>
197 bool
198 operator()(const Iterator &i) const;
199 };
200
201
202
210 {
211 public:
216 template <class Iterator>
217 bool
218 operator()(const Iterator &i) const;
219 };
220
221
231 {
232 public:
238 const bool only_locally_owned = false);
239
245 MaterialIdEqualTo(const std::set<types::material_id> &material_ids,
246 const bool only_locally_owned = false);
247
253 template <class Iterator>
254 bool
255 operator()(const Iterator &i) const;
256
257 protected:
261 const std::set<types::material_id> material_ids;
266 };
267
277 {
278 public:
283 ActiveFEIndexEqualTo(const unsigned int active_fe_index,
284 const bool only_locally_owned = false);
285
291 ActiveFEIndexEqualTo(const std::set<unsigned int> &active_fe_indices,
292 const bool only_locally_owned = false);
293
299 template <class Iterator>
300 bool
301 operator()(const Iterator &i) const;
302
303 protected:
307 const std::set<unsigned int> active_fe_indices;
312 };
313
322 {
323 public:
327 template <class Iterator>
328 bool
329 operator()(const Iterator &i) const;
330 };
331} // namespace IteratorFilters
332
333
523template <typename BaseIterator>
525{
526public:
530 using AccessorType = typename BaseIterator::AccessorType;
531
536 template <typename Predicate>
537 FilteredIterator(Predicate p);
538
556 template <typename Predicate>
557 FilteredIterator(Predicate p, const BaseIterator &bi);
558
564
572 operator=(const FilteredIterator &fi);
573
580 operator=(const BaseIterator &fi);
581
592
603
610 bool
611 operator==(const FilteredIterator &fi) const;
612
619 bool
620 operator==(const BaseIterator &fi) const;
621
628 bool
629 operator!=(const FilteredIterator &fi) const;
630
637 bool
638 operator!=(const BaseIterator &fi) const;
639
646 bool
647 operator<(const FilteredIterator &fi) const;
648
655 bool
656 operator<(const BaseIterator &fi) const;
657
663 operator++();
664
670 operator++(int);
671
677 operator--();
678
684 operator--(int);
685
692 << "The element " << arg1
693 << " with which you want to compare or which you want to"
694 << " assign from is invalid since it does not satisfy the predicate.");
695
696private:
707 {
708 public:
713 virtual ~PredicateBase() = default;
714
719 virtual bool
720 operator()(const BaseIterator &bi) const = 0;
721
726 virtual std::unique_ptr<PredicateBase>
727 clone() const = 0;
728 };
729
730
739 template <typename Predicate>
741 {
742 public:
746 PredicateTemplate(const Predicate &predicate);
747
751 virtual bool
752 operator()(const BaseIterator &bi) const override;
753
758 virtual std::unique_ptr<PredicateBase>
759 clone() const override;
760
761 private:
765 const Predicate predicate;
766 };
767
772 std::unique_ptr<const PredicateBase> predicate;
773};
774
775
776
786template <typename BaseIterator, typename Predicate>
788make_filtered_iterator(const BaseIterator &i, const Predicate &p)
789{
792 return fi;
793}
794
795
796
797namespace internal
798{
799 namespace FilteredIteratorImplementation
800 {
801 // The following classes create a nested sequence of
802 // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
803 // levels of FilteredIterator classes as there are elements in the TypeList
804 // if the latter is given as a std::tuple<Args...>.
805 template <typename BaseIterator, typename TypeList>
807
808 template <typename BaseIterator, typename Predicate>
809 struct NestFilteredIterators<BaseIterator, std::tuple<Predicate>>
810 {
812 };
813
814 template <typename BaseIterator, typename Predicate, typename... Targs>
815 struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>
816 {
819 std::tuple<Targs...>>::type>;
820 };
821 } // namespace FilteredIteratorImplementation
822} // namespace internal
823
824
825
858template <typename BaseIterator, typename Predicate>
861{
863 FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
864
866}
867
868
869
906template <typename BaseIterator, typename Predicate, typename... Targs>
908 typename internal::FilteredIteratorImplementation::
909 NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>::type>
911 const Predicate & p,
912 const Targs... args)
913{
914 // Recursively create filtered iterators, one predicate at a time
915 auto fi = filter_iterators(i, p);
916 return filter_iterators(fi, args...);
917}
918
919
920/* ------------------ Inline functions and templates ------------ */
921
922
923template <typename BaseIterator>
924template <typename Predicate>
926 : predicate(new PredicateTemplate<Predicate>(p))
927{}
928
929
930
931template <typename BaseIterator>
932template <typename Predicate>
934 const BaseIterator &bi)
935 : BaseIterator(bi)
936 , predicate(new PredicateTemplate<Predicate>(p))
937{
938 if ((this->state() == IteratorState::valid) && !(*predicate)(*this))
940}
941
942
943
944template <typename BaseIterator>
946 const FilteredIterator &fi)
947 : // this construction looks strange, but without going through the
948 // address of fi, GCC would not cast fi to the base class of type
949 // BaseIterator but tries to go through constructing a new
950 // BaseIterator with an Accessor.
951 BaseIterator(*static_cast<const BaseIterator *>(&fi))
952 , predicate(fi.predicate->clone())
953{}
954
955
956
957template <typename BaseIterator>
960{
961 // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
962 // below, some compiler would not cast fi to the base class of type
963 // BaseIterator but try to go through constructing a new Accessor from fi
964 // which fails. Hence, we just use an explicit upcast and call the above-
965 // mentioned method.
966 const BaseIterator &bi = fi;
967 return operator=(bi);
968}
969
970
971
972template <typename BaseIterator>
975{
976 Assert((bi.state() != IteratorState::valid) || (*predicate)(bi),
977 ExcInvalidElement(bi));
978 BaseIterator::operator=(bi);
979 return *this;
980}
981
982
983
984template <typename BaseIterator>
987{
988 BaseIterator::operator=(bi);
989 while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
991
992 return *this;
993}
994
995
996
997template <typename BaseIterator>
1000{
1001 BaseIterator::operator=(bi);
1002 while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1003 BaseIterator::operator--();
1004
1005 return *this;
1006}
1007
1008
1009
1010template <typename BaseIterator>
1011inline bool
1013{
1014 return (static_cast<const BaseIterator &>(*this) ==
1015 static_cast<const BaseIterator &>(fi));
1016}
1017
1018
1019
1020template <typename BaseIterator>
1021inline bool
1023{
1024 return (static_cast<const BaseIterator &>(*this) !=
1025 static_cast<const BaseIterator &>(fi));
1026}
1027
1028
1029
1030template <typename BaseIterator>
1031inline bool
1033{
1034 return (static_cast<const BaseIterator &>(*this) <
1035 static_cast<const BaseIterator &>(fi));
1036}
1037
1038
1039
1040template <typename BaseIterator>
1041inline bool
1043{
1044 return (static_cast<const BaseIterator &>(*this) == bi);
1045}
1046
1047
1048
1049template <typename BaseIterator>
1050inline bool
1052{
1053 return (static_cast<const BaseIterator &>(*this) != bi);
1054}
1055
1056
1057
1058template <typename BaseIterator>
1059inline bool
1061{
1062 return (static_cast<const BaseIterator &>(*this) < bi);
1063}
1064
1065
1066template <typename BaseIterator>
1069{
1070 if (this->state() == IteratorState::valid)
1071 do
1073 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1074 return *this;
1075}
1076
1077
1078
1079template <typename BaseIterator>
1082{
1083 const FilteredIterator old_state = *this;
1084
1085 if (this->state() == IteratorState::valid)
1086 do
1088 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1089 return old_state;
1090}
1091
1092
1093
1094template <typename BaseIterator>
1097{
1098 if (this->state() == IteratorState::valid)
1099 do
1100 BaseIterator::operator--();
1101 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1102 return *this;
1103}
1104
1105
1106
1107template <typename BaseIterator>
1110{
1111 const FilteredIterator old_state = *this;
1112
1113 if (this->state() == IteratorState::valid)
1114 do
1115 BaseIterator::operator--();
1116 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1117 return old_state;
1118}
1119
1120
1121
1122template <typename BaseIterator>
1123template <typename Predicate>
1125 Predicate>::PredicateTemplate(const Predicate &predicate)
1126 : predicate(predicate)
1127{}
1128
1129
1130
1131template <typename BaseIterator>
1132template <typename Predicate>
1133bool
1135operator()(const BaseIterator &bi) const
1136{
1137 return predicate(bi);
1138}
1139
1140
1141
1142template <typename BaseIterator>
1143template <typename Predicate>
1144std::unique_ptr<typename FilteredIterator<BaseIterator>::PredicateBase>
1146{
1147 return std::make_unique<PredicateTemplate>(predicate);
1148}
1149
1150
1151
1152namespace IteratorFilters
1153{
1154 // ---------------- IteratorFilters::Active ---------
1155
1156 template <class Iterator>
1157 inline bool
1158 Active::operator()(const Iterator &i) const
1159 {
1160 return i->is_active();
1161 }
1162
1163
1164 // ---------------- IteratorFilters::UserFlagSet ---------
1165
1166 template <class Iterator>
1167 inline bool
1168 UserFlagSet::operator()(const Iterator &i) const
1169 {
1170 return (i->user_flag_set());
1171 }
1172
1173
1174 // ---------------- IteratorFilters::UserFlagNotSet ---------
1175
1176 template <class Iterator>
1177 inline bool
1178 UserFlagNotSet::operator()(const Iterator &i) const
1179 {
1180 return (!i->user_flag_set());
1181 }
1182
1183
1184 // ---------------- IteratorFilters::LevelEqualTo ---------
1185 inline LevelEqualTo::LevelEqualTo(const unsigned int level)
1186 : level(level)
1187 {}
1188
1189
1190
1191 template <class Iterator>
1192 inline bool
1193 LevelEqualTo::operator()(const Iterator &i) const
1194 {
1195 return (static_cast<unsigned int>(i->level()) == level);
1196 }
1197
1198
1199
1200 // ---------------- IteratorFilters::SubdomainEqualTo ---------
1204 {}
1205
1206
1207
1208 template <class Iterator>
1209 inline bool
1210 SubdomainEqualTo::operator()(const Iterator &i) const
1211 {
1212 return (i->subdomain_id() == subdomain_id);
1213 }
1214
1215
1216
1217 // ---------------- IteratorFilters::LocallyOwnedCell ---------
1218
1219 template <class Iterator>
1220 inline bool
1221 LocallyOwnedCell::operator()(const Iterator &i) const
1222 {
1223 return (i->is_locally_owned());
1224 }
1225
1226
1227 // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1228
1229 template <class Iterator>
1230 inline bool
1231 LocallyOwnedLevelCell::operator()(const Iterator &i) const
1232 {
1233 return (i->is_locally_owned_on_level());
1234 }
1235
1236
1237
1238 // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1241 const bool only_locally_owned)
1242 : material_ids{material_id}
1243 , only_locally_owned(only_locally_owned)
1244 {}
1245
1246
1247
1249 const std::set<types::material_id> &material_ids,
1250 const bool only_locally_owned)
1251 : material_ids(material_ids)
1252 , only_locally_owned(only_locally_owned)
1253 {}
1254
1255
1256
1257 template <class Iterator>
1258 inline bool
1259 MaterialIdEqualTo::operator()(const Iterator &i) const
1260 {
1261 return only_locally_owned == true ?
1262 (material_ids.find(i->material_id()) != material_ids.end() &&
1263 i->is_locally_owned()) :
1264 material_ids.find(i->material_id()) != material_ids.end();
1265 }
1266
1267
1268
1269 // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1271 const unsigned int active_fe_index,
1272 const bool only_locally_owned)
1273 : active_fe_indices{active_fe_index}
1274 , only_locally_owned(only_locally_owned)
1275 {}
1276
1277
1278
1280 const std::set<unsigned int> &active_fe_indices,
1281 const bool only_locally_owned)
1282 : active_fe_indices(active_fe_indices)
1283 , only_locally_owned(only_locally_owned)
1284 {}
1285
1286
1287
1288 template <class Iterator>
1289 inline bool
1290 ActiveFEIndexEqualTo::operator()(const Iterator &i) const
1291 {
1292 return only_locally_owned == true ?
1293 (active_fe_indices.find(i->active_fe_index()) !=
1294 active_fe_indices.end() &&
1295 i->is_locally_owned()) :
1296 active_fe_indices.find(i->active_fe_index()) !=
1297 active_fe_indices.end();
1298 }
1299
1300
1301
1302 // ---------------- IteratorFilters::AtBoundary ---------
1303
1304 template <class Iterator>
1305 inline bool
1306 AtBoundary::operator()(const Iterator &i) const
1307 {
1308 return (i->at_boundary());
1309 }
1310} // namespace IteratorFilters
1311
1312
1314
1315/*------------------------- filtered_iterator.h ------------------------*/
1316#endif
1317/*------------------------- filtered_iterator.h ------------------------*/
virtual ~PredicateBase()=default
virtual bool operator()(const BaseIterator &bi) const =0
virtual std::unique_ptr< PredicateBase > clone() const =0
virtual bool operator()(const BaseIterator &bi) const override
PredicateTemplate(const Predicate &predicate)
virtual std::unique_ptr< PredicateBase > clone() const override
FilteredIterator & set_to_next_positive(const BaseIterator &bi)
FilteredIterator & set_to_previous_positive(const BaseIterator &bi)
FilteredIterator & operator--()
typename BaseIterator::AccessorType AccessorType
bool operator==(const FilteredIterator &fi) const
bool operator!=(const FilteredIterator &fi) const
FilteredIterator< BaseIterator > make_filtered_iterator(const BaseIterator &i, const Predicate &p)
FilteredIterator(Predicate p)
bool operator<(const FilteredIterator &fi) const
FilteredIterator & operator=(const FilteredIterator &fi)
std::unique_ptr< const PredicateBase > predicate
FilteredIterator & operator++()
bool operator()(const Iterator &i) const
const std::set< unsigned int > active_fe_indices
ActiveFEIndexEqualTo(const unsigned int active_fe_index, const bool only_locally_owned=false)
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
LevelEqualTo(const unsigned int level)
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
MaterialIdEqualTo(const types::material_id material_id, const bool only_locally_owned=false)
const std::set< types::material_id > material_ids
SubdomainEqualTo(const types::subdomain_id subdomain_id)
bool operator()(const Iterator &i) const
const types::subdomain_id subdomain_id
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
IteratorOverIterators end() const
IteratorOverIterators begin()
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:402
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:403
unsigned int level
Definition: grid_out.cc:4590
IteratorRange< typename internal::FilteredIteratorImplementation::NestFilteredIterators< BaseIterator, std::tuple< Predicate, Targs... > >::type > filter_iterators(IteratorRange< BaseIterator > i, const Predicate &p, const Targs... args)
IteratorRange< FilteredIterator< BaseIterator > > filter_iterators(IteratorRange< BaseIterator > i, const Predicate &p)
static ::ExceptionBase & ExcInvalidElement(BaseIterator arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1465
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:515
@ valid
Iterator points to a valid object.
STL namespace.
unsigned int subdomain_id
Definition: types.h:43
unsigned int material_id
Definition: types.h:152
SynchronousIterators< Iterators > operator++(SynchronousIterators< Iterators > &a)