deal.II version GIT relicensing-6809-ge913b9bb34 2026-09-25 17:20:01+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: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2002 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_filtered_iterator_h
14#define dealii_filtered_iterator_h
15
16
17#include <deal.II/base/config.h>
18
21#include <deal.II/base/types.h>
22
24
25#include <memory>
26#include <set>
27#include <tuple>
28
29#ifdef DEAL_II_HAVE_CXX20
30# include <concepts>
31#endif
32
33
35
36
53{
60 class Active
61 {
62 public:
67 template <class Iterator>
68 bool
69 operator()(const Iterator &i) const;
70 };
71
81 {
82 public:
87 template <class Iterator>
88 bool
89 operator()(const Iterator &i) const;
90 };
91
92
101 {
102 public:
107 template <class Iterator>
108 bool
109 operator()(const Iterator &i) const;
110 };
111
112
121 {
122 public:
127 LevelEqualTo(const unsigned int level);
128
134 template <class Iterator>
135 bool
136 operator()(const Iterator &i) const;
137
138 protected:
142 const unsigned int level;
143 };
144
145
146
156 {
157 public:
163
169 template <class Iterator>
170 bool
171 operator()(const Iterator &i) const;
172
173 protected:
178 };
179
180
181
194 {
195 public:
199 template <class Iterator>
200 bool
201 operator()(const Iterator &i) const;
202 };
203
204
205
213 {
214 public:
219 template <class Iterator>
220 bool
221 operator()(const Iterator &i) const;
222 };
223
224
234 {
235 public:
240 MaterialIdEqualTo(const types::material_id material_id,
241 const bool only_locally_owned = false);
242
248 MaterialIdEqualTo(const std::set<types::material_id> &material_ids,
249 const bool only_locally_owned = false);
250
256 template <class Iterator>
257 bool
258 operator()(const Iterator &i) const;
259
260 protected:
264 const std::set<types::material_id> material_ids;
269 };
270
279 {
280 public:
285 ActiveFEIndexEqualTo(const unsigned int active_fe_index,
286 const bool only_locally_owned = false);
287
293 ActiveFEIndexEqualTo(const std::set<unsigned int> &active_fe_indices,
294 const bool only_locally_owned = false);
295
301 template <class Iterator>
302 bool
303 operator()(const Iterator &i) const;
304
305 protected:
309 const std::set<unsigned int> active_fe_indices;
314 };
315
324 {
325 public:
329 template <class Iterator>
330 bool
331 operator()(const Iterator &i) const;
332 };
333
334
343 {
344 public:
349 BoundaryIdEqualTo(const types::boundary_id boundary_id);
350
355 BoundaryIdEqualTo(const std::set<types::boundary_id> &boundary_ids);
356
361 template <class Iterator>
362 bool
363 operator()(const Iterator &i) const;
364
365 protected:
369 const std::set<types::boundary_id> boundary_ids;
370 };
371
372
381 {
382 public:
387 ManifoldIdEqualTo(const types::manifold_id manifold_id);
388
393 ManifoldIdEqualTo(const std::set<types::manifold_id> &manifold_ids);
394
399 template <class Iterator>
400 bool
401 operator()(const Iterator &i) const;
402
403 protected:
407 const std::set<types::manifold_id> manifold_ids;
408 };
409} // namespace IteratorFilters
410
411
632template <typename BaseIterator>
634{
635public:
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
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
811private:
822 {
823 public:
828 virtual ~PredicateBase() = default;
829
834 virtual bool
835 operator()(const BaseIterator &bi) const = 0;
836 };
837
838
847 template <typename Predicate>
849 {
850 public:
854 PredicateTemplate(const Predicate &predicate);
855
859 virtual bool
860 operator()(const BaseIterator &bi) const override;
861
862 private:
866 const Predicate predicate;
867 };
868
873 std::shared_ptr<const PredicateBase> predicate;
874};
875
876
877
889template <typename BaseIterator, typename Predicate>
890DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
892 const Predicate &p)
893{
896 return fi;
897}
898
899
900
901namespace internal
902{
903 namespace FilteredIteratorImplementation
904 {
905 // The following classes create a nested sequence of
906 // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
907 // levels of FilteredIterator classes as there are elements in the TypeList
908 // if the latter is given as a std::tuple<Args...>.
909 template <typename BaseIterator, typename TypeList>
911
912 template <typename BaseIterator, typename Predicate>
913 struct NestFilteredIterators<BaseIterator, std::tuple<Predicate>>
914 {
916 };
917
918 template <typename BaseIterator, typename Predicate, typename... Targs>
919 struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>
920 {
923 std::tuple<Targs...>>::type>;
924 };
925 } // namespace FilteredIteratorImplementation
926} // namespace internal
927
928
929
982template <typename BaseIterator, typename Predicate>
983DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
986 const Predicate &p)
987{
988 FilteredIterator<BaseIterator> fi(p, *(i.begin()));
989 FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
990
992}
993
994
995
1053template <typename BaseIterator, typename Predicate, typename... Targs>
1054DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1056 typename internal::FilteredIteratorImplementation::
1057 NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>::
1059 const Predicate &p,
1060 const Targs... args)
1061{
1062 // Recursively create filtered iterators, one predicate at a time
1063 auto fi = filter_iterators(i, p);
1064 return filter_iterators(fi, args...);
1065}
1066
1067
1068
1129template <typename BaseIterator, typename Predicate>
1130DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1133{
1134 return filter_iterators(i, p);
1135}
1136
1137
1138
1139/* ------------------ Inline functions and templates ------------ */
1140
1141
1142template <typename BaseIterator>
1143template <typename Predicate>
1144DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1146 : predicate(std::make_shared<PredicateTemplate<Predicate>>(p))
1147{}
1148
1149
1150
1151template <typename BaseIterator>
1152template <typename Predicate>
1153DEAL_II_CXX20_REQUIRES((std::predicate<Predicate, BaseIterator>))
1155 const BaseIterator &bi)
1156 : BaseIterator(bi)
1157 , predicate(std::make_shared<PredicateTemplate<Predicate>>(p))
1158{
1159 if ((this->state() == IteratorState::valid) && !(*predicate)(*this))
1160 set_to_next_positive(bi);
1161}
1162
1163
1164
1165template <typename BaseIterator>
1167 const FilteredIterator &fi)
1168 : // this construction looks strange, but without going through the
1169 // address of fi, GCC would not cast fi to the base class of type
1170 // BaseIterator but tries to go through constructing a new
1171 // BaseIterator with an Accessor.
1172 BaseIterator(*static_cast<const BaseIterator *>(&fi))
1173 , predicate(fi.predicate)
1174{}
1175
1176
1177
1178template <typename BaseIterator>
1181{
1182 // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
1183 // below, some compiler would not cast fi to the base class of type
1184 // BaseIterator but try to go through constructing a new Accessor from fi
1185 // which fails. Hence, we just use an explicit upcast and call the above-
1186 // mentioned method.
1187 const BaseIterator &bi = fi;
1188 return operator=(bi);
1189}
1190
1191
1192
1193template <typename BaseIterator>
1196{
1197 Assert((bi.state() != IteratorState::valid) || (*predicate)(bi),
1198 ExcInvalidElement(bi));
1199 BaseIterator::operator=(bi);
1200 return *this;
1201}
1202
1203
1204
1205template <typename BaseIterator>
1208{
1209 BaseIterator::operator=(bi);
1210 while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1211 BaseIterator::operator++();
1212
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>
1232inline bool
1234{
1235 return (static_cast<const BaseIterator &>(*this) ==
1236 static_cast<const BaseIterator &>(fi));
1237}
1238
1239
1240
1241template <typename BaseIterator>
1242inline bool
1244{
1245 return (static_cast<const BaseIterator &>(*this) !=
1246 static_cast<const BaseIterator &>(fi));
1247}
1248
1249
1250
1251template <typename BaseIterator>
1252inline bool
1254{
1255 return (static_cast<const BaseIterator &>(*this) <
1256 static_cast<const BaseIterator &>(fi));
1257}
1258
1259
1260
1261template <typename BaseIterator>
1262inline bool
1264{
1265 return (static_cast<const BaseIterator &>(*this) == bi);
1266}
1267
1268
1269
1270template <typename BaseIterator>
1271inline bool
1273{
1274 return (static_cast<const BaseIterator &>(*this) != bi);
1275}
1276
1277
1278
1279template <typename BaseIterator>
1280inline bool
1282{
1283 return (static_cast<const BaseIterator &>(*this) < bi);
1284}
1285
1286
1287template <typename BaseIterator>
1290{
1291 if (this->state() == IteratorState::valid)
1292 do
1293 BaseIterator::operator++();
1294 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1295 return *this;
1296}
1297
1298
1299
1300template <typename BaseIterator>
1303{
1304 const FilteredIterator old_state = *this;
1305
1306 if (this->state() == IteratorState::valid)
1307 do
1308 BaseIterator::operator++();
1309 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1310 return old_state;
1311}
1312
1313
1314
1315template <typename BaseIterator>
1318{
1319 if (this->state() == IteratorState::valid)
1320 do
1321 BaseIterator::operator--();
1322 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1323 return *this;
1324}
1325
1326
1327
1328template <typename BaseIterator>
1331{
1332 const FilteredIterator old_state = *this;
1333
1334 if (this->state() == IteratorState::valid)
1335 do
1336 BaseIterator::operator--();
1337 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1338 return old_state;
1339}
1340
1341
1342
1343template <typename BaseIterator>
1344template <typename Predicate>
1346 Predicate>::PredicateTemplate(const Predicate &predicate)
1347 : predicate(predicate)
1348{}
1349
1350
1351
1352template <typename BaseIterator>
1353template <typename Predicate>
1354bool
1360
1361
1362
1363namespace IteratorFilters
1364{
1365 // ---------------- IteratorFilters::Active ---------
1366
1367 template <class Iterator>
1368 inline bool
1369 Active::operator()(const Iterator &i) const
1370 {
1371 return i->is_active();
1372 }
1373
1374
1375 // ---------------- IteratorFilters::UserFlagSet ---------
1376
1377 template <class Iterator>
1378 inline bool
1379 UserFlagSet::operator()(const Iterator &i) const
1380 {
1381 return (i->user_flag_set());
1382 }
1383
1384
1385 // ---------------- IteratorFilters::UserFlagNotSet ---------
1386
1387 template <class Iterator>
1388 inline bool
1389 UserFlagNotSet::operator()(const Iterator &i) const
1390 {
1391 return (!i->user_flag_set());
1392 }
1393
1394
1395 // ---------------- IteratorFilters::LevelEqualTo ---------
1396 inline LevelEqualTo::LevelEqualTo(const unsigned int level)
1397 : level(level)
1398 {}
1399
1400
1401
1402 template <class Iterator>
1403 inline bool
1404 LevelEqualTo::operator()(const Iterator &i) const
1405 {
1406 return (static_cast<unsigned int>(i->level()) == level);
1407 }
1408
1409
1410
1411 // ---------------- IteratorFilters::SubdomainEqualTo ---------
1413 const types::subdomain_id subdomain_id)
1414 : subdomain_id(subdomain_id)
1415 {}
1416
1417
1418
1419 template <class Iterator>
1420 inline bool
1421 SubdomainEqualTo::operator()(const Iterator &i) const
1422 {
1423 return (i->subdomain_id() == subdomain_id);
1424 }
1425
1426
1427
1428 // ---------------- IteratorFilters::LocallyOwnedCell ---------
1429
1430 template <class Iterator>
1431 inline bool
1432 LocallyOwnedCell::operator()(const Iterator &i) const
1433 {
1434 return (i->is_locally_owned());
1435 }
1436
1437
1438 // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1439
1440 template <class Iterator>
1441 inline bool
1442 LocallyOwnedLevelCell::operator()(const Iterator &i) const
1443 {
1444 return (i->is_locally_owned_on_level());
1445 }
1446
1447
1448
1449 // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1451 const types::material_id material_id,
1452 const bool only_locally_owned)
1453 : material_ids{material_id}
1454 , only_locally_owned(only_locally_owned)
1455 {}
1456
1457
1458
1460 const std::set<types::material_id> &material_ids,
1461 const bool only_locally_owned)
1462 : material_ids(material_ids)
1463 , only_locally_owned(only_locally_owned)
1464 {}
1465
1466
1467
1468 template <class Iterator>
1469 inline bool
1470 MaterialIdEqualTo::operator()(const Iterator &i) const
1471 {
1472 return only_locally_owned == true ?
1473 (material_ids.find(i->material_id()) != material_ids.end() &&
1474 i->is_locally_owned()) :
1475 material_ids.find(i->material_id()) != material_ids.end();
1476 }
1477
1478
1479
1480 // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1482 const unsigned int active_fe_index,
1483 const bool only_locally_owned)
1484 : active_fe_indices{active_fe_index}
1485 , only_locally_owned(only_locally_owned)
1486 {}
1487
1488
1489
1491 const std::set<unsigned int> &active_fe_indices,
1492 const bool only_locally_owned)
1493 : active_fe_indices(active_fe_indices)
1494 , only_locally_owned(only_locally_owned)
1495 {}
1496
1497
1498
1499 template <class Iterator>
1500 inline bool
1501 ActiveFEIndexEqualTo::operator()(const Iterator &i) const
1502 {
1503 return only_locally_owned == true ?
1504 (i->is_locally_owned() &&
1505 active_fe_indices.find(i->active_fe_index()) !=
1506 active_fe_indices.end()) :
1507 active_fe_indices.find(i->active_fe_index()) !=
1508 active_fe_indices.end();
1509 }
1510
1511
1512
1513 // ---------------- IteratorFilters::AtBoundary ---------
1514
1515 template <class Iterator>
1516 inline bool
1517 AtBoundary::operator()(const Iterator &i) const
1518 {
1519 return (i->at_boundary());
1520 }
1521
1522
1523
1524 // ---------------- IteratorFilters::BoundaryIdEqualTo ---------
1526 const types::boundary_id boundary_id)
1527 : boundary_ids{boundary_id}
1528 {}
1529
1530
1531
1533 const std::set<types::boundary_id> &boundary_ids)
1534 : boundary_ids(boundary_ids)
1535 {}
1536
1537
1538
1539 template <class Iterator>
1540 inline bool
1541 BoundaryIdEqualTo::operator()(const Iterator &i) const
1542 {
1543 return boundary_ids.find(i->boundary_id()) != boundary_ids.end();
1544 }
1545
1546
1547
1548 // ---------------- IteratorFilters::ManifoldIdEqualTo ---------
1550 const types::manifold_id manifold_id)
1551 : manifold_ids{manifold_id}
1552 {}
1553
1554
1555
1557 const std::set<types::manifold_id> &manifold_ids)
1558 : manifold_ids(manifold_ids)
1559 {}
1560
1561
1562
1563 template <class Iterator>
1564 inline bool
1565 ManifoldIdEqualTo::operator()(const Iterator &i) const
1566 {
1567 return manifold_ids.find(i->manifold_id()) != manifold_ids.end();
1568 }
1569} // namespace IteratorFilters
1570
1571
1573
1574#endif
virtual ~PredicateBase()=default
virtual bool operator()(const BaseIterator &bi) const =0
virtual bool operator()(const BaseIterator &bi) 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
std::shared_ptr< const PredicateBase > predicate
FilteredIterator & operator=(const FilteredIterator &fi)
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:38
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:249
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
FilteredIterator< BaseIterator > make_filtered_iterator(const BaseIterator &i, const Predicate &p)
unsigned int level
Definition grid_out.cc:4642
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)
@ valid
Iterator points to a valid object.
STL namespace.