Reference documentation for deal.II version GIT f6a5d312c9 2023-10-04 08:50: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 - 2023 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 
647  template <typename Predicate>
648  DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
649  FilteredIterator(Predicate p);
650 
670  template <typename Predicate>
671  DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
672  FilteredIterator(Predicate p, const BaseIterator &bi);
673 
679 
687  operator=(const FilteredIterator &fi);
688 
695  operator=(const BaseIterator &fi);
696 
707 
718 
725  bool
726  operator==(const FilteredIterator &fi) const;
727 
734  bool
735  operator==(const BaseIterator &fi) const;
736 
743  bool
744  operator!=(const FilteredIterator &fi) const;
745 
752  bool
753  operator!=(const BaseIterator &fi) const;
754 
761  bool
762  operator<(const FilteredIterator &fi) const;
763 
770  bool
771  operator<(const BaseIterator &fi) const;
772 
778  operator++();
779 
785  operator++(int);
786 
792  operator--();
793 
799  operator--(int);
800 
806  BaseIterator,
807  << "The element " << arg1
808  << " with which you want to compare or which you want to"
809  << " assign from is invalid since it does not satisfy the predicate.");
810 
811 private:
822  {
823  public:
828  virtual ~PredicateBase() = default;
829 
834  virtual bool
835  operator()(const BaseIterator &bi) const = 0;
836 
841  virtual std::unique_ptr<PredicateBase>
842  clone() const = 0;
843  };
844 
845 
854  template <typename Predicate>
856  {
857  public:
861  PredicateTemplate(const Predicate &predicate);
862 
866  virtual bool
867  operator()(const BaseIterator &bi) const override;
868 
873  virtual std::unique_ptr<PredicateBase>
874  clone() const override;
875 
876  private:
880  const Predicate predicate;
881  };
882 
887  std::unique_ptr<const PredicateBase> predicate;
888 };
889 
890 
891 
903 template <typename BaseIterator, typename Predicate>
904 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
906  const Predicate &p)
907 {
909  fi.set_to_next_positive(i);
910  return fi;
911 }
912 
913 
914 
915 namespace internal
916 {
917  namespace FilteredIteratorImplementation
918  {
919  // The following classes create a nested sequence of
920  // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
921  // levels of FilteredIterator classes as there are elements in the TypeList
922  // if the latter is given as a std::tuple<Args...>.
923  template <typename BaseIterator, typename TypeList>
925 
926  template <typename BaseIterator, typename Predicate>
927  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate>>
928  {
930  };
931 
932  template <typename BaseIterator, typename Predicate, typename... Targs>
933  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>
934  {
937  std::tuple<Targs...>>::type>;
938  };
939  } // namespace FilteredIteratorImplementation
940 } // namespace internal
941 
942 
943 
996 template <typename BaseIterator, typename Predicate>
997 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1000  const Predicate &p)
1001 {
1002  FilteredIterator<BaseIterator> fi(p, *(i.begin()));
1003  FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
1004 
1006 }
1007 
1008 
1009 
1067 template <typename BaseIterator, typename Predicate, typename... Targs>
1068 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1070  typename internal::FilteredIteratorImplementation::
1071  NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>::
1073  const Predicate &p,
1074  const Targs... args)
1075 {
1076  // Recursively create filtered iterators, one predicate at a time
1077  auto fi = filter_iterators(i, p);
1078  return filter_iterators(fi, args...);
1079 }
1080 
1081 
1082 
1143 template <typename BaseIterator, typename Predicate>
1144 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1147 {
1148  return filter_iterators(i, p);
1149 }
1150 
1151 
1152 
1153 /* ------------------ Inline functions and templates ------------ */
1154 
1155 
1156 template <typename BaseIterator>
1157 template <typename Predicate>
1158 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1160  : predicate(new PredicateTemplate<Predicate>(p))
1161 {}
1162 
1163 
1164 
1165 template <typename BaseIterator>
1166 template <typename Predicate>
1167 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1169  const BaseIterator &bi)
1170  : BaseIterator(bi)
1171  , predicate(new PredicateTemplate<Predicate>(p))
1172 {
1173  if ((this->state() == IteratorState::valid) && !(*predicate)(*this))
1174  set_to_next_positive(bi);
1175 }
1176 
1177 
1178 
1179 template <typename BaseIterator>
1181  const FilteredIterator &fi)
1182  : // this construction looks strange, but without going through the
1183  // address of fi, GCC would not cast fi to the base class of type
1184  // BaseIterator but tries to go through constructing a new
1185  // BaseIterator with an Accessor.
1186  BaseIterator(*static_cast<const BaseIterator *>(&fi))
1187  , predicate(fi.predicate->clone())
1188 {}
1189 
1190 
1191 
1192 template <typename BaseIterator>
1195 {
1196  // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
1197  // below, some compiler would not cast fi to the base class of type
1198  // BaseIterator but try to go through constructing a new Accessor from fi
1199  // which fails. Hence, we just use an explicit upcast and call the above-
1200  // mentioned method.
1201  const BaseIterator &bi = fi;
1202  return operator=(bi);
1203 }
1204 
1205 
1206 
1207 template <typename BaseIterator>
1210 {
1211  Assert((bi.state() != IteratorState::valid) || (*predicate)(bi),
1212  ExcInvalidElement(bi));
1213  BaseIterator::operator=(bi);
1214  return *this;
1215 }
1216 
1217 
1218 
1219 template <typename BaseIterator>
1222 {
1223  BaseIterator::operator=(bi);
1224  while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1226 
1227  return *this;
1228 }
1229 
1230 
1231 
1232 template <typename BaseIterator>
1235 {
1236  BaseIterator::operator=(bi);
1237  while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1238  BaseIterator::operator--();
1239 
1240  return *this;
1241 }
1242 
1243 
1244 
1245 template <typename BaseIterator>
1246 inline bool
1248 {
1249  return (static_cast<const BaseIterator &>(*this) ==
1250  static_cast<const BaseIterator &>(fi));
1251 }
1252 
1253 
1254 
1255 template <typename BaseIterator>
1256 inline bool
1258 {
1259  return (static_cast<const BaseIterator &>(*this) !=
1260  static_cast<const BaseIterator &>(fi));
1261 }
1262 
1263 
1264 
1265 template <typename BaseIterator>
1266 inline bool
1268 {
1269  return (static_cast<const BaseIterator &>(*this) <
1270  static_cast<const BaseIterator &>(fi));
1271 }
1272 
1273 
1274 
1275 template <typename BaseIterator>
1276 inline bool
1278 {
1279  return (static_cast<const BaseIterator &>(*this) == bi);
1280 }
1281 
1282 
1283 
1284 template <typename BaseIterator>
1285 inline bool
1287 {
1288  return (static_cast<const BaseIterator &>(*this) != bi);
1289 }
1290 
1291 
1292 
1293 template <typename BaseIterator>
1294 inline bool
1296 {
1297  return (static_cast<const BaseIterator &>(*this) < bi);
1298 }
1299 
1300 
1301 template <typename BaseIterator>
1304 {
1305  if (this->state() == IteratorState::valid)
1306  do
1308  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1309  return *this;
1310 }
1311 
1312 
1313 
1314 template <typename BaseIterator>
1317 {
1318  const FilteredIterator old_state = *this;
1319 
1320  if (this->state() == IteratorState::valid)
1321  do
1323  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1324  return old_state;
1325 }
1326 
1327 
1328 
1329 template <typename BaseIterator>
1332 {
1333  if (this->state() == IteratorState::valid)
1334  do
1335  BaseIterator::operator--();
1336  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1337  return *this;
1338 }
1339 
1340 
1341 
1342 template <typename BaseIterator>
1345 {
1346  const FilteredIterator old_state = *this;
1347 
1348  if (this->state() == IteratorState::valid)
1349  do
1350  BaseIterator::operator--();
1351  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1352  return old_state;
1353 }
1354 
1355 
1356 
1357 template <typename BaseIterator>
1358 template <typename Predicate>
1360  Predicate>::PredicateTemplate(const Predicate &predicate)
1361  : predicate(predicate)
1362 {}
1363 
1364 
1365 
1366 template <typename BaseIterator>
1367 template <typename Predicate>
1368 bool
1370  const BaseIterator &bi) const
1371 {
1372  return predicate(bi);
1373 }
1374 
1375 
1376 
1377 template <typename BaseIterator>
1378 template <typename Predicate>
1379 std::unique_ptr<typename FilteredIterator<BaseIterator>::PredicateBase>
1381 {
1382  return std::make_unique<PredicateTemplate>(predicate);
1383 }
1384 
1385 
1386 
1387 namespace IteratorFilters
1388 {
1389  // ---------------- IteratorFilters::Active ---------
1390 
1391  template <class Iterator>
1392  inline bool
1393  Active::operator()(const Iterator &i) const
1394  {
1395  return i->is_active();
1396  }
1397 
1398 
1399  // ---------------- IteratorFilters::UserFlagSet ---------
1400 
1401  template <class Iterator>
1402  inline bool
1403  UserFlagSet::operator()(const Iterator &i) const
1404  {
1405  return (i->user_flag_set());
1406  }
1407 
1408 
1409  // ---------------- IteratorFilters::UserFlagNotSet ---------
1410 
1411  template <class Iterator>
1412  inline bool
1413  UserFlagNotSet::operator()(const Iterator &i) const
1414  {
1415  return (!i->user_flag_set());
1416  }
1417 
1418 
1419  // ---------------- IteratorFilters::LevelEqualTo ---------
1420  inline LevelEqualTo::LevelEqualTo(const unsigned int level)
1421  : level(level)
1422  {}
1423 
1424 
1425 
1426  template <class Iterator>
1427  inline bool
1428  LevelEqualTo::operator()(const Iterator &i) const
1429  {
1430  return (static_cast<unsigned int>(i->level()) == level);
1431  }
1432 
1433 
1434 
1435  // ---------------- IteratorFilters::SubdomainEqualTo ---------
1439  {}
1440 
1441 
1442 
1443  template <class Iterator>
1444  inline bool
1445  SubdomainEqualTo::operator()(const Iterator &i) const
1446  {
1447  return (i->subdomain_id() == subdomain_id);
1448  }
1449 
1450 
1451 
1452  // ---------------- IteratorFilters::LocallyOwnedCell ---------
1453 
1454  template <class Iterator>
1455  inline bool
1456  LocallyOwnedCell::operator()(const Iterator &i) const
1457  {
1458  return (i->is_locally_owned());
1459  }
1460 
1461 
1462  // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1463 
1464  template <class Iterator>
1465  inline bool
1466  LocallyOwnedLevelCell::operator()(const Iterator &i) const
1467  {
1468  return (i->is_locally_owned_on_level());
1469  }
1470 
1471 
1472 
1473  // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1476  const bool only_locally_owned)
1477  : material_ids{material_id}
1478  , only_locally_owned(only_locally_owned)
1479  {}
1480 
1481 
1482 
1484  const std::set<types::material_id> &material_ids,
1485  const bool only_locally_owned)
1486  : material_ids(material_ids)
1487  , only_locally_owned(only_locally_owned)
1488  {}
1489 
1490 
1491 
1492  template <class Iterator>
1493  inline bool
1494  MaterialIdEqualTo::operator()(const Iterator &i) const
1495  {
1496  return only_locally_owned == true ?
1497  (material_ids.find(i->material_id()) != material_ids.end() &&
1498  i->is_locally_owned()) :
1499  material_ids.find(i->material_id()) != material_ids.end();
1500  }
1501 
1502 
1503 
1504  // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1506  const unsigned int active_fe_index,
1507  const bool only_locally_owned)
1508  : active_fe_indices{active_fe_index}
1509  , only_locally_owned(only_locally_owned)
1510  {}
1511 
1512 
1513 
1515  const std::set<unsigned int> &active_fe_indices,
1516  const bool only_locally_owned)
1517  : active_fe_indices(active_fe_indices)
1518  , only_locally_owned(only_locally_owned)
1519  {}
1520 
1521 
1522 
1523  template <class Iterator>
1524  inline bool
1525  ActiveFEIndexEqualTo::operator()(const Iterator &i) const
1526  {
1527  return only_locally_owned == true ?
1528  (i->is_locally_owned() &&
1529  active_fe_indices.find(i->active_fe_index()) !=
1530  active_fe_indices.end()) :
1531  active_fe_indices.find(i->active_fe_index()) !=
1532  active_fe_indices.end();
1533  }
1534 
1535 
1536 
1537  // ---------------- IteratorFilters::AtBoundary ---------
1538 
1539  template <class Iterator>
1540  inline bool
1541  AtBoundary::operator()(const Iterator &i) const
1542  {
1543  return (i->at_boundary());
1544  }
1545 
1546 
1547 
1548  // ---------------- IteratorFilters::BoundaryIdEqualTo ---------
1551  : boundary_ids{boundary_id}
1552  {}
1553 
1554 
1555 
1557  const std::set<types::boundary_id> &boundary_ids)
1558  : boundary_ids(boundary_ids)
1559  {}
1560 
1561 
1562 
1563  template <class Iterator>
1564  inline bool
1565  BoundaryIdEqualTo::operator()(const Iterator &i) const
1566  {
1567  return boundary_ids.find(i->boundary_id()) != boundary_ids.end();
1568  }
1569 
1570 
1571 
1572  // ---------------- IteratorFilters::ManifoldIdEqualTo ---------
1575  : manifold_ids{manifold_id}
1576  {}
1577 
1578 
1579 
1581  const std::set<types::manifold_id> &manifold_ids)
1582  : manifold_ids(manifold_ids)
1583  {}
1584 
1585 
1586 
1587  template <class Iterator>
1588  inline bool
1589  ManifoldIdEqualTo::operator()(const Iterator &i) const
1590  {
1591  return manifold_ids.find(i->manifold_id()) != manifold_ids.end();
1592  }
1593 } // namespace IteratorFilters
1594 
1595 
1597 
1598 #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:477
#define DEAL_II_CXX20_REQUIRES(condition)
Definition: config.h:166
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
unsigned int level
Definition: grid_out.cc:4617
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:1616
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:512
@ 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)