From 204af7e30b932f1b49cc3b95dfdd266bb773b250 Mon Sep 17 00:00:00 2001 From: bangerth Date: Mon, 5 Mar 2007 23:09:54 +0000 Subject: [PATCH] Move some documentation. Document the new partial specialization of TriaAccessor. git-svn-id: https://svn.dealii.org/trunk@14522 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/deal.II/include/grid/tria_accessor.h | 87 ++++++++----------- .../include/grid/tria_accessor.templates.h | 13 ++- deal.II/doc/doxygen/headers/iterators.h | 76 ++++++++++++++-- 3 files changed, 117 insertions(+), 59 deletions(-) diff --git a/deal.II/deal.II/include/grid/tria_accessor.h b/deal.II/deal.II/include/grid/tria_accessor.h index b45d70fb76..798cb29301 100644 --- a/deal.II/deal.II/include/grid/tria_accessor.h +++ b/deal.II/deal.II/include/grid/tria_accessor.h @@ -19,8 +19,6 @@ #include -//TODO[WB]: since line and face iterators do not have levels, we can save a bit of memory by splitting TriaAccessor into a class for cells and one for everything else, and getting rid of the present_level field for the latter - namespace std { template @@ -124,62 +122,23 @@ namespace TriaAccessorExceptions /** - * Implements the accessor class used by TriaRawIterator and derived - * classes. + * A base class for the accessor classes used by TriaRawIterator and + * derived classes. * - * This class offers only the basic functionality erquired by the + * This class offers only the basic functionality required by the * iterators (stores the necessary data members, offers comparison * operators and the like), but has no functionality to actually * dereference data. This is done in the derived classes. * - *

Internals

- * - * 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, it sets #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 - * distiction between the iterators pointing past the two ends of a - * vector. - * - * 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. + * This template is used for faces and edges, which have no level in + * the triangulation hierarchy associated with them. There exists a + * partial specialization of the current class template where + * structdim (the dimensionality of the object represented, + * for example 1 for a line) equals dim (the dimensionality + * of the space the object lives in, for example 3 if we solve + * three-dimensional problems). * - * Cells are stored based on a hierachical structure of levels, therefore - * the above mentioned structure is useful. Faces however are not organized - * in levels, therefore the #present_level variable is ignored in that - * cases and is set to 0 for all faces. Several Accessor- and Iterator- - * functions check for that value, if the object accessed is not a cell - * but a face in the current triangulation. + * Some internals of this class are discussed in @ref IteratorAccessorInternals . * * @ingroup grid * @ingroup Accessors @@ -335,6 +294,30 @@ class TriaAccessor +/** + * A base class for the accessor classes used by TriaRawIterator and + * derived classes. + * + * This class offers only the basic functionality required by the + * iterators (stores the necessary data members, offers comparison + * operators and the like), but has no functionality to actually + * dereference data. This is done in the derived classes. + * + * This template is a partial specialization of the general template + * used for cells only, i.e. for the case where structdim + * (the dimensionality of the object represented, for example 1 for a + * line) equals dim (the dimensionality of the space the + * object lives in, for example 3 if we solve three-dimensional + * problems). The difference is that cells have a level in the + * triangulation hierarchy associated with them, whereas faces and + * edges do not. + * + * Some internals of this class are discussed in @ref IteratorAccessorInternals . + * + * @ingroup grid + * @ingroup Accessors + * @author Wolfgang Bangerth, 1998 + */ template class TriaAccessor { diff --git a/deal.II/deal.II/include/grid/tria_accessor.templates.h b/deal.II/deal.II/include/grid/tria_accessor.templates.h index 2ce6b5f691..0e03942d1d 100644 --- a/deal.II/deal.II/include/grid/tria_accessor.templates.h +++ b/deal.II/deal.II/include/grid/tria_accessor.templates.h @@ -32,13 +32,22 @@ DEAL_II_NAMESPACE_OPEN template inline TriaAccessor::TriaAccessor (const Triangulation *parent, - const int /*level*/, + const int level, const int index, const AccessorData *) : present_index (index), tria (parent) -{} +{ + + // non-cells have no level, so a 0 + // should have been passed, or a -1 + // for an end-iterator, or -2 for + // an invalid (default constructed) + // iterator + Assert ((level == 0) || (level == -1) || (level == -2), + ExcInternalError()); +} diff --git a/deal.II/doc/doxygen/headers/iterators.h b/deal.II/doc/doxygen/headers/iterators.h index 004392da32..0c0aba4a6d 100644 --- a/deal.II/doc/doxygen/headers/iterators.h +++ b/deal.II/doc/doxygen/headers/iterators.h @@ -191,11 +191,18 @@ objects is the same for all iterators in the following snippet: Iterators are like pointers: they can be incremented and decremented, but they are really rather dumb. Their magic only lies in the fact that they point to -some useful object, in this case the Accessor. Accessing data that -characterizes a cell is always done through the Accessor, i.e. the expression -i-> grants access to all attributes of this Accessor. - -Examples of properties you can query from an iterator are +some useful object, in this case the Accessor. For pointers, they point to an +actual object that stores some data. On the other hand, the deal.II iterators, +when dereferenced, do not return a reference to an actual object, but return +an object that knows how to get at the data that represents cells. In general, this +object doesn't store itself where the vertices of a cell are or what its neighbors +are. However, it knows how to tease this sort of information from out of the +arrays and tables and lists that the Triangulation class sets up to describe a +mesh. + +Accessing data that characterizes a cell is always done through the Accessor, +i.e. the expression i-> grants access to all attributes of +this Accessor. Examples of properties you can query from an iterator are @code cell->vertex(1); line->child(0); @@ -355,6 +362,65 @@ a hexehedron in 3d), there are corresponding types and calls like dimension independent geometric objects line, quad, and hex. These calls, just as the ones above, exist in active and non-active forms. + +@section IteratorAccessorInternals Iterator and accessor internals + +Iterators, being like pointer, act as if they pointed to an actual +object, but in reality all they do is to return an accessor when +dereferenced. The accessor object contains the state, i.e. it knows +which object it represents, by storing for example which Triangulation +it belongs to, and the level and index within this level of a cell. It +is therefore able to access the data that corresponds to the cell (or +face, or edge) it represents + +There is a representation of past-the-end-pointers, denoted by special +values of the member variables #present_level and #present_index in +the TriaAccessor class: 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, it sets #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 +distiction between the iterators pointing past the two ends of a +vector. + +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. + +Cells are stored based on a hierachical structure of levels, therefore +the above mentioned structure is useful. Faces however are not organized +in levels, therefore the #present_level variable is ignored in that +cases and is set to 0 for all faces. Several Accessor- and Iterator- +functions check for that value, if the object accessed is not a cell +but a face in the current triangulation. + + @ingroup grid */ -- 2.39.5