Reference documentation for deal.II version 9.1.0-pre
Classes | Functions
deal.II and the C++11 standard

Classes

class  IteratorRange< Iterator >
 

Functions

template<typename FunctionObjectType >
auto Threads::new_thread (FunctionObjectType function_object) -> Thread< decltype(function_object())>
 
template<typename FunctionObjectType >
auto Threads::new_task (FunctionObjectType function_object) -> Task< decltype(function_object())>
 
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 > > 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)
 

Cell iterator functions returning ranges of iterators

IteratorRange< cell_iterator > DoFHandler< dim, spacedim >::cell_iterators () const
 
IteratorRange< active_cell_iterator > DoFHandler< dim, spacedim >::active_cell_iterators () const
 
IteratorRange< level_cell_iterator > DoFHandler< dim, spacedim >::mg_cell_iterators () const
 
IteratorRange< cell_iterator > DoFHandler< dim, spacedim >::cell_iterators_on_level (const unsigned int level) const
 
IteratorRange< active_cell_iterator > DoFHandler< dim, spacedim >::active_cell_iterators_on_level (const unsigned int level) const
 
IteratorRange< level_cell_iterator > DoFHandler< dim, spacedim >::mg_cell_iterators_on_level (const unsigned int level) const
 

Cell iterator functions returning ranges of iterators

IteratorRange< cell_iterator > Triangulation< dim, spacedim >::cell_iterators () const
 
IteratorRange< active_cell_iterator > Triangulation< dim, spacedim >::active_cell_iterators () const
 
IteratorRange< cell_iterator > Triangulation< dim, spacedim >::cell_iterators_on_level (const unsigned int level) const
 
IteratorRange< active_cell_iterator > Triangulation< dim, spacedim >::active_cell_iterators_on_level (const unsigned int level) const
 

Cell iterator functions returning ranges of iterators

IteratorRange< cell_iterator > hp::DoFHandler< dim, spacedim >::cell_iterators () const
 
IteratorRange< active_cell_iterator > hp::DoFHandler< dim, spacedim >::active_cell_iterators () const
 
IteratorRange< cell_iterator > hp::DoFHandler< dim, spacedim >::cell_iterators_on_level (const unsigned int level) const
 
IteratorRange< active_cell_iterator > hp::DoFHandler< dim, spacedim >::active_cell_iterators_on_level (const unsigned int level) const
 

Detailed Description

Since version 9.0, deal.II requires a compiler that supports at least C++11. As part of this, many places in the internal implementation of deal.II are now using features that were only introduced in C++11. That said, deal.II also has functions and classes that make using it with C++11 features easier.

One example is support for C++11 range-based for loops. deal.II-based codes often have many loops of the kind

Triangulation<dim> triangulation;
...
cell = triangulation.begin_active(),
endc = triangulation.end();
for (; cell!=endc; ++cell)
cell->set_refine_flag();

Using C++11's range-based for loops, you can now write this as follows:

Triangulation<dim> triangulation;
...
for (auto cell : triangulation.active_cell_iterators())
cell->set_refine_flag();

This relies on functions such as Triangulation::active_cell_iterators(), and equivalents in the DoF handler classes, DoFHandler::active_cell_iterators(), hp::DoFHandler::active_cell_iterators(). There are variants of these functions that provide iterator ranges for all cells (not just the active ones) and for cells on individual levels.

Function Documentation

template<typename FunctionObjectType >
auto Threads::new_thread ( FunctionObjectType  function_object) -> Thread<decltype(function_object())>
inline

Overload of the new_thread() function for objects that can be called like a function object without arguments. In particular, this function allows calling Threads::new_thread() with either objects that result from using std::bind, or using lambda functions. For example, this function is called when writing code such as

thread = Threads::new_thread ( [] () {
do_this();
then_do_that();
return 42;
});

Here, we run the sequence of functions do_this() and then_do_that() on a separate thread, by making the lambda function declared here the function to execute on the thread. The lambda function then returns 42 (which is a bit pointless here, but it could of course be some computed number), and this is going to be the returned value you can later retrieve via thread.return_value() once the thread (i.e., the body of the lambda function) has completed.

Note
Every lambda function (or whatever else it is you pass to the new_thread() function here, for example the result of a std::bind() expression) has a return type and consequently returns an object of this type. This type can be inferred using the C++11 decltype statement used in the declaration of this function, and it is then used as the template argument of the Threads::Thread object returned by the current function. In the example above, because the lambda function returns 42 (which in C++ has data type int), the inferred type is int and the task object will have type Task<int>. In other words, it is not necessary to explicitly specify in user code what that return type of the lambda or std::bind expression will be, though it is possible to explicitly do so by (entirely equivalently) writing
thread = Threads::new_thread ( [] () -> int {
do_this();
then_do_that();
return 42;
});
In practice, the lambda functions you will pass to new_thread() will of course typically be more complicated. In particular, they will likely capture variables from the surrounding context and use them within the lambda. See https://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B_.28since_C.2B.2B11.29 for more on how lambda functions work.
If you pass a lambda function as an argument to the current function that captures a variable by reference, or if you use a std::bind that binds a function argument to a reference variable using std::ref() or std::cref(), then obviously you can only do this if the variables you reference or capture have a lifetime that extends at least until the time where the thread finishes.

Definition at line 1284 of file thread_management.h.

template<typename FunctionObjectType >
auto Threads::new_task ( FunctionObjectType  function_object) -> Task<decltype(function_object())>
inline

Overload of the new_task function for objects that can be called like a function object without arguments. In particular, this function allows calling Threads::new_task() with either objects that result from using std::bind, or using lambda functions. For example, this function is called when writing code such as

task = Threads::new_task ( [] () {
do_this();
then_do_that();
return 42;
});

Here, we schedule the call to the sequence of functions do_this() and then_do_that() on a separate task, by making the lambda function declared here the function to execute on the task. The lambda function then returns 42 (which is a bit pointless here, but it could of course be some computed number), and this is going to be the returned value you can later retrieve via task.return_value() once the task (i.e., the body of the lambda function) has completed.

Note
Every lambda function (or whatever else it is you pass to the new_task() function here, for example the result of a std::bind() expression) has a return type and consequently returns an object of this type. This type can be inferred using the C++11 decltype statement used in the declaration of this function, and it is then used as the template argument of the Threads::Task object returned by the current function. In the example above, because the lambda function returns 42 (which in C++ has data type int), the inferred type is int and the task object will have type Task<int>. In other words, it is not necessary to explicitly specify in user code what that return type of the lambda or std::bind expression will be, though it is possible to explicitly do so by (entirely equivalently) writing
task = Threads::new_task ( [] () -> int {
do_this();
then_do_that();
return 42;
});
In practice, the lambda functions you will pass to new_task() will of course typically be more complicated. In particular, they will likely capture variables from the surrounding context and use them within the lambda. See https://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B_.28since_C.2B.2B11.29 for more on how lambda functions work.
If you pass a lambda function as an argument to the current function that captures a variable by reference, or if you use a std::bind that binds a function argument to a reference variable using std::ref() or std::cref(), then obviously you can only do this if the variables you reference or capture have a lifetime that extends at least until the time where the task finishes.

Definition at line 1957 of file thread_management.h.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::cell_iterator > DoFHandler< dim, spacedim >::cell_iterators ( ) const

Return an iterator range that contains all cells (active or not) that make up this DoFHandler. Such a range is useful to initialize range-based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Returns
The half open range [this->begin(), this->end())

Definition at line 1029 of file dof_handler.cc.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::active_cell_iterator > DoFHandler< dim, spacedim >::active_cell_iterators ( ) const

Return an iterator range that contains all active cells that make up this DoFHandler. Such a range is useful to initialize range-based for loops as supported by C++11, see also C++11 standard.

Range-based for loops are useful in that they require much less code than traditional loops (see here for a discussion of how they work). An example is that without range-based for loops, one often writes code such as the following:

DoFHandler<dim> dof_handler;
...
cell = dof_handler.begin_active(),
endc = dof_handler.end();
for (; cell!=endc; ++cell)
{
fe_values.reinit (cell);
...do the local integration on 'cell'...;
}

Using C++11's range-based for loops, this is now entirely equivalent to the following:

DoFHandler<dim> dof_handler;
...
for (const auto &cell : dof_handler.active_cell_iterators())
{
fe_values.reinit (cell);
...do the local integration on 'cell'...;
}
Returns
The half open range [this->begin_active(), this->end())

Definition at line 1038 of file dof_handler.cc.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::level_cell_iterator > DoFHandler< dim, spacedim >::mg_cell_iterators ( ) const

Return an iterator range that contains all cells (active or not) that make up this DoFHandler in their level-cell form. Such a range is useful to initialize range-based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Returns
The half open range [this->begin_mg(), this->end_mg())

Definition at line 1049 of file dof_handler.cc.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::cell_iterator > DoFHandler< dim, spacedim >::cell_iterators_on_level ( const unsigned int  level) const

Return an iterator range that contains all cells (active or not) that make up the given level of this DoFHandler. Such a range is useful to initialize range-based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Parameters
[in]levelA given level in the refinement hierarchy of this triangulation.
Returns
The half open range [this->begin(level), this->end(level))
Precondition
level must be less than this->n_levels().

Definition at line 1059 of file dof_handler.cc.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::active_cell_iterator > DoFHandler< dim, spacedim >::active_cell_iterators_on_level ( const unsigned int  level) const

Return an iterator range that contains all active cells that make up the given level of this DoFHandler. Such a range is useful to initialize range-based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Parameters
[in]levelA given level in the refinement hierarchy of this triangulation.
Returns
The half open range [this->begin_active(level), this->end(level))
Precondition
level must be less than this->n_levels().

Definition at line 1070 of file dof_handler.cc.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::level_cell_iterator > DoFHandler< dim, spacedim >::mg_cell_iterators_on_level ( const unsigned int  level) const

Return an iterator range that contains all cells (active or not) that make up the given level of this DoFHandler in their level-cell form. Such a range is useful to initialize range-based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Parameters
[in]levelA given level in the refinement hierarchy of this triangulation.
Returns
The half open range [this->begin_mg(level), this->end_mg(level))
Precondition
level must be less than this->n_levels().

Definition at line 1082 of file dof_handler.cc.

template<typename BaseIterator , typename Predicate >
IteratorRange< FilteredIterator< BaseIterator > > filter_iterators ( IteratorRange< BaseIterator >  i,
const Predicate &  p 
)

Filter the given range of iterators using a Predicate. This allows to replace:

1 DoFHandler<dim> dof_handler;
2 ...
3 for (const auto &cell : dof_handler.active_cell_iterators())
4  {
5  if (cell->is_locally_owned())
6  {
7  fe_values.reinit (cell);
8  ...do the local integration on 'cell'...;
9  }
10  }

by:

1 DoFHandler<dim> dof_handler;
2 ...
3 const auto filtered_iterators_range =
4  filter_iterators(dof_handler.active_cell_iterators(),
5  IteratorFilters::LocallyOwned());
6 for (const auto &cell : filtered_iterators_range)
7  {
8  fe_values.reinit (cell);
9  ...do the local integration on 'cell'...;
10  }
Author
Bruno Turcksin, 2016

Definition at line 871 of file filtered_iterator.h.

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 
)

Filter the given range of iterators through an arbitrary number of Predicates. This allows to replace:

1 DoFHandler<dim> dof_handler;
2 ...
3 for (const auto &cell : dof_handler.active_cell_iterators())
4  {
5  if (cell->is_locally_owned())
6  {
7  if (cell->at_boundary())
8  {
9  fe_values.reinit (cell);
10  ...do the local integration on 'cell'...;
11  }
12  }
13  }

by:

1 DoFHandler<dim> dof_handler;
2 ...
3 const auto filtered_iterators_range =
4  filter_iterators(dof_handler.active_cell_iterators(),
5  IteratorFilters::LocallyOwnedCell(),
6  IteratorFilters::AtBoundary());
7 for (const auto &cell : filter_iterators_range)
8  {
9  fe_values.reinit (cell);
10  ...do the local integration on 'cell'...;
11  }
Author
Bruno Turcksin, 2016

Definition at line 922 of file filtered_iterator.h.

template<int dim, int spacedim>
IteratorRange< typename Triangulation< dim, spacedim >::cell_iterator > Triangulation< dim, spacedim >::cell_iterators ( ) const

Return an iterator range that contains all cells (active or not) that make up this triangulation. Such a range is useful to initialize range- based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Returns
The half open range [this->begin(), this->end())

Definition at line 12051 of file tria.cc.

template<int dim, int spacedim>
IteratorRange< typename Triangulation< dim, spacedim >::active_cell_iterator > Triangulation< dim, spacedim >::active_cell_iterators ( ) const

Return an iterator range that contains all active cells that make up this triangulation. Such a range is useful to initialize range-based for loops as supported by C++11, see also C++11 standard.

Range-based for loops are useful in that they require much less code than traditional loops (see here for a discussion of how they work). An example is that without range-based for loops, one often writes code such as the following (assuming for a moment that our goal is setting the user flag on every active cell):

Triangulation<dim> triangulation;
...
cell = triangulation.begin_active(),
endc = triangulation.end();
for (; cell!=endc; ++cell)
cell->set_user_flag();

Using C++11's range-based for loops, this is now entirely equivalent to the following:

Triangulation<dim> triangulation;
...
for (const auto &cell : triangulation.active_cell_iterators())
cell->set_user_flag();
Returns
The half open range [this->begin_active(), this->end())

Definition at line 12060 of file tria.cc.

template<int dim, int spacedim>
IteratorRange< typename Triangulation< dim, spacedim >::cell_iterator > Triangulation< dim, spacedim >::cell_iterators_on_level ( const unsigned int  level) const

Return an iterator range that contains all cells (active or not) that make up the given level of this triangulation. Such a range is useful to initialize range-based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Parameters
[in]levelA given level in the refinement hierarchy of this triangulation.
Returns
The half open range [this->begin(level), this->end(level))
Precondition
level must be less than this->n_levels().

Definition at line 12071 of file tria.cc.

template<int dim, int spacedim>
IteratorRange< typename Triangulation< dim, spacedim >::active_cell_iterator > Triangulation< dim, spacedim >::active_cell_iterators_on_level ( const unsigned int  level) const

Return an iterator range that contains all active cells that make up the given level of this triangulation. Such a range is useful to initialize range-based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Parameters
[in]levelA given level in the refinement hierarchy of this triangulation.
Returns
The half open range [this->begin_active(level), this->end(level))
Precondition
level must be less than this->n_levels().

Definition at line 12082 of file tria.cc.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::cell_iterator > DoFHandler< dim, spacedim >::cell_iterators ( ) const

Return an iterator range that contains all cells (active or not) that make up this DoFHandler. Such a range is useful to initialize range- based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Returns
The half open range [this->begin(), this->end())

Definition at line 1110 of file dof_handler.cc.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::active_cell_iterator > DoFHandler< dim, spacedim >::active_cell_iterators ( ) const

Return an iterator range that contains all active cells that make up this DoFHandler. Such a range is useful to initialize range-based for loops as supported by C++11, see also C++11 standard.

Range-based for loops are useful in that they require much less code than traditional loops (see here for a discussion of how they work). An example is that without range-based for loops, one often writes code such as the following:

DoFHandler<dim> dof_handler;
...
cell = dof_handler.begin_active(),
endc = dof_handler.end();
for (; cell!=endc; ++cell)
{
fe_values.reinit (cell);
...do the local integration on 'cell'...;
}

Using C++11's range-based for loops, this is now entirely equivalent to the following:

DoFHandler<dim> dof_handler;
...
for (const auto &cell : dof_handler.active_cell_iterators())
{
fe_values.reinit (cell);
...do the local integration on 'cell'...;
}
Returns
The half open range [this->begin_active(), this->end())

Definition at line 1119 of file dof_handler.cc.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::cell_iterator > DoFHandler< dim, spacedim >::cell_iterators_on_level ( const unsigned int  level) const

Return an iterator range that contains all cells (active or not) that make up the given level of this DoFHandler. Such a range is useful to initialize range-based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Parameters
[in]levelA given level in the refinement hierarchy of this triangulation.
Returns
The half open range [this->begin(level), this->end(level))
Precondition
level must be less than this->n_levels().

Definition at line 1130 of file dof_handler.cc.

template<int dim, int spacedim>
IteratorRange< typename DoFHandler< dim, spacedim >::active_cell_iterator > DoFHandler< dim, spacedim >::active_cell_iterators_on_level ( const unsigned int  level) const

Return an iterator range that contains all active cells that make up the given level of this DoFHandler. Such a range is useful to initialize range-based for loops as supported by C++11. See the example in the documentation of active_cell_iterators().

Parameters
[in]levelA given level in the refinement hierarchy of this triangulation.
Returns
The half open range [this->begin_active(level), this->end(level))
Precondition
level must be less than this->n_levels().

Definition at line 1141 of file dof_handler.cc.

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

Filter the given range of iterators using a Predicate. This allows to replace:

DoFHandler<dim> dof_handler;
...
for (const auto &cell : dof_handler.active_cell_iterators())
{
if (cell->is_locally_owned())
{
fe_values.reinit (cell);
...do the local integration on 'cell'...;
}
}

by:

DoFHandler<dim> dof_handler;
...
const auto filtered_iterators_range =
IteratorFilters::LocallyOwned());
for (const auto &cell : filtered_iterators_range)
{
fe_values.reinit (cell);
...do the local integration on 'cell'...;
}
Author
Bruno Turcksin, 2016

Definition at line 871 of file filtered_iterator.h.

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 
)
related

Filter the given range of iterators through an arbitrary number of Predicates. This allows to replace:

DoFHandler<dim> dof_handler;
...
for (const auto &cell : dof_handler.active_cell_iterators())
{
if (cell->is_locally_owned())
{
if (cell->at_boundary())
{
fe_values.reinit (cell);
...do the local integration on 'cell'...;
}
}
}

by:

DoFHandler<dim> dof_handler;
...
const auto filtered_iterators_range =
for (const auto &cell : filter_iterators_range)
{
fe_values.reinit (cell);
...do the local integration on 'cell'...;
}
Author
Bruno Turcksin, 2016

Definition at line 922 of file filtered_iterator.h.