deal.II version GIT relicensing-2165-gc91f007519 2024-11-20 01:40:00+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\}}\)
Loading...
Searching...
No Matches
filtered_iterator.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2002 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_filtered_iterator_h
16#define dealii_filtered_iterator_h
17
18
19#include <deal.II/base/config.h>
20
23
25
26#include <memory>
27#include <set>
28#include <tuple>
29
30#ifdef DEAL_II_HAVE_CXX20
31# include <concepts>
32#endif
33
34
36
37
54{
61 class Active
62 {
63 public:
68 template <class Iterator>
69 bool
70 operator()(const Iterator &i) const;
71 };
72
82 {
83 public:
88 template <class Iterator>
89 bool
90 operator()(const Iterator &i) const;
91 };
92
93
102 {
103 public:
108 template <class Iterator>
109 bool
110 operator()(const Iterator &i) const;
111 };
112
113
122 {
123 public:
128 LevelEqualTo(const unsigned int level);
129
135 template <class Iterator>
136 bool
137 operator()(const Iterator &i) const;
138
139 protected:
143 const unsigned int level;
144 };
145
146
147
157 {
158 public:
164
170 template <class Iterator>
171 bool
172 operator()(const Iterator &i) const;
173
174 protected:
179 };
180
181
182
195 {
196 public:
200 template <class Iterator>
201 bool
202 operator()(const Iterator &i) const;
203 };
204
205
206
214 {
215 public:
220 template <class Iterator>
221 bool
222 operator()(const Iterator &i) const;
223 };
224
225
235 {
236 public:
241 MaterialIdEqualTo(const types::material_id material_id,
242 const bool only_locally_owned = false);
243
249 MaterialIdEqualTo(const std::set<types::material_id> &material_ids,
250 const bool only_locally_owned = false);
251
257 template <class Iterator>
258 bool
259 operator()(const Iterator &i) const;
260
261 protected:
265 const std::set<types::material_id> material_ids;
270 };
271
281 {
282 public:
287 ActiveFEIndexEqualTo(const unsigned int active_fe_index,
288 const bool only_locally_owned = false);
289
295 ActiveFEIndexEqualTo(const std::set<unsigned int> &active_fe_indices,
296 const bool only_locally_owned = false);
297
303 template <class Iterator>
304 bool
305 operator()(const Iterator &i) const;
306
307 protected:
311 const std::set<unsigned int> active_fe_indices;
316 };
317
326 {
327 public:
331 template <class Iterator>
332 bool
333 operator()(const Iterator &i) const;
334 };
335
336
345 {
346 public:
351 BoundaryIdEqualTo(const types::boundary_id boundary_id);
352
357 BoundaryIdEqualTo(const std::set<types::boundary_id> &boundary_ids);
358
363 template <class Iterator>
364 bool
365 operator()(const Iterator &i) const;
366
367 protected:
371 const std::set<types::boundary_id> boundary_ids;
372 };
373
374
383 {
384 public:
389 ManifoldIdEqualTo(const types::manifold_id manifold_id);
390
395 ManifoldIdEqualTo(const std::set<types::manifold_id> &manifold_ids);
396
401 template <class Iterator>
402 bool
403 operator()(const Iterator &i) const;
404
405 protected:
409 const std::set<types::manifold_id> manifold_ids;
410 };
411} // namespace IteratorFilters
412
413
631template <typename BaseIterator>
633{
634public:
638 using AccessorType = typename BaseIterator::AccessorType;
639
646 template <typename Predicate>
647 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
648 FilteredIterator(Predicate p);
649
669 template <typename Predicate>
670 DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
671 FilteredIterator(Predicate p, const BaseIterator &bi);
672
678
686 operator=(const FilteredIterator &fi);
687
694 operator=(const BaseIterator &fi);
695
706
717
724 bool
725 operator==(const FilteredIterator &fi) const;
726
733 bool
734 operator==(const BaseIterator &fi) const;
735
742 bool
743 operator!=(const FilteredIterator &fi) const;
744
751 bool
752 operator!=(const BaseIterator &fi) const;
753
760 bool
761 operator<(const FilteredIterator &fi) const;
762
769 bool
770 operator<(const BaseIterator &fi) const;
771
777 operator++();
778
784 operator++(int);
785
791 operator--();
792
798 operator--(int);
799
806 << "The element " << arg1
807 << " with which you want to compare or which you want to"
808 << " assign from is invalid since it does not satisfy the predicate.");
809
810private:
821 {
822 public:
827 virtual ~PredicateBase() = default;
828
833 virtual bool
834 operator()(const BaseIterator &bi) const = 0;
835
840 virtual std::unique_ptr<PredicateBase>
841 clone() const = 0;
842 };
843
844
853 template <typename Predicate>
855 {
856 public:
860 PredicateTemplate(const Predicate &predicate);
861
865 virtual bool
866 operator()(const BaseIterator &bi) const override;
867
872 virtual std::unique_ptr<PredicateBase>
873 clone() const override;
874
875 private:
879 const Predicate predicate;
880 };
881
886 std::unique_ptr<const PredicateBase> predicate;
887};
888
889
890
902template <typename BaseIterator, typename Predicate>
903DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
905 const Predicate &p)
906{
909 return fi;
910}
911
912
913
914namespace internal
915{
916 namespace FilteredIteratorImplementation
917 {
918 // The following classes create a nested sequence of
919 // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
920 // levels of FilteredIterator classes as there are elements in the TypeList
921 // if the latter is given as a std::tuple<Args...>.
922 template <typename BaseIterator, typename TypeList>
924
925 template <typename BaseIterator, typename Predicate>
926 struct NestFilteredIterators<BaseIterator, std::tuple<Predicate>>
927 {
929 };
930
931 template <typename BaseIterator, typename Predicate, typename... Targs>
932 struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>
933 {
936 std::tuple<Targs...>>::type>;
937 };
938 } // namespace FilteredIteratorImplementation
939} // namespace internal
940
941
942
995template <typename BaseIterator, typename Predicate>
996DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
999 const Predicate &p)
1000{
1001 FilteredIterator<BaseIterator> fi(p, *(i.begin()));
1002 FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
1003
1005}
1006
1007
1008
1066template <typename BaseIterator, typename Predicate, typename... Targs>
1067DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1069 typename internal::FilteredIteratorImplementation::
1070 NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>::
1072 const Predicate &p,
1073 const Targs... args)
1074{
1075 // Recursively create filtered iterators, one predicate at a time
1076 auto fi = filter_iterators(i, p);
1077 return filter_iterators(fi, args...);
1078}
1079
1080
1081
1142template <typename BaseIterator, typename Predicate>
1143DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1146{
1147 return filter_iterators(i, p);
1148}
1149
1150
1151
1152/* ------------------ Inline functions and templates ------------ */
1153
1154
1155template <typename BaseIterator>
1156template <typename Predicate>
1157DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1159 : predicate(new PredicateTemplate<Predicate>(p))
1160{}
1161
1162
1163
1164template <typename BaseIterator>
1165template <typename Predicate>
1166DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1168 const BaseIterator &bi)
1169 : BaseIterator(bi)
1170 , predicate(new PredicateTemplate<Predicate>(p))
1171{
1172 if ((this->state() == IteratorState::valid) && !(*predicate)(*this))
1173 set_to_next_positive(bi);
1174}
1175
1176
1177
1178template <typename BaseIterator>
1180 const FilteredIterator &fi)
1181 : // this construction looks strange, but without going through the
1182 // address of fi, GCC would not cast fi to the base class of type
1183 // BaseIterator but tries to go through constructing a new
1184 // BaseIterator with an Accessor.
1185 BaseIterator(*static_cast<const BaseIterator *>(&fi))
1186 , predicate(fi.predicate->clone())
1187{}
1188
1189
1190
1191template <typename BaseIterator>
1194{
1195 // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
1196 // below, some compiler would not cast fi to the base class of type
1197 // BaseIterator but try to go through constructing a new Accessor from fi
1198 // which fails. Hence, we just use an explicit upcast and call the above-
1199 // mentioned method.
1200 const BaseIterator &bi = fi;
1201 return operator=(bi);
1202}
1203
1204
1205
1206template <typename BaseIterator>
1209{
1210 Assert((bi.state() != IteratorState::valid) || (*predicate)(bi),
1211 ExcInvalidElement(bi));
1212 BaseIterator::operator=(bi);
1213 return *this;
1214}
1215
1216
1217
1218template <typename BaseIterator>
1221{
1222 BaseIterator::operator=(bi);
1223 while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1224 BaseIterator::operator++();
1225
1226 return *this;
1227}
1228
1229
1230
1231template <typename BaseIterator>
1234{
1235 BaseIterator::operator=(bi);
1236 while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1237 BaseIterator::operator--();
1238
1239 return *this;
1240}
1241
1242
1243
1244template <typename BaseIterator>
1245inline bool
1247{
1248 return (static_cast<const BaseIterator &>(*this) ==
1249 static_cast<const BaseIterator &>(fi));
1250}
1251
1252
1253
1254template <typename BaseIterator>
1255inline bool
1257{
1258 return (static_cast<const BaseIterator &>(*this) !=
1259 static_cast<const BaseIterator &>(fi));
1260}
1261
1262
1263
1264template <typename BaseIterator>
1265inline bool
1267{
1268 return (static_cast<const BaseIterator &>(*this) <
1269 static_cast<const BaseIterator &>(fi));
1270}
1271
1272
1273
1274template <typename BaseIterator>
1275inline bool
1277{
1278 return (static_cast<const BaseIterator &>(*this) == bi);
1279}
1280
1281
1282
1283template <typename BaseIterator>
1284inline bool
1286{
1287 return (static_cast<const BaseIterator &>(*this) != bi);
1288}
1289
1290
1291
1292template <typename BaseIterator>
1293inline bool
1295{
1296 return (static_cast<const BaseIterator &>(*this) < bi);
1297}
1298
1299
1300template <typename BaseIterator>
1303{
1304 if (this->state() == IteratorState::valid)
1305 do
1306 BaseIterator::operator++();
1307 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1308 return *this;
1309}
1310
1311
1312
1313template <typename BaseIterator>
1316{
1317 const FilteredIterator old_state = *this;
1318
1319 if (this->state() == IteratorState::valid)
1320 do
1321 BaseIterator::operator++();
1322 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1323 return old_state;
1324}
1325
1326
1327
1328template <typename BaseIterator>
1331{
1332 if (this->state() == IteratorState::valid)
1333 do
1334 BaseIterator::operator--();
1335 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1336 return *this;
1337}
1338
1339
1340
1341template <typename BaseIterator>
1344{
1345 const FilteredIterator old_state = *this;
1346
1347 if (this->state() == IteratorState::valid)
1348 do
1349 BaseIterator::operator--();
1350 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1351 return old_state;
1352}
1353
1354
1355
1356template <typename BaseIterator>
1357template <typename Predicate>
1359 Predicate>::PredicateTemplate(const Predicate &predicate)
1360 : predicate(predicate)
1361{}
1362
1363
1364
1365template <typename BaseIterator>
1366template <typename Predicate>
1367bool
1373
1374
1375
1376template <typename BaseIterator>
1377template <typename Predicate>
1378std::unique_ptr<typename FilteredIterator<BaseIterator>::PredicateBase>
1380{
1381 return std::make_unique<PredicateTemplate>(predicate);
1382}
1383
1384
1385
1386namespace IteratorFilters
1387{
1388 // ---------------- IteratorFilters::Active ---------
1389
1390 template <class Iterator>
1391 inline bool
1392 Active::operator()(const Iterator &i) const
1393 {
1394 return i->is_active();
1395 }
1396
1397
1398 // ---------------- IteratorFilters::UserFlagSet ---------
1399
1400 template <class Iterator>
1401 inline bool
1402 UserFlagSet::operator()(const Iterator &i) const
1403 {
1404 return (i->user_flag_set());
1405 }
1406
1407
1408 // ---------------- IteratorFilters::UserFlagNotSet ---------
1409
1410 template <class Iterator>
1411 inline bool
1412 UserFlagNotSet::operator()(const Iterator &i) const
1413 {
1414 return (!i->user_flag_set());
1415 }
1416
1417
1418 // ---------------- IteratorFilters::LevelEqualTo ---------
1419 inline LevelEqualTo::LevelEqualTo(const unsigned int level)
1420 : level(level)
1421 {}
1422
1423
1424
1425 template <class Iterator>
1426 inline bool
1427 LevelEqualTo::operator()(const Iterator &i) const
1428 {
1429 return (static_cast<unsigned int>(i->level()) == level);
1430 }
1431
1432
1433
1434 // ---------------- IteratorFilters::SubdomainEqualTo ---------
1436 const types::subdomain_id subdomain_id)
1437 : subdomain_id(subdomain_id)
1438 {}
1439
1440
1441
1442 template <class Iterator>
1443 inline bool
1444 SubdomainEqualTo::operator()(const Iterator &i) const
1445 {
1446 return (i->subdomain_id() == subdomain_id);
1447 }
1448
1449
1450
1451 // ---------------- IteratorFilters::LocallyOwnedCell ---------
1452
1453 template <class Iterator>
1454 inline bool
1455 LocallyOwnedCell::operator()(const Iterator &i) const
1456 {
1457 return (i->is_locally_owned());
1458 }
1459
1460
1461 // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1462
1463 template <class Iterator>
1464 inline bool
1465 LocallyOwnedLevelCell::operator()(const Iterator &i) const
1466 {
1467 return (i->is_locally_owned_on_level());
1468 }
1469
1470
1471
1472 // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1474 const types::material_id material_id,
1475 const bool only_locally_owned)
1476 : material_ids{material_id}
1477 , only_locally_owned(only_locally_owned)
1478 {}
1479
1480
1481
1483 const std::set<types::material_id> &material_ids,
1484 const bool only_locally_owned)
1485 : material_ids(material_ids)
1486 , only_locally_owned(only_locally_owned)
1487 {}
1488
1489
1490
1491 template <class Iterator>
1492 inline bool
1493 MaterialIdEqualTo::operator()(const Iterator &i) const
1494 {
1495 return only_locally_owned == true ?
1496 (material_ids.find(i->material_id()) != material_ids.end() &&
1497 i->is_locally_owned()) :
1498 material_ids.find(i->material_id()) != material_ids.end();
1499 }
1500
1501
1502
1503 // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1505 const unsigned int active_fe_index,
1506 const bool only_locally_owned)
1507 : active_fe_indices{active_fe_index}
1508 , only_locally_owned(only_locally_owned)
1509 {}
1510
1511
1512
1514 const std::set<unsigned int> &active_fe_indices,
1515 const bool only_locally_owned)
1516 : active_fe_indices(active_fe_indices)
1517 , only_locally_owned(only_locally_owned)
1518 {}
1519
1520
1521
1522 template <class Iterator>
1523 inline bool
1524 ActiveFEIndexEqualTo::operator()(const Iterator &i) const
1525 {
1526 return only_locally_owned == true ?
1527 (i->is_locally_owned() &&
1528 active_fe_indices.find(i->active_fe_index()) !=
1529 active_fe_indices.end()) :
1530 active_fe_indices.find(i->active_fe_index()) !=
1531 active_fe_indices.end();
1532 }
1533
1534
1535
1536 // ---------------- IteratorFilters::AtBoundary ---------
1537
1538 template <class Iterator>
1539 inline bool
1540 AtBoundary::operator()(const Iterator &i) const
1541 {
1542 return (i->at_boundary());
1543 }
1544
1545
1546
1547 // ---------------- IteratorFilters::BoundaryIdEqualTo ---------
1549 const types::boundary_id boundary_id)
1550 : boundary_ids{boundary_id}
1551 {}
1552
1553
1554
1556 const std::set<types::boundary_id> &boundary_ids)
1557 : boundary_ids(boundary_ids)
1558 {}
1559
1560
1561
1562 template <class Iterator>
1563 inline bool
1564 BoundaryIdEqualTo::operator()(const Iterator &i) const
1565 {
1566 return boundary_ids.find(i->boundary_id()) != boundary_ids.end();
1567 }
1568
1569
1570
1571 // ---------------- IteratorFilters::ManifoldIdEqualTo ---------
1573 const types::manifold_id manifold_id)
1574 : manifold_ids{manifold_id}
1575 {}
1576
1577
1578
1580 const std::set<types::manifold_id> &manifold_ids)
1581 : manifold_ids(manifold_ids)
1582 {}
1583
1584
1585
1586 template <class Iterator>
1587 inline bool
1588 ManifoldIdEqualTo::operator()(const Iterator &i) const
1589 {
1590 return manifold_ids.find(i->manifold_id()) != manifold_ids.end();
1591 }
1592} // namespace IteratorFilters
1593
1594
1596
1597#endif
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
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(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
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:498
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:175
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
FilteredIterator< BaseIterator > make_filtered_iterator(const BaseIterator &i, const Predicate &p)
unsigned int level
Definition grid_out.cc:4626
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)
#define DeclException1(Exception1, type1, outsequence)
Definition exceptions.h:511
@ valid
Iterator points to a valid object.
STL namespace.