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