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
22 # include <deal.II/base/exceptions.h>
23 # include <deal.II/base/iterator_range.h>
24
25 # include <deal.II/grid/tria_iterator_base.h>
26
27 # include <memory>
28 # include <set>
29 # include <tuple>
30
31 DEAL_II_NAMESPACE_OPEN
32
33
34 /**
35 * In this namespace a number of classes is declared that may be used as
36 * filters in the FilteredIterator class. The filters either check for binary
37 * information (for example, the IteratorFilters::Active filter class checks
38 * whether the object pointed to is active), or for valued information by
39 * comparison with prescribed values (for example, the LevelEqualTo filter
40 * class checks whether the level of the object pointed to by the iterator
41 * under consideration is equal to a value that was given to the filter upon
42 * construction.
43 *
44 * For examples of use of these classes as well as requirements on filters see
45 * the general description of the FilteredIterator class.
46 *
47 * @ingroup Iterators
48 */
49 namespace IteratorFilters
50 {
51 /**
52 * Filter that evaluates to true if either the iterator points to an active
53 * object or an iterator past the end.
54 *
55 * @ingroup Iterators
56 */
57 class Active
58 {
59 public:
60 /**
61 * Evaluate the iterator and return true if the object is active or past
62 * the end.
63 */
64 template <class Iterator>
65 bool
66 operator()(const Iterator &i) const;
67 };
68
69 /**
70 * Filter that evaluates to true if either the iterator points to an object
71 * for which the user flag is set or an iterator past the end. See
72 * @ref GlossUserFlags
73 * for information about user flags.
74 *
75 * @ingroup Iterators
76 */
77 class UserFlagSet
78 {
79 public:
80 /**
81 * Evaluate the iterator and return true if the object has a set user flag
82 * or past the end.
83 */
84 template <class Iterator>
85 bool
86 operator()(const Iterator &i) const;
87 };
88
89
90 /**
91 * Filter that evaluates to true if either the iterator points to an object
92 * for which the user flag is not set or an iterator past the end. Inverse
93 * filter to the previous class.
94 *
95 * @ingroup Iterators
96 */
97 class UserFlagNotSet
98 {
99 public:
100 /**
101 * Evaluate the iterator and return true if the object has an unset user
102 * flag or past the end.
103 */
104 template <class Iterator>
105 bool
106 operator()(const Iterator &i) const;
107 };
108
109
110 /**
111 * Filter for iterators that evaluates to true if either the iterator is
112 * past the end or the level of the object pointed to is equal to a value
113 * given to the constructor.
114 *
115 * @ingroup Iterators
116 */
117 class LevelEqualTo
118 {
119 public:
120 /**
121 * Constructor. Store the level which iterators shall have to be evaluated
122 * to true.
123 */
124 LevelEqualTo(const unsigned int level);
125
126 /**
127 * Evaluation operator. Returns true if either the level of the object
128 * pointed to is equal to the stored value or the iterator is past the
129 * end.
130 */
131 template <class Iterator>
132 bool
133 operator()(const Iterator &i) const;
134
135 protected:
136 /**
137 * Stored value to compare the level with.
138 */
139 const unsigned int level;
140 };
141
142
143
144 /**
145 * Filter for iterators that evaluates to true if either the iterator is
146 * past the end or the subdomain id of the object pointed to is equal to a
147 * value given to the constructor, assuming that the iterator allows
148 * querying for a subdomain id.
149 *
150 * @ingroup Iterators
151 */
152 class SubdomainEqualTo
153 {
154 public:
155 /**
156 * Constructor. Store the subdomain which iterators shall have to be
157 * evaluated to true.
158 */
159 SubdomainEqualTo(const types::subdomain_id subdomain_id);
160
161 /**
162 * Evaluation operator. Returns true if either the subdomain of the object
163 * pointed to is equal to the stored value or the iterator is past the
164 * end.
165 */
166 template <class Iterator>
167 bool
168 operator()(const Iterator &i) const;
169
170 protected:
171 /**
172 * Stored value to compare the subdomain with.
173 */
174 const types::subdomain_id subdomain_id;
175 };
176
177
178
179 /**
180 * Filter for iterators that evaluates to true if a cell is owned by the
181 * current processor, i.e., if it is a
182 * @ref GlossLocallyOwnedCell "locally owned cell".
183 *
184 * This class is used in step-32, in connection with the methods of the
185 * @ref distributed
186 * module.
187 *
188 * @ingroup Iterators
189 */
190 class LocallyOwnedCell
191 {
192 public:
193 /**
194 * Evaluation operator. Returns true if the cell is locally owned.
195 */
196 template <class Iterator>
197 bool
198 operator()(const Iterator &i) const;
199 };
200
201
202
203 /**
204 * Filter for iterators that evaluates to true if the level subdomain id of
205 * a cell is equal to the current processor id.
206 *
207 * @ingroup Iterators
208 */
209 class LocallyOwnedLevelCell
210 {
211 public:
212 /**
213 * Evaluation operator. Returns true if the level subdomain id of the cell
214 * is equal to the current processor id.
215 */
216 template <class Iterator>
217 bool
218 operator()(const Iterator &i) const;
219 };
220
221
222 /**
223 * Filter for iterators that evaluates to true if the iterator of the object
224 * pointed to is equal to a value or set of values given to the constructor,
225 * assuming that the iterator allows querying for a material id.
226 *
227 *
228 * @ingroup Iterators
229 */
230 class MaterialIdEqualTo
231 {
232 public:
233 /**
234 * Constructor. Store the material id which iterators shall have to be
235 * evaluated to true and state if the iterator must be locally owned.
236 */
237 MaterialIdEqualTo(const types::material_id material_id,
238 const bool only_locally_owned = false);
239
240 /**
241 * Constructor. Store a collection of material ids which iterators shall
242 * have to be evaluated to true and state if the iterator must be locally
243 * owned.
244 */
245 MaterialIdEqualTo(const std::set<types::material_id> &material_ids,
246 const bool only_locally_owned = false);
247
248 /**
249 * Evaluation operator. Returns true if the material id of the object
250 * pointed to is equal within the stored set of value allowable values
251 * and, if required, if the cell is locally owned.
252 */
253 template <class Iterator>
254 bool
255 operator()(const Iterator &i) const;
256
257 protected:
258 /**
259 * Stored value to compare the material id with.
260 */
261 const std::set<types::material_id> material_ids;
262 /**
263 * Flag stating whether only locally owned cells must return true.
264 */
265 const bool only_locally_owned;
266 };
267
268 /**
269 * Filter for iterators that evaluates to true if the iterator of the object
270 * pointed to is equal to a value or set of values given to the constructor,
271 * assuming that the iterator allows querying for an active FE index.
272 *
273 *
274 * @ingroup Iterators
275 */
276 class ActiveFEIndexEqualTo
277 {
278 public:
279 /**
280 * Constructor. Store the active FE index which iterators shall have to be
281 * evaluated to true and state if the iterator must be locally owned.
282 */
283 ActiveFEIndexEqualTo(const unsigned int active_fe_index,
284 const bool only_locally_owned = false);
285
286 /**
287 * Constructor. Store a collection of active FE indices which iterators
288 * shall have to be evaluated to true and state if the iterator must be
289 * locally owned.
290 */
291 ActiveFEIndexEqualTo(const std::set<unsigned int> &active_fe_indices,
292 const bool only_locally_owned = false);
293
294 /**
295 * Evaluation operator. Returns true if the active FE index of the object
296 * pointed to is equal within the stored set of value allowable values
297 * and, if required, if the cell is locally owned.
298 */
299 template <class Iterator>
300 bool
301 operator()(const Iterator &i) const;
302
303 protected:
304 /**
305 * Stored value to compare the material id with.
306 */
307 const std::set<unsigned int> active_fe_indices;
308 /**
309 * Flag stating whether only locally owned cells must return true.
310 */
311 const bool only_locally_owned;
312 };
313
314 /**
315 * Filter for iterators that evaluates to true if the iterator of the object
316 * pointed to is on the boundary.
317 *
318 *
319 * @ingroup Iterators
320 */
321 class AtBoundary
322 {
323 public:
324 /**
325 * Evaluate the iterator and return true if the object at the boundary.
326 */
327 template <class Iterator>
328 bool
329 operator()(const Iterator &i) const;
330 };
331 } // namespace IteratorFilters
332
333
334 /**
335 * This class provides a certain view on a range of triangulation or
336 * DoFHandler iterators by only iterating over elements that satisfy a given
337 * filter (called a <em>predicate</em>, following the notation of the C++
338 * standard library). Once initialized with a predicate and a value for the
339 * iterator, a filtered iterator hops to the next or previous element that
340 * satisfies the predicate if operators ++ or \-- are invoked. Intermediate
341 * iterator values that lie in between but do not satisfy the predicate are
342 * skipped. It is thus very simple to write loops over a certain class of
343 * objects without the need to explicitly write down the condition they have
344 * to satisfy in each loop iteration. This in particular is helpful if
345 * functions are called with a pair of iterators denoting a range on which
346 * they shall act, by choosing a filtered iterator instead of usual ones.
347 *
348 * This class is used in step-32.
349 *
350 *
351 * <h3>Predicates</h3>
352 *
353 * The object that represent the condition an iterator has to satisfy only
354 * have to provide an interface that allows to call the evaluation operator,
355 * i.e. <code>bool operator() (const BaseIterator&)</code>. This includes
356 * function pointers as well as classes that implement an <code>bool operator
357 * ()(const BaseIterator&)</code>. Then, the FilteredIterator will skip all
358 * objects where the return value of this function is <code>false</code>.
359 *
360 *
361 * An example of a simple valid predicate is the following: given the function
362 * @code
363 * template <typename BIterator>
364 * bool level_equal_to_3 (const BIterator& c)
365 * {
366 * return (static_cast<unsigned int>(c->level()) == 3);
367 * };
368 * @endcode
369 * then
370 * @code
371 * &level_equal_to_3<typename Triangulation<dim>::active_cell_iterator>
372 * @endcode
373 * is a valid predicate.
374 *
375 * Likewise, given the following binary function
376 * @code
377 * template <typename BIterator>
378 * bool level_equal_to (const BIterator& c,
379 * const unsigned int level)
380 * {
381 * return (static_cast<unsigned int>(c->level()) == level);
382 * };
383 * @endcode
384 * then
385 * @code
386 * [](const BIterator& c){ return level_equal_to<active_cell_iterator>(c, 3);}
387 * @endcode
388 * is another valid predicate (here: a function that returns true if either
389 * the iterator is past the end or the level is equal to the second argument;
390 * this second argument is taken considered fixed when creating the lambda
391 * function).
392 *
393 * Finally, classes can be predicates. The following class is one:
394 * @code
395 * class Active
396 * {
397 * public:
398 * template <class Iterator>
399 * bool operator () (const Iterator &i) const
400 * {
401 * return i->is_active();
402 * }
403 * };
404 * @endcode
405 * and objects of this type can be used as predicates. Likewise, this more
406 * complicated one can also be used:
407 * @code
408 * class SubdomainEqualTo
409 * {
410 * public:
411 * SubdomainEqualTo (const types::subdomain_id subdomain_id)
412 * : subdomain_id (subdomain_id)
413 * {};
414 *
415 * template <class Iterator>
416 * bool operator () (const Iterator &i) const
417 * {
418 * return (i->subdomain_id() == subdomain_id);
419 * }
420 *
421 * private:
422 * const types::subdomain_id subdomain_id;
423 * };
424 * @endcode
425 * Objects like <code>SubdomainEqualTo(3)</code> can then be used as
426 * predicates.
427 *
428 * Since whenever a predicate is evaluated it is checked that the iterator
429 * checked is actually valid (i.e. not past the end), no checks for this case
430 * have to be performed inside predicates.
431 *
432 * A number of filter classes are already implemented in the IteratorFilters
433 * namespace, but writing different ones is simple following the examples
434 * above.
435 *
436 *
437 * <h3>Initialization of filtered iterators</h3>
438 *
439 * Filtered iterators are given a predicate at construction time which cannot
440 * be changed any more. This behaviour would be expected if the predicate
441 * would have been given as a template parameter to the class, but since that
442 * would make the declaration of filtered iterators a nightmare, we rather
443 * give the predicate as an unchangeable entity to the constructor. Note that
444 * one can assign a filtered iterator with one predicate to another filtered
445 * iterator with another type; yet, this does <em>not</em> change the
446 * predicate of the assigned-to iterator, only the pointer indicating the
447 * iterator is changed.
448 *
449 * If a filtered iterator is not assigned a value of the underlying
450 * (unfiltered) iterator type, the default value is taken. If, however, a
451 * value is given to the constructor, that value has either to be past the
452 * end, or has to satisfy the predicate. For example, if the predicate only
453 * evaluates to true if the level of an object is equal to three, then
454 * <code>tria.begin_active(3)</code> would be a valid choice while
455 * <code>tria.begin()</code> would not since the latter also returns iterators
456 * to non-active cells which always start at level 0.
457 *
458 * Since one often only has some iterator and wants to set a filtered iterator
459 * to the first one that satisfies a predicate (for example, the first one for
460 * which the user flag is set, or the first one with a given subdomain id),
461 * there are assignment functions #set_to_next_positive and
462 * #set_to_previous_positive that assign the next or last previous iterator
463 * that satisfies the predicate, i.e. they follow the list of iterators in
464 * either direction until they find a matching one (or the past-the-end
465 * iterator). Like the <code>operator=</code> they return the resulting value
466 * of the filtered iterator.
467 *
468 *
469 * <h3>Examples</h3>
470 *
471 * The following call counts the number of active cells that have a set user
472 * flag:
473 * @code
474 * FilteredIterator<typename Triangulation<dim>::active_cell_iterator>
475 * begin (IteratorFilters::UserFlagSet()),
476 * end (IteratorFilters::UserFlagSet());
477 * begin.set_to_next_positive(tria.begin_active());
478 * end = tria.end();
479 * n_flagged_cells = std::distance (begin, end);
480 * @endcode
481 * Note that by the @p set_to_next_positive call the first cell with a set
482 * user flag was assigned to the @p begin iterator. For the end iterator, no
483 * such call was necessary, since the past-the-end iterator always satisfies
484 * all predicates.
485 *
486 * The same can be achieved by the following snippet, though harder to read:
487 * @code
488 * using FI =
489 * FilteredIterator<typename Triangulation<dim>::active_cell_iterator>;
490 * n_flagged_cells =
491 * std::distance (
492 * FI(IteratorFilters::UserFlagSet()).set_to_next_positive(
493 * tria.begin_active()),
494 * FI(IteratorFilters::UserFlagSet(), tria.end()));
495 * @endcode
496 * It relies on the fact that if we create an unnamed filtered iterator with a
497 * given predicate but no iterator value and assign it the next positive value
498 * with respect to this predicate, it returns itself which is then used as the
499 * first parameter to the @p std::distance function. This procedure is not
500 * necessary for the end element to this function here, since the past-the-end
501 * iterator always satisfies the predicate so that we can assign this value to
502 * the filtered iterator directly in the constructor.
503 *
504 * Finally, the following loop only assembles the matrix on cells with
505 * subdomain id equal to three:
506 * @code
507 * FilteredIterator<typename Triangulation<dim>::active_cell_iterator>
508 * cell (IteratorFilters::SubdomainEqualTo(3)),
509 * endc (IteratorFilters::SubdomainEqualTo(3), tria.end());
510 * cell.set_to_next_positive (tria.begin_active());
511 * for (; cell!=endc; ++cell)
512 * assemble_local_matrix (cell);
513 * @endcode
514 *
515 * Since comparison between filtered and unfiltered iterators is defined, we
516 * could as well have let the @p endc variable in the last example be of type
517 * Triangulation::active_cell_iterator since it is unchanged and its value
518 * does not depend on the filter.
519 *
520 * @ingroup grid
521 * @ingroup Iterators
522 */
523 template <typename BaseIterator>
524 class FilteredIterator : public BaseIterator
525 {
526 public:
527 /**
528 * Typedef to the accessor type of the underlying iterator.
529 */
530 using AccessorType = typename BaseIterator::AccessorType;
531
532 /**
533 * Constructor. Set the iterator to the default state and use the given
534 * predicate for filtering subsequent assignment and iteration.
535 */
536 template <typename Predicate>
537 FilteredIterator(Predicate p);
538
539 /**
540 * Constructor. Use the given predicate for filtering and initialize the
541 * iterator with the given value.
542 *
543 * If the initial value @p bi does not satisfy the predicate @p p then it is
544 * advanced until we either hit the past-the-end iterator, or the
545 * predicate is satisfied. This allows, for example, to write code like
546 * @code
547 * FilteredIterator<typename Triangulation<dim>::active_cell_iterator>
548 * cell (IteratorFilters::SubdomainEqualTo(13),
549 * triangulation.begin_active());
550 * @endcode
551 *
552 * If the cell <code>triangulation.begin_active()</code> does not have a
553 * subdomain_id equal to 13, then the iterator will automatically be
554 * advanced to the first cell that has.
555 */
556 template <typename Predicate>
557 FilteredIterator(Predicate p, const BaseIterator &bi);
558
559 /**
560 * Copy constructor. Copy the predicate and iterator value of the given
561 * argument.
562 */
563 FilteredIterator(const FilteredIterator &fi);
564
565 /**
566 * Assignment operator. Copy the iterator value of the argument, but as
567 * discussed in the class documentation, the predicate of the argument is
568 * not copied. The iterator value underlying the argument has to satisfy the
569 * predicate of the object assigned to, as given at its construction time.
570 */
571 FilteredIterator &
572 operator=(const FilteredIterator &fi);
573
574 /**
575 * Assignment operator. Copy the iterator value of the argument, and keep
576 * the predicate of this object. The given iterator value has to satisfy the
577 * predicate of the object assigned to, as given at its construction time.
578 */
579 FilteredIterator &
580 operator=(const BaseIterator &fi);
581
582 /**
583 * Search for the next iterator from @p bi onwards that satisfies the
584 * predicate of this object and assign it to this object.
585 *
586 * Since filtered iterators are automatically converted to the underlying
587 * base iterator type, you can also give a filtered iterator as argument to
588 * this function.
589 */
590 FilteredIterator &
591 set_to_next_positive(const BaseIterator &bi);
592
593 /**
594 * As above, but search for the previous iterator from @p bi backwards that
595 * satisfies the predicate of this object and assign it to this object.
596 *
597 * Since filtered iterators are automatically converted to the underlying
598 * base iterator type, you can also give a filtered iterator as argument to
599 * this function.
600 */
601 FilteredIterator &
602 set_to_previous_positive(const BaseIterator &bi);
603
604 /**
605 * Compare for equality of the underlying iterator values of this and the
606 * given object.
607 *
608 * We do not compare for equality of the predicates.
609 */
610 bool
611 operator==(const FilteredIterator &fi) const;
612
613 /**
614 * Compare for equality of the underlying iterator value of this object with
615 * the given object.
616 *
617 * The predicate of this object is irrelevant for this operation.
618 */
619 bool
620 operator==(const BaseIterator &fi) const;
621
622 /**
623 * Compare for inequality of the underlying iterator values of this and the
624 * given object.
625 *
626 * We do not compare for equality of the predicates.
627 */
628 bool
629 operator!=(const FilteredIterator &fi) const;
630
631 /**
632 * Compare for inequality of the underlying iterator value of this object
633 * with the given object.
634 *
635 * The predicate of this object is irrelevant for this operation.
636 */
637 bool
638 operator!=(const BaseIterator &fi) const;
639
640 /**
641 * Compare for ordering of the underlying iterator values of this and the
642 * given object.
643 *
644 * We do not compare the predicates.
645 */
646 bool
647 operator<(const FilteredIterator &fi) const;
648
649 /**
650 * Compare for ordering of the underlying iterator value of this object with
651 * the given object.
652 *
653 * The predicate of this object is irrelevant for this operation.
654 */
655 bool
656 operator<(const BaseIterator &fi) const;
657
658 /**
659 * Prefix advancement operator: move to the next iterator value satisfying
660 * the predicate and return the new iterator value.
661 */
662 FilteredIterator &
663 operator++();
664
665 /**
666 * Postfix advancement operator: move to the next iterator value satisfying
667 * the predicate and return the old iterator value.
668 */
669 FilteredIterator
670 operator++(int);
671
672 /**
673 * Prefix decrement operator: move to the previous iterator value satisfying
674 * the predicate and return the new iterator value.
675 */
676 FilteredIterator &
677 operator--();
678
679 /**
680 * Postfix advancement operator: move to the previous iterator value
681 * satisfying the predicate and return the old iterator value.
682 */
683 FilteredIterator
684 operator--(int);
685
686 /**
687 * Exception.
688 */
689 DeclException1(
690 ExcInvalidElement,
691 BaseIterator,
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
696 private:
697 /**
698 * Base class to encapsulate a predicate object. Since predicates can be of
699 * different types and we do not want to code these types into the template
700 * parameter list of the filtered iterator class, we use a base class with
701 * an abstract function and templatized derived classes that implement the
702 * use of actual predicate types through the virtual function.
703 *
704 * @ingroup Iterators
705 */
706 class PredicateBase
707 {
708 public:
709 /**
710 * Mark the destructor virtual to allow destruction through pointers to
711 * the base class.
712 */
713 virtual ~PredicateBase() = default;
714
715 /**
716 * Abstract function which in derived classes denotes the evaluation of
717 * the predicate on the given iterator.
718 */
719 virtual bool
720 operator()(const BaseIterator &bi) const = 0;
721
722 /**
723 * Generate a copy of this object, i.e. of the actual type of this
724 * pointer.
725 */
726 virtual std::unique_ptr<PredicateBase>
727 clone() const = 0;
728 };
729
730
731 /**
732 * Actual implementation of the above abstract base class. Use a template
733 * parameter to denote the actual type of the predicate and store a copy of
734 * it. When the virtual function is called evaluate the given iterator with
735 * the stored copy of the predicate.
736 *
737 * @ingroup Iterators
738 */
739 template <typename Predicate>
740 class PredicateTemplate : public PredicateBase
741 {
742 public:
743 /**
744 * Constructor. Take a predicate and store a copy of it.
745 */
746 PredicateTemplate(const Predicate &predicate);
747
748 /**
749 * Evaluate the iterator with the stored copy of the predicate.
750 */
751 virtual bool
752 operator()(const BaseIterator &bi) const override;
753
754 /**
755 * Generate a copy of this object, i.e. of the actual type of this
756 * pointer.
757 */
758 virtual std::unique_ptr<PredicateBase>
759 clone() const override;
760
761 private:
762 /**
763 * Copy of the predicate.
764 */
765 const Predicate predicate;
766 };
767
768 /**
769 * Pointer to an object that encapsulated the actual data type of the
770 * predicate given to the constructor.
771 */
772 std::unique_ptr<const PredicateBase> predicate;
773 };
774
775
776
777 /**
778 * Create an object of type FilteredIterator given the base iterator and
779 * predicate. This function makes the creation of temporary objects (for
780 * example as function arguments) a lot simpler because one does not have to
781 * explicitly specify the type of the base iterator by hand -- it is deduced
782 * automatically here.
783 *
784 * @relatesalso FilteredIterator
785 */
786 template <typename BaseIterator, typename Predicate>
787 FilteredIterator<BaseIterator>
make_filtered_iterator(const BaseIterator & i,const Predicate & p)788 make_filtered_iterator(const BaseIterator &i, const Predicate &p)
789 {
790 FilteredIterator<BaseIterator> fi(p);
791 fi.set_to_next_positive(i);
792 return fi;
793 }
794
795
796
797 namespace 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>
806 struct NestFilteredIterators;
807
808 template <typename BaseIterator, typename Predicate>
809 struct NestFilteredIterators<BaseIterator, std::tuple<Predicate>>
810 {
811 using type = ::dealii::FilteredIterator<BaseIterator>;
812 };
813
814 template <typename BaseIterator, typename Predicate, typename... Targs>
815 struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>
816 {
817 using type = ::dealii::FilteredIterator<
818 typename NestFilteredIterators<BaseIterator,
819 std::tuple<Targs...>>::type>;
820 };
821 } // namespace FilteredIteratorImplementation
822 } // namespace internal
823
824
825
826 /**
827 * Filter the given range of iterators using a Predicate. This allows to
828 * replace:
829 * @code
830 * DoFHandler<dim> dof_handler;
831 * ...
832 * for (const auto &cell : dof_handler.active_cell_iterators())
833 * {
834 * if (cell->is_locally_owned())
835 * {
836 * fe_values.reinit (cell);
837 * ...do the local integration on 'cell'...;
838 * }
839 * }
840 * @endcode
841 * by:
842 * @code
843 * DoFHandler<dim> dof_handler;
844 * ...
845 * const auto filtered_iterators_range =
846 * filter_iterators(dof_handler.active_cell_iterators(),
847 * IteratorFilters::LocallyOwnedCell());
848 * for (const auto &cell : filtered_iterators_range)
849 * {
850 * fe_values.reinit (cell);
851 * ...do the local integration on 'cell'...;
852 * }
853 * @endcode
854 *
855 * @relatesalso FilteredIterator
856 * @ingroup CPP11
857 */
858 template <typename BaseIterator, typename Predicate>
859 IteratorRange<FilteredIterator<BaseIterator>>
860 filter_iterators(IteratorRange<BaseIterator> i, const Predicate &p)
861 {
862 FilteredIterator<BaseIterator> fi(p, *(i.begin()));
863 FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
864
865 return IteratorRange<FilteredIterator<BaseIterator>>(fi, fi_end);
866 }
867
868
869
870 /**
871 * Filter the given range of iterators through an arbitrary number of
872 * Predicates. This allows to replace:
873 * @code
874 * DoFHandler<dim> dof_handler;
875 * ...
876 * for (const auto &cell : dof_handler.active_cell_iterators())
877 * {
878 * if (cell->is_locally_owned())
879 * {
880 * if (cell->at_boundary())
881 * {
882 * fe_values.reinit (cell);
883 * ...do the local integration on 'cell'...;
884 * }
885 * }
886 * }
887 * @endcode
888 * by:
889 * @code
890 * DoFHandler<dim> dof_handler;
891 * ...
892 * const auto filtered_iterators_range =
893 * filter_iterators(dof_handler.active_cell_iterators(),
894 * IteratorFilters::LocallyOwnedCell(),
895 * IteratorFilters::AtBoundary());
896 * for (const auto &cell : filter_iterators_range)
897 * {
898 * fe_values.reinit (cell);
899 * ...do the local integration on 'cell'...;
900 * }
901 * @endcode
902 *
903 * @relatesalso FilteredIterator
904 * @ingroup CPP11
905 */
906 template <typename BaseIterator, typename Predicate, typename... Targs>
907 IteratorRange<
908 typename internal::FilteredIteratorImplementation::
909 NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>::type>
910 filter_iterators(IteratorRange<BaseIterator> i,
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
923 template <typename BaseIterator>
924 template <typename Predicate>
925 inline FilteredIterator<BaseIterator>::FilteredIterator(Predicate p)
926 : predicate(new PredicateTemplate<Predicate>(p))
927 {}
928
929
930
931 template <typename BaseIterator>
932 template <typename Predicate>
933 inline FilteredIterator<BaseIterator>::FilteredIterator(Predicate p,
934 const BaseIterator &bi)
935 : BaseIterator(bi)
936 , predicate(new PredicateTemplate<Predicate>(p))
937 {
938 if ((this->state() == IteratorState::valid) && !(*predicate)(*this))
939 set_to_next_positive(bi);
940 }
941
942
943
944 template <typename BaseIterator>
945 inline FilteredIterator<BaseIterator>::FilteredIterator(
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
957 template <typename BaseIterator>
958 inline FilteredIterator<BaseIterator> &
959 FilteredIterator<BaseIterator>::operator=(const FilteredIterator &fi)
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
972 template <typename BaseIterator>
973 inline FilteredIterator<BaseIterator> &
974 FilteredIterator<BaseIterator>::operator=(const BaseIterator &bi)
975 {
976 Assert((bi.state() != IteratorState::valid) || (*predicate)(bi),
977 ExcInvalidElement(bi));
978 BaseIterator::operator=(bi);
979 return *this;
980 }
981
982
983
984 template <typename BaseIterator>
985 inline FilteredIterator<BaseIterator> &
986 FilteredIterator<BaseIterator>::set_to_next_positive(const BaseIterator &bi)
987 {
988 BaseIterator::operator=(bi);
989 while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
990 BaseIterator::operator++();
991
992 return *this;
993 }
994
995
996
997 template <typename BaseIterator>
998 inline FilteredIterator<BaseIterator> &
999 FilteredIterator<BaseIterator>::set_to_previous_positive(const BaseIterator &bi)
1000 {
1001 BaseIterator::operator=(bi);
1002 while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1003 BaseIterator::operator--();
1004
1005 return *this;
1006 }
1007
1008
1009
1010 template <typename BaseIterator>
1011 inline bool
1012 FilteredIterator<BaseIterator>::operator==(const FilteredIterator &fi) const
1013 {
1014 return (static_cast<const BaseIterator &>(*this) ==
1015 static_cast<const BaseIterator &>(fi));
1016 }
1017
1018
1019
1020 template <typename BaseIterator>
1021 inline bool
1022 FilteredIterator<BaseIterator>::operator!=(const FilteredIterator &fi) const
1023 {
1024 return (static_cast<const BaseIterator &>(*this) !=
1025 static_cast<const BaseIterator &>(fi));
1026 }
1027
1028
1029
1030 template <typename BaseIterator>
1031 inline bool
1032 FilteredIterator<BaseIterator>::operator<(const FilteredIterator &fi) const
1033 {
1034 return (static_cast<const BaseIterator &>(*this) <
1035 static_cast<const BaseIterator &>(fi));
1036 }
1037
1038
1039
1040 template <typename BaseIterator>
1041 inline bool
1042 FilteredIterator<BaseIterator>::operator==(const BaseIterator &bi) const
1043 {
1044 return (static_cast<const BaseIterator &>(*this) == bi);
1045 }
1046
1047
1048
1049 template <typename BaseIterator>
1050 inline bool
1051 FilteredIterator<BaseIterator>::operator!=(const BaseIterator &bi) const
1052 {
1053 return (static_cast<const BaseIterator &>(*this) != bi);
1054 }
1055
1056
1057
1058 template <typename BaseIterator>
1059 inline bool
1060 FilteredIterator<BaseIterator>::operator<(const BaseIterator &bi) const
1061 {
1062 return (static_cast<const BaseIterator &>(*this) < bi);
1063 }
1064
1065
1066 template <typename BaseIterator>
1067 inline FilteredIterator<BaseIterator> &
1068 FilteredIterator<BaseIterator>::operator++()
1069 {
1070 if (this->state() == IteratorState::valid)
1071 do
1072 BaseIterator::operator++();
1073 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1074 return *this;
1075 }
1076
1077
1078
1079 template <typename BaseIterator>
1080 inline FilteredIterator<BaseIterator>
1081 FilteredIterator<BaseIterator>::operator++(int)
1082 {
1083 const FilteredIterator old_state = *this;
1084
1085 if (this->state() == IteratorState::valid)
1086 do
1087 BaseIterator::operator++();
1088 while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1089 return old_state;
1090 }
1091
1092
1093
1094 template <typename BaseIterator>
1095 inline FilteredIterator<BaseIterator> &
1096 FilteredIterator<BaseIterator>::operator--()
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
1107 template <typename BaseIterator>
1108 inline FilteredIterator<BaseIterator>
1109 FilteredIterator<BaseIterator>::operator--(int)
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
1122 template <typename BaseIterator>
1123 template <typename Predicate>
1124 inline FilteredIterator<BaseIterator>::PredicateTemplate<
1125 Predicate>::PredicateTemplate(const Predicate &predicate)
1126 : predicate(predicate)
1127 {}
1128
1129
1130
1131 template <typename BaseIterator>
1132 template <typename Predicate>
1133 bool
1134 FilteredIterator<BaseIterator>::PredicateTemplate<Predicate>::
1135 operator()(const BaseIterator &bi) const
1136 {
1137 return predicate(bi);
1138 }
1139
1140
1141
1142 template <typename BaseIterator>
1143 template <typename Predicate>
1144 std::unique_ptr<typename FilteredIterator<BaseIterator>::PredicateBase>
1145 FilteredIterator<BaseIterator>::PredicateTemplate<Predicate>::clone() const
1146 {
1147 return std::make_unique<PredicateTemplate>(predicate);
1148 }
1149
1150
1151
1152 namespace 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 ---------
1201 inline SubdomainEqualTo::SubdomainEqualTo(
1202 const types::subdomain_id subdomain_id)
1203 : subdomain_id(subdomain_id)
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 ---------
1239 inline MaterialIdEqualTo::MaterialIdEqualTo(
1240 const types::material_id material_id,
1241 const bool only_locally_owned)
1242 : material_ids{material_id}
1243 , only_locally_owned(only_locally_owned)
1244 {}
1245
1246
1247
1248 inline MaterialIdEqualTo::MaterialIdEqualTo(
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 ---------
1270 inline ActiveFEIndexEqualTo::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
1279 inline ActiveFEIndexEqualTo::ActiveFEIndexEqualTo(
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
1313 DEAL_II_NAMESPACE_CLOSE
1314
1315 /*------------------------- filtered_iterator.h ------------------------*/
1316 #endif
1317 /*------------------------- filtered_iterator.h ------------------------*/
1318