deal.II version GIT relicensing-2206-gaa53ff9447 2024-12-02 09:10:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Private Attributes | Related Symbols | List of all members
FilteredIterator< BaseIterator > Class Template Reference

#include <deal.II/grid/filtered_iterator.h>

Inheritance diagram for FilteredIterator< BaseIterator >:
Inheritance graph
[legend]

Classes

class  PredicateBase
 
class  PredicateTemplate
 

Public Types

using AccessorType = typename BaseIterator::AccessorType
 

Public Member Functions

template<typename Predicate >
 FilteredIterator (Predicate p)
 
template<typename Predicate >
 FilteredIterator (Predicate p, const BaseIterator &bi)
 
 FilteredIterator (const FilteredIterator &fi)
 
FilteredIteratoroperator= (const FilteredIterator &fi)
 
FilteredIteratoroperator= (const BaseIterator &fi)
 
FilteredIteratorset_to_next_positive (const BaseIterator &bi)
 
FilteredIteratorset_to_previous_positive (const BaseIterator &bi)
 
bool operator== (const FilteredIterator &fi) const
 
bool operator== (const BaseIterator &fi) const
 
bool operator!= (const FilteredIterator &fi) const
 
bool operator!= (const BaseIterator &fi) const
 
bool operator< (const FilteredIterator &fi) const
 
bool operator< (const BaseIterator &fi) const
 
FilteredIteratoroperator++ ()
 
FilteredIterator operator++ (int)
 
FilteredIteratoroperator-- ()
 
FilteredIterator operator-- (int)
 

Static Public Member Functions

static ::ExceptionBaseExcInvalidElement (BaseIterator arg1)
 

Private Attributes

std::unique_ptr< const PredicateBasepredicate
 

Related Symbols

(Note that these are not member symbols.)

template<typename BaseIterator , typename Predicate >
FilteredIterator< BaseIteratormake_filtered_iterator (const BaseIterator &i, const Predicate &p)
 
template<typename BaseIterator , typename Predicate >
IteratorRange< FilteredIterator< BaseIterator > > filter_iterators (IteratorRange< BaseIterator > i, const Predicate &p)
 
template<typename BaseIterator , typename Predicate , typename... Targs>
IteratorRange< typename internal::FilteredIteratorImplementation::NestFilteredIterators< BaseIterator, std::tuple< Predicate, Targs... > >::type > filter_iterators (IteratorRange< BaseIterator > i, const Predicate &p, const Targs... args)
 
template<typename BaseIterator , typename Predicate >
IteratorRange< FilteredIterator< BaseIterator > > operator| (IteratorRange< BaseIterator > i, const Predicate &p)
 

Detailed Description

template<typename BaseIterator>
class FilteredIterator< BaseIterator >

This class provides a certain view on a range of triangulation or DoFHandler iterators by only iterating over elements that satisfy a given filter (called a predicate, following the notation of the C++ standard library). Once initialized with a predicate and a value for the iterator, a filtered iterator advances to the next or previous element that satisfies the predicate if operators ++ or -- are invoked. Intermediate iterator values that lie in between but do not satisfy the predicate are skipped. It is thus very simple to write loops over a certain class of objects without the need to explicitly write down the condition they have to satisfy in each loop iteration. This in particular is helpful if functions are called with a pair of iterators denoting a range on which they shall act, by choosing a filtered iterator instead of usual ones. The use of this class is particularly useful when writing "ranged-based" for loops of the form

for (const auto &cell : <some FilteredIterator object>)
{ ... }

An example is to write

DoFHandler<dim> dof_handler;
...
for (const auto &cell :
dof_handler.active_cell_iterators()
| IteratorFilters::LocallyOwnedCell()
| IteratorFilters::AtBoundary())
{
fe_values.reinit (cell);
...do the local integration on 'cell'...;
}
void reinit(const Triangulation< dim, spacedim > &tria)

where the resulting loop iterates over all active cells that are also locally owned and that point to cells that are at the boundary of the domain.

This class implements functionality comparable to what was added to C++20 in the form of range adaptors and the filters and filter views that represent them.

This class is used in step-32.

Predicates

The object that represent the condition an iterator has to satisfy only has to provide an interface that allows to call the evaluation operator, i.e. bool operator() (const BaseIterator&). This includes function pointers as well as classes that implement an bool operator ()(const BaseIterator&). Then, the FilteredIterator will skip all objects where the return value of this function is false.

An example of a simple valid predicate is the following: given the function

template <typename BIterator>
bool level_equal_to_3 (const BIterator& c)
{
return (static_cast<unsigned int>(c->level()) == 3);
};

then

&level_equal_to_3<typename Triangulation<dim>::active_cell_iterator>

is a valid predicate.

Likewise, given the following binary function

template <typename BIterator>
bool level_equal_to (const BIterator& c,
const unsigned int level)
{
return (static_cast<unsigned int>(c->level()) == level);
};
unsigned int level
Definition grid_out.cc:4626

then the lambda function

[](const BIterator& c) { return level_equal_to<active_cell_iterator>(c,
3);}

is another valid predicate (here: a function that returns true if either the iterator is past the end or the level is equal to the second argument; this second argument is taken considered fixed when creating the lambda function).

Finally, classes can be predicates. The following class is one:

class Active
{
public:
template <class Iterator>
bool operator () (const Iterator &i) const
{
return i->is_active();
}
};

and objects of this type can be used as predicates. Likewise, this more complicated one can also be used:

class SubdomainEqualTo
{
public:
SubdomainEqualTo (const types::subdomain_id subdomain_id)
: subdomain_id (subdomain_id)
{};
template <class Iterator>
bool operator () (const Iterator &i) const
{
return (i->subdomain_id() == subdomain_id);
}
private:
};
unsigned int subdomain_id
Definition types.h:43

Objects like SubdomainEqualTo(3) can then be used as predicates.

Since whenever a predicate is evaluated it is checked that the iterator checked is actually valid (i.e. not past the end), no checks for this case have to be performed inside predicates.

A number of filter classes are already implemented in the IteratorFilters namespace, but writing different ones is simple following the examples above.

Initialization of filtered iterators

Filtered iterators are given a predicate at construction time which cannot be changed any more. This behavior would be expected if the predicate would have been given as a template parameter to the class, but since that would make the declaration of filtered iterators a nightmare, we rather give the predicate as an unchangeable entity to the constructor. Note that one can assign a filtered iterator with one predicate to another filtered iterator with another type; yet, this does not change the predicate of the assigned-to iterator, only the pointer indicating the iterator is changed.

If a filtered iterator is not assigned a value of the underlying (unfiltered) iterator type, the default value is taken. If, however, a value is given to the constructor, that value has either to be past the end, or has to satisfy the predicate. For example, if the predicate only evaluates to true if the level of an object is equal to three, then tria.begin_active(3) would be a valid choice while tria.begin() would not since the latter also returns iterators to non-active cells which always start at level 0.

Since one often only has some iterator and wants to set a filtered iterator to the first one that satisfies a predicate (for example, the first one for which the user flag is set, or the first one with a given subdomain id), there are assignment functions set_to_next_positive and set_to_previous_positive that assign the next or last previous iterator that satisfies the predicate, i.e. they follow the list of iterators in either direction until they find a matching one (or the past-the-end iterator). Like the operator= they return the resulting value of the filtered iterator.

Examples

The following call counts the number of active cells that have a set user flag:

begin.set_to_next_positive(tria.begin_active());
end = tria.end();
n_flagged_cells = std::distance (begin, end);

Note that by the set_to_next_positive call the first cell with a set user flag was assigned to the begin iterator. For the end iterator, no such call was necessary, since the past-the-end iterator always satisfies all predicates.

The same can be achieved by the following snippet, though harder to read:

using FI =
n_flagged_cells =
std::distance (
tria.begin_active()),
FI(IteratorFilters::UserFlagSet(), tria.end()));
FilteredIterator & set_to_next_positive(const BaseIterator &bi)

It relies on the fact that if we create an unnamed filtered iterator with a given predicate but no iterator value and assign it the next positive value with respect to this predicate, it returns itself which is then used as the first parameter to the std::distance function. This procedure is not necessary for the end element to this function here, since the past-the-end iterator always satisfies the predicate so that we can assign this value to the filtered iterator directly in the constructor.

Finally, the following loop only assembles the matrix on cells with subdomain id equal to three:

endc (IteratorFilters::SubdomainEqualTo(3), tria.end());
cell.set_to_next_positive (tria.begin_active());
for (; cell!=endc; ++cell)
assemble_local_matrix (cell);

Since comparison between filtered and unfiltered iterators is defined, we could as well have let the endc variable in the last example be of type Triangulation::active_cell_iterator since it is unchanged and its value does not depend on the filter.

Definition at line 632 of file filtered_iterator.h.

Member Typedef Documentation

◆ AccessorType

template<typename BaseIterator >
using FilteredIterator< BaseIterator >::AccessorType = typename BaseIterator::AccessorType

Typedef to the accessor type of the underlying iterator.

Definition at line 638 of file filtered_iterator.h.

Constructor & Destructor Documentation

◆ FilteredIterator() [1/3]

template<typename BaseIterator >
template<typename Predicate >
FilteredIterator< BaseIterator >::FilteredIterator ( Predicate  p)
inline

Constructor. Set the iterator to the default state and use the given predicate for filtering subsequent assignment and iteration.

Note
This class, function, or variable is a template, and it can only be instantiated if the following condition is true:
(std::predicate<Predicate, BaseIterator>)
If your compiler supports the C++20 standard, then this constraint will be enforced by a C++20 requires clause.

Definition at line 1158 of file filtered_iterator.h.

◆ FilteredIterator() [2/3]

template<typename BaseIterator >
template<typename Predicate >
FilteredIterator< BaseIterator >::FilteredIterator ( Predicate  p,
const BaseIterator bi 
)
inline

Constructor. Use the given predicate for filtering and initialize the iterator with the given value.

If the initial value bi does not satisfy the predicate p then it is advanced until we either hit the past-the-end iterator, or the predicate is satisfied. This allows, for example, to write code like

triangulation.begin_active());
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation

If the cell triangulation.begin_active() does not have a subdomain_id equal to 13, then the iterator will automatically be advanced to the first cell that has.

Note
This class, function, or variable is a template, and it can only be instantiated if the following condition is true:
(std::predicate<Predicate, BaseIterator>)
If your compiler supports the C++20 standard, then this constraint will be enforced by a C++20 requires clause.

Definition at line 1167 of file filtered_iterator.h.

◆ FilteredIterator() [3/3]

Copy constructor. Copy the predicate and iterator value of the given argument.

Definition at line 1179 of file filtered_iterator.h.

Member Function Documentation

◆ operator=() [1/2]

template<typename BaseIterator >
FilteredIterator< BaseIterator > & FilteredIterator< BaseIterator >::operator= ( const FilteredIterator< BaseIterator > &  fi)
inline

Assignment operator. Copy the iterator value of the argument, but as discussed in the class documentation, the predicate of the argument is not copied. The iterator value underlying the argument has to satisfy the predicate of the object assigned to, as given at its construction time.

Definition at line 1193 of file filtered_iterator.h.

◆ operator=() [2/2]

template<typename BaseIterator >
FilteredIterator< BaseIterator > & FilteredIterator< BaseIterator >::operator= ( const BaseIterator fi)
inline

Assignment operator. Copy the iterator value of the argument, and keep the predicate of this object. The given iterator value has to satisfy the predicate of the object assigned to, as given at its construction time.

Definition at line 1208 of file filtered_iterator.h.

◆ set_to_next_positive()

template<typename BaseIterator >
FilteredIterator< BaseIterator > & FilteredIterator< BaseIterator >::set_to_next_positive ( const BaseIterator bi)
inline

Search for the next iterator from bi onwards that satisfies the predicate of this object and assign it to this object.

Since filtered iterators are automatically converted to the underlying base iterator type, you can also give a filtered iterator as argument to this function.

Definition at line 1220 of file filtered_iterator.h.

◆ set_to_previous_positive()

template<typename BaseIterator >
FilteredIterator< BaseIterator > & FilteredIterator< BaseIterator >::set_to_previous_positive ( const BaseIterator bi)
inline

As above, but search for the previous iterator from bi backwards that satisfies the predicate of this object and assign it to this object.

Since filtered iterators are automatically converted to the underlying base iterator type, you can also give a filtered iterator as argument to this function.

Definition at line 1233 of file filtered_iterator.h.

◆ operator==() [1/2]

template<typename BaseIterator >
bool FilteredIterator< BaseIterator >::operator== ( const FilteredIterator< BaseIterator > &  fi) const
inline

Compare for equality of the underlying iterator values of this and the given object.

We do not compare for equality of the predicates.

Definition at line 1246 of file filtered_iterator.h.

◆ operator==() [2/2]

template<typename BaseIterator >
bool FilteredIterator< BaseIterator >::operator== ( const BaseIterator fi) const
inline

Compare for equality of the underlying iterator value of this object with the given object.

The predicate of this object is irrelevant for this operation.

Definition at line 1276 of file filtered_iterator.h.

◆ operator!=() [1/2]

template<typename BaseIterator >
bool FilteredIterator< BaseIterator >::operator!= ( const FilteredIterator< BaseIterator > &  fi) const
inline

Compare for inequality of the underlying iterator values of this and the given object.

We do not compare for equality of the predicates.

Definition at line 1256 of file filtered_iterator.h.

◆ operator!=() [2/2]

template<typename BaseIterator >
bool FilteredIterator< BaseIterator >::operator!= ( const BaseIterator fi) const
inline

Compare for inequality of the underlying iterator value of this object with the given object.

The predicate of this object is irrelevant for this operation.

Definition at line 1285 of file filtered_iterator.h.

◆ operator<() [1/2]

template<typename BaseIterator >
bool FilteredIterator< BaseIterator >::operator< ( const FilteredIterator< BaseIterator > &  fi) const
inline

Compare for ordering of the underlying iterator values of this and the given object.

We do not compare the predicates.

Definition at line 1265 of file filtered_iterator.h.

◆ operator<() [2/2]

template<typename BaseIterator >
bool FilteredIterator< BaseIterator >::operator< ( const BaseIterator fi) const
inline

Compare for ordering of the underlying iterator value of this object with the given object.

The predicate of this object is irrelevant for this operation.

Definition at line 1293 of file filtered_iterator.h.

◆ operator++() [1/2]

template<typename BaseIterator >
FilteredIterator< BaseIterator > & FilteredIterator< BaseIterator >::operator++ ( )
inline

Prefix advancement operator: move to the next iterator value satisfying the predicate and return the new iterator value.

Definition at line 1302 of file filtered_iterator.h.

◆ operator++() [2/2]

template<typename BaseIterator >
FilteredIterator< BaseIterator > FilteredIterator< BaseIterator >::operator++ ( int  )
inline

Postfix advancement operator: move to the next iterator value satisfying the predicate and return the old iterator value.

Definition at line 1315 of file filtered_iterator.h.

◆ operator--() [1/2]

template<typename BaseIterator >
FilteredIterator< BaseIterator > & FilteredIterator< BaseIterator >::operator-- ( )
inline

Prefix decrement operator: move to the previous iterator value satisfying the predicate and return the new iterator value.

Definition at line 1330 of file filtered_iterator.h.

◆ operator--() [2/2]

template<typename BaseIterator >
FilteredIterator< BaseIterator > FilteredIterator< BaseIterator >::operator-- ( int  )
inline

Postfix advancement operator: move to the previous iterator value satisfying the predicate and return the old iterator value.

Definition at line 1343 of file filtered_iterator.h.

Friends And Related Symbol Documentation

◆ make_filtered_iterator()

template<typename BaseIterator , typename Predicate >
FilteredIterator< BaseIterator > make_filtered_iterator ( const BaseIterator i,
const Predicate &  p 
)
related

Create an object of type FilteredIterator given the base iterator and predicate. This function makes the creation of temporary objects (for example as function arguments) a lot simpler because one does not have to explicitly specify the type of the base iterator by hand – it is deduced automatically here.

Note
This class, function, or variable is a template, and it can only be instantiated if the following condition is true:
(std::predicate<Predicate, BaseIterator>)
If your compiler supports the C++20 standard, then this constraint will be enforced by a C++20 requires clause.

Definition at line 904 of file filtered_iterator.h.

Member Data Documentation

◆ predicate

template<typename BaseIterator >
std::unique_ptr<const PredicateBase> FilteredIterator< BaseIterator >::predicate
private

Pointer to an object that encapsulated the actual data type of the predicate given to the constructor.

Definition at line 886 of file filtered_iterator.h.


The documentation for this class was generated from the following file: