![]() |
Reference documentation for deal.II version 8.1.0
|
#include <tria_iterator.h>
Public Types | |
typedef Accessor | AccessorType |
Public Member Functions | |
TriaRawIterator () | |
TriaRawIterator (const TriaRawIterator &) | |
TriaRawIterator (const Accessor &a) | |
template<typename OtherAccessor > | |
TriaRawIterator (const OtherAccessor &a) | |
TriaRawIterator (const Triangulation< Accessor::dimension, Accessor::space_dimension > *parent, const int level, const int index, const typename AccessorType::AccessorData *local_data=0) | |
template<typename OtherAccessor > | |
TriaRawIterator (const TriaRawIterator< OtherAccessor > &i) | |
TriaRawIterator (const TriaAccessorBase< Accessor::structure_dimension, Accessor::dimension, Accessor::space_dimension > &tria_accessor, const typename Accessor::AccessorData *local_data) | |
template<typename OtherAccessor > | |
TriaRawIterator (const TriaIterator< OtherAccessor > &i) | |
template<typename OtherAccessor > | |
TriaRawIterator (const TriaActiveIterator< OtherAccessor > &i) | |
TriaRawIterator & | operator= (const TriaRawIterator &) |
bool | operator== (const TriaRawIterator &) const |
bool | operator!= (const TriaRawIterator &) const |
bool | operator< (const TriaRawIterator &) const |
IteratorState::IteratorStates | state () const |
template<class STREAM > | |
void | print (STREAM &out) const |
std::size_t | memory_consumption () const |
template<typename Accessor > | |
TriaRawIterator (const Triangulation< Accessor::dimension, Accessor::space_dimension > *parent, const int level, const int index, const typename Accessor::AccessorData *local_data) | |
Dereferencing | |
const Accessor & | operator* () const |
Accessor & | operator* () |
const Accessor * | operator-> () const |
Accessor * | operator-> () |
const Accessor & | access_any () const |
Advancement of iterators | |
TriaRawIterator & | operator++ () |
TriaRawIterator | operator++ (int) |
TriaRawIterator & | operator-- () |
TriaRawIterator | operator-- (int) |
Exceptions | |
DeclException1 (ExcDereferenceInvalidCell, Accessor,<< "You tried to dereference a cell iterator for which this "<< "is not possible. More information on this iterator: "<< "level="<< arg1.level()<< ", index="<< arg1.index()<< ", state="<< (arg1.state()==IteratorState::valid?"valid":(arg1.state()==IteratorState::past_the_end?"past_the_end":"invalid"))) | |
DeclException1 (ExcDereferenceInvalidObject, Accessor,<< "You tried to dereference an iterator for which this "<< "is not possible. More information on this iterator: "<< "index="<< arg1.index()<< ", state="<< (arg1.state()==IteratorState::valid?"valid":(arg1.state()==IteratorState::past_the_end?"past_the_end":"invalid"))) | |
DeclException0 (ExcAdvanceInvalidObject) | |
DeclException0 (ExcInvalidComparison) | |
Protected Attributes | |
Accessor | accessor |
Friends | |
template<typename SomeAccessor > | |
class | TriaRawIterator |
template<typename SomeAccessor > | |
class | TriaIterator |
template<typename SomeAccessor > | |
class | TriaActiveIterator |
This class implements an iterator, analogous to those of the standard template library (STL). It fulfills the requirements of a bidirectional iterator. See the C++ documentation for further details of iterator specification and usage.
In addition to the STL iterators an iterator of this class provides a ->
operator, i.e. you can write statements like
Iterators are used whenever a loop over all lines, quads, cells etc. is to be performed. These loops can then be coded like this:
Note the usage of ++i
instead of i++
since this does not involve temporaries and copying. It is recommended to use a fixed value end
inside the loop instead of tria.end()
, since the creation and copying of these iterators is rather expensive compared to normal pointers.
The objects pointed to are accessors, derived from TriaAccessorBase. Which kind of accessor is determined by the template argument Accessor. These accessors are not so much data structures as they are a collection of functions providing access to the data stored in Tringulation or DoFHandler objects. Using these accessors, the structure of these classes is hidden from the application program.
TriaRawIterator objects point to lines, cells, etc in the lists whether they are used or not (in the vectors, also dead objects are stored, since deletion in vectors is expensive and we also do not want to destroy the ordering induced by the numbering in the vectors). Therefore not all raw iterators point to valid objects.
The derived class TriaIterator selects the valid cells, that is, cells used somewhere in the triangulation hierarchy.
Iterators are not much slower than operating directly on the data structures, since they perform the loops that you had to handcode yourself anyway. Most iterator and accessor functions are inlined.
The main functionality of iterators, resides in the ++
and –
operators. These move the iterator forward or backward just as if it were a pointer into an array. Here, this operation is not so easy, since it may include skipping some elements and the transition between the triangulation levels. This is completely hidden from the user, though you can still create an iterator pointing to an arbitrary element. Actually, the operation of moving iterators back and forth is not done in the iterator classes, but rather in the accessor classes. Since these are passed as template arguments, you can write your own versions here to add more functionality.
Furthermore, the iterators described here satisfy the requirement of input and bidirectional iterators as stated by the C++ standard and the STL documentation. It is therefore possible to use the functions from the algorithm section of the C++ standard, e.g. count_if (see the documentation for Triangulation for an example) and several others.
The iterator class itself does not have much functionality. It only becomes useful when assigned an Accessor (the second template parameter), which really does the access to data. An Accessor has to fulfil some requirements:
It must have two members named present_level
and present_index
storing the address of the element in the triangulation presently pointed to. These data have to be accessible by all triangulation iterators listed above.
It must have a constructor which takes a Triangulation* and two unsigned integers, denoting the initial level and index, as well as a data object depending on its type.
For the TriaIterator and the TriaActiveIterator class, it must have a member function bool used()
, for the latter a member function bool active()
.
It must have void operators ++
and –
.
typedef AccessorData
which states the data type the accessor expects to get passed as fourth constructor argument. By declaring a local data type, the respective iterator class may type-safely enforce that data type to be one of its own constructor argument types. If an accessor class does not need additional data, this type shall be void
. Then the iterator is able to do what it is supposed to. All of the necessary functions are implemented in the Accessor
base class, but you may write your own version (non-virtual, since we use templates) to add functionality.
The accessors provided by the library are distributed in three groups, determined by whether they access the data of Triangulation, DoFHandler or MGDoFHandler. They are derived from TriaAccessor, DoFAccessor and MGDoFAccessor, respectively. In each group, there is an accessor to cells, which have more functionality.
const
triangulation object, you should be well aware that you might involuntarily alter the data stored in the triangulation.There is a representation of past-the-end-pointers, denoted by special values of the member variables present_level
and present_index:
If present_level>=0
and present_index>=0
, then the object is valid (there is no check whether the triangulation really has that many levels or that many cells on the present level when we investigate the state of an iterator; however, in many places where an iterator is dereferenced we make this check); if present_level==-1
and present_index==-1
, then the iterator points past the end; in all other cases, the iterator is considered invalid. You can check this by calling the state()
function.
An iterator is also invalid, if the pointer pointing to the Triangulation object is invalid or zero.
Finally, an iterator is invalid, if the element pointed to by present_level
and present_index
is not used, i.e. if the used
flag is set to false.
The last two checks are not made in state()
since both cases should only occur upon unitialized construction through memcpy
and the like (the parent triangulation can only be set upon construction). If an iterator is constructed empty through the empty constructor, present_level==-2
and present_index==-2
. Thus, the iterator is invalid anyway, regardless of the state of the triangulation pointer and the state of the element pointed to.
Past-the-end iterators may also be used to compare an iterator with the before-the-start value, when running backwards. There is no distinction between the iterators pointing past the two ends of a vector.
By defining only one value to be past-the-end and making all other values invalid provides a second track of security: if we should have forgotten a check in the library when an iterator is incremented or decremented, we automatically convert the iterator from the allowed state "past-the-end" to the disallowed state "invalid" which increases the chance that somehwen earlier than for past-the-end iterators an exception is raised.
Definition at line 30 of file mg_dof_iterator_selector.h.
typedef Accessor TriaRawIterator< Accessor >::AccessorType |
Declare the type of the Accessor for use in the outside world. This way other functions can use the Accessor's type without knowledge of how the exact implementation actually is.
Definition at line 243 of file tria_iterator.h.
|
inline |
Empty constructor. Such an object is not usable!
Definition at line 39 of file tria_iterator.templates.h.
|
inline |
Copy constructor.
Definition at line 47 of file tria_iterator.templates.h.
|
inlineexplicit |
Construct an iterator from the given accessor; the given accessor needs not be of the same type as the accessor of this class is, but it needs to be convertible.
Through this constructor, it is also possible to construct objects for derived iterators:
Definition at line 1057 of file tria_iterator.h.
|
inlineexplicit |
Constructor. Assumes that the other accessor type is convertible to the current one.
Definition at line 1068 of file tria_iterator.h.
TriaRawIterator< Accessor >::TriaRawIterator | ( | const Triangulation< Accessor::dimension, Accessor::space_dimension > * | parent, |
const int | level, | ||
const int | index, | ||
const typename AccessorType::AccessorData * | local_data = 0 |
||
) |
Proper constructor, initialized with the triangulation, the level and index of the object pointed to. The last parameter is of a type declared by the accessor class.
|
inline |
This is a conversion operator (constructor) which takes another iterator type and copies the data; this conversion works, if there is a conversion path from the OtherAccessor
class to the Accessor
class of this object. One such path would be derived class to base class, which for example may be used to get a Triangulation::raw_cell_iterator from a DoFHandler::raw_cell_iterator, since the DoFAccessor class is derived from the TriaAccessorBase class.
Definition at line 1079 of file tria_iterator.h.
|
inline |
Another conversion operator, where we use the pointers to the Triangulation from a TriaAccessorBase object, while the additional data is used according to the actual type of Accessor.
Definition at line 68 of file tria_iterator.templates.h.
|
inline |
Conversion constructor. Same as above with the difference that it converts from TriaIterator classes (not TriaRawIterator).
Definition at line 1090 of file tria_iterator.h.
|
inline |
Conversion constructor. Same as above with the difference that it converts from TriaActiveIterator classes (not TriaRawIterator).
Definition at line 1101 of file tria_iterator.h.
|
inline |
Dereferencing operator, returns a reference to an accessor. Usage is thus like (*i).index ();
This function has to be specialized explicitly for the different Pointees
, to allow an iterator<1,TriangulationLevel<1>::LinesData>
to point to tria->lines.cells[index]
while for one dimension higher it has to point to tria->quads.cells[index]
.
You must not dereference invalid or past the end iterators.
Definition at line 1111 of file tria_iterator.h.
|
inline |
Dereferencing operator, non-const
version.
Definition at line 1128 of file tria_iterator.h.
|
inline |
Dereferencing operator, returns a reference of the cell pointed to. Usage is thus like i->index ();
There is a const
and a non-const
version.
Definition at line 1155 of file tria_iterator.h.
|
inline |
Dereferencing operator, non-const
version.
Definition at line 1165 of file tria_iterator.h.
|
inline |
In order be able to assign end-iterators for different accessors to each other, we need an access function which returns the accessor regardless of its state.
Definition at line 1145 of file tria_iterator.h.
|
inline |
Assignment operator.
Definition at line 81 of file tria_iterator.templates.h.
|
inline |
Assignment operator. Assignment operator. Assignment operator. Compare for equality.
Definition at line 125 of file tria_iterator.templates.h.
|
inline |
Compare for inequality.
Definition at line 134 of file tria_iterator.templates.h.
|
inline |
Ordering relation for iterators.
This relation attempts a total ordering of cells. For lower dimensional objects on distributed meshes, we only attempt a partial ordering.
The relation is defined as follows:
For objects of Accessor::structure_dimension < Accessor::dimension
, we simply compare the index of such an object. This consitutes an ordering of the elements of same dimension on a mesh on a single process. For a distributed mesh, the result of the ordering relation between faces across processes is not defined, but most likely irrelevant.
For cells, there is a total ordering even in a distributed::parallel::Triangulation. The ordering is lexicographic according to the following hierarchy (in the sense, that the next test is only applied if the previous was inconclusive):
The past-the-end iterator is always ordered last. Two past-the-end iterators rank the same, thus false is returned in that case.
Definition at line 1185 of file tria_iterator.h.
|
inline |
Prefix ++
operator: ++i
. This operator advances the iterator to the next element and returns a reference to *this
.
The next element is next on this level if there are more. If the present element is the last on this level, the first on the next level is accessed. This is only valid for iterators pointing to cells, faces have no level.
Definition at line 1206 of file tria_iterator.h.
|
inline |
Postfix ++
operator: i++
. This operator advances the iterator to the next element, but returns an iterator to the element priviously pointed to. Since this involves a temporary and a copy operation and since an iterator
is quite a large object for a pointer, use the prefix operator ++i
whenever possible, especially in the head of for loops (for (; i!=end; ++i)
) since there you normally never need the returned value.
Definition at line 154 of file tria_iterator.templates.h.
|
inline |
Prefix –
operator: –i
. This operator advances the iterator to the previous element and returns a reference to *this
.
The previous element is previous on this level if index>0
. If the present element is the first on this level, the last on the previous level is accessed. This is only valid for iterators pointing to cells, faces have no level.
Definition at line 1219 of file tria_iterator.h.
|
inline |
Postfix –
operator: i–
. This operator advances the iterator to the previous element, but returns an iterator to the element priviously pointed to. Since this involves a temporary and a copy operation and since an iterator
is quite a large object for a pointer, use the prefix operator –i
whenever possible, especially in the head of for loops (for (; i!=end; –i)
) since there you normally never need the returned value.
Definition at line 166 of file tria_iterator.templates.h.
|
inline |
Return the state of the iterator.
Definition at line 1175 of file tria_iterator.h.
|
inline |
Print the iterator to a stream out
. The format is level.index
.
Definition at line 1233 of file tria_iterator.h.
|
inline |
Determine an estimate for the memory consumption (in bytes) of this object.
Definition at line 1246 of file tria_iterator.h.
TriaRawIterator< Accessor >::DeclException1 | ( | ExcDereferenceInvalidCell | , |
Accessor | , | ||
<< "You tried to dereference a cell iterator for which this "<< "is not possible. More information on this iterator: "<< " | level = "<< arg1.level()<< " , |
||
index | = "<< arg1.index()<< " |
||
) |
Exception for TriaObjects with level, i.e. cells.
TriaRawIterator< Accessor >::DeclException1 | ( | ExcDereferenceInvalidObject | , |
Accessor | , | ||
<< "You tried to dereference an iterator for which this "<< "is not possible. More information on this iterator: "<< " | index = "<< arg1.index()<< " |
||
) |
Exception for lower-dimensional TriaObjects without level, i.e. objects faces are constructed with.
TriaRawIterator< Accessor >::DeclException0 | ( | ExcAdvanceInvalidObject | ) |
Exception
TriaRawIterator< Accessor >::DeclException0 | ( | ExcInvalidComparison | ) |
Exception
Make all other iterator class templates friends of this class. This is necessary for the implementation of conversion constructors.
In fact, we would not need them to be friends if they were for different dimensions, but the compiler dislikes giving a fixed dimension and variable accessor since then it says that would be a artial specialization.
Definition at line 635 of file tria_iterator.h.
|
protected |
Object holding the real data.
Definition at line 619 of file tria_iterator.h.