Reference documentation for deal.II version GIT b8135fa6eb 2023-03-25 15:55:02+00:00
\(\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\}}\)
filtered_iterator.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2002 - 2021 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 
31 #ifdef DEAL_II_HAVE_CXX20
32 # include <concepts>
33 #endif
34 
35 
37 
38 
54 namespace IteratorFilters
55 {
62  class Active
63  {
64  public:
69  template <class Iterator>
70  bool
71  operator()(const Iterator &i) const;
72  };
73 
83  {
84  public:
89  template <class Iterator>
90  bool
91  operator()(const Iterator &i) const;
92  };
93 
94 
103  {
104  public:
109  template <class Iterator>
110  bool
111  operator()(const Iterator &i) const;
112  };
113 
114 
123  {
124  public:
129  LevelEqualTo(const unsigned int level);
130 
136  template <class Iterator>
137  bool
138  operator()(const Iterator &i) const;
139 
140  protected:
144  const unsigned int level;
145  };
146 
147 
148 
158  {
159  public:
165 
171  template <class Iterator>
172  bool
173  operator()(const Iterator &i) const;
174 
175  protected:
180  };
181 
182 
183 
196  {
197  public:
201  template <class Iterator>
202  bool
203  operator()(const Iterator &i) const;
204  };
205 
206 
207 
215  {
216  public:
221  template <class Iterator>
222  bool
223  operator()(const Iterator &i) const;
224  };
225 
226 
236  {
237  public:
243  const bool only_locally_owned = false);
244 
250  MaterialIdEqualTo(const std::set<types::material_id> &material_ids,
251  const bool only_locally_owned = false);
252 
258  template <class Iterator>
259  bool
260  operator()(const Iterator &i) const;
261 
262  protected:
266  const std::set<types::material_id> material_ids;
270  const bool only_locally_owned;
271  };
272 
282  {
283  public:
288  ActiveFEIndexEqualTo(const unsigned int active_fe_index,
289  const bool only_locally_owned = false);
290 
296  ActiveFEIndexEqualTo(const std::set<unsigned int> &active_fe_indices,
297  const bool only_locally_owned = false);
298 
304  template <class Iterator>
305  bool
306  operator()(const Iterator &i) const;
307 
308  protected:
312  const std::set<unsigned int> active_fe_indices;
316  const bool only_locally_owned;
317  };
318 
327  {
328  public:
332  template <class Iterator>
333  bool
334  operator()(const Iterator &i) const;
335  };
336 
337 
346  {
347  public:
353 
358  BoundaryIdEqualTo(const std::set<types::boundary_id> &boundary_ids);
359 
364  template <class Iterator>
365  bool
366  operator()(const Iterator &i) const;
367 
368  protected:
372  const std::set<types::boundary_id> boundary_ids;
373  };
374 
375 
384  {
385  public:
391 
396  ManifoldIdEqualTo(const std::set<types::manifold_id> &manifold_ids);
397 
402  template <class Iterator>
403  bool
404  operator()(const Iterator &i) const;
405 
406  protected:
410  const std::set<types::manifold_id> manifold_ids;
411  };
412 } // namespace IteratorFilters
413 
414 
632 template <typename BaseIterator>
634 {
635 public:
639  using AccessorType = typename BaseIterator::AccessorType;
640 
645  template <typename Predicate>
646  DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
647  FilteredIterator(Predicate p);
648 
666  template <typename Predicate>
667  DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
668  FilteredIterator(Predicate p, const BaseIterator &bi);
669 
675 
683  operator=(const FilteredIterator &fi);
684 
691  operator=(const BaseIterator &fi);
692 
703 
714 
721  bool
722  operator==(const FilteredIterator &fi) const;
723 
730  bool
731  operator==(const BaseIterator &fi) const;
732 
739  bool
740  operator!=(const FilteredIterator &fi) const;
741 
748  bool
749  operator!=(const BaseIterator &fi) const;
750 
757  bool
758  operator<(const FilteredIterator &fi) const;
759 
766  bool
767  operator<(const BaseIterator &fi) const;
768 
774  operator++();
775 
781  operator++(int);
782 
788  operator--();
789 
795  operator--(int);
796 
802  BaseIterator,
803  << "The element " << arg1
804  << " with which you want to compare or which you want to"
805  << " assign from is invalid since it does not satisfy the predicate.");
806 
807 private:
818  {
819  public:
824  virtual ~PredicateBase() = default;
825 
830  virtual bool
831  operator()(const BaseIterator &bi) const = 0;
832 
837  virtual std::unique_ptr<PredicateBase>
838  clone() const = 0;
839  };
840 
841 
850  template <typename Predicate>
852  {
853  public:
857  PredicateTemplate(const Predicate &predicate);
858 
862  virtual bool
863  operator()(const BaseIterator &bi) const override;
864 
869  virtual std::unique_ptr<PredicateBase>
870  clone() const override;
871 
872  private:
876  const Predicate predicate;
877  };
878 
883  std::unique_ptr<const PredicateBase> predicate;
884 };
885 
886 
887 
897 template <typename BaseIterator, typename Predicate>
898 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
900  const Predicate & p)
901 {
903  fi.set_to_next_positive(i);
904  return fi;
905 }
906 
907 
908 
909 namespace internal
910 {
911  namespace FilteredIteratorImplementation
912  {
913  // The following classes create a nested sequence of
914  // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
915  // levels of FilteredIterator classes as there are elements in the TypeList
916  // if the latter is given as a std::tuple<Args...>.
917  template <typename BaseIterator, typename TypeList>
919 
920  template <typename BaseIterator, typename Predicate>
921  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate>>
922  {
924  };
925 
926  template <typename BaseIterator, typename Predicate, typename... Targs>
927  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>
928  {
931  std::tuple<Targs...>>::type>;
932  };
933  } // namespace FilteredIteratorImplementation
934 } // namespace internal
935 
936 
937 
988 template <typename BaseIterator, typename Predicate>
989 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
992  const Predicate & p)
993 {
994  FilteredIterator<BaseIterator> fi(p, *(i.begin()));
995  FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
996 
998 }
999 
1000 
1001 
1057 template <typename BaseIterator, typename Predicate, typename... Targs>
1058 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1060  typename internal::FilteredIteratorImplementation::
1061  NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>::
1063  const Predicate & p,
1064  const Targs... args)
1065 {
1066  // Recursively create filtered iterators, one predicate at a time
1067  auto fi = filter_iterators(i, p);
1068  return filter_iterators(fi, args...);
1069 }
1070 
1071 
1072 
1131 template <typename BaseIterator, typename Predicate>
1132 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1135 {
1136  return filter_iterators(i, p);
1137 }
1138 
1139 
1140 
1141 /* ------------------ Inline functions and templates ------------ */
1142 
1143 
1144 template <typename BaseIterator>
1145 template <typename Predicate>
1146 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1148  : predicate(new PredicateTemplate<Predicate>(p))
1149 {}
1150 
1151 
1152 
1153 template <typename BaseIterator>
1154 template <typename Predicate>
1155 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1157  const BaseIterator &bi)
1158  : BaseIterator(bi)
1159  , predicate(new PredicateTemplate<Predicate>(p))
1160 {
1161  if ((this->state() == IteratorState::valid) && !(*predicate)(*this))
1162  set_to_next_positive(bi);
1163 }
1164 
1165 
1166 
1167 template <typename BaseIterator>
1169  const FilteredIterator &fi)
1170  : // this construction looks strange, but without going through the
1171  // address of fi, GCC would not cast fi to the base class of type
1172  // BaseIterator but tries to go through constructing a new
1173  // BaseIterator with an Accessor.
1174  BaseIterator(*static_cast<const BaseIterator *>(&fi))
1175  , predicate(fi.predicate->clone())
1176 {}
1177 
1178 
1179 
1180 template <typename BaseIterator>
1183 {
1184  // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
1185  // below, some compiler would not cast fi to the base class of type
1186  // BaseIterator but try to go through constructing a new Accessor from fi
1187  // which fails. Hence, we just use an explicit upcast and call the above-
1188  // mentioned method.
1189  const BaseIterator &bi = fi;
1190  return operator=(bi);
1191 }
1192 
1193 
1194 
1195 template <typename BaseIterator>
1198 {
1199  Assert((bi.state() != IteratorState::valid) || (*predicate)(bi),
1200  ExcInvalidElement(bi));
1201  BaseIterator::operator=(bi);
1202  return *this;
1203 }
1204 
1205 
1206 
1207 template <typename BaseIterator>
1210 {
1211  BaseIterator::operator=(bi);
1212  while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1214 
1215  return *this;
1216 }
1217 
1218 
1219 
1220 template <typename BaseIterator>
1223 {
1224  BaseIterator::operator=(bi);
1225  while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1226  BaseIterator::operator--();
1227 
1228  return *this;
1229 }
1230 
1231 
1232 
1233 template <typename BaseIterator>
1234 inline bool
1236 {
1237  return (static_cast<const BaseIterator &>(*this) ==
1238  static_cast<const BaseIterator &>(fi));
1239 }
1240 
1241 
1242 
1243 template <typename BaseIterator>
1244 inline bool
1246 {
1247  return (static_cast<const BaseIterator &>(*this) !=
1248  static_cast<const BaseIterator &>(fi));
1249 }
1250 
1251 
1252 
1253 template <typename BaseIterator>
1254 inline bool
1256 {
1257  return (static_cast<const BaseIterator &>(*this) <
1258  static_cast<const BaseIterator &>(fi));
1259 }
1260 
1261 
1262 
1263 template <typename BaseIterator>
1264 inline bool
1266 {
1267  return (static_cast<const BaseIterator &>(*this) == bi);
1268 }
1269 
1270 
1271 
1272 template <typename BaseIterator>
1273 inline bool
1275 {
1276  return (static_cast<const BaseIterator &>(*this) != bi);
1277 }
1278 
1279 
1280 
1281 template <typename BaseIterator>
1282 inline bool
1284 {
1285  return (static_cast<const BaseIterator &>(*this) < bi);
1286 }
1287 
1288 
1289 template <typename BaseIterator>
1292 {
1293  if (this->state() == IteratorState::valid)
1294  do
1296  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1297  return *this;
1298 }
1299 
1300 
1301 
1302 template <typename BaseIterator>
1305 {
1306  const FilteredIterator old_state = *this;
1307 
1308  if (this->state() == IteratorState::valid)
1309  do
1311  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1312  return old_state;
1313 }
1314 
1315 
1316 
1317 template <typename BaseIterator>
1320 {
1321  if (this->state() == IteratorState::valid)
1322  do
1323  BaseIterator::operator--();
1324  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1325  return *this;
1326 }
1327 
1328 
1329 
1330 template <typename BaseIterator>
1333 {
1334  const FilteredIterator old_state = *this;
1335 
1336  if (this->state() == IteratorState::valid)
1337  do
1338  BaseIterator::operator--();
1339  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1340  return old_state;
1341 }
1342 
1343 
1344 
1345 template <typename BaseIterator>
1346 template <typename Predicate>
1348  Predicate>::PredicateTemplate(const Predicate &predicate)
1349  : predicate(predicate)
1350 {}
1351 
1352 
1353 
1354 template <typename BaseIterator>
1355 template <typename Predicate>
1356 bool
1358  const BaseIterator &bi) const
1359 {
1360  return predicate(bi);
1361 }
1362 
1363 
1364 
1365 template <typename BaseIterator>
1366 template <typename Predicate>
1367 std::unique_ptr<typename FilteredIterator<BaseIterator>::PredicateBase>
1369 {
1370  return std::make_unique<PredicateTemplate>(predicate);
1371 }
1372 
1373 
1374 
1375 namespace IteratorFilters
1376 {
1377  // ---------------- IteratorFilters::Active ---------
1378 
1379  template <class Iterator>
1380  inline bool
1381  Active::operator()(const Iterator &i) const
1382  {
1383  return i->is_active();
1384  }
1385 
1386 
1387  // ---------------- IteratorFilters::UserFlagSet ---------
1388 
1389  template <class Iterator>
1390  inline bool
1391  UserFlagSet::operator()(const Iterator &i) const
1392  {
1393  return (i->user_flag_set());
1394  }
1395 
1396 
1397  // ---------------- IteratorFilters::UserFlagNotSet ---------
1398 
1399  template <class Iterator>
1400  inline bool
1401  UserFlagNotSet::operator()(const Iterator &i) const
1402  {
1403  return (!i->user_flag_set());
1404  }
1405 
1406 
1407  // ---------------- IteratorFilters::LevelEqualTo ---------
1408  inline LevelEqualTo::LevelEqualTo(const unsigned int level)
1409  : level(level)
1410  {}
1411 
1412 
1413 
1414  template <class Iterator>
1415  inline bool
1416  LevelEqualTo::operator()(const Iterator &i) const
1417  {
1418  return (static_cast<unsigned int>(i->level()) == level);
1419  }
1420 
1421 
1422 
1423  // ---------------- IteratorFilters::SubdomainEqualTo ---------
1427  {}
1428 
1429 
1430 
1431  template <class Iterator>
1432  inline bool
1433  SubdomainEqualTo::operator()(const Iterator &i) const
1434  {
1435  return (i->subdomain_id() == subdomain_id);
1436  }
1437 
1438 
1439 
1440  // ---------------- IteratorFilters::LocallyOwnedCell ---------
1441 
1442  template <class Iterator>
1443  inline bool
1444  LocallyOwnedCell::operator()(const Iterator &i) const
1445  {
1446  return (i->is_locally_owned());
1447  }
1448 
1449 
1450  // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1451 
1452  template <class Iterator>
1453  inline bool
1454  LocallyOwnedLevelCell::operator()(const Iterator &i) const
1455  {
1456  return (i->is_locally_owned_on_level());
1457  }
1458 
1459 
1460 
1461  // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1464  const bool only_locally_owned)
1465  : material_ids{material_id}
1466  , only_locally_owned(only_locally_owned)
1467  {}
1468 
1469 
1470 
1472  const std::set<types::material_id> &material_ids,
1473  const bool only_locally_owned)
1474  : material_ids(material_ids)
1475  , only_locally_owned(only_locally_owned)
1476  {}
1477 
1478 
1479 
1480  template <class Iterator>
1481  inline bool
1482  MaterialIdEqualTo::operator()(const Iterator &i) const
1483  {
1484  return only_locally_owned == true ?
1485  (material_ids.find(i->material_id()) != material_ids.end() &&
1486  i->is_locally_owned()) :
1487  material_ids.find(i->material_id()) != material_ids.end();
1488  }
1489 
1490 
1491 
1492  // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1494  const unsigned int active_fe_index,
1495  const bool only_locally_owned)
1496  : active_fe_indices{active_fe_index}
1497  , only_locally_owned(only_locally_owned)
1498  {}
1499 
1500 
1501 
1503  const std::set<unsigned int> &active_fe_indices,
1504  const bool only_locally_owned)
1505  : active_fe_indices(active_fe_indices)
1506  , only_locally_owned(only_locally_owned)
1507  {}
1508 
1509 
1510 
1511  template <class Iterator>
1512  inline bool
1513  ActiveFEIndexEqualTo::operator()(const Iterator &i) const
1514  {
1515  return only_locally_owned == true ?
1516  (i->is_locally_owned() &&
1517  active_fe_indices.find(i->active_fe_index()) !=
1518  active_fe_indices.end()) :
1519  active_fe_indices.find(i->active_fe_index()) !=
1520  active_fe_indices.end();
1521  }
1522 
1523 
1524 
1525  // ---------------- IteratorFilters::AtBoundary ---------
1526 
1527  template <class Iterator>
1528  inline bool
1529  AtBoundary::operator()(const Iterator &i) const
1530  {
1531  return (i->at_boundary());
1532  }
1533 
1534 
1535 
1536  // ---------------- IteratorFilters::BoundaryIdEqualTo ---------
1539  : boundary_ids{boundary_id}
1540  {}
1541 
1542 
1543 
1545  const std::set<types::boundary_id> &boundary_ids)
1546  : boundary_ids(boundary_ids)
1547  {}
1548 
1549 
1550 
1551  template <class Iterator>
1552  inline bool
1553  BoundaryIdEqualTo::operator()(const Iterator &i) const
1554  {
1555  return boundary_ids.find(i->boundary_id()) != boundary_ids.end();
1556  }
1557 
1558 
1559 
1560  // ---------------- IteratorFilters::ManifoldIdEqualTo ---------
1563  : manifold_ids{manifold_id}
1564  {}
1565 
1566 
1567 
1569  const std::set<types::manifold_id> &manifold_ids)
1570  : manifold_ids(manifold_ids)
1571  {}
1572 
1573 
1574 
1575  template <class Iterator>
1576  inline bool
1577  ManifoldIdEqualTo::operator()(const Iterator &i) const
1578  {
1579  return manifold_ids.find(i->manifold_id()) != manifold_ids.end();
1580  }
1581 } // namespace IteratorFilters
1582 
1583 
1585 
1586 #endif
virtual std::unique_ptr< PredicateBase > clone() const =0
virtual ~PredicateBase()=default
virtual bool operator()(const BaseIterator &bi) 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
const std::set< types::boundary_id > boundary_ids
BoundaryIdEqualTo(const types::boundary_id boundary_id)
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
ManifoldIdEqualTo(const types::manifold_id manifold_id)
const std::set< types::manifold_id > manifold_ids
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
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:474
#define DEAL_II_CXX20_REQUIRES(condition)
Definition: config.h:162
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:475
unsigned int level
Definition: grid_out.cc:4618
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)
IteratorRange< FilteredIterator< BaseIterator > > operator|(IteratorRange< BaseIterator > i, const Predicate &p)
static ::ExceptionBase & ExcInvalidElement(BaseIterator arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1586
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:510
@ valid
Iterator points to a valid object.
unsigned int manifold_id
Definition: types.h:153
unsigned int subdomain_id
Definition: types.h:44
unsigned int material_id
Definition: types.h:164
unsigned int boundary_id
Definition: types.h:141
SynchronousIterators< Iterators > operator++(SynchronousIterators< Iterators > &a)