From: hartmann Date: Tue, 13 Jun 2006 12:15:41 +0000 (+0000) Subject: Merge branch_faces_without_level to main branch. X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91f512b54565d86ec2b1a24cc99d3aaf19f80713;p=dealii-svn.git Merge branch_faces_without_level to main branch. git-svn-id: https://svn.dealii.org/trunk@13221 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/deal.II/include/dofs/dof_accessor.templates.h b/deal.II/deal.II/include/dofs/dof_accessor.templates.h index 6086d32c87..8cea838d5e 100644 --- a/deal.II/deal.II/include/dofs/dof_accessor.templates.h +++ b/deal.II/deal.II/include/dofs/dof_accessor.templates.h @@ -129,8 +129,14 @@ DoFAccessor::child (const unsigned int i) const Assert (static_cast(this->present_level) < this->dof_handler->levels.size(), ExcMessage ("DoFHandler not initialized")); + int next_level; + if (DH::dimension==structdim) + next_level = this->present_level+1; + else + next_level = 0; + TriaIterator > q (this->tria, - this->present_level+1, + next_level, this->child_index (i), this->dof_handler); @@ -183,18 +189,12 @@ unsigned int DoFAccessor::dof_index (const unsigned int i, const unsigned int fe_index) const { - // access the respective DoF. the - // last argument disambiguates - // between the functions of same - // name in the DoFLevel hierarchy, - // to make sure we get at lines, - // quads, or hexes - return this->dof_handler->levels[this->present_level] - ->get_dof_index (*this->dof_handler, - this->present_index, - fe_index, - i, - internal::StructuralDimension()); + // access the respective DoF + return this->dof_handler + ->template get_dof_index (this->present_level, + this->present_index, + fe_index, + i); } @@ -206,19 +206,13 @@ DoFAccessor::set_dof_index (const unsigned int i, const unsigned int index, const unsigned int fe_index) const { - // access the respective DoF. the - // last argument disambiguates - // between the functions of same - // name in the DoFLevel hierarchy, - // to make sure we get at lines, - // quads, or hexes - this->dof_handler->levels[this->present_level] - ->set_dof_index (*this->dof_handler, - this->present_index, - fe_index, - i, - index, - internal::StructuralDimension()); + // access the respective DoF + this->dof_handler + ->template set_dof_index (this->present_level, + this->present_index, + fe_index, + i, + index); } @@ -228,16 +222,10 @@ inline unsigned int DoFAccessor::n_active_fe_indices () const { - // access the respective DoF. the - // last argument disambiguates - // between the functions of same - // name in the DoFLevel hierarchy, - // to make sure we get at lines, - // quads, or hexes - return this->dof_handler->levels[this->present_level] - ->template n_active_fe_indices (*this->dof_handler, - this->present_index, - internal::StructuralDimension()); + // access the respective DoF + return this->dof_handler + ->template n_active_fe_indices (this->present_level, + this->present_index); } @@ -247,17 +235,11 @@ inline bool DoFAccessor::fe_index_is_active (const unsigned int fe_index) const { - // access the respective DoF. the - // last argument disambiguates - // between the functions of same - // name in the DoFLevel hierarchy, - // to make sure we get at lines, - // quads, or hexes - return this->dof_handler->levels[this->present_level] - ->template fe_index_is_active (*this->dof_handler, - this->present_index, - fe_index, - internal::StructuralDimension()); + // access the respective DoF + return this->dof_handler + ->template fe_index_is_active (this->present_level, + this->present_index, + fe_index); } @@ -347,7 +329,7 @@ DoFObjectAccessor<2,DH>::line (const unsigned int i) const return TriaIterator > ( this->tria, - this->present_level, + 0, this->line_index (i), this->dof_handler ); @@ -426,7 +408,7 @@ DoFObjectAccessor<3,DH>::line (const unsigned int i) const return TriaIterator > ( this->tria, - this->present_level, + 0, l->index(), this->dof_handler ); @@ -443,7 +425,7 @@ DoFObjectAccessor<3,DH>::quad (const unsigned int i) const return TriaIterator > ( this->tria, - this->present_level, + 0, this->quad_index (i), this->dof_handler ); diff --git a/deal.II/deal.II/include/dofs/dof_faces.h b/deal.II/deal.II/include/dofs/dof_faces.h new file mode 100644 index 0000000000..d1e0a40442 --- /dev/null +++ b/deal.II/deal.II/include/dofs/dof_faces.h @@ -0,0 +1,167 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- +#ifndef __deal2__dof_faces_h +#define __deal2__dof_faces_h + + +#include +#include +#include +#include + + +template class DoFHandler; +template class MGDoFHandler; + +namespace internal +{ +/** + * A namespace for internal data structures of the DoFHandler group of classes. + * + * @ingroup dofs + */ + namespace DoFHandler + { + +/** + * + *

DoFFaces

+ * + * These classes are similar to the DoFLevel classes. We here store information + * that is associated with faces, rather than cells, as this information is independent of + * the hierachical structure of cells, which are organized in levels. In 2D we store + * information on degrees of freedom located on lines whereas in 3D we store information on + * drefrees of freedom located on quads and lines. In 1D we do nothing, as the faces of + * lines are vertices which are treated seperately. + * + * Apart from the DoFObjects object containing the data to store (degree of freedom + * indices) we do not store any data or provide any functionality. However, we do implement + * a function to determine an estimate of the memory consumption of the contained + * DoFObjects object(s). + * + * The data contained isn't usually directly accessed. Rather, except for some access from + * the DoFHandler class, access is usually through the DoFAccessor::set_dof_index() and + * DoFAccessor::dof_index() functions or similar functions of derived classes that in turn + * access the member variables using the DoFHandler::get_dof_index() and corresponding + * setter functions. Knowledge of the actual data format is therefore encapsulated to the + * present hierarchy of classes as well as the ::DoFHandler class. + * + * @ingroup dofs + * @author Tobias Leicht, 2006 + */ + template + class DoFFaces + { + /** + * Make the constrctor private to prevent the use + * of this template, only the specializations + * should be used + */ + private: + DoFFaces(); + }; + +/** + * Store the indices of degrees of freedom on faces in 1D. As these would be vertices, which + * are treted seperately, don't do anything. + * + * @ingroup dofs + * @author Tobias Leicht, 2006 + */ + template<> + class DoFFaces<1> + { + public: + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + }; + +/** + * Store the indices of degrees of freedom on faces in 2D, which are lines. + * + * @ingroup dofs + * @author Tobias Leicht, 2006 + */ + template<> + class DoFFaces<2> + { + private: + /** + * The object containing the data of DoFs on lines. + */ + internal::DoFHandler::DoFObjects<1> lines; + + public: + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + + /** + * Make the DoFHandler and + * MGDoFHandler classes a + * friend, so that it can + * resize arrays as + * necessary. + */ + template friend class ::DoFHandler; + template friend class ::MGDoFHandler; + }; + +/** + * Store the indices of degrees of freedom on faces in 3D, which are quads, additionaly also on lines. + * + * @ingroup dofs + * @author Tobias Leicht, 2006 + */ + template<> + class DoFFaces<3> + { + private: + /** + * The object containing the data of DoFs on lines. + */ + internal::DoFHandler::DoFObjects<1> lines; + /** + * The object containing the data of DoFs on quads. + */ + internal::DoFHandler::DoFObjects<2> quads; + + public: + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + + /** + * Make the DoFHandler and + * MGDoFHandler classes a + * friend, so that it can + * resize arrays as + * necessary. + */ + template friend class ::DoFHandler; + template friend class ::MGDoFHandler; + }; + + } +} +#endif diff --git a/deal.II/deal.II/include/dofs/dof_handler.h b/deal.II/deal.II/include/dofs/dof_handler.h index 8bed1d2e59..79d2363c7b 100644 --- a/deal.II/deal.II/include/dofs/dof_handler.h +++ b/deal.II/deal.II/include/dofs/dof_handler.h @@ -30,6 +30,7 @@ namespace internal namespace DoFHandler { template class DoFLevel; + template class DoFFaces; } } @@ -313,7 +314,7 @@ class DoFHandler : public Subscriptor * dimension less. */ unsigned int max_couplings_between_boundary_dofs () const; - + /** * @name Cell iterator functions */ @@ -452,7 +453,7 @@ class DoFHandler : public Subscriptor * This function calls @p begin_raw_line * in 2D and @p begin_raw_quad in 3D. */ - raw_face_iterator begin_raw_face (const unsigned int level = 0) const; + raw_face_iterator begin_raw_face () const; /** * Iterator to the first used face @@ -461,7 +462,7 @@ class DoFHandler : public Subscriptor * This function calls @p begin_line * in 2D and @p begin_quad in 3D. */ - face_iterator begin_face (const unsigned int level = 0) const; + face_iterator begin_face () const; /** * Iterator to the first active @@ -470,7 +471,7 @@ class DoFHandler : public Subscriptor * This function calls @p begin_active_line * in 2D and @p begin_active_quad in 3D. */ - active_face_iterator begin_active_face(const unsigned int level = 0) const; + active_face_iterator begin_active_face() const; /** * Iterator past the end; this @@ -483,21 +484,13 @@ class DoFHandler : public Subscriptor */ raw_face_iterator end_face () const; - /** - * Return an iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ - face_iterator end_face (const unsigned int level) const; - /** * Return a raw iterator which is the first * iterator not on level. If @p level is * the last level, then this returns * end(). */ - raw_face_iterator end_raw_face (const unsigned int level) const; + raw_face_iterator end_raw_face () const; /** * Return an active iterator which is the @@ -505,7 +498,7 @@ class DoFHandler : public Subscriptor * is the last level, then this returns * end(). */ - active_face_iterator end_active_face (const unsigned int level) const; + active_face_iterator end_active_face () const; /** * Return an iterator pointing to the @@ -516,15 +509,6 @@ class DoFHandler : public Subscriptor */ raw_face_iterator last_raw_face () const; - /** - * Return an iterator pointing to the last - * face of the level @p level, used or not. - * - * This function calls @p last_raw_line - * in 2D and @p last_raw_quad in 3D. - */ - raw_face_iterator last_raw_face (const unsigned int level) const; - /** * Return an iterator pointing to the last * used face. @@ -552,14 +536,6 @@ class DoFHandler : public Subscriptor */ active_face_iterator last_active_face () const; - /** - * Return an iterator pointing to the last - * active face on level @p level. - * - * This function calls @p last_active_line - * in 2D and @p last_active_quad in 3D. - */ - active_face_iterator last_active_face (const unsigned int level) const; //@} @@ -1119,6 +1095,41 @@ class DoFHandler : public Subscriptor const unsigned int fe_index, const unsigned int local_index) const; + /** + * Return the @p i-th dof-index. This function calls + * the respective function of DoFObjects. + */ + template + unsigned int get_dof_index (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const; + /** + * Set the @p i-th dof-index. This function calls + * the respective function of DoFObjects. + */ + template + void set_dof_index (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const; + /** + * number of active fe-indices, calls the respective + * function in DoFObjects + */ + template + unsigned int n_active_fe_indices (const unsigned int obj_level, + const unsigned int obj_index) const; + /** + * return, wether fe-index is an active fe, calls the + * respective function in DoFObjects + */ + template + bool fe_index_is_active (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const; + /** * Space to store the DoF numbers for the * different levels. Analogous to the @@ -1127,6 +1138,7 @@ class DoFHandler : public Subscriptor */ std::vector*> levels; + internal::DoFHandler::DoFFaces * faces; /** * Store the number of dofs created last * time. @@ -1182,16 +1194,13 @@ template <> DoFHandler<1>::cell_iterator DoFHandler<1>::last () const; template <> DoFHandler<1>::cell_iterator DoFHandler<1>::last (const unsigned int level) const; template <> DoFHandler<1>::active_cell_iterator DoFHandler<1>::last_active () const; template <> DoFHandler<1>::active_cell_iterator DoFHandler<1>::last_active (const unsigned int level) const; -template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::begin_raw_face (const unsigned int) const; -template <> DoFHandler<1>::face_iterator DoFHandler<1>::begin_face (const unsigned int) const; -template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::begin_active_face (const unsigned int) const; +template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::begin_raw_face () const; +template <> DoFHandler<1>::face_iterator DoFHandler<1>::begin_face () const; +template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::begin_active_face () const; template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::end_face () const; template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::last_raw_face () const; -template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::last_raw_face (const unsigned int) const; template <> DoFHandler<1>::face_iterator DoFHandler<1>::last_face () const; -template <> DoFHandler<1>::face_iterator DoFHandler<1>::last_face (const unsigned int) const; template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::last_active_face () const; -template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::last_active_face (const unsigned int) const; template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::begin_raw_quad (const unsigned int) const; template <> DoFHandler<1>::quad_iterator DoFHandler<1>::begin_quad (const unsigned int) const; template <> DoFHandler<1>::active_quad_iterator DoFHandler<1>::begin_active_quad (const unsigned int) const; @@ -1222,16 +1231,13 @@ template <> DoFHandler<2>::cell_iterator DoFHandler<2>::last () const; template <> DoFHandler<2>::cell_iterator DoFHandler<2>::last (const unsigned int level) const; template <> DoFHandler<2>::active_cell_iterator DoFHandler<2>::last_active () const; template <> DoFHandler<2>::active_cell_iterator DoFHandler<2>::last_active (const unsigned int level) const; -template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::begin_raw_face (const unsigned int level) const; -template <> DoFHandler<2>::face_iterator DoFHandler<2>::begin_face (const unsigned int level) const; -template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::begin_active_face (const unsigned int level) const; +template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::begin_raw_face () const; +template <> DoFHandler<2>::face_iterator DoFHandler<2>::begin_face () const; +template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::begin_active_face () const; template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::end_face () const; template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::last_raw_face () const; -template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::last_raw_face (const unsigned int level) const; template <> DoFHandler<2>::face_iterator DoFHandler<2>::last_face () const; -template <> DoFHandler<2>::face_iterator DoFHandler<2>::last_face (const unsigned int level) const; template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::last_active_face () const; -template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::last_active_face (const unsigned int level) const; template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::begin_raw_hex (const unsigned int) const; template <> DoFHandler<2>::hex_iterator DoFHandler<2>::begin_hex (const unsigned int) const; template <> DoFHandler<2>::active_hex_iterator DoFHandler<2>::begin_active_hex (const unsigned int) const; @@ -1252,16 +1258,13 @@ template <> DoFHandler<3>::cell_iterator DoFHandler<3>::last () const; template <> DoFHandler<3>::cell_iterator DoFHandler<3>::last (const unsigned int level) const; template <> DoFHandler<3>::active_cell_iterator DoFHandler<3>::last_active () const; template <> DoFHandler<3>::active_cell_iterator DoFHandler<3>::last_active (const unsigned int level) const; -template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::begin_raw_face (const unsigned int level) const; -template <> DoFHandler<3>::face_iterator DoFHandler<3>::begin_face (const unsigned int level) const; -template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::begin_active_face (const unsigned int level) const; +template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::begin_raw_face () const; +template <> DoFHandler<3>::face_iterator DoFHandler<3>::begin_face () const; +template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::begin_active_face () const; template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::end_face () const; template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::last_raw_face () const; -template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::last_raw_face (const unsigned int level) const; template <> DoFHandler<3>::face_iterator DoFHandler<3>::last_face () const; -template <> DoFHandler<3>::face_iterator DoFHandler<3>::last_face (const unsigned int level) const; template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::last_active_face () const; -template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::last_active_face (const unsigned int level) const; template <> unsigned int DoFHandler<1>::distribute_dofs_on_cell (active_cell_iterator &cell, diff --git a/deal.II/deal.II/include/dofs/dof_levels.h b/deal.II/deal.II/include/dofs/dof_levels.h index 0001f692a3..37388b3141 100644 --- a/deal.II/deal.II/include/dofs/dof_levels.h +++ b/deal.II/deal.II/include/dofs/dof_levels.h @@ -16,6 +16,7 @@ #include #include +#include #include template class DoFHandler; @@ -24,17 +25,6 @@ template class MGDoFHandler; namespace internal { -/** - * A class that is used to disambiguate between functions of the same - * name but that operate on objects of different structural dimension. - * The class is only used in the interface between DoF accessors and - * the level information stored in the internal::DoFHandler::DoFLevel - * and internal::hp::DoFLevel classes. - */ - template - struct StructuralDimension - {}; - /** * A namespace for internal data structures of the DoFHandler group of classes. @@ -44,57 +34,8 @@ namespace internal namespace DoFHandler { -/** - * Store the indices of the degrees of freedom which are located on - * objects of dimension @p N. We declare this general template - * class, but do not actually use it. Rather, only specializations of - * this class are used. - * - *

Information for all DoFLevel classes

- * - * The DoFLevel classes store the global indices of the - * degrees of freedom for each cell on a certain level. The global - * index or number of a degree of freedom is the zero-based index of - * the according value in the solution vector and the row and column - * index in the global matrix or the multigrid matrix for this - * level. These indices refer to the unconstrained vectors and - * matrices, where we have not taken account of the constraints - * introduced by hanging nodes. - * - * The storage format of the degrees of freedom indices (short: DoF - * indices) is somewhat like a mirror of the data structures of the - * triangulation classes. There is a hierarchy of DoFLevel - * classes for the different dimensions which have objects named @p - * line_dofs, @p quad_dofs and so on, in which the indices of DoFs - * located on lines and quads, respectively, are stored. The indices - * are stored levelwise. The layout in these arrays is as follows: if - * for a selected finite element (use DoFHandler::distribute_dofs() to - * select a finite element) the number of DoFs on each line (without - * those in the vertices) is @p N, then the length of the @p line_dofs - * array is @p N times the number of lines on this level. The DoF - * indices for the @p ith line are at the positions - * N*i...(N+1)*i-1. It is true that this scheme wastes some - * memory since we actually only use the memory so allocated for - * active lines, whereas the index entries for line i remain unused if - * this line has children. On the other hand, it is easy to see that - * at least for dim>1 this does not constitute a too big fraction of - * memory entries, and we opt for higher memory consumption in return - * for less index computations that usually slow down modern - * processors due to more complex memory access patterns. - * - * Since vertices are not associated with a particular level, the - * indices associated with vertices are not stored in the DoFLevel - * classes but rather in the DoFHandler::vertex_dofs array. - * - * In the following, we describe the individual classes of the - * DoFLevel hierachy. Note that in 1d, the hierarchy consists of - * DoFLevel<1> (storing line dofs) which is derived from DoFLevel<0> - * (storing things that are related to cells, whatever that may be in - * a given space dimension); in 2d, the class hierarchy consists of - * DoFLevel<2> which is derived from DoFLevel<1>, thus extending the - * previous data by quad dofs; a similar hierarchy of course also - * exists for higher dimensions. - * + +/** * *

DoFLevel@<0@>

* @@ -106,44 +47,38 @@ namespace internal * At present, all we store are cached values for the DoF indices on * each cell, since this is a frequently requested operation. The * values are set by DoFCellAccessor::update_cell_dof_indices_cache - * and are used by DoFCellAccessor::get_dof_indices. Note that for - * objects that are not cell, such as lines in 2d and 3d, or quads in - * 3d, no caching is done since accessing the degrees of freedom on - * these objects is a comparatively rare operation. + * and are used by DoFCellAccessor::get_dof_indices. * * Note that vertices are separate from, and in fact have nothing to * do with cells. The indices of degrees of freedom located on * vertices therefore are not stored here, but rather in member * variables of the ::DoFHandler class. * + * The indices of degrees of freedom located on lower dimensional + * objects, i.e. on lines for 2D and on quads and lines for 3D are + * treated similarly than that on cells. However, theses geometrical + * objects, which are called faces as a generalisation, are not + * organised in a hierachical structure of levels. Therefore, the + * degrees of freedom located on these objects are stored in seperate + * classes, namely the DoFFaces classes. + * * *

DoFLevel@<1@>, DoFLevel@<2@>, and DoFLevel@<3@>

* * These classes are used, respectively, to store the indices located * on lines, quads, and hexes. The storage format is as laid out - * above, and data is stored in arrays line_dofs, quad_dofs, and - * hex_dofs. However, it isn't usually directly accessed. Rather, + * above, and data is stored in objects lines, quads, and + * hexes, which are all instantiations of DoFObjects. + * However, it isn't usually directly accessed. Rather, * except for some access from the DoFHandler class, access is usually * through the DoFAccessor::set_dof_index() and * DoFAccessor::dof_index() functions or similar functions of derived * classes that in turn access the member variables using the - * DoFLevel<1>::get_dof_index(), corresponding setter functions, - * and similar functions in the DoFLevel<2> and DoFLevel<3> - * classes. Knowledge of the actual data format is therefore + * DoFHandler::get_dof_index() and corresponding setter functions. + * Knowledge of the actual data format is therefore * encapsulated to the present hierarchy of classes as well as the * ::DoFHandler class. * - * The DoFLevel classes all have functions get_dof_index() and - * set_dof_index(). Since they have the same name, it is necessary to - * disambiguate which one we want to call when accessing line or quad - * DoFs, for example. To this end, they take an additional argument of - * type internal::StructuralDimension where the template argument - * indicates the structural dimension of the object accessed, i.e. 1 - * for lines, 2 for quads, etc. Using this trick, it is possible to - * write the functions DoFAccessor::dof_index() - * completely general, without having to specialize for the space - * dimension or the dimension of the object we access. - * * @ingroup dofs * @author Wolfgang Bangerth, 1998, 2006 */ @@ -180,45 +115,6 @@ namespace internal */ std::vector cell_dof_indices_cache; - /** - * Return the value 1. The - * meaning of this function - * becomes clear by looking - * at what the corresponding - * functions in the classes - * internal::hp::DoFLevel do. - * Since we always have to - * return 1, there is no - * point in implementing this - * function multiple times in - * the derived classes, and - * we just do it once as a - * template in the common - * base class. - */ - template - unsigned int - n_active_fe_indices (const ::DoFHandler &dof_handler, - const unsigned int index, - const StructuralDimension) const; - - /** - * Similar to the function - * above. Assert that the - * given index is zero, and - * the return true. - * - * See the - * internal::hp::DoFLevel - * hierarchy for more - * information. - */ - template - bool - fe_index_is_active (const ::DoFHandler &dof_handler, - const unsigned int index, - const unsigned int fe_index, - const StructuralDimension) const; /** * Determine an estimate for the @@ -228,10 +124,9 @@ namespace internal unsigned int memory_consumption () const; }; - /** * Store the indices of the degrees of freedom which are located on - * the lines. See the general template DoFLevel for more information. + * lines. See the general template DoFLevel for more information. * * @ingroup dofs * @author Wolfgang Bangerth, 1998, 2006 @@ -241,98 +136,13 @@ namespace internal { private: /** - * Store the global indices of - * the degrees of freedom. See - * DoFLevel for detailed - * information. - */ - std::vector line_dofs; + * the object containing dof-indices + * and related access-functions + */ + DoFObjects<1> lines; public: - /** - * Set the global index of - * the @p local_index-th - * degree of freedom located - * on the line with number @p - * line_index to the value - * given by the last - * argument. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, must equal - * zero. It is otherwise - * unused, but we retain the - * argument so that we can - * use the same interface for - * non-hp and hp finite - * element methods, in effect - * making it possible to - * share the DoFAccessor - * class hierarchy between hp - * and non-hp classes. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - void - set_dof_index (const ::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<1> dummy); - - /** - * Return the global index of - * the @p local_index-th - * degree of freedom located - * on the line with number @p - * line_index. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, must equal - * zero. It is otherwise - * unused, but we retain the - * argument so that we can - * use the same interface for - * non-hp and hp finite - * element methods, in effect - * making it possible to - * share the DoFAccessor - * class hierarchy between hp - * and non-hp classes. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - unsigned int - get_dof_index (const ::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<1> dummy) const; - - /** + /** * Determine an estimate for the * memory consumption (in bytes) * of this object. @@ -351,7 +161,6 @@ namespace internal }; - /** * Store the indices of the degrees of freedom which are located on * quads. See the general template DoFLevel for more information. @@ -360,110 +169,17 @@ namespace internal * @author Wolfgang Bangerth, 1998, 2006 */ template <> - class DoFLevel<2> : public DoFLevel<1> + class DoFLevel<2> : public DoFLevel<0> { private: /** - * Store the global indices of - * the degrees of freedom. See - * DoFLevel for detailed - * information. - */ - std::vector quad_dofs; + * the object containing dof-indices + * and related access-functions + */ + internal::DoFHandler::DoFObjects<2> quads; public: - /** - * Set the global index of - * the @p local_index-th - * degree of freedom located - * on the quad with number @p - * quad_index to the value - * given by the last - * argument. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, must equal - * zero. It is otherwise - * unused, but we retain the - * argument so that we can - * use the same interface for - * non-hp and hp finite - * element methods, in effect - * making it possible to - * share the DoFAccessor - * class hierarchy between hp - * and non-hp classes. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - void - set_dof_index (const ::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<2> dummy); - - /** - * Return the global index of - * the @p local_index-th - * degree of freedom located - * on the quad with number @p - * quad_index. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, must equal - * zero. It is otherwise - * unused, but we retain the - * argument so that we can - * use the same interface for - * non-hp and hp finite - * element methods, in effect - * making it possible to - * share the DoFAccessor - * class hierarchy between hp - * and non-hp classes. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - unsigned int - get_dof_index (const ::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<2> dummy) const; - /** - * Import the respective - * functions from the base - * class. - */ - using DoFLevel<1>::set_dof_index; - using DoFLevel<1>::get_dof_index; - - /** * Determine an estimate for the * memory consumption (in bytes) * of this object. @@ -482,7 +198,6 @@ namespace internal }; - /** * Store the indices of the degrees of freedom which are located on * hexhedra. See the general template DoFLevel for more information. @@ -491,110 +206,18 @@ namespace internal * @author Wolfgang Bangerth, 1998, 2006 */ template <> - class DoFLevel<3> : public DoFLevel<2> + class DoFLevel<3> : public DoFLevel<0> { private: /** - * Store the global indices of - * the degrees of freedom. See - * DoFLevel for detailed - * information. - */ - std::vector hex_dofs; + * the object containing dof-indices + * and related access-functions + */ + internal::DoFHandler::DoFObjects<3> hexes; public: - /** - * Set the global index of - * the @p local_index-th - * degree of freedom located - * on the hex with number @p - * hex_index to the value - * given by the last - * argument. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, must equal - * zero. It is otherwise - * unused, but we retain the - * argument so that we can - * use the same interface for - * non-hp and hp finite - * element methods, in effect - * making it possible to - * share the DoFAccessor - * class hierarchy between hp - * and non-hp classes. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - void - set_dof_index (const ::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<3> dummy); - - /** - * Return the global index of - * the @p local_index-th - * degree of freedom located - * on the hex with number @p - * hex_index. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, must equal - * zero. It is otherwise - * unused, but we retain the - * argument so that we can - * use the same interface for - * non-hp and hp finite - * element methods, in effect - * making it possible to - * share the DoFAccessor - * class hierarchy between hp - * and non-hp classes. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - unsigned int - get_dof_index (const ::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<3> dummy) const; - + /** - * Import the respective - * functions from the base - * class. - */ - using DoFLevel<2>::set_dof_index; - using DoFLevel<2>::get_dof_index; - - /** * Determine an estimate for the * memory consumption (in bytes) * of this object. @@ -612,36 +235,7 @@ namespace internal template friend class ::MGDoFHandler; }; - -// ----------- inline functions --------------------- - - template - inline - unsigned int - DoFLevel<0>::n_active_fe_indices (const ::DoFHandler &, - const unsigned int, - const StructuralDimension) const - { - return 1; - } - - - template - inline - bool - DoFLevel<0>::fe_index_is_active (const ::DoFHandler &, - const unsigned int, - const unsigned int fe_index, - const StructuralDimension) const - { - Assert (fe_index == 0, - ExcMessage ("Only zero fe_index values are allowed for " - "non-hp DoFHandlers.")); - return true; - } - } - } #endif diff --git a/deal.II/deal.II/include/dofs/dof_objects.h b/deal.II/deal.II/include/dofs/dof_objects.h new file mode 100644 index 0000000000..c4550c2107 --- /dev/null +++ b/deal.II/deal.II/include/dofs/dof_objects.h @@ -0,0 +1,184 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- +#ifndef __deal2__dof_objects_h +#define __deal2__dof_objects_h + + +#include +#include +#include + +template class DoFHandler; + +namespace internal +{ +/** + * A namespace for internal data structures of the DoFHandler group of classes. + * + * @ingroup dofs + */ + namespace DoFHandler + { + template class DoFLevel; + template class DoFFaces; + + +/** + * Store the indices of the degrees of freedom which are located on + * objects of dimension @p dim. + * + *

Information for all DoFObjects classes

+ * + * The DoFObjects classes store the global indices of the + * degrees of freedom for each cell on a certain level. The global + * index or number of a degree of freedom is the zero-based index of + * the according value in the solution vector and the row and column + * index in the global matrix or the multigrid matrix for this + * level. These indices refer to the unconstrained vectors and + * matrices, where we have not taken account of the constraints + * introduced by hanging nodes. + * + * Since vertices are not associated with a particular level, the + * indices associated with vertices are not stored in the DoFObjects + * classes but rather in the DoFHandler::vertex_dofs array. + * + * The DoFObjects classes are not used directly, but objects + * of theses classes are included in the DoFLevel and + * DoFFaces classes. + * + * @ingroup dofs + * @author Tobias Leicht, 2006 + */ + template + class DoFObjects{ + public: + /** + * Store the global indices of + * the degrees of freedom. + */ + std::vector dofs; + + public: + /** + * Set the global index of + * the @p local_index-th + * degree of freedom located + * on the object with number @p + * obj_index to the value + * given by the last + * argument. The @p + * dof_handler argument is + * used to access the finite + * element that is to be used + * to compute the location + * where this data is stored. + * + * The third argument, @p + * fe_index, must equal + * zero. It is otherwise + * unused, but we retain the + * argument so that we can + * use the same interface for + * non-hp and hp finite + * element methods, in effect + * making it possible to + * share the DoFAccessor + * class hierarchy between hp + * and non-hp classes. + */ + template + void + set_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index); + + /** + * Return the global index of + * the @p local_index-th + * degree of freedom located + * on the object with number @p + * obj_index. The @p + * dof_handler argument is + * used to access the finite + * element that is to be used + * to compute the location + * where this data is stored. + * + * The third argument, @p + * fe_index, must equal + * zero. It is otherwise + * unused, but we retain the + * argument so that we can + * use the same interface for + * non-hp and hp finite + * element methods, in effect + * making it possible to + * share the DoFAccessor + * class hierarchy between hp + * and non-hp classes. + */ + template + unsigned int + get_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const; + /** + * Return the value 1. The + * meaning of this function + * becomes clear by looking + * at what the corresponding + * functions in the classes + * internal::hp::DoFObjects + */ + template + unsigned int + n_active_fe_indices (const ::DoFHandler &dof_handler, + const unsigned int index) const; + + /** + * Similar to the function + * above. Assert that the + * given index is zero, and + * the return true. + */ + template + bool + fe_index_is_active (const ::DoFHandler &dof_handler, + const unsigned int index, + const unsigned int fe_index) const; + + + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + + /** + * Make the DoFHandler and + * MGDoFHandler classes a + * friend, so that they can + * resize arrays as + * necessary. + */ + template friend class DoFLevel; + template friend class DoFFaces; + }; + + } +} +#endif diff --git a/deal.II/deal.II/include/dofs/hp_dof_faces.h b/deal.II/deal.II/include/dofs/hp_dof_faces.h new file mode 100644 index 0000000000..1d3de9bf65 --- /dev/null +++ b/deal.II/deal.II/include/dofs/hp_dof_faces.h @@ -0,0 +1,154 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- +#ifndef __deal2__hp_dof_faces_h +#define __deal2__hp_dof_faces_h + + +#include +#include +#include +#include + +#include + + +namespace hp +{ + template + class FECollection; +} + + +namespace internal +{ + namespace hp + { + +/** + * + *

DoFFaces

+ * + * These classes are similar to the internal::hp::DoFLevel classes. We here store + * information that is associated with faces, rather than cells, as this information is + * independent of the hierachical structure of cells, which are organized in levels. In 2D + * we store information on degrees of freedom located on lines whereas in 3D we store + * information on drefrees of freedom located on quads and lines. In 1D we do nothing, as + * the faces of lines are vertices which are treated seperately. + * + * Apart from the internal::hp::DoFObjects object containing the data to store + * (degree of freedom indices) and all the access-functionality to this data, we do not + * store any data or provide any functionality. However, we do implement a function to + * determine an estimate of the memory consumption of the contained + * internal::hp::DoFObjects object(s). + * + * The data contained isn't usually directly accessed. Rather, except for some access from + * the DoFHandler class, access is usually through the DoFAccessor::set_dof_index() and + * DoFAccessor::dof_index() functions or similar functions of derived classes that in turn + * access the member variables using the DoFHandler::get_dof_index() and corresponding + * setter functions. Knowledge of the actual data format is therefore encapsulated to the + * present hierarchy of classes as well as the ::DoFHandler class. + * + * @ingroup dofs + * @author Tobias Leicht, 2006 + */ + + + + + + + template + class DoFFaces + { + /** + * Make the constrctor private to prevent the use + * of this template, only the specializations + * should be used + */ + private: + DoFFaces(); + }; + +/** + * Store the indices of degrees of freedom on faces in 1D. As these would be vertices, which + * are treted seperately, don't do anything. + * + * @ingroup hp + * @author Tobias Leicht, 2006 + */ + template<> + class DoFFaces<1> + { + public: + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + + template friend class ::hp::DoFHandler; + }; + +/** + * Store the indices of degrees of freedom on faces in 2D, which are lines. + * + * @ingroup hp + * @author Tobias Leicht, 2006 + */ + template<> + class DoFFaces<2> + { + private: + internal::hp::DoFObjects<1> lines; + + public: + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + + template friend class ::hp::DoFHandler; + }; + +/** + * Store the indices of degrees of freedom on faces in 3D, which are quads, additionaly also on lines. + * + * @ingroup hp + * @author Tobias Leicht, 2006 + */ + template<> + class DoFFaces<3> + { + private: + internal::hp::DoFObjects<1> lines; + internal::hp::DoFObjects<2> quads; + + public: + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + + template friend class ::hp::DoFHandler; + }; + + } // namespace hp + +} // namespace internal + +#endif diff --git a/deal.II/deal.II/include/dofs/hp_dof_handler.h b/deal.II/deal.II/include/dofs/hp_dof_handler.h index 170c3b4d49..fe1c7afc12 100644 --- a/deal.II/deal.II/include/dofs/hp_dof_handler.h +++ b/deal.II/deal.II/include/dofs/hp_dof_handler.h @@ -32,10 +32,8 @@ namespace internal namespace hp { template class DoFLevel; - template <> class DoFLevel<0>; - template <> class DoFLevel<1>; - template <> class DoFLevel<2>; - template <> class DoFLevel<3>; + template class DoFFaces; + template class DoFObjects; } } @@ -234,554 +232,512 @@ namespace hp */ unsigned int max_couplings_between_boundary_dofs () const; - /** - * @name Cell iterator functions - */ - /*@{*/ - /** - * Iterator to the first cell, used - * or not, on level @p level. If a level - * has no cells, a past-the-end iterator - * is returned. - * - * This function calls @p begin_raw_line - * in 1D and @p begin_raw_quad in 2D. - */ + /** + * @name Cell iterator functions + */ + /*@{*/ + /** + * Iterator to the first cell, used + * or not, on level @p level. If a level + * has no cells, a past-the-end iterator + * is returned. + * + * This function calls @p begin_raw_line + * in 1D and @p begin_raw_quad in 2D. + */ raw_cell_iterator begin_raw (const unsigned int level = 0) const; - /** - * Iterator to the first used cell - * on level @p level. - * - * This function calls @p begin_line - * in 1D and @p begin_quad in 2D. - */ + /** + * Iterator to the first used cell + * on level @p level. + * + * This function calls @p begin_line + * in 1D and @p begin_quad in 2D. + */ cell_iterator begin (const unsigned int level = 0) const; - /** - * Iterator to the first active - * cell on level @p level. - * - * This function calls @p begin_active_line - * in 1D and @p begin_active_quad in 2D. - */ + /** + * Iterator to the first active + * cell on level @p level. + * + * This function calls @p begin_active_line + * in 1D and @p begin_active_quad in 2D. + */ active_cell_iterator begin_active(const unsigned int level = 0) const; - /** - * Iterator past the end; this - * iterator serves for comparisons of - * iterators with past-the-end or - * before-the-beginning states. - * - * This function calls @p end_line - * in 1D and @p end_quad in 2D. - */ + /** + * Iterator past the end; this + * iterator serves for comparisons of + * iterators with past-the-end or + * before-the-beginning states. + * + * This function calls @p end_line + * in 1D and @p end_quad in 2D. + */ raw_cell_iterator end () const; - /** - * Return an iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ + /** + * Return an iterator which is the first + * iterator not on level. If @p level is + * the last level, then this returns + * end(). + */ cell_iterator end (const unsigned int level) const; - /** - * Return a raw iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ + /** + * Return a raw iterator which is the first + * iterator not on level. If @p level is + * the last level, then this returns + * end(). + */ raw_cell_iterator end_raw (const unsigned int level) const; - /** - * Return an active iterator which is the - * first iterator not on level. If @p level - * is the last level, then this returns - * end(). - */ + /** + * Return an active iterator which is the + * first iterator not on level. If @p level + * is the last level, then this returns + * end(). + */ active_cell_iterator end_active (const unsigned int level) const; - /** - * Return an iterator pointing to the - * last cell, used or not. - * - * This function calls @p last_raw_line - * in 1D and @p last_raw_quad in 2D. - */ + /** + * Return an iterator pointing to the + * last cell, used or not. + * + * This function calls @p last_raw_line + * in 1D and @p last_raw_quad in 2D. + */ raw_cell_iterator last_raw () const; - /** - * Return an iterator pointing to the last - * cell of the level @p level, used or not. - * - * This function calls @p last_raw_line - * in 1D and @p last_raw_quad in 2D. - */ + /** + * Return an iterator pointing to the last + * cell of the level @p level, used or not. + * + * This function calls @p last_raw_line + * in 1D and @p last_raw_quad in 2D. + */ raw_cell_iterator last_raw (const unsigned int level) const; - /** - * Return an iterator pointing to the last - * used cell. - * - * This function calls @p last_line - * in 1D and @p last_quad in 2D. - */ + /** + * Return an iterator pointing to the last + * used cell. + * + * This function calls @p last_line + * in 1D and @p last_quad in 2D. + */ cell_iterator last () const; - /** - * Return an iterator pointing to the last - * used cell on level @p level. - * - * This function calls @p last_line - * in 1D and @p last_quad in 2D. - */ + /** + * Return an iterator pointing to the last + * used cell on level @p level. + * + * This function calls @p last_line + * in 1D and @p last_quad in 2D. + */ cell_iterator last (const unsigned int level) const; - /** - * Return an iterator pointing to the last - * active cell. - * - * This function calls @p last_active_line - * in 1D and @p last_active_quad in 2D. - */ + /** + * Return an iterator pointing to the last + * active cell. + * + * This function calls @p last_active_line + * in 1D and @p last_active_quad in 2D. + */ active_cell_iterator last_active () const; - /** - * Return an iterator pointing to the last - * active cell on level @p level. - * - * This function calls @p last_active_line - * in 1D and @p last_active_quad in 2D. - */ + /** + * Return an iterator pointing to the last + * active cell on level @p level. + * + * This function calls @p last_active_line + * in 1D and @p last_active_quad in 2D. + */ active_cell_iterator last_active (const unsigned int level) const; - //@} + //@} - /*---------------------------------------*/ + /*---------------------------------------*/ - /** - * @name Face iterator functions - */ - /*@{*/ - /** - * Iterator to the first face, used - * or not, on level @p level. If a level - * has no faces, a past-the-end iterator - * is returned. - * - * This function calls @p begin_raw_line - * in 2D and @p begin_raw_quad in 3D. - */ - raw_face_iterator begin_raw_face (const unsigned int level = 0) const; + /** + * @name Face iterator functions + */ + /*@{*/ + /** + * Iterator to the first face, used + * or not. + * + * This function calls @p begin_raw_line + * in 2D and @p begin_raw_quad in 3D. + */ + raw_face_iterator begin_raw_face () const; - /** - * Iterator to the first used face - * on level @p level. - * - * This function calls @p begin_line - * in 2D and @p begin_quad in 3D. - */ - face_iterator begin_face (const unsigned int level = 0) const; + /** + * Iterator to the first used face. + * + * This function calls @p begin_line + * in 2D and @p begin_quad in 3D. + */ + face_iterator begin_face () const; - /** - * Iterator to the first active - * face on level @p level. - * - * This function calls @p begin_active_line - * in 2D and @p begin_active_quad in 3D. - */ - active_face_iterator begin_active_face(const unsigned int level = 0) const; + /** + * Iterator to the first active face. + * + * This function calls @p begin_active_line + * in 2D and @p begin_active_quad in 3D. + */ + active_face_iterator begin_active_face() const; - /** - * Iterator past the end; this - * iterator serves for comparisons of - * iterators with past-the-end or - * before-the-beginning states. - * - * This function calls @p end_line - * in 2D and @p end_quad in 3D. - */ + /** + * Iterator past the end; this + * iterator serves for comparisons of + * iterators with past-the-end or + * before-the-beginning states. + * + * This function calls @p end_line + * in 2D and @p end_quad in 3D. + */ raw_face_iterator end_face () const; - /** - * Return an iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ - face_iterator end_face (const unsigned int level) const; - - /** - * Return a raw iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ - raw_face_iterator end_raw_face (const unsigned int level) const; + /** + * Return a raw iterator past-the-end. + * This is the same as end_face(). + */ + raw_face_iterator end_raw_face () const; - /** - * Return an active iterator which is the - * first iterator not on level. If @p level - * is the last level, then this returns - * end(). - */ - active_face_iterator end_active_face (const unsigned int level) const; + /** + * Return an active iterator past-the-end. + * This is the same as end_face(). + */ + active_face_iterator end_active_face () const; - /** - * Return an iterator pointing to the - * last face, used or not. - * - * This function calls @p last_raw_line - * in 2D and @p last_raw_quad in 3D. - */ + /** + * Return an iterator pointing to the + * last face, used or not. + * + * This function calls @p last_raw_line + * in 2D and @p last_raw_quad in 3D. + */ raw_face_iterator last_raw_face () const; - /** - * Return an iterator pointing to the last - * face of the level @p level, used or not. - * - * This function calls @p last_raw_line - * in 2D and @p last_raw_quad in 3D. - */ - raw_face_iterator last_raw_face (const unsigned int level) const; - - /** - * Return an iterator pointing to the last - * used face. - * - * This function calls @p last_line - * in 2D and @p last_quad in 3D. - */ + /** + * Return an iterator pointing to the last + * used face. + * + * This function calls @p last_line + * in 2D and @p last_quad in 3D. + */ face_iterator last_face () const; - /** - * Return an iterator pointing to the last - * used face on level @p level. - * - * This function calls @p last_line - * in 2D and @p last_quad in 3D. - */ - face_iterator last_face (const unsigned int level) const; - - /** - * Return an iterator pointing to the last - * active face. - * - * This function calls @p last_active_line - * in 2D and @p last_active_quad in 3D. - */ + /** + * Return an iterator pointing to the last + * active face. + * + * This function calls @p last_active_line + * in 2D and @p last_active_quad in 3D. + */ active_face_iterator last_active_face () const; - /** - * Return an iterator pointing to the last - * active face on level @p level. - * - * This function calls @p last_active_line - * in 2D and @p last_active_quad in 3D. - */ - active_face_iterator last_active_face (const unsigned int level) const; - //@} + //@} - /*---------------------------------------*/ + /*---------------------------------------*/ - /** - * @name Line iterator functions - */ - /*@{*/ - /** - * Iterator to the first line, used - * or not, on level @p level. If a level - * has no lines, a past-the-end iterator - * is returned. - */ + /** + * @name Line iterator functions + */ + /*@{*/ + /** + * Iterator to the first line, used + * or not, on level @p level. If a level + * has no lines, a past-the-end iterator + * is returned. + */ raw_line_iterator begin_raw_line (const unsigned int level = 0) const; - /** - * Iterator to the first used line - * on level @p level. - */ + /** + * Iterator to the first used line + * on level @p level. + */ line_iterator begin_line (const unsigned int level = 0) const; - /** - * Iterator to the first active - * line on level @p level. - */ + /** + * Iterator to the first active + * line on level @p level. + */ active_line_iterator begin_active_line(const unsigned int level = 0) const; - /** - * Iterator past the end; this - * iterator serves for comparisons of - * iterators with past-the-end or - * before-the-beginning states. - */ + /** + * Iterator past the end; this + * iterator serves for comparisons of + * iterators with past-the-end or + * before-the-beginning states. + */ raw_line_iterator end_line () const; - /** - * Return an iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ + /** + * Return an iterator which is the first + * iterator not on level. If @p level is + * the last level, then this returns + * end(). + */ line_iterator end_line (const unsigned int level) const; - /** - * Return a raw iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ + /** + * Return a raw iterator which is the first + * iterator not on level. If @p level is + * the last level, then this returns + * end(). + */ raw_line_iterator end_raw_line (const unsigned int level) const; - /** - * Return an active iterator which is the - * first iterator not on level. If @p level - * is the last level, then this returns - * end(). - */ + /** + * Return an active iterator which is the + * first iterator not on level. If @p level + * is the last level, then this returns + * end(). + */ active_line_iterator end_active_line (const unsigned int level) const; - /** - * Return an iterator pointing to the - * last line, used or not. - */ + /** + * Return an iterator pointing to the + * last line, used or not. + */ raw_line_iterator last_raw_line () const; - /** - * Return an iterator pointing to the last - * line of the level @p level, used or not. + /** + * Return an iterator pointing to the last + * line of the level @p level, used or not. - */ + */ raw_line_iterator last_raw_line (const unsigned int level) const; - /** - * Return an iterator pointing to the last - * used line. - */ + /** + * Return an iterator pointing to the last + * used line. + */ line_iterator last_line () const; - /** - * Return an iterator pointing to the last - * used line on level @p level. - */ + /** + * Return an iterator pointing to the last + * used line on level @p level. + */ line_iterator last_line (const unsigned int level) const; - /** - * Return an iterator pointing to the last - * active line. - */ + /** + * Return an iterator pointing to the last + * active line. + */ active_line_iterator last_active_line () const; - /** - * Return an iterator pointing to the last - * active line on level @p level. - */ + /** + * Return an iterator pointing to the last + * active line on level @p level. + */ active_line_iterator last_active_line (const unsigned int level) const; - /*@}*/ + /*@}*/ - /*---------------------------------------*/ + /*---------------------------------------*/ - /** - * @name Quad iterator functions*/ - /*@{ - */ - /** - * Iterator to the first quad, used - * or not, on level @p level. If a level - * has no quads, a past-the-end iterator - * is returned. - */ + /** + * @name Quad iterator functions*/ + /*@{ + */ + /** + * Iterator to the first quad, used + * or not, on level @p level. If a level + * has no quads, a past-the-end iterator + * is returned. + */ raw_quad_iterator begin_raw_quad (const unsigned int level = 0) const; - /** - * Iterator to the first used quad - * on level @p level. - */ + /** + * Iterator to the first used quad + * on level @p level. + */ quad_iterator begin_quad (const unsigned int level = 0) const; - /** - * Iterator to the first active - * quad on level @p level. - */ + /** + * Iterator to the first active + * quad on level @p level. + */ active_quad_iterator begin_active_quad(const unsigned int level = 0) const; - /** - * Iterator past the end; this - * iterator serves for comparisons of - * iterators with past-the-end or - * before-the-beginning states. - */ + /** + * Iterator past the end; this + * iterator serves for comparisons of + * iterators with past-the-end or + * before-the-beginning states. + */ raw_quad_iterator end_quad () const; - /** - * Return an iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ + /** + * Return an iterator which is the first + * iterator not on level. If @p level is + * the last level, then this returns + * end(). + */ quad_iterator end_quad (const unsigned int level) const; - /** - * Return a raw iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ + /** + * Return a raw iterator which is the first + * iterator not on level. If @p level is + * the last level, then this returns + * end(). + */ raw_quad_iterator end_raw_quad (const unsigned int level) const; - /** - * Return an active iterator which is the - * first iterator not on level. If @p level - * is the last level, then this returns - * end(). - */ + /** + * Return an active iterator which is the + * first iterator not on level. If @p level + * is the last level, then this returns + * end(). + */ active_quad_iterator end_active_quad (const unsigned int level) const; - /** - * Return an iterator pointing to the - * last quad, used or not. - */ + /** + * Return an iterator pointing to the + * last quad, used or not. + */ raw_quad_iterator last_raw_quad () const; - /** - * Return an iterator pointing to the last - * quad of the level @p level, used or not. + /** + * Return an iterator pointing to the last + * quad of the level @p level, used or not. - */ + */ raw_quad_iterator last_raw_quad (const unsigned int level) const; - /** - * Return an iterator pointing to the last - * used quad. - */ + /** + * Return an iterator pointing to the last + * used quad. + */ quad_iterator last_quad () const; - /** - * Return an iterator pointing to the last - * used quad on level @p level. - */ + /** + * Return an iterator pointing to the last + * used quad on level @p level. + */ quad_iterator last_quad (const unsigned int level) const; - /** - * Return an iterator pointing to the last - * active quad. - */ + /** + * Return an iterator pointing to the last + * active quad. + */ active_quad_iterator last_active_quad () const; - /** - * Return an iterator pointing to the last - * active quad on level @p level. - */ + /** + * Return an iterator pointing to the last + * active quad on level @p level. + */ active_quad_iterator last_active_quad (const unsigned int level) const; - /*@}*/ + /*@}*/ - /*---------------------------------------*/ + /*---------------------------------------*/ - /** - * @name Hex iterator functions*/ - /*@{ - */ - /** - * Iterator to the first hex, used - * or not, on level @p level. If a level - * has no hexs, a past-the-end iterator - * is returned. - */ + /** + * @name Hex iterator functions*/ + /*@{ + */ + /** + * Iterator to the first hex, used + * or not, on level @p level. If a level + * has no hexs, a past-the-end iterator + * is returned. + */ raw_hex_iterator begin_raw_hex (const unsigned int level = 0) const; - /** - * Iterator to the first used hex - * on level @p level. - */ + /** + * Iterator to the first used hex + * on level @p level. + */ hex_iterator begin_hex (const unsigned int level = 0) const; - /** - * Iterator to the first active - * hex on level @p level. - */ + /** + * Iterator to the first active + * hex on level @p level. + */ active_hex_iterator begin_active_hex(const unsigned int level = 0) const; - /** - * Iterator past the end; this - * iterator serves for comparisons of - * iterators with past-the-end or - * before-the-beginning states. - */ + /** + * Iterator past the end; this + * iterator serves for comparisons of + * iterators with past-the-end or + * before-the-beginning states. + */ raw_hex_iterator end_hex () const; - /** - * Return an iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ + /** + * Return an iterator which is the first + * iterator not on level. If @p level is + * the last level, then this returns + * end(). + */ hex_iterator end_hex (const unsigned int level) const; - /** - * Return a raw iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ + /** + * Return a raw iterator which is the first + * iterator not on level. If @p level is + * the last level, then this returns + * end(). + */ raw_hex_iterator end_raw_hex (const unsigned int level) const; - /** - * Return an active iterator which is the - * first iterator not on level. If @p level - * is the last level, then this returns - * end(). - */ + /** + * Return an active iterator which is the + * first iterator not on level. If @p level + * is the last level, then this returns + * end(). + */ active_hex_iterator end_active_hex (const unsigned int level) const; - /** - * Return an iterator pointing to the - * last hex, used or not. - */ + /** + * Return an iterator pointing to the + * last hex, used or not. + */ raw_hex_iterator last_raw_hex () const; - /** - * Return an iterator pointing to the last - * hex of the level @p level, used or not. + /** + * Return an iterator pointing to the last + * hex of the level @p level, used or not. - */ + */ raw_hex_iterator last_raw_hex (const unsigned int level) const; - /** - * Return an iterator pointing to the last - * used hex. - */ + /** + * Return an iterator pointing to the last + * used hex. + */ hex_iterator last_hex () const; - /** - * Return an iterator pointing to the last - * used hex on level @p level. - */ + /** + * Return an iterator pointing to the last + * used hex on level @p level. + */ hex_iterator last_hex (const unsigned int level) const; - /** - * Return an iterator pointing to the last - * active hex. - */ + /** + * Return an iterator pointing to the last + * active hex. + */ active_hex_iterator last_active_hex () const; - /** - * Return an iterator pointing to the last - * active hex on level @p level. - */ + /** + * Return an iterator pointing to the last + * active hex on level @p level. + */ active_hex_iterator last_active_hex (const unsigned int level) const; - /*@}*/ + /*@}*/ /*---------------------------------------*/ @@ -1066,7 +1022,41 @@ namespace hp get_vertex_dof_index (const unsigned int vertex_index, const unsigned int fe_index, const unsigned int local_index) const; - + /** + * Return the @p i-th dof-index. This function calls + * the respective function of DoFObjects. + */ + template + unsigned int get_dof_index (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const; + /** + * Set the @p i-th dof-index. This function calls + * the respective function of DoFObjects. + */ + template + void set_dof_index (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const; + /** + * number of active fe-indices, calls the respective + * function in DoFObjects + */ + template + unsigned int n_active_fe_indices (const unsigned int obj_level, + const unsigned int obj_index) const; + /** + * return, wether fe-index is an active fe, calls the + * respective function in DoFObjects + */ + template + bool fe_index_is_active (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const; + /** * Space to store the DoF * numbers for the different @@ -1075,6 +1065,15 @@ namespace hp * the Triangulation objects. */ std::vector*> levels; + /** + * Space to store the DoF + * numbers for the faces. + * Analogous to the + * faces pointer of + * the Triangulation objects. + */ + internal::hp::DoFFaces * faces; + /** * Store the number of dofs @@ -1157,13 +1156,15 @@ namespace hp template friend class ::DoFCellAccessor; /** - * Likewise for DoFLevel<0> + * Likewise for DoFLevel * objects since they need to * access the vertex dofs in * the functions that set and * retrieve vertex dof indices. */ template friend class internal::hp::DoFLevel; + template friend class internal::hp::DoFObjects; + }; @@ -1193,16 +1194,13 @@ namespace hp template <> DoFHandler<1>::cell_iterator DoFHandler<1>::last (const unsigned int level) const; template <> DoFHandler<1>::active_cell_iterator DoFHandler<1>::last_active () const; template <> DoFHandler<1>::active_cell_iterator DoFHandler<1>::last_active (const unsigned int level) const; - template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::begin_raw_face (const unsigned int) const; - template <> DoFHandler<1>::face_iterator DoFHandler<1>::begin_face (const unsigned int) const; - template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::begin_active_face (const unsigned int) const; + template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::begin_raw_face () const; + template <> DoFHandler<1>::face_iterator DoFHandler<1>::begin_face () const; + template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::begin_active_face () const; template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::end_face () const; template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::last_raw_face () const; - template <> DoFHandler<1>::raw_face_iterator DoFHandler<1>::last_raw_face (const unsigned int) const; template <> DoFHandler<1>::face_iterator DoFHandler<1>::last_face () const; - template <> DoFHandler<1>::face_iterator DoFHandler<1>::last_face (const unsigned int) const; template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::last_active_face () const; - template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::last_active_face (const unsigned int) const; template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::begin_raw_quad (const unsigned int) const; template <> DoFHandler<1>::quad_iterator DoFHandler<1>::begin_quad (const unsigned int) const; template <> DoFHandler<1>::active_quad_iterator DoFHandler<1>::begin_active_quad (const unsigned int) const; @@ -1233,16 +1231,13 @@ namespace hp template <> DoFHandler<2>::cell_iterator DoFHandler<2>::last (const unsigned int level) const; template <> DoFHandler<2>::active_cell_iterator DoFHandler<2>::last_active () const; template <> DoFHandler<2>::active_cell_iterator DoFHandler<2>::last_active (const unsigned int level) const; - template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::begin_raw_face (const unsigned int level) const; - template <> DoFHandler<2>::face_iterator DoFHandler<2>::begin_face (const unsigned int level) const; - template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::begin_active_face (const unsigned int level) const; + template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::begin_raw_face () const; + template <> DoFHandler<2>::face_iterator DoFHandler<2>::begin_face () const; + template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::begin_active_face () const; template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::end_face () const; template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::last_raw_face () const; - template <> DoFHandler<2>::raw_face_iterator DoFHandler<2>::last_raw_face (const unsigned int level) const; template <> DoFHandler<2>::face_iterator DoFHandler<2>::last_face () const; - template <> DoFHandler<2>::face_iterator DoFHandler<2>::last_face (const unsigned int level) const; template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::last_active_face () const; - template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::last_active_face (const unsigned int level) const; template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::begin_raw_hex (const unsigned int) const; template <> DoFHandler<2>::hex_iterator DoFHandler<2>::begin_hex (const unsigned int) const; template <> DoFHandler<2>::active_hex_iterator DoFHandler<2>::begin_active_hex (const unsigned int) const; @@ -1263,16 +1258,13 @@ namespace hp template <> DoFHandler<3>::cell_iterator DoFHandler<3>::last (const unsigned int level) const; template <> DoFHandler<3>::active_cell_iterator DoFHandler<3>::last_active () const; template <> DoFHandler<3>::active_cell_iterator DoFHandler<3>::last_active (const unsigned int level) const; - template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::begin_raw_face (const unsigned int level) const; - template <> DoFHandler<3>::face_iterator DoFHandler<3>::begin_face (const unsigned int level) const; - template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::begin_active_face (const unsigned int level) const; + template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::begin_raw_face () const; + template <> DoFHandler<3>::face_iterator DoFHandler<3>::begin_face () const; + template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::begin_active_face () const; template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::end_face () const; template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::last_raw_face () const; - template <> DoFHandler<3>::raw_face_iterator DoFHandler<3>::last_raw_face (const unsigned int level) const; template <> DoFHandler<3>::face_iterator DoFHandler<3>::last_face () const; - template <> DoFHandler<3>::face_iterator DoFHandler<3>::last_face (const unsigned int level) const; template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::last_active_face () const; - template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::last_active_face (const unsigned int level) const; template <> unsigned int DoFHandler<1>::distribute_dofs_on_cell (active_cell_iterator &cell, diff --git a/deal.II/deal.II/include/dofs/hp_dof_levels.h b/deal.II/deal.II/include/dofs/hp_dof_levels.h index c280692ab7..c41533bc21 100644 --- a/deal.II/deal.II/include/dofs/hp_dof_levels.h +++ b/deal.II/deal.II/include/dofs/hp_dof_levels.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -42,12 +43,12 @@ namespace internal * The things we store here is very similar to what is stored in the * internal::DoFHandler::DoFLevel class hierarchy (see there for more * information, in particular on the layout of the class hierarchy, - * and the use of file names and dummy arguments). There are two main + * and the use of file names). There are two main * differences, discussed in the following subsections. In addition to * the data already stored by the internal::DoFHandler::DoFLevel * classes, we also have to store which finite element each cell * uses. This is done in the DoFLevel<0> class, where for each cell we - * have an entry within the active_fe_indices field for each cell. + * have an entry within the active_fe_indices field. * * *

Offset computations

@@ -61,9 +62,9 @@ namespace internal * dof_handler.get_fe().dofs_per_line. This of course doesn't * work any more if different lines may have different numbers of * degrees of freedom associated with them. Consequently, rather than - * using this simple multiplication, each of the line_dofs, quad_dofs, - * and hex_dofs arrays has an associated array line_dof_offsets, - * quad_dof_offsets, and hex_dof_offsets. The data corresponding to a + * using this simple multiplication, each of the lines.dofs, quads.dofs, + * and hexes.dofs arrays has an associated array lines.dof_offsets, + * quads.dof_offsets, and hexes.dof_offsets. The data corresponding to a * line then starts at index line_dof_offsets[line_index] * within the line_dofs array. * @@ -75,7 +76,7 @@ namespace internal * order. * * However, if two adjacent cells use different finite elements, then - * the face that the share needs to store DoF indices for both + * the face that they share needs to store DoF indices for both * involved finite elements. While faces therefore have to have at * most two sets of DoF indices, it is easy to see that vertices for * example can have as many sets of DoF indices associated with them @@ -89,7 +90,7 @@ namespace internal * will have the same finite element, and only a single entry will * exist in the map), what we do is instead to store a linked list. In * this format, the first entry starting at position - * line_dofs[line_dof_offsets[line_index]] will denote + * lines.dofs[lines.dof_offsets[line_index]] will denote * the finite element index of the set of DoF indices following; after * this set, we will store the finite element index of the second set * followed by the corresponding DoF indices; and so on. Finally, when @@ -98,12 +99,8 @@ namespace internal * * Access to this kind of data, as well as the distinction between * cells and objects of lower dimensionality are encoded in the - * accessor functions, DoFLevel<1>::set_line_dof_index(), - * DoFLevel<1>::get_line_dof_index(), - * DoFLevel<2>::set_quad_dof_index(), - * DoFLevel<2>::get_quad_dof_index(), and - * DoFLevel<3>::set_hex_dof_index(), - * DoFLevel<3>::get_hex_dof_index(). The are able to traverse this + * accessor functions, DoFObjects::set_dof_index() and + * DoFLevel::get_dof_index() They are able to traverse this * list and pick out or set a DoF index given the finite element index * and its location within the set of DoFs corresponding to this * finite element. @@ -152,6 +149,12 @@ namespace internal */ std::vector active_fe_indices; + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; }; @@ -165,168 +168,21 @@ namespace internal template <> class DoFLevel<1> : public DoFLevel<0> { - private: - - /** - * Store the start index for - * the degrees of freedom of each - * line in the @p line_dofs array. - */ - std::vector line_dof_offsets; - - /** - * Store the global indices of - * the degrees of freedom. See - * DoFLevel() for detailed - * information. - */ - std::vector line_dofs; + private: + /** + * store the dof-indices and related functions of + * lines + */ + internal::hp::DoFObjects<1> lines; public: - - /** - * Set the global index of - * the @p local_index-th - * degree of freedom located - * on the line with number @p - * line_index to the value - * given by the last - * argument. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, denotes which of - * the finite elements - * associated with this - * object we shall - * access. Refer to the - * general documentation of - * the internal::hp::DoFLevel - * class template for more - * information. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - void - set_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<1> dummy); - - /** - * Return the global index of - * the @p local_index-th - * degree of freedom located - * on the line with number @p - * line_index. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, denotes which of - * the finite elements - * associated with this - * object we shall - * access. Refer to the - * general documentation of - * the internal::hp::DoFLevel - * class template for more - * information. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - unsigned int - get_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<1> dummy) const; - - /** - * Return the number of - * finite elements that are - * active on a given - * object. If this is a cell, - * the answer is of course - * one. If it is a face, the - * answer may be one or two, - * depending on whether the - * two adjacent cells use the - * same finite element or - * not. If it is an edge in - * 3d, the possible return - * value may be one or any - * other value larger than - * that. - * - * The last argument is used - * in the same way as for the - * other functions, i.e. it - * disambiguates between the - * different functions in the - * class hierarchy, whereas - * the template argument - * denotes the space - * dimension we operate in. - */ - template - unsigned int - n_active_fe_indices (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const StructuralDimension<1>) const; - - /** - * Check whether a given - * finite element index is - * used on the present - * object or not. - * - * The last argument is used - * in the same way as for the - * other functions, i.e. it - * disambiguates between the - * different functions in the - * class hierarchy, whereas - * the template argument - * denotes the space - * dimension we operate in. - */ - template - bool - fe_index_is_active (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const StructuralDimension<1>) const; - - /** - * Determine an estimate for the + /** + * Determine an estimate for the * memory consumption (in bytes) * of this object. */ unsigned int memory_consumption () const; - - /** + /** * Make the DoFHandler class * a friend, so that it can * resize arrays as @@ -344,179 +200,22 @@ namespace internal * @author Wolfgang Bangerth, 1998, 2006, Oliver Kayser-Herold 2003. */ template <> - class DoFLevel<2> : public DoFLevel<1> + class DoFLevel<2> : public DoFLevel<0> { - private: - - /** - * Store the start index for - * the degrees of freedom of each - * quad in the @p quad_dofs array. - */ - std::vector quad_dof_offsets; - - /** - * Store the global indices of - * the degrees of freedom. See - * DoFLevel() for detailed - * information. - */ - std::vector quad_dofs; + public: + /** + * store the dof-indices and related functions of + * quads + */ + internal::hp::DoFObjects<2> quads; public: - - /** - * Set the global index of - * the @p local_index-th - * degree of freedom located - * on the quad with number @p - * quad_index to the value - * given by the last - * argument. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, denotes which of - * the finite elements - * associated with this - * object we shall - * access. Refer to the - * general documentation of - * the internal::hp::DoFLevel - * class template for more - * information. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - void - set_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<2> dummy); - - /** - * Return the global index of - * the @p local_index-th - * degree of freedom located - * on the quad with number @p - * quad_index. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, denotes which of - * the finite elements - * associated with this - * object we shall - * access. Refer to the - * general documentation of - * the internal::hp::DoFLevel - * class template for more - * information. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - unsigned int - get_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<2> dummy) const; - - /** - * Return the number of - * finite elements that are - * active on a given - * object. If this is a cell, - * the answer is of course - * one. If it is a face, the - * answer may be one or two, - * depending on whether the - * two adjacent cells use the - * same finite element or - * not. If it is an edge in - * 3d, the possible return - * value may be one or any - * other value larger than - * that. - * - * The last argument is used - * in the same way as for the - * other functions, i.e. it - * disambiguates between the - * different functions in the - * class hierarchy, whereas - * the template argument - * denotes the space - * dimension we operate in. - */ - template - unsigned int - n_active_fe_indices (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - const StructuralDimension<2>) const; - - /** - * Check whether a given - * finite element index is - * used on the present - * object or not. - * - * The last argument is used - * in the same way as for the - * other functions, i.e. it - * disambiguates between the - * different functions in the - * class hierarchy, whereas - * the template argument - * denotes the space - * dimension we operate in. - */ - template - bool - fe_index_is_active (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const StructuralDimension<2>) const; - - /** - * Import the respective - * functions from the base - * class. - */ - using DoFLevel<1>::set_dof_index; - using DoFLevel<1>::get_dof_index; - using DoFLevel<1>::n_active_fe_indices; - using DoFLevel<1>::fe_index_is_active; - - /** + /** * Determine an estimate for the * memory consumption (in bytes) * of this object. */ unsigned int memory_consumption () const; - /** * Make the DoFHandler class * a friend, so that it can @@ -536,179 +235,22 @@ namespace internal * @author Wolfgang Bangerth, 1998, 2006, Oliver Kayser-Herold 2003. */ template <> - class DoFLevel<3> : public DoFLevel<2> + class DoFLevel<3> : public DoFLevel<0> { - private: - - /** - * Store the start index for - * the degrees of freedom of each - * hex in the @p hex_dofs array. - */ - std::vector hex_dof_offsets; - - /** - * Store the global indices of - * the degrees of freedom. See - * DoFLevel() for detailed - * information. - */ - std::vector hex_dofs; - - public: - - /** - * Set the global index of - * the @p local_index-th - * degree of freedom located - * on the hex with number @p - * hex_index to the value - * given by the last - * argument. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, denotes which of - * the finite elements - * associated with this - * object we shall - * access. Refer to the - * general documentation of - * the internal::hp::DoFLevel - * class template for more - * information. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - void - set_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<3> dummy); - - /** - * Return the global index of - * the @p local_index-th - * degree of freedom located - * on the hex with number @p - * hex_index. The @p - * dof_handler argument is - * used to access the finite - * element that is to be used - * to compute the location - * where this data is stored. - * - * The third argument, @p - * fe_index, denotes which of - * the finite elements - * associated with this - * object we shall - * access. Refer to the - * general documentation of - * the internal::hp::DoFLevel - * class template for more - * information. - * - * For the meaning of the - * last argument, see the - * general documentation of - * the - * internal::DoFHandler::DoFLevel - * class. - */ - template - unsigned int - get_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<3> dummy) const; - - /** - * Return the number of - * finite elements that are - * active on a given - * object. If this is a cell, - * the answer is of course - * one. If it is a face, the - * answer may be one or two, - * depending on whether the - * two adjacent cells use the - * same finite element or - * not. If it is an edge in - * 3d, the possible return - * value may be one or any - * other value larger than - * that. - * - * The last argument is used - * in the same way as for the - * other functions, i.e. it - * disambiguates between the - * different functions in the - * class hierarchy, whereas - * the template argument - * denotes the space - * dimension we operate in. - */ - template - unsigned int - n_active_fe_indices (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - const StructuralDimension<3>) const; - - /** - * Check whether a given - * finite element index is - * used on the present - * object or not. - * - * The last argument is used - * in the same way as for the - * other functions, i.e. it - * disambiguates between the - * different functions in the - * class hierarchy, whereas - * the template argument - * denotes the space - * dimension we operate in. - */ - template - bool - fe_index_is_active (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const StructuralDimension<3>) const; - - /** - * Import the respective - * functions from the base - * classes. + private: + /** + * store the dof-indices and related functions of + * hexes */ - using DoFLevel<2>::set_dof_index; - using DoFLevel<2>::get_dof_index; - using DoFLevel<2>::n_active_fe_indices; - using DoFLevel<2>::fe_index_is_active; + internal::hp::DoFObjects<3> hexes; - /** + public: + /** * Determine an estimate for the * memory consumption (in bytes) * of this object. */ unsigned int memory_consumption () const; - /** * Make the DoFHandler class * a friend, so that it can @@ -718,12 +260,6 @@ namespace internal template friend class ::hp::DoFHandler; }; - -// ------------------ inline and template functions - - - - } // namespace hp } // namespace internal diff --git a/deal.II/deal.II/include/dofs/hp_dof_objects.h b/deal.II/deal.II/include/dofs/hp_dof_objects.h new file mode 100644 index 0000000000..a3d6198a76 --- /dev/null +++ b/deal.II/deal.II/include/dofs/hp_dof_objects.h @@ -0,0 +1,238 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- +#ifndef __deal2__hp_dof_objects_h +#define __deal2__hp_dof_objects_h + +#include +#include + +#include + + +namespace internal +{ + namespace hp + { + +/** + * Store the indices of the degrees of freedom which are located on + * objects of dimension @p dim. + * + * The things we store here is very similar to what is stored in the + * internal::DoFHandler::DoFObjects classes (see there for more + * information, in particular on the layout of the class hierarchy, + * and the use of file names). + * + *

Offset computations

+ * + * For hp methods, not all cells may use the same finite element, and + * it is consequently more complicated to determine where the DoF + * indices for a given line, quad, or hex are stored. As described in + * the documentation of the internal::DoFHandler::DoFLevel class, we + * can compute the location of the first line DoF, for example, by + * calculating the offset as line_index * + * dof_handler.get_fe().dofs_per_line. This of course doesn't + * work any more if different lines may have different numbers of + * degrees of freedom associated with them. Consequently, rather than + * using this simple multiplication, the dofs array has an associated + * array dof_offsets. The data corresponding to a + * line then starts at index line_dof_offsets[line_index] + * within the line_dofs array. + * + * + *

Multiple data sets per object

+ * + * If an object corresponds to a cell, the global dof indices of this + * cell are stored at the location indicated above in sequential + * order. + * + * However, if two adjacent cells use different finite elements, then + * the face that they share needs to store DoF indices for both + * involved finite elements. While faces therefore have to have at + * most two sets of DoF indices, it is easy to see that vertices for + * example can have as many sets of DoF indices associated with them + * as there are adjacent cells, and the same holds for lines in 3d. + * + * Consequently, for objects that have a lower dimensionality than + * cells, we have to store a map from the finite element index to the + * set of DoF indices associated. Since real sets are typically very + * inefficient to store, and since most of the time we expect the + * number of individual keys to be small (frequently, adjacent cells + * will have the same finite element, and only a single entry will + * exist in the map), what we do is instead to store a linked list. In + * this format, the first entry starting at position + * lines.dofs[lines.dof_offsets[line_index]] will denote + * the finite element index of the set of DoF indices following; after + * this set, we will store the finite element index of the second set + * followed by the corresponding DoF indices; and so on. Finally, when + * all finite element indices adjacent to this object have been + * covered, we write a -1 to indicate the end of the list. + * + * Access to this kind of data, as well as the distinction between + * cells and objects of lower dimensionality are encoded in the + * accessor functions, DoFObjects::set_dof_index() and + * DoFLevel::get_dof_index() They are able to traverse this + * list and pick out or set a DoF index given the finite element index + * and its location within the set of DoFs corresponding to this + * finite element. + * + * + * @ingroup hp + * @author Tobias Leicht, 2006 + */ + + template + class DoFObjects + { + + private: + + /** + * Store the start index for + * the degrees of freedom of each + * hex in the @p hex_dofs array. + */ + std::vector dof_offsets; + + /** + * Store the global indices of + * the degrees of freedom. See + * DoFLevel() for detailed + * information. + */ + std::vector dofs; + + public: + + /** + * Set the global index of + * the @p local_index-th + * degree of freedom located + * on the hex with number @p + * hex_index to the value + * given by the last + * argument. The @p + * dof_handler argument is + * used to access the finite + * element that is to be used + * to compute the location + * where this data is stored. + * + * The third argument, @p + * fe_index, denotes which of + * the finite elements + * associated with this + * object we shall + * access. Refer to the + * general documentation of + * the internal::hp::DoFLevel + * class template for more + * information. + */ + template + void + set_dof_index (const ::hp::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index, + const unsigned int obj_level); + + /** + * Return the global index of + * the @p local_index-th + * degree of freedom located + * on the hex with number @p + * hex_index. The @p + * dof_handler argument is + * used to access the finite + * element that is to be used + * to compute the location + * where this data is stored. + * + * The third argument, @p + * fe_index, denotes which of + * the finite elements + * associated with this + * object we shall + * access. Refer to the + * general documentation of + * the internal::hp::DoFLevel + * class template for more + * information. + */ + template + unsigned int + get_dof_index (const ::hp::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int obj_level) const; + + /** + * Return the number of + * finite elements that are + * active on a given + * object. If this is a cell, + * the answer is of course + * one. If it is a face, the + * answer may be one or two, + * depending on whether the + * two adjacent cells use the + * same finite element or + * not. If it is an edge in + * 3d, the possible return + * value may be one or any + * other value larger than + * that. + */ + template + unsigned int + n_active_fe_indices (const ::hp::DoFHandler &dof_handler, + const unsigned int obj_index) const; + + /** + * Check whether a given + * finite element index is + * used on the present + * object or not. + */ + template + bool + fe_index_is_active (const ::hp::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int obj_level) const; + + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + + /** + * Make the DoFHandler class + * a friend, so that it can + * resize arrays as + * necessary. + */ + template friend class ::hp::DoFHandler; + }; + } +} + +#endif + + + diff --git a/deal.II/deal.II/include/grid/tria.h b/deal.II/deal.II/include/grid/tria.h index 5f31767820..201f409e7d 100644 --- a/deal.II/deal.II/include/grid/tria.h +++ b/deal.II/deal.II/include/grid/tria.h @@ -31,6 +31,7 @@ namespace internal namespace Triangulation { template class TriaLevel; + template class TriaFaces; } } template class DoFHandler; @@ -2016,32 +2017,30 @@ class Triangulation : public Subscriptor /*@{*/ /** * Iterator to the first face, used - * or not, on level @p level. If a level - * has no faces, a past-the-end iterator - * is returned. + * or not. As faces have no level, + * no argument can be given. * * This function calls @p begin_raw_line * in 2D and @p begin_raw_quad in 3D. */ - raw_face_iterator begin_raw_face (const unsigned int level = 0) const; + raw_face_iterator begin_raw_face () const; /** - * Iterator to the first used face - * on level @p level. + * Iterator to the first used face. * * This function calls @p begin_line * in 2D and @p begin_quad in 3D. */ - face_iterator begin_face (const unsigned int level = 0) const; + face_iterator begin_face () const; /** * Iterator to the first active - * face on level @p level. + * face. * * This function calls @p begin_active_line * in 2D and @p begin_active_quad in 3D. */ - active_face_iterator begin_active_face(const unsigned int level = 0) const; + active_face_iterator begin_active_face() const; /** * Iterator past the end; this @@ -2055,28 +2054,18 @@ class Triangulation : public Subscriptor raw_face_iterator end_face () const; /** - * Return an iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). + * Return a raw iterator which is past the end. + * This is the same as end() and is + * only for combatibility with older versions. */ - face_iterator end_face (const unsigned int level) const; - - /** - * Return a raw iterator which is the first - * iterator not on level. If @p level is - * the last level, then this returns - * end(). - */ - raw_face_iterator end_raw_face (const unsigned int level) const; + raw_face_iterator end_raw_face () const; /** - * Return an active iterator which is the - * first iterator not on level. If @p level - * is the last level, then this returns - * end(). + * Return an active iterator which is past the end. + * This is the same as end() and is + * only for combatibility with older versions. */ - active_face_iterator end_active_face (const unsigned int level) const; + active_face_iterator end_active_face () const; /** * Return an iterator pointing to the @@ -2087,15 +2076,6 @@ class Triangulation : public Subscriptor */ raw_face_iterator last_raw_face () const; - /** - * Return an iterator pointing to the last - * face of the level @p level, used or not. - * - * This function calls @p last_raw_line - * in 2D and @p last_raw_quad in 3D. - */ - raw_face_iterator last_raw_face (const unsigned int level) const; - /** * Return an iterator pointing to the last * used face. @@ -2105,15 +2085,6 @@ class Triangulation : public Subscriptor */ face_iterator last_face () const; - /** - * Return an iterator pointing to the last - * used face on level @p level. - * - * This function calls @p last_line - * in 2D and @p last_quad in 3D. - */ - face_iterator last_face (const unsigned int level) const; - /** * Return an iterator pointing to the last * active face. @@ -2123,14 +2094,6 @@ class Triangulation : public Subscriptor */ active_face_iterator last_active_face () const; - /** - * Return an iterator pointing to the last - * active face on level @p level. - * - * This function calls @p last_active_line - * in 2D and @p last_active_quad in 3D. - */ - active_face_iterator last_active_face (const unsigned int level) const; /*@}*/ @@ -2145,6 +2108,10 @@ class Triangulation : public Subscriptor * or not, on level @p level. If a level * has no lines, a past-the-end iterator * is returned. + * If lines are no cells, i.e. for @p dim>1 + * no @p level argument must be given. + * The same applies for all the other functions + * above, of course. */ raw_line_iterator begin_raw_line (const unsigned int level = 0) const; @@ -2251,6 +2218,9 @@ class Triangulation : public Subscriptor * or not, on level @p level. If a level * has no quads, a past-the-end iterator * is returned. + * If quads are no cells, i.e. for @p dim>2 + * no #level argument must be given. + */ raw_quad_iterator begin_raw_quad (const unsigned int level = 0) const; @@ -2459,6 +2429,23 @@ class Triangulation : public Subscriptor */ /*@{*/ + /** + * In the following, most functions are provided in two + * versions, with and without an argument describing + * the level. The versions with this argument are only + * applicable for objects descibing the cells of the + * present triangulation. For example: in 2d + * n_lines(level) cannot be called, only + * n_lines(), as lines are faces in 2d and + * therefore have no level. + */ + + /** + * Total Number of lines, used or + * unused. + */ + unsigned int n_raw_lines () const; + /** * Number of lines, used or * unused, on the given level. @@ -2488,6 +2475,12 @@ class Triangulation : public Subscriptor */ unsigned int n_active_lines (const unsigned int level) const; + /** + * Total number of quads, used or + * unused. + */ + unsigned int n_raw_quads () const; + /** * Number of quads, used or * unused, on the given level. @@ -2518,6 +2511,12 @@ class Triangulation : public Subscriptor */ unsigned int n_active_quads (const unsigned int level) const; + /** + * Total number of hexs, used or + * unused. + */ + unsigned int n_raw_hexs () const; + /** * Number of hexs, used or * unused, on the given level. @@ -2593,14 +2592,6 @@ class Triangulation : public Subscriptor */ unsigned int n_faces () const; - /** - * Return total number of used faces, - * active or not, on level @p level. - * Maps to n_lines(level) in two space - * dimensions and so on. - */ - unsigned int n_faces (const unsigned int level) const; - /** * Return total number of active faces. * Maps to n_active_lines() in two space @@ -2608,14 +2599,6 @@ class Triangulation : public Subscriptor */ unsigned int n_active_faces () const; - /** - * Return total number of active faces - * on level @p level. - * Maps to n_active_lines(level) in two - * space dimensions and so on. - */ - unsigned int n_active_faces (const unsigned int level) const; - /** * Return number of levels in use. This * may be less than the number of levels @@ -2735,7 +2718,7 @@ class Triangulation : public Subscriptor /*@{*/ /** * Exception - * @ingroup Exceptions + * @ingroup Exceptions */ DeclException1 (ExcInvalidLevel, int, @@ -2743,17 +2726,17 @@ class Triangulation : public Subscriptor << " is not in the valid range!"); /** * Exception - * @ingroup Exceptions + * @ingroup Exceptions */ DeclException0 (ExcCellShouldBeUnused); /** * Exception - * @ingroup Exceptions + * @ingroup Exceptions */ DeclException0 (ExcTooFewVerticesAllocated); /** * Exception - * @ingroup Exceptions + * @ingroup Exceptions */ DeclException0 (ExcUncaughtState); /** @@ -2854,6 +2837,11 @@ class Triangulation : public Subscriptor * @ingroup Exceptions */ DeclException0 (ExcInteriorQuadCantBeBoundary); + /** + * Exception + * @ingroup Exceptions + */ + DeclException0 (ExcFacesHaveNoLevel); /** * Exception * @ingroup Exceptions @@ -3031,11 +3019,21 @@ class Triangulation : public Subscriptor /** * Array of pointers pointing to the - * objects storing the data on the + * objects storing the cell data on the * different levels. */ std::vector*> levels; + /** + * Pointer to the faces of the triangulation. In 1d + * this contains nothing, in 2d it contains data + * concerning lines and in 3d quads and lines. All of + * these have no level and are therefore treated + * seperately. + */ + internal::Triangulation::TriaFaces * faces; + + /** * Array of the vertices of this * triangulation. @@ -3114,6 +3112,7 @@ class Triangulation : public Subscriptor friend class TriaRawIterator<3,CellAccessor<3> >; friend class hp::DoFHandler; + }; @@ -3180,16 +3179,13 @@ template <> Triangulation<1>::cell_iterator Triangulation<1>::last () const; template <> Triangulation<1>::cell_iterator Triangulation<1>::last (const unsigned int level) const; template <> Triangulation<1>::active_cell_iterator Triangulation<1>::last_active () const; template <> Triangulation<1>::active_cell_iterator Triangulation<1>::last_active (const unsigned int level) const; -template <> Triangulation<1>::raw_face_iterator Triangulation<1>::begin_raw_face (const unsigned int) const; -template <> Triangulation<1>::face_iterator Triangulation<1>::begin_face (const unsigned int) const; -template <> Triangulation<1>::active_face_iterator Triangulation<1>::begin_active_face (const unsigned int) const; +template <> Triangulation<1>::raw_face_iterator Triangulation<1>::begin_raw_face () const; +template <> Triangulation<1>::face_iterator Triangulation<1>::begin_face () const; +template <> Triangulation<1>::active_face_iterator Triangulation<1>::begin_active_face () const; template <> Triangulation<1>::raw_face_iterator Triangulation<1>::end_face () const; template <> Triangulation<1>::raw_face_iterator Triangulation<1>::last_raw_face () const; -template <> Triangulation<1>::raw_face_iterator Triangulation<1>::last_raw_face (const unsigned int) const; template <> Triangulation<1>::face_iterator Triangulation<1>::last_face () const; -template <> Triangulation<1>::face_iterator Triangulation<1>::last_face (const unsigned int) const; template <> Triangulation<1>::active_face_iterator Triangulation<1>::last_active_face () const; -template <> Triangulation<1>::active_face_iterator Triangulation<1>::last_active_face (const unsigned int) const; template <> Triangulation<1>::raw_quad_iterator Triangulation<1>::begin_raw_quad (const unsigned int) const; template <> Triangulation<1>::quad_iterator Triangulation<1>::begin_quad (const unsigned int) const; template <> Triangulation<1>::active_quad_iterator Triangulation<1>::begin_active_quad (const unsigned int) const; @@ -3218,16 +3214,13 @@ template <> Triangulation<2>::cell_iterator Triangulation<2>::last () const; template <> Triangulation<2>::cell_iterator Triangulation<2>::last (const unsigned int level) const; template <> Triangulation<2>::active_cell_iterator Triangulation<2>::last_active () const; template <> Triangulation<2>::active_cell_iterator Triangulation<2>::last_active (const unsigned int level) const; -template <> Triangulation<2>::raw_face_iterator Triangulation<2>::begin_raw_face (const unsigned int level) const; -template <> Triangulation<2>::face_iterator Triangulation<2>::begin_face (const unsigned int level) const; -template <> Triangulation<2>::active_face_iterator Triangulation<2>::begin_active_face (const unsigned int level) const; +template <> Triangulation<2>::raw_face_iterator Triangulation<2>::begin_raw_face () const; +template <> Triangulation<2>::face_iterator Triangulation<2>::begin_face () const; +template <> Triangulation<2>::active_face_iterator Triangulation<2>::begin_active_face () const; template <> Triangulation<2>::raw_face_iterator Triangulation<2>::end_face () const; template <> Triangulation<2>::raw_face_iterator Triangulation<2>::last_raw_face () const; -template <> Triangulation<2>::raw_face_iterator Triangulation<2>::last_raw_face (const unsigned int level) const; template <> Triangulation<2>::face_iterator Triangulation<2>::last_face () const; -template <> Triangulation<2>::face_iterator Triangulation<2>::last_face (const unsigned int level) const; template <> Triangulation<2>::active_face_iterator Triangulation<2>::last_active_face () const; -template <> Triangulation<2>::active_face_iterator Triangulation<2>::last_active_face (const unsigned int level) const; template <> Triangulation<2>::raw_hex_iterator Triangulation<2>::begin_raw_hex (const unsigned int) const; template <> Triangulation<2>::hex_iterator Triangulation<2>::begin_hex (const unsigned int) const; template <> Triangulation<2>::active_hex_iterator Triangulation<2>::begin_active_hex (const unsigned int) const; @@ -3246,17 +3239,13 @@ template <> Triangulation<3>::cell_iterator Triangulation<3>::last () const; template <> Triangulation<3>::cell_iterator Triangulation<3>::last (const unsigned int level) const; template <> Triangulation<3>::active_cell_iterator Triangulation<3>::last_active () const; template <> Triangulation<3>::active_cell_iterator Triangulation<3>::last_active (const unsigned int level) const; -template <> Triangulation<3>::raw_face_iterator Triangulation<3>::begin_raw_face (const unsigned int level) const; -template <> Triangulation<3>::face_iterator Triangulation<3>::begin_face (const unsigned int level) const; -template <> Triangulation<3>::active_face_iterator Triangulation<3>::begin_active_face (const unsigned int level) const; +template <> Triangulation<3>::raw_face_iterator Triangulation<3>::begin_raw_face () const; +template <> Triangulation<3>::face_iterator Triangulation<3>::begin_face () const; +template <> Triangulation<3>::active_face_iterator Triangulation<3>::begin_active_face () const; template <> Triangulation<3>::raw_face_iterator Triangulation<3>::end_face () const; template <> Triangulation<3>::raw_face_iterator Triangulation<3>::last_raw_face () const; -template <> Triangulation<3>::raw_face_iterator Triangulation<3>::last_raw_face (const unsigned int level) const; template <> Triangulation<3>::face_iterator Triangulation<3>::last_face () const; -template <> Triangulation<3>::face_iterator Triangulation<3>::last_face (const unsigned int level) const; template <> Triangulation<3>::active_face_iterator Triangulation<3>::last_active_face () const; -template <> Triangulation<3>::active_face_iterator Triangulation<3>::last_active_face (const unsigned int level) const; - template <> unsigned int Triangulation<1>::n_raw_cells (const unsigned int level) const; template <> unsigned int Triangulation<1>::n_cells (const unsigned int level) const; template <> unsigned int Triangulation<1>::n_active_cells (const unsigned int level) const; diff --git a/deal.II/deal.II/include/grid/tria_accessor.h b/deal.II/deal.II/include/grid/tria_accessor.h index 0abcef35b3..383bbe1c8a 100644 --- a/deal.II/deal.II/include/grid/tria_accessor.h +++ b/deal.II/deal.II/include/grid/tria_accessor.h @@ -104,6 +104,13 @@ namespace std * "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 * @ingroup Accessors * @author Wolfgang Bangerth, 1998 @@ -198,6 +205,7 @@ class TriaAccessor /** * Return the level the element * pointed to belongs to. + * This is only valid for cells. */ int level () const; @@ -282,12 +290,18 @@ class TriaAccessor * @ingroup Exceptions */ DeclException0 (ExcNeighborIsNotCoarser); + /** + * @ingroup Exceptions + */ + DeclException0 (ExcFacesHaveNoLevel); /*@}*/ protected: /** * Used to store the level - * presently pointed to. + * presently pointed to. For + * faces this should always be + * 0. */ int present_level; @@ -565,9 +579,11 @@ class TriaObjectAccessor : public TriaAccessor * Index of the @p ith child. * The level of the child is one * higher than that of the - * present cell. If the child - * does not exist, -1 is - * returned. + * present cell, if the children + * of a cell are accessed. The + * children of faces have no level. + * If the child does not exist, -1 + * is returned. */ int child_index (const unsigned int i) const; @@ -797,6 +813,7 @@ class TriaObjectAccessor : public TriaAccessor * This operator advances the * iterator to the next element. * + * For cells only: * The next element is next on * this level if there are * more. If the present element @@ -811,6 +828,7 @@ class TriaObjectAccessor : public TriaAccessor * iterator to the previous * element. * + * For cells only: * The previous element is * previous on this level if * index>0. If the present @@ -1054,8 +1072,11 @@ class TriaObjectAccessor<1, dim> : public TriaAccessor * Return the index of the * @p ith child. The level of * the child is one higher than - * that of the present cell. If - * the child does not exist, -1 + * that of the present cell if + * @p dim=1 and lines are cells. + * Otherwise the line and its children + * have no level. + * If the child does not exist, -1 * is returned. */ int child_index (const unsigned int i) const; @@ -1069,7 +1090,10 @@ class TriaObjectAccessor<1, dim> : public TriaAccessor * given. The level of the child * is one level up of the level * of the cell to which this - * iterator points. + * iterator points if + * @p dim=1 and lines are cells. + * Otherwise the line and its children + * have no level. */ void set_children (const int index) const; @@ -1295,6 +1319,7 @@ class TriaObjectAccessor<1, dim> : public TriaAccessor * This operator advances the * iterator to the next element. * + * For @p dim=1 only: * The next element is next on * this level if there are * more. If the present element @@ -1309,6 +1334,7 @@ class TriaObjectAccessor<1, dim> : public TriaAccessor * iterator to the previous * element. * + * For @p dim=1 only: * The previous element is * previous on this level if * index>0. If the present @@ -1397,8 +1423,7 @@ class TriaObjectAccessor<2, dim> : public TriaAccessor /** * Return the line index of the * @p ith side (a line). The - * level is naturally the same as - * that of the quad. + * line has no level. */ unsigned int line_index (const unsigned int i) const; @@ -1545,8 +1570,11 @@ class TriaObjectAccessor<2, dim> : public TriaAccessor * Return the index of the * @p ith child. The level of * the child is one higher than - * that of the present cell. If - * the child does not exist, -1 + * that of the present cell if + * @p dim=2 and quads are cells. + * Otherwise the quad and its children + * have no level. + * If the child does not exist, -1 * is returned. */ int child_index (const unsigned int i) const; @@ -1812,6 +1840,7 @@ class TriaObjectAccessor<2, dim> : public TriaAccessor * This operator advances the * iterator to the next element. * + * For @p dim=2 only: * The next element is next on * this level if there are * more. If the present element @@ -1826,6 +1855,7 @@ class TriaObjectAccessor<2, dim> : public TriaAccessor * iterator to the previous * element. * + * For @p dim=2 only: * The previous element is * previous on this level if * index>0. If the present @@ -1912,9 +1942,8 @@ class TriaObjectAccessor<3, dim> : public TriaAccessor /** * Return the line index of the - * @p ith line. The level is - * naturally the same as that of - * the hex. + * @p ith line. The line has no + * level. */ unsigned int line_index (const unsigned int i) const; @@ -1928,9 +1957,8 @@ class TriaObjectAccessor<3, dim> : public TriaAccessor /** * Return the quad index of the - * @p ith side (a quad). The - * level is naturally the same as - * that of the hex. + * @p ith side (a quad). The quad + * has no level. */ unsigned int quad_index (const unsigned int i) const; 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 105f2bfc0e..34a0137ccb 100644 --- a/deal.II/deal.II/include/grid/tria_accessor.templates.h +++ b/deal.II/deal.II/include/grid/tria_accessor.templates.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -105,7 +106,7 @@ TriaAccessor::state () const if ((present_level>=0) && (present_index>=0)) return IteratorState::valid; else - if ((present_level==-1) && (present_index==-1)) + if ((present_index==-1) && (present_index==-1)) return IteratorState::past_the_end; else return IteratorState::invalid; @@ -145,6 +146,19 @@ TriaObjectAccessor<1,dim>::used () const { Assert (this->state() == IteratorState::valid, typename TriaAccessor::ExcDereferenceInvalidObject()); + return this->tria->faces->lines.used[this->present_index]; +} + + + +template <> +inline +bool +TriaObjectAccessor<1,1>::used () const +{ + const int dim=1; + Assert (this->state() == IteratorState::valid, + TriaAccessor::ExcDereferenceInvalidObject()); return this->tria->levels[this->present_level]->lines.used[this->present_index]; } @@ -156,6 +170,18 @@ bool TriaObjectAccessor<1,dim>::user_flag_set () const { Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); + return this->tria->faces->lines.user_flags[this->present_index]; +} + + + +template <> +inline +bool +TriaObjectAccessor<1,1>::user_flag_set () const +{ + const int dim=1; + Assert (this->used(), TriaAccessor::ExcCellNotUsed()); return this->tria->levels[this->present_level]->lines.user_flags[this->present_index]; } @@ -164,9 +190,21 @@ TriaObjectAccessor<1,dim>::user_flag_set () const template inline void -TriaObjectAccessor<1,dim>::set_user_flag () const +TriaObjectAccessor<1,dim>::set_user_flag () const { Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); + this->tria->faces->lines.user_flags[this->present_index] = true; +} + + + +template <> +inline +void +TriaObjectAccessor<1,1>::set_user_flag () const +{ + const int dim=1; + Assert (this->used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->lines.user_flags[this->present_index] = true; } @@ -178,6 +216,18 @@ void TriaObjectAccessor<1,dim>::clear_user_flag () const { Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); + this->tria->faces->lines.user_flags[this->present_index] = false; +} + + + +template <> +inline +void +TriaObjectAccessor<1,1>::clear_user_flag () const +{ + const int dim=1; + Assert (this->used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->lines.user_flags[this->present_index] = false; } @@ -185,18 +235,25 @@ TriaObjectAccessor<1,dim>::clear_user_flag () const template inline -TriaIterator > -TriaObjectAccessor<1,dim>::child (const unsigned int i) const +bool +TriaObjectAccessor<1,dim>::has_children () const { - Assert (i<2, ExcIndexRange(i,0,2)); - - TriaIterator > - q (this->tria, this->present_level+1, child_index (i)); - - Assert ((q.state() == IteratorState::past_the_end) || q->used(), - typename TriaAccessor::ExcUnusedCellAsChild()); + Assert (this->state() == IteratorState::valid, + typename TriaAccessor::ExcDereferenceInvalidObject()); + return (this->tria->faces->lines.children[this->present_index] != -1); +} - return q; + + +template <> +inline +bool +TriaObjectAccessor<1,1>::has_children () const +{ + const int dim=1; + Assert (this->state() == IteratorState::valid, + TriaAccessor::ExcDereferenceInvalidObject()); + return (this->tria->levels[this->present_level]->lines.children[this->present_index] != -1); } @@ -208,6 +265,19 @@ TriaObjectAccessor<1,dim>::child_index (unsigned const int i) const { Assert (i<2, ExcIndexRange(i,0,2)); Assert (has_children(), typename TriaAccessor::ExcCellHasNoChildren()); + return this->tria->faces->lines.children[this->present_index]+i; +} + + + +template <> +inline +int +TriaObjectAccessor<1,1>::child_index (unsigned const int i) const +{ + const int dim=1; + Assert (i<2, ExcIndexRange(i,0,2)); + Assert (has_children(), TriaAccessor::ExcCellHasNoChildren()); return this->tria->levels[this->present_level]->lines.children[this->present_index]+i; } @@ -215,15 +285,27 @@ TriaObjectAccessor<1,dim>::child_index (unsigned const int i) const template inline -bool -TriaObjectAccessor<1,dim>::has_children () const +TriaIterator > +TriaObjectAccessor<1,dim>::child (const unsigned int i) const { - Assert (this->state() == IteratorState::valid, - typename TriaAccessor::ExcDereferenceInvalidObject()); - return (this->tria->levels[this->present_level]->lines.children[this->present_index] != -1); + Assert (i<2, ExcIndexRange(i,0,2)); + int next_level; + if (dim==1) + next_level = this->present_level+1; + else + next_level = 0; + + TriaIterator > + q (this->tria, next_level, child_index (i)); + + Assert ((q.state() == IteratorState::past_the_end) || q->used(), + typename TriaAccessor::ExcUnusedCellAsChild()); + + return q; } + template inline unsigned int @@ -234,6 +316,7 @@ TriaObjectAccessor<1,dim>::n_children () const } + template inline unsigned int @@ -263,13 +346,29 @@ template inline void TriaObjectAccessor<1,dim>::operator ++ () +{ + ++this->present_index; + // is index still in the range of + // the vector? + if (this->present_index + >= + static_cast(this->tria->faces->lines.cells.size())) + this->present_level = this->present_index = -1; +} + + + +template <> +inline +void +TriaObjectAccessor<1,1>::operator ++ () { ++this->present_index; // is index still in the range of // the vector? while (this->present_index >= - static_cast(this->tria->levels[this->present_level]->lines.lines.size())) + static_cast(this->tria->levels[this->present_level]->lines.cells.size())) { // no -> go one level up until we find // one with more than zero cells @@ -281,8 +380,8 @@ TriaObjectAccessor<1,dim>::operator ++ () // return with past the end pointer this->present_level = this->present_index = -1; return; - }; - }; + } + } } @@ -291,6 +390,20 @@ template inline void TriaObjectAccessor<1,dim>::operator -- () +{ + --this->present_index; + // is index still in the range of + // the vector? + if (this->present_index <0 ) + this->present_level = this->present_index = -1; + return; +} + + +template <> +inline +void +TriaObjectAccessor<1,1>::operator -- () { --this->present_index; // is index still in the range of @@ -305,10 +418,10 @@ TriaObjectAccessor<1,dim>::operator -- () // return with past the end pointer this->present_level = this->present_index = -1; return; - }; - // else - this->present_index = this->tria->levels[this->present_level]->lines.lines.size()-1; - }; + } + // else + this->present_index = this->tria->levels[this->present_level]->lines.cells.size()-1; + } } @@ -335,6 +448,19 @@ TriaObjectAccessor<2,dim>::used () const { Assert (this->state() == IteratorState::valid, typename TriaAccessor::ExcDereferenceInvalidObject()); + return this->tria->faces->quads.used[this->present_index]; +} + + + +template <> +inline +bool +TriaObjectAccessor<2,2>::used () const +{ + const int dim=2; + Assert (this->state() == IteratorState::valid, + TriaAccessor::ExcDereferenceInvalidObject()); return this->tria->levels[this->present_level]->quads.used[this->present_index]; } @@ -346,6 +472,18 @@ bool TriaObjectAccessor<2,dim>::user_flag_set () const { Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); + return this->tria->faces->quads.user_flags[this->present_index]; +} + + + +template <> +inline +bool +TriaObjectAccessor<2,2>::user_flag_set () const +{ + const int dim=2; + Assert (this->used(), TriaAccessor::ExcCellNotUsed()); return this->tria->levels[this->present_level]->quads.user_flags[this->present_index]; } @@ -357,6 +495,18 @@ void TriaObjectAccessor<2,dim>::set_user_flag () const { Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); + this->tria->faces->quads.user_flags[this->present_index] = true; +} + + + +template <> +inline +void +TriaObjectAccessor<2,2>::set_user_flag () const +{ + const int dim=2; + Assert (this->used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->quads.user_flags[this->present_index] = true; } @@ -368,6 +518,18 @@ void TriaObjectAccessor<2,dim>::clear_user_flag () const { Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); + this->tria->faces->quads.user_flags[this->present_index] = false; +} + + + +template <> +inline +void +TriaObjectAccessor<2,2>::clear_user_flag () const +{ + const int dim=2; + Assert (this->used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->quads.user_flags[this->present_index] = false; } @@ -382,7 +544,7 @@ TriaObjectAccessor<2,dim>::line (const unsigned int i) const TriaIterator > ( this->tria, - this->present_level, + 0, line_index (i) ); } @@ -395,26 +557,40 @@ unsigned int TriaObjectAccessor<2,dim>::line_index (const unsigned int i) const { Assert (i<4, ExcIndexRange(i,0,4)); - - return this->tria->levels[this->present_level]->quads.quads[this->present_index].line(i); + return this->tria->faces->quads.cells[this->present_index].line(i); } +template <> +inline +unsigned int +TriaObjectAccessor<2,2>::line_index (const unsigned int i) const +{ +Assert (i<4, ExcIndexRange(i,0,4)); + return this->tria->levels[this->present_level]->quads.cells[this->present_index].line(i); +} template inline -TriaIterator > -TriaObjectAccessor<2,dim>::child (const unsigned int i) const +bool +TriaObjectAccessor<2,dim>::has_children () const { - Assert (i<4, ExcIndexRange(i,0,4)); - - TriaIterator > - q (this->tria, this->present_level+1, child_index (i)); - - Assert ((q.state() == IteratorState::past_the_end) || q->used(), - typename TriaAccessor::ExcUnusedCellAsChild()); + Assert (this->state() == IteratorState::valid, + typename TriaAccessor::ExcDereferenceInvalidObject()); + return (this->tria->faces->quads.children[this->present_index] != -1); +} - return q; + + +template <> +inline +bool +TriaObjectAccessor<2,2>::has_children () const +{ + const int dim=2; + Assert (this->state() == IteratorState::valid, + TriaAccessor::ExcDereferenceInvalidObject()); + return (this->tria->levels[this->present_level]->quads.children[this->present_index] != -1); } @@ -425,6 +601,18 @@ int TriaObjectAccessor<2,dim>::child_index (const unsigned int i) const { Assert (i<4, ExcIndexRange(i,0,4)); Assert (has_children(), typename TriaAccessor::ExcCellHasNoChildren()); + return this->tria->faces->quads.children[this->present_index]+i; +} + + + +template <> +inline +int TriaObjectAccessor<2,2>::child_index (const unsigned int i) const +{ + const int dim=2; + Assert (i<4, ExcIndexRange(i,0,4)); + Assert (has_children(), TriaAccessor::ExcCellHasNoChildren()); return this->tria->levels[this->present_level]->quads.children[this->present_index]+i; } @@ -432,15 +620,27 @@ int TriaObjectAccessor<2,dim>::child_index (const unsigned int i) const template inline -bool -TriaObjectAccessor<2,dim>::has_children () const +TriaIterator > +TriaObjectAccessor<2,dim>::child (const unsigned int i) const { - Assert (this->state() == IteratorState::valid, - typename TriaAccessor::ExcDereferenceInvalidObject()); - return (this->tria->levels[this->present_level]->quads.children[this->present_index] != -1); + Assert (i<4, ExcIndexRange(i,0,4)); + int next_level; + if (dim==2) + next_level = this->present_level+1; + else + next_level = 0; + + TriaIterator > + q (this->tria, next_level, child_index (i)); + + Assert ((q.state() == IteratorState::past_the_end) || q->used(), + typename TriaAccessor::ExcUnusedCellAsChild()); + + return q; } + template inline unsigned int @@ -484,13 +684,29 @@ template inline void TriaObjectAccessor<2,dim>::operator ++ () +{ + ++this->present_index; + // is index still in the range of + // the vector? + if (this->present_index + >= + static_cast(this->tria->faces->quads.cells.size())) + this->present_level = this->present_index = -1; +} + + + +template <> +inline +void +TriaObjectAccessor<2,2>::operator ++ () { ++this->present_index; // is index still in the range of // the vector? while (this->present_index >= - static_cast(this->tria->levels[this->present_level]->quads.quads.size())) + static_cast(this->tria->levels[this->present_level]->quads.cells.size())) { // no -> go one level up ++this->present_level; @@ -501,8 +717,8 @@ TriaObjectAccessor<2,dim>::operator ++ () // return with past the end pointer this->present_level = this->present_index = -1; return; - }; - }; + } + } } @@ -511,6 +727,19 @@ template inline void TriaObjectAccessor<2,dim>::operator -- () +{ + --this->present_index; + // is index still in the range of + // the vector? + if (this->present_index<0) + this->present_level = this->present_index = -1; +} + + +template <> +inline +void +TriaObjectAccessor<2,2>::operator -- () { --this->present_index; // is index still in the range of @@ -525,10 +754,10 @@ TriaObjectAccessor<2,dim>::operator -- () // return with past the end pointer this->present_level = this->present_index = -1; return; - }; + } // else - this->present_index = this->tria->levels[this->present_level]->quads.quads.size()-1; - }; + this->present_index = this->tria->levels[this->present_level]->quads.cells.size()-1; + } } @@ -548,46 +777,50 @@ TriaObjectAccessor (const Triangulation *parent, -template +template <> inline bool -TriaObjectAccessor<3,dim>::used () const +TriaObjectAccessor<3,3>::used () const { + const int dim=3; Assert (this->state() == IteratorState::valid, - typename TriaAccessor::ExcDereferenceInvalidObject()); - return this->tria->levels[this->present_level]->hexes.used[this->present_index]; + TriaAccessor::ExcDereferenceInvalidObject()); + return this->tria->levels[this->present_level]->hexes.used[this->present_index]; } -template +template <> inline bool -TriaObjectAccessor<3,dim>::user_flag_set () const +TriaObjectAccessor<3,3>::user_flag_set () const { - Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); - return this->tria->levels[this->present_level]->hexes.user_flags[this->present_index]; + const int dim=3; + Assert (this->used(), TriaAccessor::ExcCellNotUsed()); + return this->tria->levels[this->present_level]->hexes.user_flags[this->present_index]; } -template +template <> inline void -TriaObjectAccessor<3,dim>::set_user_flag () const +TriaObjectAccessor<3,3>::set_user_flag () const { - Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); - this->tria->levels[this->present_level]->hexes.user_flags[this->present_index] = true; + const int dim=3; + Assert (this->used(), TriaAccessor::ExcCellNotUsed()); + this->tria->levels[this->present_level]->hexes.user_flags[this->present_index] = true; } -template +template <> inline -void TriaObjectAccessor<3,dim>::clear_user_flag () const +void TriaObjectAccessor<3,3>::clear_user_flag () const { - Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); - this->tria->levels[this->present_level]->hexes.user_flags[this->present_index] = false; + const int dim=3; + Assert (this->used(), TriaAccessor::ExcCellNotUsed()); + this->tria->levels[this->present_level]->hexes.user_flags[this->present_index] = false; } @@ -598,38 +831,13 @@ TriaIterator > TriaObjectAccessor<3,dim>::line (const unsigned int i) const { Assert (this->used(), typename TriaAccessor::ExcCellNotUsed()); - Assert (i<12, ExcIndexRange (i,0,12)); - - // get the line index by asking the - // quads. make sure we handle - // reverted faces correctly - // - // so set up a table that for each - // line describes a) from which - // quad to take it, b) which line - // therein it is if the face is - // oriented correctly, and c) if in - // the opposite direction - static const unsigned int lookup_table[12][3] = - { { 4, 0, 2 }, // take first four lines from bottom face - { 4, 1, 3 }, - { 4, 2, 0 }, - { 4, 3, 1 }, - - { 5, 0, 2 }, // second four lines from top face - { 5, 1, 3 }, - { 5, 2, 0 }, - { 5, 3, 1 }, - - { 0, 0, 2 }, // the rest randomly - { 1, 0, 2 }, - { 0, 1, 3 }, - { 1, 1, 3 }}; - - return (this->quad(lookup_table[i][0]) - ->line(face_orientation(lookup_table[i][0]) ? - lookup_table[i][1] : - lookup_table[i][2])); + return + TriaIterator > + ( + this->tria, + 0, + line_index (i) + ); } @@ -644,7 +852,7 @@ TriaObjectAccessor<3,dim>::quad (const unsigned int i) const TriaIterator > ( this->tria, - this->present_level, + 0, quad_index (i) ); } @@ -692,57 +900,60 @@ TriaObjectAccessor<3,dim>::line_index (const unsigned int i) const -template +template <> inline unsigned int -TriaObjectAccessor<3,dim>::quad_index (const unsigned int i) const +TriaObjectAccessor<3,3>::quad_index (const unsigned int i) const { Assert (i<6, ExcIndexRange(i,0,6)); - return this->tria->levels[this->present_level]->hexes.hexes[this->present_index].quad(i); + return this->tria->levels[this->present_level]->hexes.cells[this->present_index].quad(i); } -template +template <> inline -TriaIterator > -TriaObjectAccessor<3,dim>::child (const unsigned int i) const +bool +TriaObjectAccessor<3,3>::has_children () const { - Assert (i<8, ExcIndexRange(i,0,8)); - - TriaIterator > q (this->tria, this->present_level+1, child_index (i)); - - Assert ((q.state() == IteratorState::past_the_end) || q->used(), - typename TriaAccessor::ExcUnusedCellAsChild()); - - return q; + const int dim=3; + Assert (this->state() == IteratorState::valid, + TriaAccessor::ExcDereferenceInvalidObject()); + return (this->tria->levels[this->present_level]->hexes.children[this->present_index] != -1); } - -template +template <> inline -int TriaObjectAccessor<3,dim>::child_index (const unsigned int i) const +int TriaObjectAccessor<3,3>::child_index (const unsigned int i) const { + const int dim=3; Assert (i<8, ExcIndexRange(i,0,8)); - Assert (has_children(), typename TriaAccessor::ExcCellHasNoChildren()); - return this->tria->levels[this->present_level]->hexes.children[this->present_index]+i; + Assert (has_children(), TriaAccessor::ExcCellHasNoChildren()); + return this->tria->levels[this->present_level]->hexes.children[this->present_index]+i; } -template +template <> inline -bool -TriaObjectAccessor<3,dim>::has_children () const +TriaIterator<3,TriaObjectAccessor<3,3> > +TriaObjectAccessor<3,3>::child (const unsigned int i) const { - Assert (this->state() == IteratorState::valid, - typename TriaAccessor::ExcDereferenceInvalidObject()); - return (this->tria->levels[this->present_level]->hexes.children[this->present_index] != -1); + const int dim=3; + Assert (i<8, ExcIndexRange(i,0,8)); + + TriaIterator > q (this->tria, this->present_level+1, child_index (i)); + + Assert ((q.state() == IteratorState::past_the_end) || q->used(), + TriaAccessor::ExcUnusedCellAsChild()); + + return q; } + template inline unsigned int @@ -777,78 +988,78 @@ TriaObjectAccessor<3,dim>::max_refinement_depth () const -template +template <> inline bool -TriaObjectAccessor<3, dim>:: +TriaObjectAccessor<3, 3>:: face_orientation (const unsigned int face) const { - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + const int dim=3; + Assert (used(), TriaAccessor::ExcCellNotUsed()); Assert (face::faces_per_cell, ExcIndexRange (face, 0, GeometryInfo<3>::faces_per_cell)); - Assert (this->present_index * GeometryInfo<3>::faces_per_cell + face - < this->tria->levels[this->present_level] - ->hexes.face_orientations.size(), - ExcInternalError()); - - return (this->tria->levels[this->present_level] - ->hexes.face_orientations[this->present_index * - GeometryInfo<3>::faces_per_cell - + - face]); + Assert (this->present_index * GeometryInfo<3>::faces_per_cell + face + < this->tria->levels[this->present_level] + ->hexes.face_orientations.size(), + ExcInternalError()); + + return (this->tria->levels[this->present_level] + ->hexes.face_orientations[this->present_index * + GeometryInfo<3>::faces_per_cell + + face]); } -template +template <> inline void -TriaObjectAccessor<3,dim>::operator ++ () +TriaObjectAccessor<3,3>::operator ++ () { ++this->present_index; // is index still in the range of // the vector? - while (this->present_index - >= - static_cast(this->tria->levels[this->present_level]->hexes.hexes.size())) - { - // no -> go one level up - ++this->present_level; - this->present_index = 0; - // highest level reached? - if (this->present_level >= static_cast(this->tria->levels.size())) - { - // return with past the end pointer - this->present_level = this->present_index = -1; - return; - }; - }; + while (this->present_index + >= + static_cast(this->tria->levels[this->present_level]->hexes.cells.size())) + { + // no -> go one level up + ++this->present_level; + this->present_index = 0; + // highest level reached? + if (this->present_level >= static_cast(this->tria->levels.size())) + { + // return with past the end pointer + this->present_level = this->present_index = -1; + return; + } + } } -template +template <> inline void -TriaObjectAccessor<3,dim>::operator -- () +TriaObjectAccessor<3,3>::operator -- () { --this->present_index; // is index still in the range of // the vector? - while (this->present_index < 0) - { - // no -> go one level down - --this->present_level; - // lowest level reached? - if (this->present_level == -1) - { - // return with past the end pointer - this->present_level = this->present_index = -1; - return; - }; - // else - this->present_index = this->tria->levels[this->present_level]->hexes.hexes.size()-1; - }; + while (this->present_index < 0) + { + // no -> go one level down + --this->present_level; + // lowest level reached? + if (this->present_level == -1) + { + // return with past the end pointer + this->present_level = this->present_index = -1; + return; + } + // else + this->present_index = this->tria->levels[this->present_level]->hexes.cells.size()-1; + } } diff --git a/deal.II/deal.II/include/grid/tria_faces.h b/deal.II/deal.II/include/grid/tria_faces.h new file mode 100644 index 0000000000..247df642d1 --- /dev/null +++ b/deal.II/deal.II/include/grid/tria_faces.h @@ -0,0 +1,132 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- +#ifndef __deal2__tria_faces_h +#define __deal2__tria_faces_h + +#include +#include +#include +#include +#include + +namespace internal +{ + /** + * A namespace for classes internal to the + * triangulation classes and helpers. + */ + namespace Triangulation + { +/** + * General template for information belonging to the faces of a triangulation. These classes + * are similar to the TriaLevel classes. As cells are organised in a hierarchical + * structure of levels, each triangulation consists of several such TriaLevels. However the + * faces of a triangulation, lower dimensional objects like lines in 2D or lines and quads + * in 3D, do not have to be based on such a hierachical structure. In fact we have to + * organise them in only one object if we want to enable anisotropic refinement. Therefore + * the TriaFaces classes store the information belonging to the faces of a + * triangualtion seperately from the TriaLevel classes. + * + * This general template is only provided to enable a specialisation below. + * + * @ingroup grid + * @author Tobias Leicht, 2006 + */ + + template + class TriaFaces + { + private: + /** + * Make the constructor private so no one can use + * this general template. Only the specializations + * should be used. + */ + TriaFaces(); + }; + + + +/** + * Faces only have a meaning in dim@>=1. In dim=1 they are vertices, + * which are handled differently, so only for dim@>=2 the use of TriaFaces + * is reasonable, for dim=1 the class is empty. + * @ingroup grid + */ + template<> + class TriaFaces<1> + { + + public: + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + * Of course this returns 0. + */ + unsigned int memory_consumption () const; + }; + +/** + * In dim=2 the cells are quads, the faces accordingly are lines. + * @ingroup grid + */ + template<> + class TriaFaces<2> + { + public: + /** + * The TriaObject containing the data of lines. + */ + TriaObjects lines; + + public: + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + }; + +/** + * In dim=3 the cells are hexes, the faces accordingly are quads. In + * addition to that we also have to enable the storage of lines. + * @ingroup grid + */ + template<> + class TriaFaces<3> + { + public: + /** + * The TriaObject containing the data of quads. + */ + + TriaObjects quads; + + /** + * The TriaObject containing the data of lines. + */ + TriaObjects lines; + + public: + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + }; + } +} +#endif diff --git a/deal.II/deal.II/include/grid/tria_iterator.h b/deal.II/deal.II/include/grid/tria_iterator.h index 35cc0849f5..a69633518b 100644 --- a/deal.II/deal.II/include/grid/tria_iterator.h +++ b/deal.II/deal.II/include/grid/tria_iterator.h @@ -318,9 +318,9 @@ class TriaRawIterator : * explicitly for the different * @p Pointees, to allow an * iterator<1,TriangulationLevel<1>::LinesData> - * to point to tria->lines.lines[index] while + * to point to tria->lines.cells[index] while * for one dimension higher it has - * to point to tria->quads.quads[index]. + * to point to tria->quads.cells[index]. * * You must not dereference invalid or * past the end iterators. @@ -396,7 +396,9 @@ class TriaRawIterator : * level if there are more. If the * present element is the last on * this level, the first on the - * next level is accessed. + * next level is accessed. This is only + * valid for iterators pointing to cells, + * faces have no level. */ TriaRawIterator & operator ++ (); @@ -429,7 +431,9 @@ class TriaRawIterator : * this level if index>0. If the * present element is the first on * this level, the last on the - * previous level is accessed. + * previous level is accessed. This is only + * valid for iterators pointing to cells, + * faces have no level. */ TriaRawIterator & operator -- (); @@ -1052,7 +1056,7 @@ TriaActiveIterator::TriaActiveIterator (const TriaRawIterator::TriaActiveIterator (const TriaRawIterator::TriaActiveIterator (const TriaIterator::TriaActiveIterator (const Triangulation * #ifdef DEBUG // do this like this, because: // if we write - // "Assert (IteratorState::past_the_end || used)" + // "Assert (IteratorState::past_the_end || !has_children())" // has_children() is called anyway, even if // state==IteratorState::past_the_end, and will then // throw the exception! @@ -329,7 +329,7 @@ TriaActiveIterator::operator = (const TriaRawIterator::operator = (const TriaIterator & #ifdef DEBUG // do this like this, because: // if we write - // "Assert (IteratorState::past_the_end || used)" + // "Assert (IteratorState::past_the_end || !has_children())" // has_children() is called anyway, even if // state==IteratorState::past_the_end, and will then // throw the exception! diff --git a/deal.II/deal.II/include/grid/tria_levels.h b/deal.II/deal.II/include/grid/tria_levels.h index 2fe525e7e0..2a63aee2fd 100644 --- a/deal.II/deal.II/include/grid/tria_levels.h +++ b/deal.II/deal.II/include/grid/tria_levels.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace internal { @@ -32,7 +33,12 @@ namespace internal /** * General template for information belonging to one level of a multilevel - * hierarchy of a triangulation. This template is only declared to allow + * hierarchy of a triangulation. However, only the cells are really + * level-based data if anisotropic rfeinement is allowed. Therefore, only the + * information concerning cells is considered here, the information concerning + * cell-faces can be found in the TriaFaces classes. + * + * This template is only declared to allow * specializations for different dimensions. * * @ingroup grid @@ -207,154 +213,24 @@ namespace internal /** * Store all information which belongs to one level of the multilevel hierarchy. * - * In one dimension, this is a list of the lines associated with this level, - * as well as a list with the indices of the children of these lines. - * The TriangulationsLevel objects of higher dimensions are derived from - * this one. + * In one dimension, this contains the lines on this level. * * @ingroup grid * @author Wolfgang Bangerth, 1998 */ template <> class TriaLevel<1> : public TriaLevel<0> + { - private: - - /** - * This subclass groups together all that - * is needed to describe the lines on one - * level. - */ - struct LinesData - { - /** - * Vector of the lines belonging to - * this level. The index of the line - * on this level equals the index in - * this container, while the global - * index of a line is stored in the - * line itself. - */ - std::vector lines; - /** - * Index of the first child of a line - * in the list on the next level. - * Since when lines are refined, both - * children are created at the same - * time, they are appended to the list - * on the next level after each other. - * We therefore only store the index - * of the first child, the second - * follows immediately afterwards. - * - * If a line has no children, -1 is - * stored in this list. A line is - * called active if it has no - * children. The function - * TriaAccessor::has_children() - * tests for this. - */ - std::vector children; - - /** - * Vector storing whether a line is - * used in the @p lines vector. - * - * Since it is difficult to delete - * elements in a @p vector, when an - * element is not needed any more - * (e.g. after derefinement), it is - * not deleted from the list, but - * rather the according @p used flag - * is set to @p false. - */ - std::vector used; - - /** - * Make available a field for user data, - * one bit per line. This field is usually - * used when an operation runs over all - * cells and needs information whether - * another cell (e.g. a neighbor) has - * already been processed. - * - * You can clear all used flags using - * Triangulation::clear_user_flags(). - */ - std::vector user_flags; - - /** - * Store boundary and material data. In - * one dimension, this field stores - * the material id of a line, which is a - * number between 0 and 254. In more - * than one dimension, lines have no - * material id, but they may be at the - * boundary; then, we store the - * boundary indicator in this field, - * which denotes to which part of the - * boundary this line belongs and which - * boundary conditions hold on this - * part. The boundary indicator also - * is a number between zero and 254; - * the id 255 is reserved for lines - * in the interior and may be used - * to check whether a line is at the - * boundary or not, which otherwise - * is not possible if you don't know - * which cell it belongs to. - */ - std::vector material_id; - - /** - * Pointer which is not used by the - * library but may be accessed an set - * by the user to handle data local to - * a line/quad/etc. - */ - std::vector user_pointers; - }; - public: - /** - * Data about the lines. - */ - LinesData lines; - - /** - * Assert that enough space is - * allocated to accomodate - * new_lines new lines. - * This function does not only - * call - * vector::reserve(), - * but does really append the - * needed elements. There are - * pendants for higher - * dimensions, which you have to - * call explicitly (they can't - * hand down the call because - * there is no easy relation - * between the number of new - * quads and the number of new - * lines, etc.). Also don't - * forget to call the - * TriaLevel<0>::reserve_space - * function. - */ - void reserve_space (const unsigned int new_lines); - - /** - * Check the memory consistency of the - * different containers. Should only be - * called with the prepro flag @p DEBUG - * set. The function should be called from - * the functions of the higher - * TriaLevel classes. - */ - void monitor_memory (const unsigned int true_dimension) const; + /** + * The object containing the data on lines and + * related functions + */ + TriaObjects lines; - /** + public: + /** * Determine an estimate for the * memory consumption (in bytes) * of this object. @@ -367,115 +243,23 @@ namespace internal /** * Store all information which belongs to one level of the multilevel hierarchy. * - * In 2D this is a vector of the lines and one of the - * quads on this levels, as well as a the two associated vectors holding - * information about the children of these lines and quads. - * - * The vector of lines and their children is derived from - * TriaLevel<1>. + * In 2D this is a vector ocontains the quads on this level. * * @ingroup grid * @author Wolfgang Bangerth, 1998 */ template <> - class TriaLevel<2> : public TriaLevel<1> + class TriaLevel<2> : public TriaLevel<0> { - /** - * This subclass groups together all that - * is needed to describe the quads on one - * level. - * - * It is fully analogous to the - * TriaLevel<1>::LinesData structure inherited from - * Triangulation<1>. - */ - struct QuadsData - { - /** - * Same as for the @p lines array. - */ - std::vector quads; - /** - * Same as for the - * TriaLevel<1>::LinesData@p ::children - * array, but since there - * are four children, the - * index points to the first - * while the other three are - * following immediately - * afterwards. - */ - std::vector children; - - /** - * Same as for - * TriaLevel<1>::LinesData@p ::used. - */ - std::vector used; - - /** - * Same as for - * TriaLevel<1>::LinesData@p ::used. - */ - std::vector user_flags; - - /** - * Store boundary and material data. In - * two dimension, this field stores - * the material id of a quad, which is a - * number between 0 and 254. In more - * than two dimensions, quads have no - * material id, but they may be at the - * boundary; then, we store the - * boundary indicator in this field, - * which denotes to which part of the - * boundary this line belongs and which - * boundary conditions hold on this - * part. The boundary indicator also - * is a number between zero and 254; - * the id 255 is reserved for quads - * in the interior and may be used - * to check whether a quad is at the - * boundary or not, which otherwise - * is not possible if you don't know - * which cell it belongs to. - */ - std::vector material_id; - - - /** - * Pointer which is not used by the - * library but may be accessed and set - * by the user to handle data local to - * a line/quad/etc. - */ - std::vector user_pointers; - }; - public: - /** - * Data about the quads. - */ - QuadsData quads; - - /** - * Assert that enough space is - * allocated to accomodate - * new_quads new quads. - */ - void reserve_space (const unsigned int new_quads); + /** + * The object containing the data on quads and + * related functions + */ + TriaObjects quads; - /** - * Check the memory consistency of the - * different containers. Should only be - * called with the prepro flag @p DEBUG - * set. The function should be called from - * the functions of the higher - * TriaLevel classes. - */ - void monitor_memory (const unsigned int true_dimension) const; - - /** + public: + /** * Determine an estimate for the * memory consumption (in bytes) * of this object. @@ -488,179 +272,23 @@ namespace internal /** * Store all information which belongs to one level of the multilevel hierarchy. * - * In 3D this is a vector of the lines, one of quads and one of the - * hexahedra on this levels, as well as a the associated vectors - * holding information about the children of these lines, quads and - * hexs. In addition, we store for each face of each hexahedron - * whether its normal points in the standard direction (see the - * Triangulation class) or in the opposite direction. - * - * The vectors of lines and quads and their children are derived from - * TriaLevel<2>. + * In 3D this contains the hexahedra on this levels, * - * @ingroup grid + * @ingroup grid * @author Wolfgang Bangerth, 1998, 2003 */ template <> - class TriaLevel<3> : public TriaLevel<2> + class TriaLevel<3> : public TriaLevel<0> { - /** - * This subclass groups together - * all that is needed to - * describe the hexes on one - * level. - * - * It is fully analogous to the - * TriaLevel<1>::LinesData - * structure inherited from - * Triangulation<1>. - */ - struct HexesData - { - /** - * Same as for the @p lines array. - */ - std::vector hexes; - - /** - * Same as for the - * TriaLevel<1>::LinesData@p ::chilren - * array, but since there - * are four children, the - * index points to the first - * while the other three are - * following immediately - * afterwards. - */ - std::vector children; - - /** - * Same as for - * TriaLevel<1>::LinesData@p ::used. - */ - std::vector used; - - /** - * Same as for - * TriaLevel<1>::LinesData@p ::used. - */ - std::vector user_flags; - - /** - * Store boundary and - * material data. In two - * dimension, this field - * stores the material id of - * a hex, which is a number - * between 0 and 254. In more - * than three dimensions, - * hexes have no material id, - * but they may be at the - * boundary; then, we store - * the boundary indicator in - * this field, which denotes - * to which part of the - * boundary this line belongs - * and which boundary - * conditions hold on this - * part. The boundary - * indicator also is a number - * between zero and 254; the - * id 255 is reserved for - * hexes in the interior and - * may be used to check - * whether a hex is at the - * boundary or not, which - * otherwise is not possible - * if you don't know which - * cell it belongs to. - */ - std::vector material_id; - - /** - * Pointer which is not used - * by the library but may be - * accessed an set by the - * user to handle data local - * to a line/quad/etc. - */ - std::vector user_pointers; - - /** - * For edges, we enforce a - * standard convention that - * opposite edges should be - * parallel. Now, that's - * enforcable in most cases, - * and we have code that - * makes sure that if a mesh - * allows this to happen, - * that we have this - * convention. We also know - * that it is always possible - * to have opposite faces - * have parallel normal - * vectors. (For both things, - * see the Agelek, Anderson, - * Bangerth, Barth paper - * mentioned in the - * publications list.) - * - * The problem is that we - * originally had another - * condition, namely that - * faces 0, 2 and 6 have - * normals that point into - * the cell, while the other - * faces have normals that - * point outward. It turns - * out that this is not - * always possible. In - * effect, we have to store - * whether the normal vector - * of each face of each cell - * follows this convention or - * not. If this is so, then - * this variable stores a - * @p true value, otherwise - * a @p false value. - * - * In effect, this field has - * 6*n_cells elements, - * being the number of cells - * times the six faces each - * has. - */ - std::vector face_orientations; - }; - public: - /** - * Data about the hexes. - */ - HexesData hexes; + /** + * The object containing the data on hexes and + * related functions + */ + TriaObjectsHex hexes; - /** - * Assert that enough space is - * allocated to accomodate - * new_hexes new hexes. - */ - void reserve_space (const unsigned int new_hexes); - - /** - * Check the memory consistency - * of the different - * containers. Should only be - * called with the prepro flag - * @p DEBUG set. The function - * should be called from the - * functions of the higher - * TriaLevel - * classes. - */ - void monitor_memory (const unsigned int true_dimension) const; - - /** + public: + /** * Determine an estimate for the * memory consumption (in bytes) * of this object. @@ -670,6 +298,4 @@ namespace internal } } - - #endif diff --git a/deal.II/deal.II/include/grid/tria_objects.h b/deal.II/deal.II/include/grid/tria_objects.h new file mode 100644 index 0000000000..75f20c4d93 --- /dev/null +++ b/deal.II/deal.II/include/grid/tria_objects.h @@ -0,0 +1,278 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- +#ifndef __deal2__tria_objects_h +#define __deal2__tria_objects_h + +#include +#include +#include +#include +#include +#include +#include + +namespace internal +{ + /** + * A namespace for classes internal to the + * triangulation classes and helpers. + */ + namespace Triangulation + { + +/** + * General template for information belonging to the geometrical objects of a + * triangulation, i.e. lines, quads, hexahedrons... Apart from the vector of + * objects additional information is included, namely vectors indicating the + * children, the used-status, user-flags, material-ids.. + * + * Objects of these classes are include in the TriaLevel and TriaFaces + * classes. + * + * @ingroup grid + * @author Tobias Leicht, 2006 + */ + + template + class TriaObjects + { + public: + /** + * Vector of the objects belonging to + * this level. The index of the object + * equals the index in this container. + */ + std::vector cells; + /** + * Index of the first child of an object. + * Since when objects are refined, all + * children are created at the same + * time, they are appended to the list + * after each other. + * We therefore only store the index + * of the first child, the others + * follow immediately afterwards. + * + * If an object has no children, -1 is + * stored in this list. An object is + * called active if it has no + * children. The function + * TriaAccessor::has_children() + * tests for this. + */ + std::vector children; + + /** + * Vector storing whether an object is + * used in the @p cells vector. + * + * Since it is difficult to delete + * elements in a @p vector, when an + * element is not needed any more + * (e.g. after derefinement), it is + * not deleted from the list, but + * rather the according @p used flag + * is set to @p false. + */ + std::vector used; + + /** + * Make available a field for user data, + * one bit per object. This field is usually + * used when an operation runs over all + * cells and needs information whether + * another cell (e.g. a neighbor) has + * already been processed. + * + * You can clear all used flags using + * Triangulation::clear_user_flags(). + */ + std::vector user_flags; + + /** + * Store boundary and material data. For + * example, in one dimension, this field + * stores the material id of a line, which + * is a number between 0 and 254. In more + * than one dimension, lines have no + * material id, but they may be at the + * boundary; then, we store the + * boundary indicator in this field, + * which denotes to which part of the + * boundary this line belongs and which + * boundary conditions hold on this + * part. The boundary indicator also + * is a number between zero and 254; + * the id 255 is reserved for lines + * in the interior and may be used + * to check whether a line is at the + * boundary or not, which otherwise + * is not possible if you don't know + * which cell it belongs to. + */ + std::vector material_id; + + /** + * Pointer which is not used by the + * library but may be accessed and set + * by the user to handle data local to + * a line/quad/etc. + */ + std::vector user_pointers; + + /** + * Assert that enough space is + * allocated to accomodate + * new_objs new objects. + * This function does not only call + * vector::reserve(), but + * does really append the needed + * elements. + */ + void reserve_space (const unsigned int new_objs); + + /** + * Clear all the data contained in this object. + */ + void clear(); + + /** + * Check the memory consistency of the + * different containers. Should only be + * called with the prepro flag @p DEBUG + * set. The function should be called from + * the functions of the higher + * TriaLevel classes. + */ + void monitor_memory (const unsigned int true_dimension) const; + + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + + /** + * Exception + */ + DeclException3 (ExcMemoryWasted, + char*, int, int, + << "The container " << arg1 << " contains " + << arg2 << " elements, but it`s capacity is " + << arg3 << "."); + /** + * Exception + */ + DeclException2 (ExcMemoryInexact, + int, int, + << "The containers have sizes " << arg1 << " and " + << arg2 << ", which is not as expected."); + + }; + +/** + * For hexahedrons the data of TriaObjects needs to be extended, as we can obtain faces + * (quads) in non-standard-orientation, therefore we declare a class TriaObjectsHex, which + * additionaly contains a bool-vector of the face-orientations. + * @ingroup grid + */ + + class TriaObjectsHex: public TriaObjects + { + public: + + /** + * For edges, we enforce a + * standard convention that + * opposite edges should be + * parallel. Now, that's + * enforcable in most cases, + * and we have code that + * makes sure that if a mesh + * allows this to happen, + * that we have this + * convention. We also know + * that it is always possible + * to have opposite faces + * have parallel normal + * vectors. (For both things, + * see the Agelek, Anderson, + * Bangerth, Barth paper + * mentioned in the + * publications list.) + * + * The problem is that we + * originally had another + * condition, namely that + * faces 0, 2 and 6 have + * normals that point into + * the cell, while the other + * faces have normals that + * point outward. It turns + * out that this is not + * always possible. In + * effect, we have to store + * whether the normal vector + * of each face of each cell + * follows this convention or + * not. If this is so, then + * this variable stores a + * @p true value, otherwise + * a @p false value. + * + * In effect, this field has + * 6*n_cells elements, + * being the number of cells + * times the six faces each + * has. + */ + std::vector face_orientations; + + /** + * Assert that enough space is + * allocated to accomodate + * new_objs new objects. + * This function does not only call + * vector::reserve(), but + * does really append the needed + * elements. + */ + void reserve_space (const unsigned int new_objs); + + /** + * Clear all the data contained in this object. + */ + void clear(); + + /** + * Check the memory consistency of the + * different containers. Should only be + * called with the prepro flag @p DEBUG + * set. The function should be called from + * the functions of the higher + * TriaLevel classes. + */ + void monitor_memory (const unsigned int true_dimension) const; + + /** + * Determine an estimate for the + * memory consumption (in bytes) + * of this object. + */ + unsigned int memory_consumption () const; + }; + } +} + +#endif diff --git a/deal.II/deal.II/include/multigrid/mg_dof_accessor.h b/deal.II/deal.II/include/multigrid/mg_dof_accessor.h index 852023d458..6b52bcc4ac 100644 --- a/deal.II/deal.II/include/multigrid/mg_dof_accessor.h +++ b/deal.II/deal.II/include/multigrid/mg_dof_accessor.h @@ -232,7 +232,7 @@ class MGDoFObjectAccessor<0, dim> /** * Grant access to those aspects of multilevel degrees of freedom located on - * hexes that are dimension specific. See the MGDoFAccessor class for + * lines that are dimension specific. See the MGDoFAccessor class for * more information. * * @ingroup mg diff --git a/deal.II/deal.II/include/multigrid/mg_dof_handler.h b/deal.II/deal.II/include/multigrid/mg_dof_handler.h index 124a37e2df..fcccb47e01 100644 --- a/deal.II/deal.II/include/multigrid/mg_dof_handler.h +++ b/deal.II/deal.II/include/multigrid/mg_dof_handler.h @@ -275,37 +275,34 @@ class MGDoFHandler : public DoFHandler /*@{*/ /** * Iterator to the first face, - * used or not, on level - * @p level. If a level has no - * faces, a past-the-end iterator - * is returned. + * used or not. * * This function calls * @p begin_raw_line in 2D and * @p begin_raw_quad in 3D. */ - raw_face_iterator begin_raw_face (const unsigned int level = 0) const; + raw_face_iterator begin_raw_face () const; /** * Iterator to the first used - * face on level @p level. + * face. * * This function calls * @p begin_line in 2D and * @p begin_quad in 3D. */ - face_iterator begin_face (const unsigned int level = 0) const; + face_iterator begin_face () const; /** * Iterator to the first active - * face on level @p level. + * face. * * This function calls * @p begin_active_line in 2D * and @p begin_active_quad in * 3D. */ - active_face_iterator begin_active_face(const unsigned int level = 0) const; + active_face_iterator begin_active_face() const; /** * Iterator past the end; this @@ -321,52 +318,38 @@ class MGDoFHandler : public DoFHandler raw_face_iterator end_face () const; /** - * Return an iterator which is - * the first iterator not on - * level. If @p level is the - * last level, then this returns - * end(). - */ - face_iterator end_face (const unsigned int level) const; - - /** - * Return a raw iterator which is - * the first iterator not on - * level. If @p level is the - * last level, then this returns - * end(). - */ - raw_face_iterator end_raw_face (const unsigned int level) const; - - /** - * Return an active iterator - * which is the first iterator - * not on level. If @p level is - * the last level, then this - * returns end(). + * Iterator past the end; this + * iterator serves for + * comparisons of iterators with + * past-the-end or + * before-the-beginning states. + * + * This is the same as + * end_face(). */ - active_face_iterator end_active_face (const unsigned int level) const; + raw_face_iterator end_raw_face () const; /** - * Return an iterator pointing to - * the last face, used or not. + * Iterator past the end; this + * iterator serves for + * comparisons of iterators with + * past-the-end or + * before-the-beginning states. * - * This function calls - * @p last_raw_line in 2D and - * @p last_raw_quad in 3D. + * This is the same as + * end_face(). */ - raw_face_iterator last_raw_face () const; + active_face_iterator end_active_face () const; /** * Return an iterator pointing to - * the last face of the level - * @p level, used or not. + * the last face, used or not. * * This function calls * @p last_raw_line in 2D and * @p last_raw_quad in 3D. */ - raw_face_iterator last_raw_face (const unsigned int level) const; + raw_face_iterator last_raw_face () const; /** * Return an iterator pointing to @@ -378,17 +361,6 @@ class MGDoFHandler : public DoFHandler */ face_iterator last_face () const; - /** - * Return an iterator pointing to - * the last used face on level - * @p level. - * - * This function calls - * @p last_line in 2D and - * @p last_quad in 3D. - */ - face_iterator last_face (const unsigned int level) const; - /** * Return an iterator pointing to * the last active face. @@ -398,21 +370,10 @@ class MGDoFHandler : public DoFHandler * @p last_active_quad in 3D. */ active_face_iterator last_active_face () const; - - /** - * Return an iterator pointing to - * the last active face on level - * @p level. - * - * This function calls - * @p last_active_line in 2D and - * @p last_active_quad in 3D. - */ - active_face_iterator last_active_face (const unsigned int level) const; //@} -/*---------------------------------------*/ + /*---------------------------------------*/ /** * @name Line iterator functions @@ -723,7 +684,7 @@ class MGDoFHandler : public DoFHandler */ active_hex_iterator last_active_hex (const unsigned int level) const; /*@}*/ - + /*---------------------------------------*/ @@ -945,6 +906,26 @@ class MGDoFHandler : public DoFHandler */ unsigned int distribute_dofs_on_cell (cell_iterator &cell, unsigned int next_free_dof); + /** + * Return the @p i-th dof-index. This function calls + * the respective function of DoFObjects. + */ + template + unsigned int get_dof_index (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const; + /** + * Set the @p i-th dof-index. This function calls + * the respective function of DoFObjects. + */ + template + void set_dof_index (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const; + /** * Reserve enough space for the @@ -969,6 +950,12 @@ class MGDoFHandler : public DoFHandler * zero on each level. */ std::vector*> mg_levels; + + /** + * Space to store the DoF numbers + * for the faces. + */ + internal::DoFHandler::DoFFaces * mg_faces; /** * For each vertex there is a @@ -1077,13 +1064,13 @@ MGDoFHandler<1>::active_cell_iterator MGDoFHandler<1>::last_active (const unsigned int level) const; template <> internal::MGDoFHandler::Iterators<1>::raw_face_iterator -MGDoFHandler<1>::begin_raw_face (const unsigned int) const; +MGDoFHandler<1>::begin_raw_face () const; template <> internal::MGDoFHandler::Iterators<1>::face_iterator -MGDoFHandler<1>::begin_face (const unsigned int) const; +MGDoFHandler<1>::begin_face () const; template <> internal::MGDoFHandler::Iterators<1>::active_face_iterator -MGDoFHandler<1>::begin_active_face (const unsigned int) const; +MGDoFHandler<1>::begin_active_face () const; template <> internal::MGDoFHandler::Iterators<1>::raw_face_iterator MGDoFHandler<1>::end_face () const; @@ -1091,21 +1078,12 @@ template <> internal::MGDoFHandler::Iterators<1>::raw_face_iterator MGDoFHandler<1>::last_raw_face () const; template <> -internal::MGDoFHandler::Iterators<1>::raw_face_iterator -MGDoFHandler<1>::last_raw_face (const unsigned int) const; -template <> internal::MGDoFHandler::Iterators<1>::face_iterator MGDoFHandler<1>::last_face () const; template <> -internal::MGDoFHandler::Iterators<1>::face_iterator -MGDoFHandler<1>::last_face (const unsigned int) const; -template <> internal::MGDoFHandler::Iterators<1>::active_face_iterator MGDoFHandler<1>::last_active_face () const; template <> -internal::MGDoFHandler::Iterators<1>::active_face_iterator -MGDoFHandler<1>::last_active_face (const unsigned int) const; -template <> MGDoFHandler<1>::raw_quad_iterator MGDoFHandler<1>::begin_raw_quad (const unsigned int) const; template <> @@ -1198,13 +1176,13 @@ MGDoFHandler<2>::active_cell_iterator MGDoFHandler<2>::last_active (const unsigned int level) const; template <> internal::MGDoFHandler::Iterators<2>::raw_face_iterator -MGDoFHandler<2>::begin_raw_face (const unsigned int) const; +MGDoFHandler<2>::begin_raw_face () const; template <> internal::MGDoFHandler::Iterators<2>::face_iterator -MGDoFHandler<2>::begin_face (const unsigned int) const; +MGDoFHandler<2>::begin_face () const; template <> internal::MGDoFHandler::Iterators<2>::active_face_iterator -MGDoFHandler<2>::begin_active_face (const unsigned int) const; +MGDoFHandler<2>::begin_active_face () const; template <> internal::MGDoFHandler::Iterators<2>::raw_face_iterator MGDoFHandler<2>::end_face () const; @@ -1212,21 +1190,12 @@ template <> internal::MGDoFHandler::Iterators<2>::raw_face_iterator MGDoFHandler<2>::last_raw_face () const; template <> -internal::MGDoFHandler::Iterators<2>::raw_face_iterator -MGDoFHandler<2>::last_raw_face (const unsigned int) const; -template <> internal::MGDoFHandler::Iterators<2>::face_iterator MGDoFHandler<2>::last_face () const; template <> -internal::MGDoFHandler::Iterators<2>::face_iterator -MGDoFHandler<2>::last_face (const unsigned int) const; -template <> internal::MGDoFHandler::Iterators<2>::active_face_iterator MGDoFHandler<2>::last_active_face () const; template <> -internal::MGDoFHandler::Iterators<2>::active_face_iterator -MGDoFHandler<2>::last_active_face (const unsigned int) const; -template <> MGDoFHandler<2>::raw_hex_iterator MGDoFHandler<2>::begin_raw_hex (const unsigned int) const; template <> @@ -1289,13 +1258,13 @@ MGDoFHandler<3>::active_cell_iterator MGDoFHandler<3>::last_active (const unsigned int level) const; template <> internal::MGDoFHandler::Iterators<3>::raw_face_iterator -MGDoFHandler<3>::begin_raw_face (const unsigned int) const; +MGDoFHandler<3>::begin_raw_face () const; template <> internal::MGDoFHandler::Iterators<3>::face_iterator -MGDoFHandler<3>::begin_face (const unsigned int) const; +MGDoFHandler<3>::begin_face () const; template <> internal::MGDoFHandler::Iterators<3>::active_face_iterator -MGDoFHandler<3>::begin_active_face (const unsigned int) const; +MGDoFHandler<3>::begin_active_face () const; template <> internal::MGDoFHandler::Iterators<3>::raw_face_iterator MGDoFHandler<3>::end_face () const; @@ -1303,20 +1272,11 @@ template <> internal::MGDoFHandler::Iterators<3>::raw_face_iterator MGDoFHandler<3>::last_raw_face () const; template <> -internal::MGDoFHandler::Iterators<3>::raw_face_iterator -MGDoFHandler<3>::last_raw_face (const unsigned int) const; -template <> internal::MGDoFHandler::Iterators<3>::face_iterator MGDoFHandler<3>::last_face () const; template <> -internal::MGDoFHandler::Iterators<3>::face_iterator -MGDoFHandler<3>::last_face (const unsigned int) const; -template <> internal::MGDoFHandler::Iterators<3>::active_face_iterator MGDoFHandler<3>::last_active_face () const; -template <> -internal::MGDoFHandler::Iterators<3>::active_face_iterator -MGDoFHandler<3>::last_active_face (const unsigned int) const; template <> diff --git a/deal.II/deal.II/source/dofs/dof_accessor.cc b/deal.II/deal.II/source/dofs/dof_accessor.cc index 7bee86dcbb..a042a436c1 100644 --- a/deal.II/deal.II/source/dofs/dof_accessor.cc +++ b/deal.II/deal.II/source/dofs/dof_accessor.cc @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/deal.II/deal.II/source/dofs/dof_faces.cc b/deal.II/deal.II/source/dofs/dof_faces.cc new file mode 100644 index 0000000000..40497b06da --- /dev/null +++ b/deal.II/deal.II/source/dofs/dof_faces.cc @@ -0,0 +1,47 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include +#include + + +namespace internal +{ + namespace DoFHandler + { + + unsigned int + DoFFaces<1>::memory_consumption () const + { + return 0; + } + + + unsigned int + DoFFaces<2>::memory_consumption () const + { + return MemoryConsumption::memory_consumption (lines); + } + + + unsigned int + DoFFaces<3>::memory_consumption () const + { + return (MemoryConsumption::memory_consumption (quads) + + MemoryConsumption::memory_consumption (lines) ); + } + + } +} diff --git a/deal.II/deal.II/source/dofs/dof_handler.cc b/deal.II/deal.II/source/dofs/dof_handler.cc index 4ec8b943a5..4ffd32a7f6 100644 --- a/deal.II/deal.II/source/dofs/dof_handler.cc +++ b/deal.II/deal.II/source/dofs/dof_handler.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,7 @@ template DoFHandler::DoFHandler (const Triangulation &tria) : tria(&tria, typeid(*this).name()), selected_fe(0, typeid(*this).name()), + faces(NULL), used_dofs (0) {} @@ -138,7 +140,7 @@ DoFHandler<1>::last_active (const unsigned int level) const template <> DoFHandler<1>::raw_face_iterator -DoFHandler<1>::begin_raw_face (const unsigned int) const +DoFHandler<1>::begin_raw_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -147,7 +149,7 @@ DoFHandler<1>::begin_raw_face (const unsigned int) const template <> DoFHandler<1>::face_iterator -DoFHandler<1>::begin_face (const unsigned int) const +DoFHandler<1>::begin_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -156,7 +158,7 @@ DoFHandler<1>::begin_face (const unsigned int) const template <> DoFHandler<1>::active_face_iterator -DoFHandler<1>::begin_active_face (const unsigned int) const +DoFHandler<1>::begin_active_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -174,7 +176,7 @@ DoFHandler<1>::end_face () const template <> DoFHandler<1>::raw_face_iterator -DoFHandler<1>::last_raw_face () const +DoFHandler<1>::end_raw_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -182,8 +184,8 @@ DoFHandler<1>::last_raw_face () const template <> -DoFHandler<1>::raw_face_iterator -DoFHandler<1>::last_raw_face (const unsigned int) const +DoFHandler<1>::active_face_iterator +DoFHandler<1>::end_active_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -191,8 +193,8 @@ DoFHandler<1>::last_raw_face (const unsigned int) const template <> -DoFHandler<1>::face_iterator -DoFHandler<1>::last_face () const +DoFHandler<1>::raw_face_iterator +DoFHandler<1>::last_raw_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -201,7 +203,7 @@ DoFHandler<1>::last_face () const template <> DoFHandler<1>::face_iterator -DoFHandler<1>::last_face (const unsigned int) const +DoFHandler<1>::last_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -217,14 +219,6 @@ DoFHandler<1>::last_active_face () const } -template <> -DoFHandler<1>::active_face_iterator -DoFHandler<1>::last_active_face (const unsigned int) const -{ - return 0; -} - - template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::begin_raw_quad (const unsigned int) const @@ -261,6 +255,33 @@ DoFHandler<1>::end_quad () const } +template <> +DoFHandler<1>::quad_iterator +DoFHandler<1>::end_quad (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + +template <> +DoFHandler<1>::raw_quad_iterator +DoFHandler<1>::end_raw_quad (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + +template <> +DoFHandler<1>::active_quad_iterator +DoFHandler<1>::end_active_quad (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::last_raw_quad (const unsigned int) const @@ -351,6 +372,33 @@ DoFHandler<1>::end_hex () const } +template <> +DoFHandler<1>::hex_iterator +DoFHandler<1>::end_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + +template <> +DoFHandler<1>::raw_hex_iterator +DoFHandler<1>::end_raw_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + +template <> +DoFHandler<1>::active_hex_iterator +DoFHandler<1>::end_active_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + template <> DoFHandler<1>::raw_hex_iterator DoFHandler<1>::last_raw_hex (const unsigned int) const @@ -491,25 +539,25 @@ DoFHandler<2>::last_active (const unsigned int level) const template <> DoFHandler<2>::raw_face_iterator -DoFHandler<2>::begin_raw_face (const unsigned int level) const +DoFHandler<2>::begin_raw_face () const { - return begin_raw_line (level); + return begin_raw_line (); } template <> DoFHandler<2>::face_iterator -DoFHandler<2>::begin_face (const unsigned int level) const +DoFHandler<2>::begin_face () const { - return begin_line (level); + return begin_line (); } template <> DoFHandler<2>::active_face_iterator -DoFHandler<2>::begin_active_face (const unsigned int level) const +DoFHandler<2>::begin_active_face () const { - return begin_active_line (level); + return begin_active_line (); } @@ -523,33 +571,33 @@ DoFHandler<2>::end_face () const template <> DoFHandler<2>::raw_face_iterator -DoFHandler<2>::last_raw_face () const +DoFHandler<2>::end_raw_face () const { - return last_raw_line (); + return end_line (); } template <> -DoFHandler<2>::raw_face_iterator -DoFHandler<2>::last_raw_face (const unsigned int level) const +DoFHandler<2>::active_face_iterator +DoFHandler<2>::end_active_face () const { - return last_raw_line (level); + return end_line (); } template <> -DoFHandler<2>::face_iterator -DoFHandler<2>::last_face () const +DoFHandler<2>::raw_face_iterator +DoFHandler<2>::last_raw_face () const { - return last_line (); + return last_raw_line (); } template <> DoFHandler<2>::face_iterator -DoFHandler<2>::last_face (const unsigned int level) const +DoFHandler<2>::last_face () const { - return last_line (level); + return last_line (); } @@ -561,14 +609,6 @@ DoFHandler<2>::last_active_face () const } -template <> -DoFHandler<2>::active_face_iterator -DoFHandler<2>::last_active_face (const unsigned int level) const -{ - return last_active_line (level); -} - - template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::begin_raw_hex (const unsigned int) const @@ -605,6 +645,33 @@ DoFHandler<2>::end_hex () const } +template <> +DoFHandler<2>::hex_iterator +DoFHandler<2>::end_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(2)); + return 0; +} + + +template <> +DoFHandler<2>::raw_hex_iterator +DoFHandler<2>::end_raw_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(2)); + return 0; +} + + +template <> +DoFHandler<2>::active_hex_iterator +DoFHandler<2>::end_active_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(2)); + return 0; +} + + template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::last_raw_hex (const unsigned int) const @@ -746,25 +813,25 @@ DoFHandler<3>::last_active (const unsigned int level) const template <> DoFHandler<3>::raw_face_iterator -DoFHandler<3>::begin_raw_face (const unsigned int level) const +DoFHandler<3>::begin_raw_face () const { - return begin_raw_quad (level); + return begin_raw_quad (); } template <> DoFHandler<3>::face_iterator -DoFHandler<3>::begin_face (const unsigned int level) const +DoFHandler<3>::begin_face () const { - return begin_quad (level); + return begin_quad (); } template <> DoFHandler<3>::active_face_iterator -DoFHandler<3>::begin_active_face (const unsigned int level) const +DoFHandler<3>::begin_active_face () const { - return begin_active_quad (level); + return begin_active_quad (); } @@ -778,33 +845,33 @@ DoFHandler<3>::end_face () const template <> DoFHandler<3>::raw_face_iterator -DoFHandler<3>::last_raw_face () const +DoFHandler<3>::end_raw_face () const { - return last_raw_quad (); + return end_quad (); } template <> -DoFHandler<3>::raw_face_iterator -DoFHandler<3>::last_raw_face (const unsigned int level) const +DoFHandler<3>::active_face_iterator +DoFHandler<3>::end_active_face () const { - return last_raw_quad (level); + return end_quad (); } template <> -DoFHandler<3>::face_iterator -DoFHandler<3>::last_face () const +DoFHandler<3>::raw_face_iterator +DoFHandler<3>::last_raw_face () const { - return last_quad (); + return last_raw_quad (); } template <> DoFHandler<3>::face_iterator -DoFHandler<3>::last_face (const unsigned int level) const +DoFHandler<3>::last_face () const { - return last_quad (level); + return last_quad (); } @@ -816,14 +883,6 @@ DoFHandler<3>::last_active_face () const } -template <> -DoFHandler<3>::active_face_iterator -DoFHandler<3>::last_active_face (const unsigned int level) const -{ - return last_active_quad (level); -} - - #endif @@ -925,7 +984,12 @@ DoFHandler::begin_active_hex (const unsigned int level) const this); } - + // We can't ask the respective tria->-function here, as + // that would include dereferencing a past-the-end iterator + // which is not allowed. Therefore we have to repeat the + // code from tria.cc + // This is valid for all functions whisch return past the + // end iterators, namely all functions end_*() template typename DoFHandler::raw_line_iterator DoFHandler::end_line () const @@ -980,43 +1044,14 @@ DoFHandler::end_active (const unsigned int level) const } -template -typename DoFHandler::raw_face_iterator -DoFHandler::end_raw_face (const unsigned int level) const -{ - return (level == levels.size()-1 ? - end_face() : - begin_raw_face (level+1)); -} - - -template -typename DoFHandler::face_iterator -DoFHandler::end_face (const unsigned int level) const -{ - return (level == levels.size()-1 ? - face_iterator(end_face()) : - begin_face (level+1)); -} - - -template -typename DoFHandler::active_face_iterator -DoFHandler::end_active_face (const unsigned int level) const -{ - return (level == levels.size()-1 ? - active_face_iterator(end_face()) : - begin_active_face (level+1)); -} - - template typename DoFHandler::raw_line_iterator DoFHandler::end_raw_line (const unsigned int level) const { - return (level == levels.size()-1 ? - end_line() : - begin_raw_line (level+1)); + return raw_line_iterator(tria, + tria->end_raw_line(level)->level(), + tria->end_raw_line(level)->index(), + this); } @@ -1024,9 +1059,10 @@ template typename DoFHandler::line_iterator DoFHandler::end_line (const unsigned int level) const { - return (level == levels.size()-1 ? - line_iterator(end_line()) : - begin_line (level+1)); + return line_iterator(tria, + tria->end_line(level)->level(), + tria->end_line(level)->index(), + this); } @@ -1034,9 +1070,10 @@ template typename DoFHandler::active_line_iterator DoFHandler::end_active_line (const unsigned int level) const { - return (level == levels.size()-1 ? - active_line_iterator(end_line()) : - begin_active_line (level+1)); + return active_line_iterator(tria, + tria->end_active_line(level)->level(), + tria->end_active_line(level)->index(), + this); } @@ -1044,9 +1081,10 @@ template typename DoFHandler::raw_quad_iterator DoFHandler::end_raw_quad (const unsigned int level) const { - return (level == levels.size()-1 ? - end_quad() : - begin_raw_quad (level+1)); + return raw_quad_iterator(tria, + tria->end_raw_quad(level)->level(), + tria->end_raw_quad(level)->index(), + this); } @@ -1054,9 +1092,10 @@ template typename DoFHandler::quad_iterator DoFHandler::end_quad (const unsigned int level) const { - return (level == levels.size()-1 ? - quad_iterator(end_quad()) : - begin_quad (level+1)); + return quad_iterator(tria, + tria->end_quad(level)->level(), + tria->end_quad(level)->index(), + this); } @@ -1064,9 +1103,10 @@ template typename DoFHandler::active_quad_iterator DoFHandler::end_active_quad (const unsigned int level) const { - return (level == levels.size()-1 ? - active_quad_iterator(end_quad()) : - begin_active_quad (level+1)); + return active_quad_iterator(tria, + tria->end_active_quad(level)->level(), + tria->end_active_quad(level)->index(), + this); } @@ -1074,9 +1114,10 @@ template typename DoFHandler::raw_hex_iterator DoFHandler::end_raw_hex (const unsigned int level) const { - return (level == levels.size()-1 ? - end_hex() : - begin_raw_hex (level+1)); + return raw_hex_iterator(tria, + tria->end_raw_hex(level)->level(), + tria->end_raw_hex(level)->index(), + this); } @@ -1084,9 +1125,10 @@ template typename DoFHandler::hex_iterator DoFHandler::end_hex (const unsigned int level) const { - return (level == levels.size()-1 ? - hex_iterator(end_hex()) : - begin_hex (level+1)); + return hex_iterator(tria, + tria->end_hex(level)->level(), + tria->end_hex(level)->index(), + this); } @@ -1094,9 +1136,10 @@ template typename DoFHandler::active_hex_iterator DoFHandler::end_active_hex (const unsigned int level) const { - return (level == levels.size()-1 ? - active_hex_iterator(end_hex()) : - begin_active_hex (level+1)); + return active_hex_iterator(tria, + tria->end_active_hex(level)->level(), + tria->end_active_hex(level)->index(), + this); } @@ -1203,7 +1246,10 @@ template typename DoFHandler::raw_line_iterator DoFHandler::last_raw_line () const { - return last_raw_line (levels.size()-1); + return raw_line_iterator (tria, + tria->last_raw_line()->level(), + tria->last_raw_line()->index(), + this); } @@ -1211,7 +1257,10 @@ template typename DoFHandler::raw_quad_iterator DoFHandler::last_raw_quad () const { - return last_raw_quad (levels.size()-1); + return raw_quad_iterator (tria, + tria->last_raw_quad()->level(), + tria->last_raw_quad()->index(), + this); } @@ -1219,7 +1268,10 @@ template typename DoFHandler::raw_hex_iterator DoFHandler::last_raw_hex () const { - return last_raw_hex (levels.size()-1); + return raw_hex_iterator (tria, + tria->last_raw_hex()->level(), + tria->last_raw_hex()->index(), + this); } @@ -1227,7 +1279,10 @@ template typename DoFHandler::line_iterator DoFHandler::last_line () const { - return last_line (levels.size()-1); + return line_iterator (tria, + tria->last_line()->level(), + tria->last_line()->index(), + this); } @@ -1235,7 +1290,10 @@ template typename DoFHandler::quad_iterator DoFHandler::last_quad () const { - return last_quad (levels.size()-1); + return quad_iterator (tria, + tria->last_quad()->level(), + tria->last_quad()->index(), + this); } @@ -1243,7 +1301,10 @@ template typename DoFHandler::hex_iterator DoFHandler::last_hex () const { - return last_hex (levels.size()-1); + return hex_iterator (tria, + tria->last_hex()->level(), + tria->last_hex()->index(), + this); } @@ -1251,7 +1312,10 @@ template typename DoFHandler::active_line_iterator DoFHandler::last_active_line () const { - return last_active_line (levels.size()-1); + return active_line_iterator (tria, + tria->last_active_line()->level(), + tria->last_active_line()->index(), + this); } @@ -1259,7 +1323,10 @@ template typename DoFHandler::active_quad_iterator DoFHandler::last_active_quad () const { - return last_active_quad (levels.size()-1); + return active_quad_iterator (tria, + tria->last_active_quad()->level(), + tria->last_active_quad()->index(), + this); } @@ -1267,12 +1334,369 @@ template typename DoFHandler::active_hex_iterator DoFHandler::last_active_hex () const { - return last_active_hex (levels.size()-1); + return active_hex_iterator (tria, + tria->last_active_hex()->level(), + tria->last_active_hex()->index(), + this); } //--------------------------------------------------------------------------- +#if deal_II_dimension == 1 +template <> +template <> +unsigned int +DoFHandler<1>::get_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->levels[obj_level]->lines. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +DoFHandler<1>::set_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->levels[obj_level]->lines. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} + + +template <> +template <> +bool +DoFHandler<1>::fe_index_is_active<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const +{ + return this->levels[obj_level]->lines.fe_index_is_active(*this, + obj_index, + fe_index); +} + + +template <> +template <> +unsigned int +DoFHandler<1>::n_active_fe_indices<1> (const unsigned int obj_level, + const unsigned int obj_index) const +{ + return this->levels[obj_level]->lines.n_active_fe_indices (*this, + obj_index); +} +#endif + +#if deal_II_dimension == 2 +template <> +template <> +unsigned int +DoFHandler<2>::get_dof_index<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->faces->lines. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +DoFHandler<2>::set_dof_index<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->faces->lines. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} + + +template <> +template <> +bool +DoFHandler<2>::fe_index_is_active<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index) const +{ + return this->faces->lines.fe_index_is_active(*this, + obj_index, + fe_index); +} + + +template <> +template <> +unsigned int +DoFHandler<2>::n_active_fe_indices<1> (const unsigned int , + const unsigned int obj_index) const +{ + return this->faces->lines.n_active_fe_indices (*this, + obj_index); +} + + +template <> +template <> +unsigned int +DoFHandler<2>::get_dof_index<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->levels[obj_level]->quads. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +DoFHandler<2>::set_dof_index<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->levels[obj_level]->quads. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} + + +template <> +template <> +bool +DoFHandler<2>::fe_index_is_active<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const +{ + return this->levels[obj_level]->quads.fe_index_is_active(*this, + obj_index, + fe_index); +} + + +template <> +template <> +unsigned int +DoFHandler<2>::n_active_fe_indices<2> (const unsigned int obj_level, + const unsigned int obj_index) const +{ + return this->levels[obj_level]->quads.n_active_fe_indices (*this, + obj_index); +} +#endif + +#if deal_II_dimension == 3 +template <> +template <> +unsigned int +DoFHandler<3>::get_dof_index<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->faces->lines. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +DoFHandler<3>::set_dof_index<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->faces->lines. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} + + +template <> +template <> +bool +DoFHandler<3>::fe_index_is_active<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index) const +{ + return this->faces->lines.fe_index_is_active(*this, + obj_index, + fe_index); +} + + +template <> +template <> +unsigned int +DoFHandler<3>::n_active_fe_indices<1> (const unsigned int , + const unsigned int obj_index) const +{ + return this->faces->lines.n_active_fe_indices (*this, + obj_index); +} + +template <> +template <> +unsigned int +DoFHandler<3>::get_dof_index<2> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->faces->quads. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +unsigned int +DoFHandler<3>::get_dof_index<3> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->levels[obj_level]->hexes. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +DoFHandler<3>::set_dof_index<2> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->faces->quads. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} + + +template <> +template <> +void +DoFHandler<3>::set_dof_index<3> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->levels[obj_level]->hexes. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} + + +template <> +template <> +bool +DoFHandler<3>::fe_index_is_active<2> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index) const +{ + return this->faces->quads.fe_index_is_active(*this, + obj_index, + fe_index); +} + +template <> +template <> +bool +DoFHandler<3>::fe_index_is_active<3> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const +{ + return this->levels[obj_level]->hexes.fe_index_is_active(*this, + obj_index, + fe_index); +} + + +template <> +template <> +unsigned int +DoFHandler<3>::n_active_fe_indices<2> (const unsigned int , + const unsigned int obj_index) const +{ + return this->faces->quads.n_active_fe_indices (*this, + obj_index); +} + +template <> +template <> +unsigned int +DoFHandler<3>::n_active_fe_indices<3> (const unsigned int obj_level, + const unsigned int obj_index) const +{ + return this->levels[obj_level]->hexes.n_active_fe_indices (*this, + obj_index); +} +#endif + #if deal_II_dimension == 1 @@ -1419,10 +1843,12 @@ DoFHandler::memory_consumption () const MemoryConsumption::memory_consumption (selected_fe) + MemoryConsumption::memory_consumption (tria) + MemoryConsumption::memory_consumption (levels) + + MemoryConsumption::memory_consumption (faces) + MemoryConsumption::memory_consumption (used_dofs) + MemoryConsumption::memory_consumption (vertex_dofs)); for (unsigned int i=0; i::renumber_dofs (const std::vector &new_numbers) ExcInternalError ()); for (unsigned int level=0; level::iterator i=levels[level]->line_dofs.begin(); - i!=levels[level]->line_dofs.end(); ++i) + for (std::vector::iterator i=levels[level]->lines.dofs.begin(); + i!=levels[level]->lines.dofs.end(); ++i) if (*i != invalid_dof_index) *i = new_numbers[*i]; @@ -1740,14 +2166,15 @@ void DoFHandler<2>::renumber_dofs (const std::vector &new_numbers) selected_fe->dofs_per_vertex) == false, ExcInternalError ()); + for (std::vector::iterator i=faces->lines.dofs.begin(); + i!=faces->lines.dofs.end(); ++i) + if (*i != invalid_dof_index) + *i = new_numbers[*i]; + for (unsigned int level=0; level::iterator i=levels[level]->line_dofs.begin(); - i!=levels[level]->line_dofs.end(); ++i) - if (*i != invalid_dof_index) - *i = new_numbers[*i]; - for (std::vector::iterator i=levels[level]->quad_dofs.begin(); - i!=levels[level]->quad_dofs.end(); ++i) + for (std::vector::iterator i=levels[level]->quads.dofs.begin(); + i!=levels[level]->quads.dofs.end(); ++i) if (*i != invalid_dof_index) *i = new_numbers[*i]; } @@ -1799,18 +2226,19 @@ void DoFHandler<3>::renumber_dofs (const std::vector &new_numbers) selected_fe->dofs_per_vertex) == false, ExcInternalError ()); + for (std::vector::iterator i=faces->lines.dofs.begin(); + i!=faces->lines.dofs.end(); ++i) + if (*i != invalid_dof_index) + *i = new_numbers[*i]; + for (std::vector::iterator i=faces->quads.dofs.begin(); + i!=faces->quads.dofs.end(); ++i) + if (*i != invalid_dof_index) + *i = new_numbers[*i]; + for (unsigned int level=0; level::iterator i=levels[level]->line_dofs.begin(); - i!=levels[level]->line_dofs.end(); ++i) - if (*i != invalid_dof_index) - *i = new_numbers[*i]; - for (std::vector::iterator i=levels[level]->quad_dofs.begin(); - i!=levels[level]->quad_dofs.end(); ++i) - if (*i != invalid_dof_index) - *i = new_numbers[*i]; - for (std::vector::iterator i=levels[level]->hex_dofs.begin(); - i!=levels[level]->hex_dofs.end(); ++i) + for (std::vector::iterator i=levels[level]->hexes.dofs.begin(); + i!=levels[level]->hexes.dofs.end(); ++i) if (*i != invalid_dof_index) *i = new_numbers[*i]; } @@ -2010,9 +2438,9 @@ void DoFHandler<1>::reserve_space () { levels.push_back (new internal::DoFHandler::DoFLevel<1>); - levels.back()->line_dofs.resize (tria->n_raw_lines(i) * - selected_fe->dofs_per_line, - invalid_dof_index); + levels.back()->lines.dofs.resize (tria->n_raw_lines(i) * + selected_fe->dofs_per_line, + invalid_dof_index); levels.back()->cell_dof_indices_cache.resize (tria->n_raw_lines(i) * selected_fe->dofs_per_cell, @@ -2037,7 +2465,7 @@ void DoFHandler<2>::reserve_space () // troublesome if you want to change // their size clear_space (); - + vertex_dofs.resize(tria->n_vertices()*selected_fe->dofs_per_vertex, invalid_dof_index); @@ -2045,17 +2473,20 @@ void DoFHandler<2>::reserve_space () { levels.push_back (new internal::DoFHandler::DoFLevel<2>); - levels.back()->line_dofs.resize (tria->n_raw_lines(i) * - selected_fe->dofs_per_line, - invalid_dof_index); - levels.back()->quad_dofs.resize (tria->n_raw_quads(i) * - selected_fe->dofs_per_quad, - invalid_dof_index); + levels.back()->quads.dofs.resize (tria->n_raw_quads(i) * + selected_fe->dofs_per_quad, + invalid_dof_index); levels.back()->cell_dof_indices_cache.resize (tria->n_raw_quads(i) * selected_fe->dofs_per_cell, invalid_dof_index); } + + faces = new internal::DoFHandler::DoFFaces<2>; + faces->lines.dofs.resize (tria->n_raw_lines() * + selected_fe->dofs_per_line, + invalid_dof_index); + } #endif @@ -2082,31 +2513,37 @@ void DoFHandler<3>::reserve_space () { levels.push_back (new internal::DoFHandler::DoFLevel<3>); - levels.back()->line_dofs = std::vector (tria->n_raw_lines(i) * - selected_fe->dofs_per_line, - invalid_dof_index); - levels.back()->quad_dofs = std::vector (tria->n_raw_quads(i) * - selected_fe->dofs_per_quad, - invalid_dof_index); - levels.back()->hex_dofs = std::vector (tria->n_raw_hexs(i) * - selected_fe->dofs_per_hex, - invalid_dof_index); + levels.back()->hexes.dofs.resize (tria->n_raw_hexs(i) * + selected_fe->dofs_per_hex, + invalid_dof_index); levels.back()->cell_dof_indices_cache.resize (tria->n_raw_hexs(i) * selected_fe->dofs_per_cell, invalid_dof_index); } + faces = new internal::DoFHandler::DoFFaces<3>; + + faces->lines.dofs.resize (tria->n_raw_lines() * + selected_fe->dofs_per_line, + invalid_dof_index); + faces->quads.dofs.resize (tria->n_raw_quads() * + selected_fe->dofs_per_quad, + invalid_dof_index); + } #endif template -void DoFHandler::clear_space () { +void DoFHandler::clear_space () { for (unsigned int i=0; i tmp; std::swap (vertex_dofs, tmp); } diff --git a/deal.II/deal.II/source/dofs/dof_levels.all_dimensions.cc b/deal.II/deal.II/source/dofs/dof_levels.all_dimensions.cc index 6c0ecb7d3e..d32bc708ac 100644 --- a/deal.II/deal.II/source/dofs/dof_levels.all_dimensions.cc +++ b/deal.II/deal.II/source/dofs/dof_levels.all_dimensions.cc @@ -28,31 +28,38 @@ namespace internal return MemoryConsumption::memory_consumption (cell_dof_indices_cache); } +#if deal_II_dimension == 1 unsigned int DoFLevel<1>::memory_consumption () const { return (DoFLevel<0>::memory_consumption () + - MemoryConsumption::memory_consumption (line_dofs)); + MemoryConsumption::memory_consumption (lines)); } +#endif - +#if deal_II_dimension == 2 + unsigned int DoFLevel<2>::memory_consumption () const { - return (DoFLevel<1>::memory_consumption () + - MemoryConsumption::memory_consumption (quad_dofs)); + return (DoFLevel<0>::memory_consumption () + + MemoryConsumption::memory_consumption (quads)); } +#endif +#if deal_II_dimension == 3 unsigned int DoFLevel<3>::memory_consumption () const { - return (DoFLevel<2>::memory_consumption () + - MemoryConsumption::memory_consumption (hex_dofs)); + return (DoFLevel<0>::memory_consumption () + + MemoryConsumption::memory_consumption (hexes)); } + +#endif } } diff --git a/deal.II/deal.II/source/dofs/dof_levels.cc b/deal.II/deal.II/source/dofs/dof_levels.cc index 6d48cad484..55cc1d76e3 100644 --- a/deal.II/deal.II/source/dofs/dof_levels.cc +++ b/deal.II/deal.II/source/dofs/dof_levels.cc @@ -1,236 +1,16 @@ -//--------------------------------------------------------------------------- -// $Id$ -// Version: $Name$ -// -// Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006 by the deal.II authors -// -// This file is subject to QPL and may not be distributed -// without copyright and license information. Please refer -// to the file deal.II/doc/license.html for the text and -// further information on this license. -// -//--------------------------------------------------------------------------- #include #include -#include +#include #include #include -//TODO[WB]: make a few of these functions inline - namespace internal { namespace DoFHandler { - template - unsigned int - DoFLevel<1>:: - get_dof_index (const ::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<1> /*dummy*/) const - { - Assert (fe_index == ::DoFHandler::default_fe_index, - ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects")); - Assert (local_index - void - DoFLevel<1>:: - set_dof_index (const ::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<1> /*dummy*/) - { - Assert (fe_index == ::DoFHandler::default_fe_index, - ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects")); - Assert (local_index - unsigned int - DoFLevel<2>:: - get_dof_index (const ::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<2> /*dummy*/) const - { - Assert (fe_index == ::DoFHandler::default_fe_index, - ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects")); - Assert (local_index - void - DoFLevel<2>:: - set_dof_index (const ::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<2> /*dummy*/) - { - Assert (fe_index == ::DoFHandler::default_fe_index, - ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects")); - Assert (local_index - unsigned int - DoFLevel<3>:: - get_dof_index (const ::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<3> /*dummy*/) const - { - Assert (fe_index == ::DoFHandler::default_fe_index, - ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects")); - Assert (local_index - void - DoFLevel<3>:: - set_dof_index (const ::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<3> /*dummy*/) - { - Assert (fe_index == ::DoFHandler::default_fe_index, - ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects")); - Assert (local_index:: - get_dof_index (const ::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<1> dummy) const; - - template - void - DoFLevel<1>:: - set_dof_index (const ::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<1> dummy); - -#if deal_II_dimension >= 2 - - template - unsigned int - DoFLevel<2>:: - get_dof_index (const ::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<2> dummy) const; - - template - void - DoFLevel<2>:: - set_dof_index (const ::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<2> dummy); - -#endif - -#if deal_II_dimension >= 3 - - template - unsigned int - DoFLevel<3>:: - get_dof_index (const ::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<3> dummy) const; - - template - void - DoFLevel<3>:: - set_dof_index (const ::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<3> dummy); - -#endif } diff --git a/deal.II/deal.II/source/dofs/dof_objects.cc b/deal.II/deal.II/source/dofs/dof_objects.cc new file mode 100644 index 0000000000..94058d1b92 --- /dev/null +++ b/deal.II/deal.II/source/dofs/dof_objects.cc @@ -0,0 +1,245 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include +#include +#include +#include + +namespace internal +{ + namespace DoFHandler + { + template + unsigned int + DoFObjects::memory_consumption () const + { + return (MemoryConsumption::memory_consumption (dofs)); + } + + template + template + inline + unsigned int + DoFObjects::n_active_fe_indices (const ::DoFHandler &, + const unsigned) const + { + return 1; + } + + + template + template + inline + bool + DoFObjects::fe_index_is_active (const ::DoFHandler &, + const unsigned int, + const unsigned int fe_index) const + { + Assert (fe_index == 0, + ExcMessage ("Only zero fe_index values are allowed for " + "non-hp DoFHandlers.")); + return true; + } + + template + template + unsigned int + DoFObjects:: + get_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const + { + unsigned int dofs_per_obj; + switch (dim) + { + case 1 : + dofs_per_obj = dof_handler.get_fe().dofs_per_line; + break; + case 2 : + dofs_per_obj = dof_handler.get_fe().dofs_per_quad; + break; + case 3 : + dofs_per_obj = dof_handler.get_fe().dofs_per_hex; + } + + Assert (fe_index == ::DoFHandler::default_fe_index, + ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects")); + Assert (local_index + template + void + DoFObjects:: + set_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) + { + unsigned int dofs_per_obj; + switch (dim) + { + case 1 : + dofs_per_obj = dof_handler.get_fe().dofs_per_line; + break; + case 2 : + dofs_per_obj = dof_handler.get_fe().dofs_per_quad; + break; + case 3 : + dofs_per_obj = dof_handler.get_fe().dofs_per_hex; + } + + Assert (fe_index == ::DoFHandler::default_fe_index, + ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects")); + Assert (local_index:: + memory_consumption () const; + + + template + unsigned int + DoFObjects<1>:: + get_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const; + + template + void + DoFObjects<1>:: + set_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index); + + template + unsigned int + DoFObjects<1>:: + n_active_fe_indices (const ::DoFHandler &, + const unsigned) const; + + template + bool + DoFObjects<1>:: + fe_index_is_active (const ::DoFHandler &, + const unsigned int, + const unsigned int fe_index) const; + +#if deal_II_dimension >= 2 + + template + unsigned int + DoFObjects<2>:: + memory_consumption () const; + + + template + unsigned int + DoFObjects<2>:: + get_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const; + + template + void + DoFObjects<2>:: + set_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index); + + template + unsigned int + DoFObjects<2>:: + n_active_fe_indices (const ::DoFHandler &, + const unsigned) const; + + template + bool + DoFObjects<2>:: + fe_index_is_active (const ::DoFHandler &, + const unsigned int, + const unsigned int fe_index) const; + +#endif + +#if deal_II_dimension >= 3 + + template + unsigned int + DoFObjects<3>:: + memory_consumption () const; + + + template + unsigned int + DoFObjects<3>:: + get_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const; + + template + void + DoFObjects<3>:: + set_dof_index (const ::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index); + + template + unsigned int + DoFObjects<3>:: + n_active_fe_indices (const ::DoFHandler &, + const unsigned) const; + + template + bool + DoFObjects<3>:: + fe_index_is_active (const ::DoFHandler &, + const unsigned int, + const unsigned int fe_index) const; + +#endif + + } +} diff --git a/deal.II/deal.II/source/dofs/hp_dof_faces.cc b/deal.II/deal.II/source/dofs/hp_dof_faces.cc new file mode 100644 index 0000000000..b360130bfb --- /dev/null +++ b/deal.II/deal.II/source/dofs/hp_dof_faces.cc @@ -0,0 +1,44 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include + + +namespace internal +{ + namespace hp + { + unsigned int + DoFFaces<1>::memory_consumption () const + { + return 0; + } + + + unsigned int + DoFFaces<2>::memory_consumption () const + { + return MemoryConsumption::memory_consumption (lines); + } + + + unsigned int + DoFFaces<3>::memory_consumption () const + { + return (MemoryConsumption::memory_consumption (quads) + + MemoryConsumption::memory_consumption (quads) ); + } + } +} diff --git a/deal.II/deal.II/source/dofs/hp_dof_handler.cc b/deal.II/deal.II/source/dofs/hp_dof_handler.cc index 5672de40f8..6aac25bf7f 100644 --- a/deal.II/deal.II/source/dofs/hp_dof_handler.cc +++ b/deal.II/deal.II/source/dofs/hp_dof_handler.cc @@ -14,7 +14,9 @@ #include #include +#include #include +#include #include #include #include @@ -46,6 +48,7 @@ namespace hp DoFHandler::DoFHandler (const Triangulation &tria) : tria(&tria), + faces (NULL), used_dofs (0) { create_active_fe_table (); @@ -64,7 +67,6 @@ namespace hp clear (); } - #if deal_II_dimension == 1 template <> @@ -149,27 +151,27 @@ namespace hp template <> DoFHandler<1>::raw_face_iterator - DoFHandler<1>::begin_raw_face (const unsigned int) const + DoFHandler<1>::begin_raw_face () const { - Assert (false, ExcFunctionNotUseful()); + Assert (false, ExcImpossibleInDim(1)); return 0; } template <> DoFHandler<1>::face_iterator - DoFHandler<1>::begin_face (const unsigned int) const + DoFHandler<1>::begin_face () const { - Assert (false, ExcFunctionNotUseful()); + Assert (false, ExcImpossibleInDim(1)); return 0; } template <> DoFHandler<1>::active_face_iterator - DoFHandler<1>::begin_active_face (const unsigned int) const + DoFHandler<1>::begin_active_face () const { - Assert (false, ExcFunctionNotUseful()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -178,43 +180,43 @@ namespace hp DoFHandler<1>::raw_face_iterator DoFHandler<1>::end_face () const { - Assert (false, ExcFunctionNotUseful()); + Assert (false, ExcImpossibleInDim(1)); return 0; } template <> DoFHandler<1>::raw_face_iterator - DoFHandler<1>::last_raw_face () const + DoFHandler<1>::end_raw_face () const { - Assert (false, ExcFunctionNotUseful()); + Assert (false, ExcImpossibleInDim(1)); return 0; } template <> - DoFHandler<1>::raw_face_iterator - DoFHandler<1>::last_raw_face (const unsigned int) const + DoFHandler<1>::active_face_iterator + DoFHandler<1>::end_active_face () const { - Assert (false, ExcFunctionNotUseful()); + Assert (false, ExcImpossibleInDim(1)); return 0; } template <> - DoFHandler<1>::face_iterator - DoFHandler<1>::last_face () const + DoFHandler<1>::raw_face_iterator + DoFHandler<1>::last_raw_face () const { - Assert (false, ExcFunctionNotUseful()); + Assert (false, ExcImpossibleInDim(1)); return 0; } template <> DoFHandler<1>::face_iterator - DoFHandler<1>::last_face (const unsigned int) const + DoFHandler<1>::last_face () const { - Assert (false, ExcFunctionNotUseful()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -223,16 +225,7 @@ namespace hp DoFHandler<1>::active_face_iterator DoFHandler<1>::last_active_face () const { - Assert (false, ExcFunctionNotUseful()); - return 0; - } - - - template <> - DoFHandler<1>::active_face_iterator - DoFHandler<1>::last_active_face (const unsigned int) const - { - Assert (false, ExcFunctionNotUseful()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -241,7 +234,7 @@ namespace hp DoFHandler<1>::raw_quad_iterator DoFHandler<1>::begin_raw_quad (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -250,7 +243,7 @@ namespace hp DoFHandler<1>::quad_iterator DoFHandler<1>::begin_quad (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -259,7 +252,7 @@ namespace hp DoFHandler<1>::active_quad_iterator DoFHandler<1>::begin_active_quad (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -268,7 +261,34 @@ namespace hp DoFHandler<1>::raw_quad_iterator DoFHandler<1>::end_quad () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); + return 0; + } + + + template <> + DoFHandler<1>::quad_iterator + DoFHandler<1>::end_quad (const unsigned int) const + { + Assert (false, ExcImpossibleInDim(1)); + return 0; + } + + + template <> + DoFHandler<1>::raw_quad_iterator + DoFHandler<1>::end_raw_quad (const unsigned int) const + { + Assert (false, ExcImpossibleInDim(1)); + return 0; + } + + + template <> + DoFHandler<1>::active_quad_iterator + DoFHandler<1>::end_active_quad (const unsigned int) const + { + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -277,7 +297,7 @@ namespace hp DoFHandler<1>::raw_quad_iterator DoFHandler<1>::last_raw_quad (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -286,7 +306,7 @@ namespace hp DoFHandler<1>::quad_iterator DoFHandler<1>::last_quad (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -295,7 +315,7 @@ namespace hp DoFHandler<1>::active_quad_iterator DoFHandler<1>::last_active_quad (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -304,7 +324,7 @@ namespace hp DoFHandler<1>::raw_quad_iterator DoFHandler<1>::last_raw_quad () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -313,7 +333,7 @@ namespace hp DoFHandler<1>::quad_iterator DoFHandler<1>::last_quad () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -322,7 +342,7 @@ namespace hp DoFHandler<1>::active_quad_iterator DoFHandler<1>::last_active_quad () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -331,7 +351,7 @@ namespace hp DoFHandler<1>::raw_hex_iterator DoFHandler<1>::begin_raw_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -340,7 +360,7 @@ namespace hp DoFHandler<1>::hex_iterator DoFHandler<1>::begin_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -349,7 +369,7 @@ namespace hp DoFHandler<1>::active_hex_iterator DoFHandler<1>::begin_active_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -358,7 +378,34 @@ namespace hp DoFHandler<1>::raw_hex_iterator DoFHandler<1>::end_hex () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); + return 0; + } + + + template <> + DoFHandler<1>::hex_iterator + DoFHandler<1>::end_hex (const unsigned int) const + { + Assert (false, ExcImpossibleInDim(1)); + return 0; + } + + + template <> + DoFHandler<1>::raw_hex_iterator + DoFHandler<1>::end_raw_hex (const unsigned int) const + { + Assert (false, ExcImpossibleInDim(1)); + return 0; + } + + + template <> + DoFHandler<1>::active_hex_iterator + DoFHandler<1>::end_active_hex (const unsigned int) const + { + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -367,7 +414,7 @@ namespace hp DoFHandler<1>::raw_hex_iterator DoFHandler<1>::last_raw_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -376,7 +423,7 @@ namespace hp DoFHandler<1>::raw_hex_iterator DoFHandler<1>::last_raw_hex () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -385,7 +432,7 @@ namespace hp DoFHandler<1>::hex_iterator DoFHandler<1>::last_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -394,7 +441,7 @@ namespace hp DoFHandler<1>::hex_iterator DoFHandler<1>::last_hex () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -403,7 +450,7 @@ namespace hp DoFHandler<1>::active_hex_iterator DoFHandler<1>::last_active_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -412,7 +459,7 @@ namespace hp DoFHandler<1>::active_hex_iterator DoFHandler<1>::last_active_hex () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(1)); return 0; } @@ -503,25 +550,25 @@ namespace hp template <> DoFHandler<2>::raw_face_iterator - DoFHandler<2>::begin_raw_face (const unsigned int level) const + DoFHandler<2>::begin_raw_face () const { - return begin_raw_line (level); + return begin_raw_line (); } template <> DoFHandler<2>::face_iterator - DoFHandler<2>::begin_face (const unsigned int level) const + DoFHandler<2>::begin_face () const { - return begin_line (level); + return begin_line (); } template <> DoFHandler<2>::active_face_iterator - DoFHandler<2>::begin_active_face (const unsigned int level) const + DoFHandler<2>::begin_active_face () const { - return begin_active_line (level); + return begin_active_line (); } @@ -535,33 +582,33 @@ namespace hp template <> DoFHandler<2>::raw_face_iterator - DoFHandler<2>::last_raw_face () const + DoFHandler<2>::end_raw_face () const { - return last_raw_line (); + return end_line (); } template <> - DoFHandler<2>::raw_face_iterator - DoFHandler<2>::last_raw_face (const unsigned int level) const + DoFHandler<2>::active_face_iterator + DoFHandler<2>::end_active_face () const { - return last_raw_line (level); + return end_line (); } template <> - DoFHandler<2>::face_iterator - DoFHandler<2>::last_face () const + DoFHandler<2>::raw_face_iterator + DoFHandler<2>::last_raw_face () const { - return last_line (); + return last_raw_line (); } template <> DoFHandler<2>::face_iterator - DoFHandler<2>::last_face (const unsigned int level) const + DoFHandler<2>::last_face () const { - return last_line (level); + return last_line (); } @@ -573,19 +620,11 @@ namespace hp } - template <> - DoFHandler<2>::active_face_iterator - DoFHandler<2>::last_active_face (const unsigned int level) const - { - return last_active_line (level); - } - - template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::begin_raw_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -594,7 +633,7 @@ namespace hp DoFHandler<2>::hex_iterator DoFHandler<2>::begin_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -603,7 +642,7 @@ namespace hp DoFHandler<2>::active_hex_iterator DoFHandler<2>::begin_active_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -612,7 +651,34 @@ namespace hp DoFHandler<2>::raw_hex_iterator DoFHandler<2>::end_hex () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); + return 0; + } + + + template <> + DoFHandler<2>::hex_iterator + DoFHandler<2>::end_hex (const unsigned int) const + { + Assert (false, ExcImpossibleInDim(2)); + return 0; + } + + + template <> + DoFHandler<2>::raw_hex_iterator + DoFHandler<2>::end_raw_hex (const unsigned int) const + { + Assert (false, ExcImpossibleInDim(2)); + return 0; + } + + + template <> + DoFHandler<2>::active_hex_iterator + DoFHandler<2>::end_active_hex (const unsigned int) const + { + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -621,7 +687,7 @@ namespace hp DoFHandler<2>::raw_hex_iterator DoFHandler<2>::last_raw_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -630,7 +696,7 @@ namespace hp DoFHandler<2>::raw_hex_iterator DoFHandler<2>::last_raw_hex () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -639,7 +705,7 @@ namespace hp DoFHandler<2>::hex_iterator DoFHandler<2>::last_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -648,7 +714,7 @@ namespace hp DoFHandler<2>::hex_iterator DoFHandler<2>::last_hex () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -657,7 +723,7 @@ namespace hp DoFHandler<2>::active_hex_iterator DoFHandler<2>::last_active_hex (const unsigned int) const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -666,7 +732,7 @@ namespace hp DoFHandler<2>::active_hex_iterator DoFHandler<2>::last_active_hex () const { - Assert (false, ExcNotImplemented()); + Assert (false, ExcImpossibleInDim(2)); return 0; } @@ -758,25 +824,25 @@ namespace hp template <> DoFHandler<3>::raw_face_iterator - DoFHandler<3>::begin_raw_face (const unsigned int level) const + DoFHandler<3>::begin_raw_face () const { - return begin_raw_quad (level); + return begin_raw_quad (); } template <> DoFHandler<3>::face_iterator - DoFHandler<3>::begin_face (const unsigned int level) const + DoFHandler<3>::begin_face () const { - return begin_quad (level); + return begin_quad (); } template <> DoFHandler<3>::active_face_iterator - DoFHandler<3>::begin_active_face (const unsigned int level) const + DoFHandler<3>::begin_active_face () const { - return begin_active_quad (level); + return begin_active_quad (); } @@ -790,33 +856,33 @@ namespace hp template <> DoFHandler<3>::raw_face_iterator - DoFHandler<3>::last_raw_face () const + DoFHandler<3>::end_raw_face () const { - return last_raw_quad (); + return end_quad (); } template <> - DoFHandler<3>::raw_face_iterator - DoFHandler<3>::last_raw_face (const unsigned int level) const + DoFHandler<3>::active_face_iterator + DoFHandler<3>::end_active_face () const { - return last_raw_quad (level); + return end_quad (); } template <> - DoFHandler<3>::face_iterator - DoFHandler<3>::last_face () const + DoFHandler<3>::raw_face_iterator + DoFHandler<3>::last_raw_face () const { - return last_quad (); + return last_raw_quad (); } template <> DoFHandler<3>::face_iterator - DoFHandler<3>::last_face (const unsigned int level) const + DoFHandler<3>::last_face () const { - return last_quad (level); + return last_quad (); } @@ -828,14 +894,6 @@ namespace hp } - template <> - DoFHandler<3>::active_face_iterator - DoFHandler<3>::last_active_face (const unsigned int level) const - { - return last_active_quad (level); - } - - #endif @@ -938,6 +996,12 @@ namespace hp } + // We can't ask the respective tria->-function here, as + // that would include dereferencing a past-the-end + // iterator which is not allowed. Therefore we have to + // repeat the code from tria.cc This is valid for all + // functions whisch return past the end iterators, namely + // all functions end_*() template typename DoFHandler::raw_line_iterator DoFHandler::end_line () const @@ -992,43 +1056,14 @@ namespace hp } - template - typename DoFHandler::raw_face_iterator - DoFHandler::end_raw_face (const unsigned int level) const - { - return (level == levels.size()-1 ? - end_face() : - begin_raw_face (level+1)); - } - - - template - typename DoFHandler::face_iterator - DoFHandler::end_face (const unsigned int level) const - { - return (level == levels.size()-1 ? - face_iterator(end_face()) : - begin_face (level+1)); - } - - - template - typename DoFHandler::active_face_iterator - DoFHandler::end_active_face (const unsigned int level) const - { - return (level == levels.size()-1 ? - active_face_iterator(end_face()) : - begin_active_face (level+1)); - } - - template typename DoFHandler::raw_line_iterator DoFHandler::end_raw_line (const unsigned int level) const { - return (level == levels.size()-1 ? - end_line() : - begin_raw_line (level+1)); + return raw_line_iterator(tria, + tria->end_raw_line(level)->level(), + tria->end_raw_line(level)->index(), + this); } @@ -1036,9 +1071,10 @@ namespace hp typename DoFHandler::line_iterator DoFHandler::end_line (const unsigned int level) const { - return (level == levels.size()-1 ? - line_iterator(end_line()) : - begin_line (level+1)); + return line_iterator(tria, + tria->end_line(level)->level(), + tria->end_line(level)->index(), + this); } @@ -1046,9 +1082,10 @@ namespace hp typename DoFHandler::active_line_iterator DoFHandler::end_active_line (const unsigned int level) const { - return (level == levels.size()-1 ? - active_line_iterator(end_line()) : - begin_active_line (level+1)); + return active_line_iterator(tria, + tria->end_active_line(level)->level(), + tria->end_active_line(level)->index(), + this); } @@ -1056,9 +1093,10 @@ namespace hp typename DoFHandler::raw_quad_iterator DoFHandler::end_raw_quad (const unsigned int level) const { - return (level == levels.size()-1 ? - end_quad() : - begin_raw_quad (level+1)); + return raw_quad_iterator(tria, + tria->end_raw_quad(level)->level(), + tria->end_raw_quad(level)->index(), + this); } @@ -1066,9 +1104,10 @@ namespace hp typename DoFHandler::quad_iterator DoFHandler::end_quad (const unsigned int level) const { - return (level == levels.size()-1 ? - quad_iterator(end_quad()) : - begin_quad (level+1)); + return quad_iterator(tria, + tria->end_quad(level)->level(), + tria->end_quad(level)->index(), + this); } @@ -1076,9 +1115,10 @@ namespace hp typename DoFHandler::active_quad_iterator DoFHandler::end_active_quad (const unsigned int level) const { - return (level == levels.size()-1 ? - active_quad_iterator(end_quad()) : - begin_active_quad (level+1)); + return active_quad_iterator(tria, + tria->end_active_quad(level)->level(), + tria->end_active_quad(level)->index(), + this); } @@ -1086,9 +1126,10 @@ namespace hp typename DoFHandler::raw_hex_iterator DoFHandler::end_raw_hex (const unsigned int level) const { - return (level == levels.size()-1 ? - end_hex() : - begin_raw_hex (level+1)); + return raw_hex_iterator(tria, + tria->end_raw_hex(level)->level(), + tria->end_raw_hex(level)->index(), + this); } @@ -1096,9 +1137,10 @@ namespace hp typename DoFHandler::hex_iterator DoFHandler::end_hex (const unsigned int level) const { - return (level == levels.size()-1 ? - hex_iterator(end_hex()) : - begin_hex (level+1)); + return hex_iterator(tria, + tria->end_hex(level)->level(), + tria->end_hex(level)->index(), + this); } @@ -1106,9 +1148,10 @@ namespace hp typename DoFHandler::active_hex_iterator DoFHandler::end_active_hex (const unsigned int level) const { - return (level == levels.size()-1 ? - active_hex_iterator(end_hex()) : - begin_active_hex (level+1)); + return active_hex_iterator(tria, + tria->end_active_hex(level)->level(), + tria->end_active_hex(level)->index(), + this); } @@ -1215,7 +1258,10 @@ namespace hp typename DoFHandler::raw_line_iterator DoFHandler::last_raw_line () const { - return last_raw_line (levels.size()-1); + return raw_line_iterator (tria, + tria->last_raw_line()->level(), + tria->last_raw_line()->index(), + this); } @@ -1223,7 +1269,10 @@ namespace hp typename DoFHandler::raw_quad_iterator DoFHandler::last_raw_quad () const { - return last_raw_quad (levels.size()-1); + return raw_quad_iterator (tria, + tria->last_raw_quad()->level(), + tria->last_raw_quad()->index(), + this); } @@ -1231,7 +1280,10 @@ namespace hp typename DoFHandler::raw_hex_iterator DoFHandler::last_raw_hex () const { - return last_raw_hex (levels.size()-1); + return raw_hex_iterator (tria, + tria->last_raw_hex()->level(), + tria->last_raw_hex()->index(), + this); } @@ -1239,7 +1291,10 @@ namespace hp typename DoFHandler::line_iterator DoFHandler::last_line () const { - return last_line (levels.size()-1); + return line_iterator (tria, + tria->last_line()->level(), + tria->last_line()->index(), + this); } @@ -1247,7 +1302,10 @@ namespace hp typename DoFHandler::quad_iterator DoFHandler::last_quad () const { - return last_quad (levels.size()-1); + return quad_iterator (tria, + tria->last_quad()->level(), + tria->last_quad()->index(), + this); } @@ -1255,7 +1313,10 @@ namespace hp typename DoFHandler::hex_iterator DoFHandler::last_hex () const { - return last_hex (levels.size()-1); + return hex_iterator (tria, + tria->last_hex()->level(), + tria->last_hex()->index(), + this); } @@ -1263,7 +1324,10 @@ namespace hp typename DoFHandler::active_line_iterator DoFHandler::last_active_line () const { - return last_active_line (levels.size()-1); + return active_line_iterator (tria, + tria->last_active_line()->level(), + tria->last_active_line()->index(), + this); } @@ -1271,7 +1335,10 @@ namespace hp typename DoFHandler::active_quad_iterator DoFHandler::last_active_quad () const { - return last_active_quad (levels.size()-1); + return active_quad_iterator (tria, + tria->last_active_quad()->level(), + tria->last_active_quad()->index(), + this); } @@ -1279,11 +1346,388 @@ namespace hp typename DoFHandler::active_hex_iterator DoFHandler::last_active_hex () const { - return last_active_hex (levels.size()-1); + return active_hex_iterator (tria, + tria->last_active_hex()->level(), + tria->last_active_hex()->index(), + this); } //------------------------------------------------------------------ +#if deal_II_dimension == 1 + template <> + template <> + unsigned int + DoFHandler<1>::get_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const + { + return this->levels[obj_level]->lines. + get_dof_index (*this, + obj_index, + fe_index, + local_index, + obj_level); + } + + + template <> + template <> + void + DoFHandler<1>::set_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const + { + this->levels[obj_level]->lines. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index, + obj_level); + } + + + template <> + template <> + bool + DoFHandler<1>::fe_index_is_active<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const + { + return this->levels[obj_level]->lines.fe_index_is_active(*this, + obj_index, + fe_index, + obj_level); + } + + + template <> + template <> + unsigned int + DoFHandler<1>::n_active_fe_indices<1> (const unsigned int obj_level, + const unsigned int obj_index) const + { + return this->levels[obj_level]->lines.n_active_fe_indices (*this, + obj_index); + } +#endif + + +#if deal_II_dimension == 2 + template <> + template <> + unsigned int + DoFHandler<2>::get_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const + { + return this->faces->lines. + get_dof_index (*this, + obj_index, + fe_index, + local_index, + obj_level); + } + + + template <> + template <> + void + DoFHandler<2>::set_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const + { + this->faces->lines. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index, + obj_level); + + } + + + template <> + template <> + bool + DoFHandler<2>::fe_index_is_active<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const + { + return this->faces->lines.fe_index_is_active(*this, + obj_index, + fe_index, + obj_level); + } + + + template <> + template <> + unsigned int + DoFHandler<2>::n_active_fe_indices<1> (const unsigned int , + const unsigned int obj_index) const + { + return this->faces->lines.n_active_fe_indices (*this, + obj_index); + } + + + template <> + template <> + unsigned int + DoFHandler<2>::get_dof_index<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const + { + return this->levels[obj_level]->quads. + get_dof_index (*this, + obj_index, + fe_index, + local_index, + obj_level); + } + + + template <> + template <> + void + DoFHandler<2>::set_dof_index<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const + { + this->levels[obj_level]->quads. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index, + obj_level); + + } + + + template <> + template <> + bool + DoFHandler<2>::fe_index_is_active<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const + { + return this->levels[obj_level]->quads.fe_index_is_active(*this, + obj_index, + fe_index, + obj_level); + } + + + template <> + template <> + unsigned int + DoFHandler<2>::n_active_fe_indices<2> (const unsigned int obj_level, + const unsigned int obj_index) const + { + return this->levels[obj_level]->quads.n_active_fe_indices (*this, + obj_index); + } +#endif + +#if deal_II_dimension == 3 + template <> + template <> + unsigned int + DoFHandler<3>::get_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const + { + return this->faces->lines. + get_dof_index (*this, + obj_index, + fe_index, + local_index, + obj_level); + } + + + template <> + template <> + void + DoFHandler<3>::set_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const + { + this->faces->lines. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index, + obj_level); + + } + + + template <> + template <> + bool + DoFHandler<3>::fe_index_is_active<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const + { + return this->faces->lines.fe_index_is_active(*this, + obj_index, + fe_index, + obj_level); + } + + + template <> + template <> + unsigned int + DoFHandler<3>::n_active_fe_indices<1> (const unsigned int, + const unsigned int obj_index) const + { + return this->faces->lines.n_active_fe_indices (*this, + obj_index); + } + + + + template <> + template <> + unsigned int + DoFHandler<3>::get_dof_index<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const + { + return this->faces->quads. + get_dof_index (*this, + obj_index, + fe_index, + local_index, + obj_level); + } + + + template <> + template <> + unsigned int + DoFHandler<3>::get_dof_index<3> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const + { + return this->levels[obj_level]->hexes. + get_dof_index (*this, + obj_index, + fe_index, + local_index, + obj_level); + } + + + template <> + template <> + void + DoFHandler<3>::set_dof_index<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const + { + this->faces->quads. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index, + obj_level); + + } + + + template <> + template <> + void + DoFHandler<3>::set_dof_index<3> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const + { + this->levels[obj_level]->hexes. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index, + obj_level); + + } + + + template <> + template <> + bool + DoFHandler<3>::fe_index_is_active<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const + { + return this->faces->quads.fe_index_is_active(*this, + obj_index, + fe_index, + obj_level); + } + + template <> + template <> + bool + DoFHandler<3>::fe_index_is_active<3> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index) const + { + return this->levels[obj_level]->hexes.fe_index_is_active(*this, + obj_index, + fe_index, + obj_level); + } + + + template <> + template <> + unsigned int + DoFHandler<3>::n_active_fe_indices<2> (const unsigned int , + const unsigned int obj_index) const + { + return this->faces->quads.n_active_fe_indices (*this, + obj_index); + } + + template <> + template <> + unsigned int + DoFHandler<3>::n_active_fe_indices<3> (const unsigned int obj_level, + const unsigned int obj_index) const + { + return this->levels[obj_level]->hexes.n_active_fe_indices (*this, + obj_index); + } +#endif + @@ -1507,10 +1951,12 @@ namespace hp MemoryConsumption::memory_consumption (finite_elements) + MemoryConsumption::memory_consumption (tria) + MemoryConsumption::memory_consumption (levels) + + MemoryConsumption::memory_consumption (faces) + MemoryConsumption::memory_consumption (used_dofs) + MemoryConsumption::memory_consumption (vertex_dofs)); for (unsigned int i=0; i::iterator i=levels[level]->line_dofs.begin(); - i!=levels[level]->line_dofs.end(); ++i) + for (std::vector::iterator i=levels[level]->lines.dofs.begin(); + i!=levels[level]->lines.dofs.end(); ++i) if (*i != invalid_dof_index) *i = new_numbers[*i]; } @@ -1832,15 +2278,16 @@ namespace hp for (unsigned int level=0; level::iterator i=levels[level]->line_dofs.begin(); - i!=levels[level]->line_dofs.end(); ++i) - if (*i != invalid_dof_index) - *i = new_numbers[*i]; - for (std::vector::iterator i=levels[level]->quad_dofs.begin(); - i!=levels[level]->quad_dofs.end(); ++i) + for (std::vector::iterator i=levels[level]->quads.dofs.begin(); + i!=levels[level]->quads.dofs.end(); ++i) if (*i != invalid_dof_index) *i = new_numbers[*i]; - }; + } + for (std::vector::iterator i=faces->lines.dofs.begin(); + i!=faces->lines.dofs.end(); ++i) + if (*i != invalid_dof_index) + *i = new_numbers[*i]; + } #endif @@ -1880,19 +2327,20 @@ namespace hp for (unsigned int level=0; level::iterator i=levels[level]->line_dofs.begin(); - i!=levels[level]->line_dofs.end(); ++i) - if (*i != invalid_dof_index) - *i = new_numbers[*i]; - for (std::vector::iterator i=levels[level]->quad_dofs.begin(); - i!=levels[level]->quad_dofs.end(); ++i) + for (std::vector::iterator i=levels[level]->hexes.dofs.begin(); + i!=levels[level]->hexes.dofs.end(); ++i) if (*i != invalid_dof_index) *i = new_numbers[*i]; - for (std::vector::iterator i=levels[level]->hex_dofs.begin(); - i!=levels[level]->hex_dofs.end(); ++i) - if (*i != invalid_dof_index) - *i = new_numbers[*i]; - }; + } + for (std::vector::iterator i=faces->lines.dofs.begin(); + i!=faces->lines.dofs.end(); ++i) + if (*i != invalid_dof_index) + *i = new_numbers[*i]; + for (std::vector::iterator i=faces->quads.dofs.begin(); + i!=faces->quads.dofs.end(); ++i) + if (*i != invalid_dof_index) + *i = new_numbers[*i]; + } #endif @@ -2117,7 +2565,7 @@ namespace hp // finite element is used for it for (unsigned int level=0; leveln_levels(); ++level) { - levels[level]->line_dof_offsets + levels[level]->lines.dof_offsets = std::vector (tria->n_raw_lines(level), invalid_dof_index); @@ -2126,11 +2574,11 @@ namespace hp cell!=end_active(level); ++cell) if (!cell->has_children()) { - levels[level]->line_dof_offsets[cell->index()] = next_free_dof; + levels[level]->lines.dof_offsets[cell->index()] = next_free_dof; next_free_dof += cell->get_fe().dofs_per_line; } - levels[level]->line_dofs + levels[level]->lines.dofs = std::vector (next_free_dof, invalid_dof_index); } @@ -2150,10 +2598,10 @@ namespace hp if (!cell->has_children()) counter += cell->get_fe().dofs_per_line; - Assert (levels[level]->line_dofs.size() == counter, ExcInternalError()); + Assert (levels[level]->lines.dofs.size() == counter, ExcInternalError()); Assert (static_cast - (std::count (levels[level]->line_dof_offsets.begin(), - levels[level]->line_dof_offsets.end(), + (std::count (levels[level]->lines.dof_offsets.begin(), + levels[level]->lines.dof_offsets.end(), invalid_dof_index)) == tria->n_raw_lines(level) - tria->n_active_lines(level), @@ -2201,6 +2649,7 @@ namespace hp std::swap (active_fe_backup[level], levels[level]->active_fe_indices); } + faces = new internal::hp::DoFFaces<2>; } @@ -2222,7 +2671,7 @@ namespace hp // finite element is used for it for (unsigned int level=0; leveln_levels(); ++level) { - levels[level]->quad_dof_offsets + levels[level]->quads.dof_offsets = std::vector (tria->n_raw_quads(level), invalid_dof_index); @@ -2231,11 +2680,11 @@ namespace hp cell!=end_active(level); ++cell) if (!cell->has_children()) { - levels[level]->quad_dof_offsets[cell->index()] = next_free_dof; + levels[level]->quads.dof_offsets[cell->index()] = next_free_dof; next_free_dof += cell->get_fe().dofs_per_quad; } - levels[level]->quad_dofs + levels[level]->quads.dofs = std::vector (next_free_dof, invalid_dof_index); } @@ -2255,10 +2704,10 @@ namespace hp if (!cell->has_children()) counter += cell->get_fe().dofs_per_quad; - Assert (levels[level]->quad_dofs.size() == counter, ExcInternalError()); + Assert (levels[level]->quads.dofs.size() == counter, ExcInternalError()); Assert (static_cast - (std::count (levels[level]->quad_dof_offsets.begin(), - levels[level]->quad_dof_offsets.end(), + (std::count (levels[level]->quads.dof_offsets.begin(), + levels[level]->quads.dof_offsets.end(), invalid_dof_index)) == tria->n_raw_quads(level) - tria->n_active_quads(level), @@ -2303,7 +2752,7 @@ namespace hp // slots (see the hp::DoFLevel // class) we will have to store // on each level - std::vector n_line_slots (tria->n_levels(), 0); + unsigned int n_line_slots = 0; for (active_cell_iterator cell=begin_active(); cell!=end(); ++cell) for (unsigned int face=0; face::faces_per_cell; ++face) @@ -2341,7 +2790,7 @@ namespace hp // dofs_per_line // dofs, and one stop // index - n_line_slots[cell->level()] + n_line_slots += (*finite_elements)[cell->active_fe_index()].dofs_per_line + 2; // otherwise we do @@ -2351,7 +2800,7 @@ namespace hp // dofs, and one stop // index: else - n_line_slots[cell->level()] + n_line_slots += ((*finite_elements)[cell->active_fe_index()].dofs_per_line + (*finite_elements)[cell->neighbor(face)->active_fe_index()] @@ -2372,16 +2821,13 @@ namespace hp // lines, though only the // active ones will have a // non-invalid value later on - for (unsigned int level=0; leveln_levels(); ++level) - { - levels[level]->line_dof_offsets - = std::vector (tria->n_raw_lines(level), - invalid_dof_index); - levels[level]->line_dofs - = std::vector (n_line_slots[level], - invalid_dof_index); - } - + faces->lines.dof_offsets + = std::vector (tria->n_raw_lines(), + invalid_dof_index); + faces->lines.dofs + = std::vector (n_line_slots, + invalid_dof_index); + // with the memory now // allocated, loop over the // cells again and prime the @@ -2389,7 +2835,7 @@ namespace hp // the fe_index fields const_cast&>(*tria).clear_user_flags_line (); - std::vector next_free_line_slot (tria->n_levels(), 0); + unsigned int next_free_line_slot = 0; for (active_cell_iterator cell=begin_active(); cell!=end(); ++cell) for (unsigned int face=0; face::faces_per_cell; ++face) @@ -2409,16 +2855,16 @@ namespace hp && (cell->active_fe_index() == cell->neighbor(face)->active_fe_index()))) { - levels[cell->level()] - ->line_dof_offsets[cell->face(face)->index()] - = next_free_line_slot[cell->level()]; + faces + ->lines.dof_offsets[cell->face(face)->index()] + = next_free_line_slot; // set first slot // for this line to // active_fe_index // of this face - levels[cell->level()] - ->line_dofs[next_free_line_slot[cell->level()]] + faces + ->lines.dofs[next_free_line_slot] = cell->active_fe_index(); // the next @@ -2440,21 +2886,21 @@ namespace hp // finally, mark // those slots as // used - next_free_line_slot[cell->level()] + next_free_line_slot += (*finite_elements)[cell->active_fe_index()].dofs_per_line + 2; } else { - levels[cell->level()] - ->line_dof_offsets[cell->face(face)->index()] - = next_free_line_slot[cell->level()]; + faces + ->lines.dof_offsets[cell->face(face)->index()] + = next_free_line_slot; // set first slot // for this line to // active_fe_index // of this face - levels[cell->level()] - ->line_dofs[next_free_line_slot[cell->level()]] + faces + ->lines.dofs[next_free_line_slot] = cell->active_fe_index(); // the next @@ -2468,57 +2914,56 @@ namespace hp // fe_index for the // neighboring // cell: - levels[cell->level()] - ->line_dofs[next_free_line_slot[cell->level()] - + - (*finite_elements)[cell->active_fe_index()].dofs_per_line - + - 1] - = cell->neighbor(face)->active_fe_index(); - // then again a set - // of dofs that we - // need not set - // right now - // - // following this - // comes the stop - // index, which - // also is - // invalid_dof_index - // and therefore - // does not have to - // be explicitly - // set + faces + ->lines.dofs[next_free_line_slot + + + (*finite_elements)[cell->active_fe_index()].dofs_per_line + + + 1] + = cell->neighbor(face)->active_fe_index(); + // then again a set + // of dofs that we + // need not set + // right now + // + // following this + // comes the stop + // index, which + // also is + // invalid_dof_index + // and therefore + // does not have to + // be explicitly + // set - // finally, mark - // those slots as - // used - next_free_line_slot[cell->level()] - += ((*finite_elements)[cell->active_fe_index()].dofs_per_line - + - (*finite_elements)[cell->neighbor(face)->active_fe_index()] - .dofs_per_line - + - 3); - } + // finally, mark + // those slots as + // used + next_free_line_slot + += ((*finite_elements)[cell->active_fe_index()].dofs_per_line + + + (*finite_elements)[cell->neighbor(face)->active_fe_index()] + .dofs_per_line + + + 3); + } - // mark this face as - // visited - cell->face(face)->set_user_flag (); - } - - // we should have moved the - // cursor for each level to the - // total number of dofs on that - // level. check that - for (unsigned int level=0; leveln_levels(); ++level) - Assert (next_free_line_slot[level] == n_line_slots[level], - ExcInternalError()); + // mark this face as + // visited + cell->face(face)->set_user_flag (); + } - // at the end, restore the user - // flags for the lines + // we should have moved the + // cursor for each level to the + // total number of dofs on that + // level. check that + Assert (next_free_line_slot == n_line_slots, + ExcInternalError()); + + // at the end, restore the user + // flags for the lines const_cast&>(*tria) - .load_user_flags_line (saved_line_user_flags); + .load_user_flags_line (saved_line_user_flags); } @@ -2561,6 +3006,7 @@ namespace hp std::swap (active_fe_backup[level], levels[level]->active_fe_indices); } + faces = new internal::hp::DoFFaces<3>; } @@ -2582,7 +3028,7 @@ namespace hp // finite element is used for it for (unsigned int level=0; leveln_levels(); ++level) { - levels[level]->hex_dof_offsets + levels[level]->hexes.dof_offsets = std::vector (tria->n_raw_hexs(level), invalid_dof_index); @@ -2591,11 +3037,11 @@ namespace hp cell!=end_active(level); ++cell) if (!cell->has_children()) { - levels[level]->hex_dof_offsets[cell->index()] = next_free_dof; + levels[level]->hexes.dof_offsets[cell->index()] = next_free_dof; next_free_dof += cell->get_fe().dofs_per_hex; } - levels[level]->hex_dofs + levels[level]->hexes.dofs = std::vector (next_free_dof, invalid_dof_index); } @@ -2615,10 +3061,10 @@ namespace hp if (!cell->has_children()) counter += cell->get_fe().dofs_per_hex; - Assert (levels[level]->hex_dofs.size() == counter, ExcInternalError()); + Assert (levels[level]->hexes.dofs.size() == counter, ExcInternalError()); Assert (static_cast - (std::count (levels[level]->hex_dof_offsets.begin(), - levels[level]->hex_dof_offsets.end(), + (std::count (levels[level]->hexes.dof_offsets.begin(), + levels[level]->hexes.dof_offsets.end(), invalid_dof_index)) == tria->n_raw_hexs(level) - tria->n_active_hexs(level), @@ -2659,16 +3105,15 @@ namespace hp .save_user_flags_quad (saved_quad_user_flags); const_cast&>(*tria).clear_user_flags_quad (); - // an array to hold how many - // slots (see the hp::DoFLevel - // class) we will have to store - // on each level - std::vector n_quad_slots (tria->n_levels(), 0); + // examine, how how many + // slots (see the hp::DoFLevel + // class) we will have to store + unsigned int n_quad_slots = 0; for (active_cell_iterator cell=begin_active(); cell!=end(); ++cell) - for (unsigned int face=0; face::faces_per_cell; ++face) - if (! cell->face(face)->user_flag_set()) - { + for (unsigned int face=0; face::faces_per_cell; ++face) + if (! cell->face(face)->user_flag_set()) + { // ok, face has not been // visited. so we need to // allocate space for @@ -2701,7 +3146,7 @@ namespace hp // dofs_per_quad // dofs, and one stop // index - n_quad_slots[cell->level()] + n_quad_slots += (*finite_elements)[cell->active_fe_index()].dofs_per_quad + 2; // otherwise we do @@ -2711,7 +3156,7 @@ namespace hp // dofs, and one stop // index: else - n_quad_slots[cell->level()] + n_quad_slots += ((*finite_elements)[cell->active_fe_index()].dofs_per_quad + (*finite_elements)[cell->neighbor(face)->active_fe_index()] @@ -2726,19 +3171,19 @@ namespace hp // now that we know how many // quad dofs we will have to - // have on each level, allocate + // have, allocate // the memory. note that we // allocate offsets for all // quads, though only the // active ones will have a // non-invalid value later on - for (unsigned int level=0; leveln_levels(); ++level) + if (true) { - levels[level]->quad_dof_offsets - = std::vector (tria->n_raw_quads(level), + faces->quads.dof_offsets + = std::vector (tria->n_raw_quads(), invalid_dof_index); - levels[level]->quad_dofs - = std::vector (n_quad_slots[level], + faces->quads.dofs + = std::vector (n_quad_slots, invalid_dof_index); } @@ -2749,7 +3194,7 @@ namespace hp // the fe_index fields const_cast&>(*tria).clear_user_flags_quad (); - std::vector next_free_quad_slot (tria->n_levels(), 0); + unsigned int next_free_quad_slot = 0; for (active_cell_iterator cell=begin_active(); cell!=end(); ++cell) for (unsigned int face=0; face::faces_per_cell; ++face) @@ -2769,16 +3214,16 @@ namespace hp && (cell->active_fe_index() == cell->neighbor(face)->active_fe_index()))) { - levels[cell->level()] - ->quad_dof_offsets[cell->face(face)->index()] - = next_free_quad_slot[cell->level()]; + faces + ->quads.dof_offsets[cell->face(face)->index()] + = next_free_quad_slot; // set first slot // for this quad to // active_fe_index // of this face - levels[cell->level()] - ->quad_dofs[next_free_quad_slot[cell->level()]] + faces + ->quads.dofs[next_free_quad_slot] = cell->active_fe_index(); // the next @@ -2800,21 +3245,21 @@ namespace hp // finally, mark // those slots as // used - next_free_quad_slot[cell->level()] + next_free_quad_slot += (*finite_elements)[cell->active_fe_index()].dofs_per_quad + 2; } else { - levels[cell->level()] - ->quad_dof_offsets[cell->face(face)->index()] - = next_free_quad_slot[cell->level()]; + faces + ->quads.dof_offsets[cell->face(face)->index()] + = next_free_quad_slot; // set first slot // for this quad to // active_fe_index // of this face - levels[cell->level()] - ->quad_dofs[next_free_quad_slot[cell->level()]] + faces + ->quads.dofs[next_free_quad_slot] = cell->active_fe_index(); // the next @@ -2828,8 +3273,8 @@ namespace hp // fe_index for the // neighboring // cell: - levels[cell->level()] - ->quad_dofs[next_free_quad_slot[cell->level()] + faces + ->quads.dofs[next_free_quad_slot + (*finite_elements)[cell->active_fe_index()].dofs_per_quad + @@ -2853,7 +3298,7 @@ namespace hp // finally, mark // those slots as // used - next_free_quad_slot[cell->level()] + next_free_quad_slot += ((*finite_elements)[cell->active_fe_index()].dofs_per_quad + (*finite_elements)[cell->neighbor(face)->active_fe_index()] @@ -2868,12 +3313,10 @@ namespace hp } // we should have moved the - // cursor for each level to the - // total number of dofs on that - // level. check that - for (unsigned int level=0; leveln_levels(); ++level) - Assert (next_free_quad_slot[level] == n_quad_slots[level], - ExcInternalError()); + // cursor to the total number + // of dofs. check that + Assert (next_free_quad_slot == n_quad_slots, + ExcInternalError()); // at the end, restore the user // flags for the quads @@ -2888,18 +3331,12 @@ namespace hp // much like with vertices: there // can be an arbitrary number of // finite elements associated - // with each line. the situation - // is more complicated, however, - // since lines have no global - // ordering, but are rather - // organized into levels. + // with each line. // // the algorithm we use is // somewhat similar to what we do - // in reserve_space_vertices(), - // except that we have to to - // separate work for all levels - for (unsigned int level=0; leveln_levels(); ++level) + // in reserve_space_vertices() + if (true) { // what we do first is to set up // an array in which we record @@ -2911,11 +3348,11 @@ namespace hp // required dofs std::vector > line_fe_association (finite_elements->size(), - std::vector (tria->n_raw_lines(level), + std::vector (tria->n_raw_lines(), false)); - for (active_cell_iterator cell=begin_active(level); - cell!=end_active(level); ++cell) + for (active_cell_iterator cell=begin_active(); + cell!=end(); ++cell) for (unsigned int l=0; l::lines_per_cell; ++l) line_fe_association[cell->active_fe_index()][cell->line_index(l)] = true; @@ -2929,8 +3366,8 @@ namespace hp // case we do not have to // allocate any memory at // all - std::vector line_is_used (tria->n_raw_lines(level), false); - for (unsigned int line=0; linen_raw_lines(level); ++line) + std::vector line_is_used (tria->n_raw_lines(), false); + for (unsigned int line=0; linen_raw_lines(); ++line) for (unsigned int fe=0; fesize(); ++fe) if (line_fe_association[fe][line] == true) { @@ -2949,15 +3386,15 @@ namespace hp // fe_indices. at the same // time already fill the // line_dofs_offsets field - levels[level]->line_dof_offsets - .resize (tria->n_raw_lines(level), + faces->lines.dof_offsets + .resize (tria->n_raw_lines(), deal_II_numbers::invalid_unsigned_int); unsigned int line_slots_needed = 0; - for (unsigned int line=0; linen_raw_lines(level); ++line) + for (unsigned int line=0; linen_raw_lines(); ++line) if (line_is_used[line] == true) { - levels[level]->line_dof_offsets[line] = line_slots_needed; + faces->lines.dof_offsets[line] = line_slots_needed; for (unsigned int fe=0; fesize(); ++fe) if (line_fe_association[fe][line] == true) @@ -2969,11 +3406,11 @@ namespace hp // have determined we need, and // set up the linked lists for // each of the lines - levels[level]->line_dofs.resize (line_slots_needed, invalid_dof_index); - for (unsigned int line=0; linen_raw_lines(level); ++line) + faces->lines.dofs.resize (line_slots_needed, invalid_dof_index); + for (unsigned int line=0; linen_raw_lines(); ++line) if (line_is_used[line] == true) { - unsigned int pointer = levels[level]->line_dof_offsets[line]; + unsigned int pointer = faces->lines.dof_offsets[line]; for (unsigned int fe=0; fesize(); ++fe) if (line_fe_association[fe][line] == true) { @@ -2983,14 +3420,15 @@ namespace hp // fe_index and // move the // pointer ahead - levels[level]->line_dofs[pointer] = fe; + faces->lines.dofs[pointer] = fe; pointer += (*finite_elements)[fe].dofs_per_line + 1; } // finally place the end // marker - levels[level]->line_dofs[pointer] = deal_II_numbers::invalid_unsigned_int; + faces->lines.dofs[pointer] = deal_II_numbers::invalid_unsigned_int; } } + // VERTEX DOFS @@ -3321,6 +3759,8 @@ namespace hp for (unsigned int i=0; i tmp; diff --git a/deal.II/deal.II/source/dofs/hp_dof_levels.all_dimensions.cc b/deal.II/deal.II/source/dofs/hp_dof_levels.all_dimensions.cc index a2205358e1..8f5480aa74 100644 --- a/deal.II/deal.II/source/dofs/hp_dof_levels.all_dimensions.cc +++ b/deal.II/deal.II/source/dofs/hp_dof_levels.all_dimensions.cc @@ -20,31 +20,45 @@ namespace internal { namespace hp { + unsigned int + DoFLevel<0>::memory_consumption () const + { + return MemoryConsumption::memory_consumption (active_fe_indices); + } + +#if deal_II_dimension == 1 + unsigned int DoFLevel<1>::memory_consumption () const { - return (MemoryConsumption::memory_consumption (line_dofs) + - MemoryConsumption::memory_consumption (line_dof_offsets)); + return (DoFLevel<0>::memory_consumption() + + MemoryConsumption::memory_consumption (lines)); } + +#endif +#if deal_II_dimension == 2 unsigned int DoFLevel<2>::memory_consumption () const { - return (DoFLevel<1>::memory_consumption () + - MemoryConsumption::memory_consumption (quad_dofs) + - MemoryConsumption::memory_consumption (quad_dof_offsets)); + return (DoFLevel<0>::memory_consumption () + + MemoryConsumption::memory_consumption (quads)); } +#endif + +#if deal_II_dimension == 3 unsigned int DoFLevel<3>::memory_consumption () const { - return (DoFLevel<2>::memory_consumption () + - MemoryConsumption::memory_consumption (hex_dofs) + - MemoryConsumption::memory_consumption (hex_dof_offsets)); + return (DoFLevel<0>::memory_consumption () + + MemoryConsumption::memory_consumption (hexes)); } + +#endif } } diff --git a/deal.II/deal.II/source/dofs/hp_dof_levels.cc b/deal.II/deal.II/source/dofs/hp_dof_levels.cc index 949e3ef9df..a733dc64b2 100644 --- a/deal.II/deal.II/source/dofs/hp_dof_levels.cc +++ b/deal.II/deal.II/source/dofs/hp_dof_levels.cc @@ -13,1008 +13,12 @@ #include -#include -#include #include -//TODO[WB]: make a few of these functions inline - - namespace internal { namespace hp { - template - unsigned int - DoFLevel<1>:: - get_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<1> /*dummy*/) const - { - Assert (fe_index != ::hp::DoFHandler::default_fe_index, - ExcMessage ("You need to specify a FE index when working " - "with hp DoFHandlers")); - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (fe_index < dof_handler.get_fe().size(), - ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); - Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_line, - ExcIndexRange(local_index, 0, - dof_handler.get_fe()[fe_index].dofs_per_line)); - Assert (line_index < line_dof_offsets.size(), - ExcIndexRange (line_index, 0, line_dof_offsets.size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (line_dof_offsets[line_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 1d, then the - // only set of indices we store - // is the one for the cell, - // which is unique. then - // fe_index must be - // active_fe_index - if (dim == 1) - { - Assert (fe_index == this->active_fe_indices[line_index], - ExcMessage ("FE index does not match that of the present cell")); - return line_dofs[line_dof_offsets[line_index]+local_index]; - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = line_dof_offsets[line_index]; - const unsigned int *pointer = &line_dofs[starting_offset]; - while (true) - { - Assert (*pointer != deal_II_numbers::invalid_unsigned_int, - ExcInternalError()); - if (*pointer == fe_index) - return *(pointer + 1 + local_index); - else - pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; - } - } - } - - - - template - void - DoFLevel<1>:: - set_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<1> /*dummy*/) - { - Assert (fe_index != ::hp::DoFHandler::default_fe_index, - ExcMessage ("You need to specify a FE index when working " - "with hp DoFHandlers")); - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (fe_index < dof_handler.get_fe().size(), - ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); - Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_line, - ExcIndexRange(local_index, 0, - dof_handler.get_fe()[fe_index].dofs_per_line)); - Assert (line_index < line_dof_offsets.size(), - ExcIndexRange (line_index, 0, line_dof_offsets.size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (line_dof_offsets[line_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 1d, then the - // only set of indices we store - // is the one for the cell, - // which is unique. then - // fe_index must be - // active_fe_index - if (dim == 1) - { - Assert (fe_index == this->active_fe_indices[line_index], - ExcMessage ("FE index does not match that of the present cell")); - line_dofs[line_dof_offsets[line_index]+local_index] = global_index; - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = line_dof_offsets[line_index]; - unsigned int *pointer = &line_dofs[starting_offset]; - while (true) - { - Assert (*pointer != deal_II_numbers::invalid_unsigned_int, - ExcInternalError()); - if (*pointer == fe_index) - { - *(pointer + 1 + local_index) = global_index; - return; - } - else - pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; - } - } - } - - - - template - unsigned int - DoFLevel<1>:: - n_active_fe_indices (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - internal::StructuralDimension<1> /*dummy*/) const - { - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (line_index < line_dof_offsets.size(), - ExcIndexRange (line_index, 0, line_dof_offsets.size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (line_dof_offsets[line_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 1d, then the - // only set of indices we store - // is the one for the cell, - // which is unique - if (dim == 1) - { - return 1; - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = line_dof_offsets[line_index]; - const unsigned int *pointer = &line_dofs[starting_offset]; - unsigned int counter = 0; - while (true) - { - if (*pointer == deal_II_numbers::invalid_unsigned_int) - // end of list reached - return counter; - else - { - ++counter; - pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; - } - } - } - } - - - - template - bool - DoFLevel<1>:: - fe_index_is_active (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - internal::StructuralDimension<1> /*dummy*/) const - { - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (line_index < line_dof_offsets.size(), - ExcIndexRange (line_index, 0, line_dof_offsets.size())); - Assert (fe_index != ::hp::DoFHandler::default_fe_index, - ExcMessage ("You need to specify a FE index when working " - "with hp DoFHandlers")); - Assert (fe_index < dof_handler.get_fe().size(), - ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (line_dof_offsets[line_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 1d, then the - // only set of indices we store - // is the one for the cell, - // which is unique - if (dim == 1) - { - Assert (line_index < active_fe_indices.size(), - ExcInternalError()); - return (fe_index == active_fe_indices[line_index]); - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = line_dof_offsets[line_index]; - const unsigned int *pointer = &line_dofs[starting_offset]; - while (true) - { - if (*pointer == deal_II_numbers::invalid_unsigned_int) - // end of list reached - return false; - else - if (*pointer == fe_index) - return true; - else - pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; - } - } - } - - - - template - unsigned int - DoFLevel<2>:: - get_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<2> /*dummy*/) const - { - Assert (dim >= 2, ExcMessage ("You can only access quads in 2d or higher")); - Assert (fe_index != ::hp::DoFHandler::default_fe_index, - ExcMessage ("You need to specify a FE index when working " - "with hp DoFHandlers")); - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (fe_index < dof_handler.get_fe().size(), - ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); - Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_quad, - ExcIndexRange(local_index, 0, - dof_handler.get_fe()[fe_index].dofs_per_quad)); - Assert (quad_index < quad_dof_offsets.size(), - ExcIndexRange (quad_index, 0, quad_dof_offsets.size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (quad_dof_offsets[quad_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 1d, then the - // only set of indices we store - // is the one for the cell, - // which is unique. then - // fe_index must be - // active_fe_index - if (dim == 2) - { - Assert (fe_index == this->active_fe_indices[quad_index], - ExcMessage ("FE index does not match that of the present cell")); - return quad_dofs[quad_dof_offsets[quad_index]+local_index]; - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = quad_dof_offsets[quad_index]; - const unsigned int *pointer = &quad_dofs[starting_offset]; - while (true) - { - Assert (*pointer != deal_II_numbers::invalid_unsigned_int, - ExcInternalError()); - if (*pointer == fe_index) - return *(pointer + 1 + local_index); - else - pointer += dof_handler.get_fe()[*pointer].dofs_per_quad + 1; - } - } - } - - - - template - void - DoFLevel<2>:: - set_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<2> /*dummy*/) - { - Assert (dim >= 2, ExcMessage ("You can only access quads in 2d or higher")); - Assert (fe_index != ::hp::DoFHandler::default_fe_index, - ExcMessage ("You need to specify a FE index when working " - "with hp DoFHandlers")); - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (fe_index < dof_handler.get_fe().size(), - ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); - Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_quad, - ExcIndexRange(local_index, 0, - dof_handler.get_fe()[fe_index].dofs_per_quad)); - Assert (quad_index < quad_dof_offsets.size(), - ExcIndexRange (quad_index, 0, quad_dof_offsets.size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (quad_dof_offsets[quad_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 1d, then the - // only set of indices we store - // is the one for the cell, - // which is unique. then - // fe_index must be - // active_fe_index - if (dim == 2) - { - Assert (fe_index == this->active_fe_indices[quad_index], - ExcMessage ("FE index does not match that of the present cell")); - quad_dofs[quad_dof_offsets[quad_index]+local_index] = global_index; - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = quad_dof_offsets[quad_index]; - unsigned int *pointer = &quad_dofs[starting_offset]; - while (true) - { - Assert (*pointer != deal_II_numbers::invalid_unsigned_int, - ExcInternalError()); - if (*pointer == fe_index) - { - *(pointer + 1 + local_index) = global_index; - return; - } - else - pointer += dof_handler.get_fe()[*pointer].dofs_per_quad + 1; - } - } - } - - - - template - unsigned int - DoFLevel<2>:: - n_active_fe_indices (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - internal::StructuralDimension<2> /*dummy*/) const - { - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (quad_index < quad_dof_offsets.size(), - ExcIndexRange (quad_index, 0, quad_dof_offsets.size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (quad_dof_offsets[quad_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 2d, then the - // only set of indices we store - // is the one for the cell, - // which is unique - if (dim == 2) - { - return 1; - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = quad_dof_offsets[quad_index]; - const unsigned int *pointer = &quad_dofs[starting_offset]; - unsigned int counter = 0; - while (true) - { - if (*pointer == deal_II_numbers::invalid_unsigned_int) - // end of list reached - return counter; - else - { - ++counter; - pointer += dof_handler.get_fe()[*pointer].dofs_per_quad + 1; - } - } - } - } - - - - template - bool - DoFLevel<2>:: - fe_index_is_active (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - internal::StructuralDimension<2> /*dummy*/) const - { - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (quad_index < quad_dof_offsets.size(), - ExcIndexRange (quad_index, 0, quad_dof_offsets.size())); - Assert (fe_index != ::hp::DoFHandler::default_fe_index, - ExcMessage ("You need to specify a FE index when working " - "with hp DoFHandlers")); - Assert (fe_index < dof_handler.get_fe().size(), - ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (quad_dof_offsets[quad_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 2d, then the - // only set of indices we store - // is the one for the cell, - // which is unique - if (dim == 2) - { - Assert (quad_index < active_fe_indices.size(), - ExcInternalError()); - return (fe_index == active_fe_indices[quad_index]); - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = quad_dof_offsets[quad_index]; - const unsigned int *pointer = &quad_dofs[starting_offset]; - while (true) - { - if (*pointer == deal_II_numbers::invalid_unsigned_int) - // end of list reached - return false; - else - if (*pointer == fe_index) - return true; - else - pointer += dof_handler.get_fe()[*pointer].dofs_per_quad + 1; - } - } - } - - - - template - unsigned int - DoFLevel<3>:: - get_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<3> /*dummy*/) const - { - Assert (dim >= 3, ExcMessage ("You can only access hexs in 3d or higher")); - Assert (fe_index != ::hp::DoFHandler::default_fe_index, - ExcMessage ("You need to specify a FE index when working " - "with hp DoFHandlers")); - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (fe_index < dof_handler.get_fe().size(), - ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); - Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_hex, - ExcIndexRange(local_index, 0, - dof_handler.get_fe()[fe_index].dofs_per_hex)); - Assert (hex_index < hex_dof_offsets.size(), - ExcIndexRange (hex_index, 0, hex_dof_offsets.size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (hex_dof_offsets[hex_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 1d, then the - // only set of indices we store - // is the one for the cell, - // which is unique. then - // fe_index must be - // active_fe_index - if (dim == 3) - { - Assert (fe_index == this->active_fe_indices[hex_index], - ExcMessage ("FE index does not match that of the present cell")); - return hex_dofs[hex_dof_offsets[hex_index]+local_index]; - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = hex_dof_offsets[hex_index]; - const unsigned int *pointer = &hex_dofs[starting_offset]; - while (true) - { - Assert (*pointer != deal_II_numbers::invalid_unsigned_int, - ExcInternalError()); - if (*pointer == fe_index) - return *(pointer + 1 + local_index); - else - pointer += dof_handler.get_fe()[*pointer].dofs_per_hex + 1; - } - } - } - - - - template - void - DoFLevel<3>:: - set_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<3> /*dummy*/) - { - Assert (dim >= 3, ExcMessage ("You can only access hexs in 3d or higher")); - Assert (fe_index != ::hp::DoFHandler::default_fe_index, - ExcMessage ("You need to specify a FE index when working " - "with hp DoFHandlers")); - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (fe_index < dof_handler.get_fe().size(), - ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); - Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_hex, - ExcIndexRange(local_index, 0, - dof_handler.get_fe()[fe_index].dofs_per_hex)); - Assert (hex_index < hex_dof_offsets.size(), - ExcIndexRange (hex_index, 0, hex_dof_offsets.size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (hex_dof_offsets[hex_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 1d, then the - // only set of indices we store - // is the one for the cell, - // which is unique. then - // fe_index must be - // active_fe_index - if (dim == 3) - { - Assert (fe_index == this->active_fe_indices[hex_index], - ExcMessage ("FE index does not match that of the present cell")); - hex_dofs[hex_dof_offsets[hex_index]+local_index] = global_index; - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = hex_dof_offsets[hex_index]; - unsigned int *pointer = &hex_dofs[starting_offset]; - while (true) - { - Assert (*pointer != deal_II_numbers::invalid_unsigned_int, - ExcInternalError()); - if (*pointer == fe_index) - { - *(pointer + 1 + local_index) = global_index; - return; - } - else - pointer += dof_handler.get_fe()[*pointer].dofs_per_hex + 1; - } - } - } - - - - template - unsigned int - DoFLevel<3>:: - n_active_fe_indices (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - internal::StructuralDimension<3> /*dummy*/) const - { - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (hex_index < hex_dof_offsets.size(), - ExcIndexRange (hex_index, 0, hex_dof_offsets.size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (hex_dof_offsets[hex_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 3d, then the - // only set of indices we store - // is the one for the cell, - // which is unique - if (dim == 3) - { - return 1; - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = hex_dof_offsets[hex_index]; - const unsigned int *pointer = &hex_dofs[starting_offset]; - unsigned int counter = 0; - while (true) - { - if (*pointer == deal_II_numbers::invalid_unsigned_int) - // end of list reached - return counter; - else - { - ++counter; - pointer += dof_handler.get_fe()[*pointer].dofs_per_hex + 1; - } - } - } - } - - - - template - bool - DoFLevel<3>:: - fe_index_is_active (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - internal::StructuralDimension<3> /*dummy*/) const - { - Assert (&dof_handler != 0, - ExcMessage ("No DoFHandler is specified for this iterator")); - Assert (&dof_handler.get_fe() != 0, - ExcMessage ("No finite element collection is associated with " - "this DoFHandler")); - Assert (hex_index < hex_dof_offsets.size(), - ExcIndexRange (hex_index, 0, hex_dof_offsets.size())); - Assert (fe_index != ::hp::DoFHandler::default_fe_index, - ExcMessage ("You need to specify a FE index when working " - "with hp DoFHandlers")); - Assert (fe_index < dof_handler.get_fe().size(), - ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); - - // make sure we are on an - // object for which DoFs have - // been allocated at all - Assert (hex_dof_offsets[hex_index] != deal_II_numbers::invalid_unsigned_int, - ExcMessage ("You are trying to access degree of freedom " - "information for an object on which no such " - "information is available")); - - // if we are in 2d, then the - // only set of indices we store - // is the one for the cell, - // which is unique - if (dim == 3) - { - Assert (hex_index < active_fe_indices.size(), - ExcInternalError()); - return (fe_index == active_fe_indices[hex_index]); - } - else - { - // we are in higher space - // dimensions, so there may - // be multiple finite - // elements associated with - // this object. hop along - // the list of index sets - // until we find the one - // with the correct - // fe_index, and then poke - // into that part. trigger - // an exception if we can't - // find a set for this - // particular fe_index - const unsigned int starting_offset = hex_dof_offsets[hex_index]; - const unsigned int *pointer = &hex_dofs[starting_offset]; - while (true) - { - if (*pointer == deal_II_numbers::invalid_unsigned_int) - // end of list reached - return false; - else - if (*pointer == fe_index) - return true; - else - pointer += dof_handler.get_fe()[*pointer].dofs_per_hex + 1; - } - } - } - - - -// explicit instantiations - template - unsigned int - DoFLevel<1>:: - get_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<1> dummy) const; - - template - void - DoFLevel<1>:: - set_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<1> dummy); - - template - unsigned int - DoFLevel<1>:: - n_active_fe_indices (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - internal::StructuralDimension<1> dummy) const; - - template - bool - DoFLevel<1>:: - fe_index_is_active (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - internal::StructuralDimension<1> dummy) const; - -#if deal_II_dimension >= 2 - - template - unsigned int - DoFLevel<2>:: - get_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<2> dummy) const; - - template - void - DoFLevel<2>:: - set_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<2> dummy); - - template - unsigned int - DoFLevel<2>:: - n_active_fe_indices (const ::hp::DoFHandler &dof_handler, - const unsigned int quad_index, - internal::StructuralDimension<2> dummy) const; - - - template - bool - DoFLevel<2>:: - fe_index_is_active (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - internal::StructuralDimension<2> dummy) const; -#endif - -#if deal_II_dimension >= 3 - - template - unsigned int - DoFLevel<3>:: - get_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - internal::StructuralDimension<3> dummy) const; - - template - void - DoFLevel<3>:: - set_dof_index (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - const unsigned int fe_index, - const unsigned int local_index, - const unsigned int global_index, - internal::StructuralDimension<3> dummy); - - template - unsigned int - DoFLevel<3>:: - n_active_fe_indices (const ::hp::DoFHandler &dof_handler, - const unsigned int hex_index, - internal::StructuralDimension<3> dummy) const; - template - bool - DoFLevel<3>:: - fe_index_is_active (const ::hp::DoFHandler &dof_handler, - const unsigned int line_index, - const unsigned int fe_index, - internal::StructuralDimension<3> dummy) const; -#endif } } diff --git a/deal.II/deal.II/source/dofs/hp_dof_objects.cc b/deal.II/deal.II/source/dofs/hp_dof_objects.cc new file mode 100644 index 0000000000..67eb1e6bb0 --- /dev/null +++ b/deal.II/deal.II/source/dofs/hp_dof_objects.cc @@ -0,0 +1,1293 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include +#include +#include + + +namespace internal +{ + namespace hp + { + template + unsigned int + DoFObjects::memory_consumption () const + { + return (MemoryConsumption::memory_consumption (dofs) + + MemoryConsumption::memory_consumption (dof_offsets)); + } + +#if deal_II_dimension == 1 + template <> + template <> + unsigned int + DoFObjects<1>:: + get_dof_index<1> (const ::hp::DoFHandler<1> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int obj_level) const + { + Assert (fe_index != ::hp::DoFHandler<1>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_line, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_line)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 1d, then the + // only set of indices we store + // is the one for the cell, + // which is unique. then + // fe_index must be + // active_fe_index + + Assert (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index], + ExcMessage ("FE index does not match that of the present cell")); + return dofs[dof_offsets[obj_index]+local_index]; + } + + + template <> + template <> + void + DoFObjects<1>:: + set_dof_index<1> (const ::hp::DoFHandler<1> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index, + const unsigned int obj_level) + { + Assert (fe_index != ::hp::DoFHandler<1>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_line, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_line)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 1d, then the + // only set of indices we store + // is the one for the cell, + // which is unique. then + // fe_index must be + // active_fe_index + Assert (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index], + ExcMessage ("FE index does not match that of the present cell")); + dofs[dof_offsets[obj_index]+local_index] = global_index; + } + + + + + + template <> + template <> + unsigned int + DoFObjects<1>:: + n_active_fe_indices<1> (const ::hp::DoFHandler<1> &dof_handler, + const unsigned int obj_index) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 1d, then the + // only set of indices we store + // is the one for the cell, + // which is unique + return 1; + } + + + + template <> + template <> + bool + DoFObjects<1>:: + fe_index_is_active<1> (const ::hp::DoFHandler<1> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int obj_level) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + Assert (fe_index != ::hp::DoFHandler<1>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 1d, then the + // only set of indices we store + // is the one for the cell, + // which is unique + Assert (obj_index < dof_handler.levels[obj_level]->active_fe_indices.size(), + ExcInternalError()); + return (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index]); + } +#endif +#if deal_II_dimension == 2 + + template <> + template <> + unsigned int + DoFObjects<1>:: + get_dof_index<2> (const ::hp::DoFHandler<2> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int ) const + { + Assert (fe_index != ::hp::DoFHandler<2>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_line, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_line)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + const unsigned int *pointer = &dofs[starting_offset]; + while (true) + { + Assert (*pointer != deal_II_numbers::invalid_unsigned_int, + ExcInternalError()); + if (*pointer == fe_index) + return *(pointer + 1 + local_index); + else + pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; + } + } + + + template <> + template <> + void + DoFObjects<1>:: + set_dof_index<2> (const ::hp::DoFHandler<2> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index, + const unsigned int ) + { + Assert (fe_index != ::hp::DoFHandler<2>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_line, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_line)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + unsigned int *pointer = &dofs[starting_offset]; + while (true) + { + Assert (*pointer != deal_II_numbers::invalid_unsigned_int, + ExcInternalError()); + if (*pointer == fe_index) + { + *(pointer + 1 + local_index) = global_index; + return; + } + else + pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; + } + } + + + + + + template <> + template <> + unsigned int + DoFObjects<1>:: + n_active_fe_indices<2> (const ::hp::DoFHandler<2> &dof_handler, + const unsigned int obj_index) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + const unsigned int *pointer = &dofs[starting_offset]; + unsigned int counter = 0; + while (true) + { + if (*pointer == deal_II_numbers::invalid_unsigned_int) + // end of list reached + return counter; + else + { + ++counter; + pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; + } + } + } + + + + template <> + template <> + bool + DoFObjects<1>:: + fe_index_is_active<2> (const ::hp::DoFHandler<2> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int ) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + Assert (fe_index != ::hp::DoFHandler<2>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + const unsigned int *pointer = &dofs[starting_offset]; + while (true) + { + if (*pointer == deal_II_numbers::invalid_unsigned_int) + // end of list reached + return false; + else + if (*pointer == fe_index) + return true; + else + pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; + } + } +#endif +#if deal_II_dimension == 3 + + template <> + template <> + unsigned int + DoFObjects<1>:: + get_dof_index<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int ) const + { + Assert (fe_index != ::hp::DoFHandler<3>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_line, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_line)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + const unsigned int *pointer = &dofs[starting_offset]; + while (true) + { + Assert (*pointer != deal_II_numbers::invalid_unsigned_int, + ExcInternalError()); + if (*pointer == fe_index) + return *(pointer + 1 + local_index); + else + pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; + } + } + + + + template <> + template <> + void + DoFObjects<1>:: + set_dof_index<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index, + const unsigned int ) + { + Assert (fe_index != ::hp::DoFHandler<3>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_line, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_line)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + unsigned int *pointer = &dofs[starting_offset]; + while (true) + { + Assert (*pointer != deal_II_numbers::invalid_unsigned_int, + ExcInternalError()); + if (*pointer == fe_index) + { + *(pointer + 1 + local_index) = global_index; + return; + } + else + pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; + } + } + + + + template <> + template <> + unsigned int + DoFObjects<1>:: + n_active_fe_indices<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + const unsigned int *pointer = &dofs[starting_offset]; + unsigned int counter = 0; + while (true) + { + if (*pointer == deal_II_numbers::invalid_unsigned_int) + // end of list reached + return counter; + else + { + ++counter; + pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; + } + } + } + + + + template <> + template <> + bool + DoFObjects<1>:: + fe_index_is_active<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int ) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + Assert (fe_index != ::hp::DoFHandler<3>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + const unsigned int *pointer = &dofs[starting_offset]; + while (true) + { + if (*pointer == deal_II_numbers::invalid_unsigned_int) + // end of list reached + return false; + else + if (*pointer == fe_index) + return true; + else + pointer += dof_handler.get_fe()[*pointer].dofs_per_line + 1; + } + } + +#endif +#if deal_II_dimension == 2 + + template <> + template <> + unsigned int + DoFObjects<2>:: + get_dof_index<2> (const ::hp::DoFHandler<2> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int obj_level) const + { + Assert (fe_index != ::hp::DoFHandler<2>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_quad, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_quad)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 2d, then the + // only set of indices we store + // is the one for the cell, + // which is unique. then + // fe_index must be + // active_fe_index + Assert (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index], + ExcMessage ("FE index does not match that of the present cell")); + return dofs[dof_offsets[obj_index]+local_index]; + } + + + + template <> + template <> + void + DoFObjects<2>:: + set_dof_index<2> (const ::hp::DoFHandler<2> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index, + const unsigned int obj_level) + { + Assert (fe_index != ::hp::DoFHandler<2>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_quad, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_quad)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 2d, then the + // only set of indices we store + // is the one for the cell, + // which is unique. then + // fe_index must be + // active_fe_index + Assert (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index], + ExcMessage ("FE index does not match that of the present cell")); + dofs[dof_offsets[obj_index]+local_index] = global_index; + } + + + + template <> + template <> + unsigned int + DoFObjects<2>:: + n_active_fe_indices<2> (const ::hp::DoFHandler<2> &dof_handler, + const unsigned int obj_index) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 2d, then the + // only set of indices we store + // is the one for the cell, + // which is unique + return 1; + } + + + + template <> + template <> + bool + DoFObjects<2>:: + fe_index_is_active<2> (const ::hp::DoFHandler<2> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int obj_level) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + Assert (fe_index != ::hp::DoFHandler<2>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 2d, then the + // only set of indices we store + // is the one for the cell, + // which is unique + Assert (obj_index < dof_handler.levels[obj_level]->active_fe_indices.size(), + ExcInternalError()); + return (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index]); + } +#endif + +#if deal_II_dimension == 3 + template <> + template <> + unsigned int + DoFObjects<2>:: + get_dof_index<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int ) const + { + Assert (fe_index != ::hp::DoFHandler<3>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_quad, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_quad)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + const unsigned int *pointer = &dofs[starting_offset]; + while (true) + { + Assert (*pointer != deal_II_numbers::invalid_unsigned_int, + ExcInternalError()); + if (*pointer == fe_index) + return *(pointer + 1 + local_index); + else + pointer += dof_handler.get_fe()[*pointer].dofs_per_quad + 1; + } + } + + + + template <> + template <> + void + DoFObjects<2>:: + set_dof_index<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index, + const unsigned int ) + { + Assert (fe_index != ::hp::DoFHandler<3>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_quad, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_quad)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + unsigned int *pointer = &dofs[starting_offset]; + while (true) + { + Assert (*pointer != deal_II_numbers::invalid_unsigned_int, + ExcInternalError()); + if (*pointer == fe_index) + { + *(pointer + 1 + local_index) = global_index; + return; + } + else + pointer += dof_handler.get_fe()[*pointer].dofs_per_quad + 1; + } + } + + + + template <> + template <> + unsigned int + DoFObjects<2>:: + n_active_fe_indices<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + const unsigned int *pointer = &dofs[starting_offset]; + unsigned int counter = 0; + while (true) + { + if (*pointer == deal_II_numbers::invalid_unsigned_int) + // end of list reached + return counter; + else + { + ++counter; + pointer += dof_handler.get_fe()[*pointer].dofs_per_quad + 1; + } + } + } + + + + template <> + template <> + bool + DoFObjects<2>:: + fe_index_is_active<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int ) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + Assert (fe_index != ::hp::DoFHandler<3>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // we are in higher space + // dimensions, so there may + // be multiple finite + // elements associated with + // this object. hop along + // the list of index sets + // until we find the one + // with the correct + // fe_index, and then poke + // into that part. trigger + // an exception if we can't + // find a set for this + // particular fe_index + const unsigned int starting_offset = dof_offsets[obj_index]; + const unsigned int *pointer = &dofs[starting_offset]; + while (true) + { + if (*pointer == deal_II_numbers::invalid_unsigned_int) + // end of list reached + return false; + else + if (*pointer == fe_index) + return true; + else + pointer += dof_handler.get_fe()[*pointer].dofs_per_quad + 1; + } + } + + + + template <> + template <> + unsigned int + DoFObjects<3>:: + get_dof_index<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int obj_level) const + { + Assert (fe_index != ::hp::DoFHandler<3>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_hex, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_hex)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 3d, then the + // only set of indices we store + // is the one for the cell, + // which is unique. then + // fe_index must be + // active_fe_index + Assert (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index], + ExcMessage ("FE index does not match that of the present cell")); + return dofs[dof_offsets[obj_index]+local_index]; + } + + + + template <> + template <> + void + DoFObjects<3>:: + set_dof_index<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index, + const unsigned int obj_level) + { + Assert (fe_index != ::hp::DoFHandler<3>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < dof_handler.get_fe()[fe_index].dofs_per_hex, + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index].dofs_per_hex)); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 3d, then the + // only set of indices we store + // is the one for the cell, + // which is unique. then + // fe_index must be + // active_fe_index + Assert (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index], + ExcMessage ("FE index does not match that of the present cell")); + dofs[dof_offsets[obj_index]+local_index] = global_index; + } + + + + template <> + template <> + unsigned int + DoFObjects<3>:: + n_active_fe_indices<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 3d, then the + // only set of indices we store + // is the one for the cell, + // which is unique + return 1; + } + + + + template <> + template <> + bool + DoFObjects<3>:: + fe_index_is_active<3> (const ::hp::DoFHandler<3> &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int obj_level) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + Assert (fe_index != ::hp::DoFHandler<3>::default_fe_index, + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != deal_II_numbers::invalid_unsigned_int, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + // if we are in 3d, then the + // only set of indices we store + // is the one for the cell, + // which is unique + Assert (obj_index < dof_handler.levels[obj_level]->active_fe_indices.size(), + ExcInternalError()); + return (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index]); + } +#endif + + // explicit instantiations + template + unsigned int + DoFObjects<1>:: + memory_consumption () const; + +#if deal_II_dimension >= 2 + + template + unsigned int + DoFObjects<2>:: + memory_consumption () const; + +#endif + + +#if deal_II_dimension >= 3 + + template + unsigned int + DoFObjects<3>:: + memory_consumption () const; + +#endif + } +} diff --git a/deal.II/deal.II/source/grid/tria.all_dimensions.cc b/deal.II/deal.II/source/grid/tria.all_dimensions.cc index d07ec6ad8b..f9186abc37 100644 --- a/deal.II/deal.II/source/grid/tria.all_dimensions.cc +++ b/deal.II/deal.II/source/grid/tria.all_dimensions.cc @@ -28,8 +28,6 @@ #include #include -#include -#include #include @@ -133,298 +131,25 @@ namespace internal MemoryConsumption::memory_consumption (neighbors)); } - - - void - TriaLevel<1>::reserve_space (const unsigned int new_lines) - { - const unsigned int new_size = new_lines + - std::count_if (lines.used.begin(), - lines.used.end(), - std::bind2nd (std::equal_to(), true)); - - // same as in @p{reserve_space<0>}: only - // allocate space if necessary - if (new_size>lines.lines.size()) - { - lines.lines.reserve (new_size); - lines.lines.insert (lines.lines.end(), new_size-lines.lines.size(), Line()); - - lines.used.reserve (new_size); - lines.used.insert (lines.used.end(), new_size-lines.used.size(), false); - - lines.user_flags.reserve (new_size); - lines.user_flags.insert (lines.user_flags.end(), - new_size-lines.user_flags.size(), false); - - lines.children.reserve (new_size); - lines.children.insert (lines.children.end(), new_size-lines.children.size(), - -1); - - lines.material_id.reserve (new_size); - lines.material_id.insert (lines.material_id.end(), - new_size-lines.material_id.size(), - 255); - - lines.user_pointers.reserve (new_size); - lines.user_pointers.insert (lines.user_pointers.end(), - new_size-lines.user_pointers.size(), 0); - }; - } - - - - void - TriaLevel<1>::monitor_memory (const unsigned int true_dimension) const - { - // check that we have not allocated - // too much memory. note that bool - // vectors allocate their memory in - // chunks of whole integers, so - // they may over-allocate by up to - // as many elements as an integer - // has bits - Assert (lines.lines.size() == lines.lines.capacity() || - lines.lines.size()::monitor_memory (true_dimension); - } - - - unsigned int TriaLevel<1>::memory_consumption () const { return (TriaLevel<0>::memory_consumption() + - MemoryConsumption::memory_consumption (lines.lines) + - MemoryConsumption::memory_consumption (lines.children) + - MemoryConsumption::memory_consumption (lines.used) + - MemoryConsumption::memory_consumption (lines.user_flags) + - MemoryConsumption::memory_consumption (lines.material_id) + - MemoryConsumption::memory_consumption (lines.user_pointers)); + MemoryConsumption::memory_consumption (lines)); } - - - - void - TriaLevel<2>::reserve_space (const unsigned int new_quads) - { - const unsigned int new_size = new_quads + - std::count_if (quads.used.begin(), - quads.used.end(), - std::bind2nd (std::equal_to(), true)); - - // see above... - if (new_size>quads.quads.size()) - { - quads.quads.reserve (new_size); - quads.quads.insert (quads.quads.end(), new_size-quads.quads.size(), Quad()); - - quads.used.reserve (new_size); - quads.used.insert (quads.used.end(), new_size-quads.used.size(), false); - - quads.user_flags.reserve (new_size); - quads.user_flags.insert (quads.user_flags.end(), - new_size-quads.user_flags.size(), false); - - quads.children.reserve (new_size); - quads.children.insert (quads.children.end(), new_size-quads.children.size(), - -1); - - quads.material_id.reserve (new_size); - quads.material_id.insert (quads.material_id.end(), - new_size-quads.material_id.size(), - 255); - - quads.user_pointers.reserve (new_size); - quads.user_pointers.insert (quads.user_pointers.end(), - new_size-quads.user_pointers.size(), 0); - }; - } - - - - void - TriaLevel<2>::monitor_memory (const unsigned int true_dimension) const - { - // check that we have not allocated - // too much memory. note that bool - // vectors allocate their memory in - // chunks of whole integers, so - // they may over-allocate by up to - // as many elements as an integer - // has bits - Assert (quads.quads.size() == quads.quads.capacity() || - quads.quads.size()::monitor_memory (true_dimension); - } - - unsigned int TriaLevel<2>::memory_consumption () const { - return (TriaLevel<1>::memory_consumption() + - MemoryConsumption::memory_consumption (quads.quads) + - MemoryConsumption::memory_consumption (quads.children) + - MemoryConsumption::memory_consumption (quads.used) + - MemoryConsumption::memory_consumption (quads.user_flags) + - MemoryConsumption::memory_consumption (quads.material_id) + - MemoryConsumption::memory_consumption (quads.user_pointers)); - } - - - - void - TriaLevel<3>::reserve_space (const unsigned int new_hexes) - { - const unsigned int new_size = new_hexes + - std::count_if (hexes.used.begin(), - hexes.used.end(), - std::bind2nd (std::equal_to(), true)); - - // see above... - if (new_size>hexes.hexes.size()) - { - hexes.hexes.reserve (new_size); - hexes.hexes.insert (hexes.hexes.end(), new_size-hexes.hexes.size(), Hexahedron()); - - hexes.used.reserve (new_size); - hexes.used.insert (hexes.used.end(), new_size-hexes.used.size(), false); - - hexes.user_flags.reserve (new_size); - hexes.user_flags.insert (hexes.user_flags.end(), - new_size-hexes.user_flags.size(), false); - - hexes.children.reserve (new_size); - hexes.children.insert (hexes.children.end(), new_size-hexes.children.size(), - -1); - - hexes.material_id.reserve (new_size); - hexes.material_id.insert (hexes.material_id.end(), - new_size-hexes.material_id.size(), - 255); - - hexes.user_pointers.reserve (new_size); - hexes.user_pointers.insert (hexes.user_pointers.end(), - new_size-hexes.user_pointers.size(), 0); - - hexes.face_orientations.reserve (new_size * GeometryInfo<3>::faces_per_cell); - hexes.face_orientations.insert (hexes.face_orientations.end(), - new_size * GeometryInfo<3>::faces_per_cell - - hexes.face_orientations.size(), - true); - }; - } - - - - void - TriaLevel<3>::monitor_memory (const unsigned int true_dimension) const - { - // check that we have not allocated - // too much memory. note that bool - // vectors allocate their memory in - // chunks of whole integers, so - // they may over-allocate by up to - // as many elements as an integer - // has bits - Assert (hexes.hexes.size() == hexes.hexes.capacity() || - hexes.hexes.size()::faces_per_cell - == hexes.face_orientations.size(), - ExcMemoryInexact (hexes.hexes.size() * GeometryInfo<3>::faces_per_cell, - hexes.face_orientations.size())); - - TriaLevel<2>::monitor_memory (true_dimension); + return (TriaLevel<0>::memory_consumption() + + MemoryConsumption::memory_consumption (quads)); } - - unsigned int TriaLevel<3>::memory_consumption () const { - return (TriaLevel<2>::memory_consumption() + - MemoryConsumption::memory_consumption (hexes.hexes) + - MemoryConsumption::memory_consumption (hexes.children) + - MemoryConsumption::memory_consumption (hexes.used) + - MemoryConsumption::memory_consumption (hexes.user_flags) + - MemoryConsumption::memory_consumption (hexes.material_id) + - MemoryConsumption::memory_consumption (hexes.user_pointers) + - MemoryConsumption::memory_consumption (hexes.face_orientations)); + return (TriaLevel<0>::memory_consumption() + + MemoryConsumption::memory_consumption (hexes)); } diff --git a/deal.II/deal.II/source/grid/tria.cc b/deal.II/deal.II/source/grid/tria.cc index 567a6f71e9..b21926db7b 100644 --- a/deal.II/deal.II/source/grid/tria.cc +++ b/deal.II/deal.II/source/grid/tria.cc @@ -11,10 +11,10 @@ // //--------------------------------------------------------------------------- - #include #include #include +#include #include #include #include @@ -51,6 +51,7 @@ Triangulation::dimension; template Triangulation::Triangulation (const MeshSmoothing smooth_grid) : Subscriptor (), + faces(NULL), smooth_grid(smooth_grid) { // set default boundary for all @@ -78,6 +79,7 @@ Triangulation::~Triangulation () for (unsigned int i=0; i::end () const return end_line (); } +template <> +Triangulation<1>::raw_line_iterator +Triangulation<1>::begin_raw_line (const unsigned int level) const; + +template <> +Triangulation<1>::raw_line_iterator +Triangulation<1>::last_raw_line (const unsigned int level) const; + +template <> +unsigned int +Triangulation<1>::n_raw_lines (const unsigned int level) const; #endif @@ -194,6 +207,17 @@ Triangulation<2>::end () const return end_quad (); } +template <> +Triangulation<2>::raw_quad_iterator +Triangulation<2>::begin_raw_quad (const unsigned int level) const; + +template <> +Triangulation<2>::raw_quad_iterator +Triangulation<2>::last_raw_quad (const unsigned int level) const; + +template <> +unsigned int +Triangulation<2>::n_raw_quads (const unsigned int level) const; #endif @@ -225,14 +249,19 @@ void Triangulation::copy_triangulation (const Triangulation &old_tria) { Assert (vertices.size() == 0, ExcTriangulationNotEmpty()); Assert (levels.size () == 0, ExcTriangulationNotEmpty()); + Assert (faces == NULL, ExcTriangulationNotEmpty()); Assert (old_tria.levels.size() != 0, ExcInternalError()); Assert (old_tria.vertices.size() != 0, ExcInternalError()); + Assert (dim == 1 || old_tria.faces != NULL, ExcInternalError()); + // copy normal elements vertices = old_tria.vertices; vertices_used = old_tria.vertices_used; smooth_grid = old_tria.smooth_grid; + + faces = new internal::Triangulation::TriaFaces(*old_tria.faces); for (unsigned i=0;i<255;++i) boundary[i] = old_tria.boundary[i]; @@ -277,6 +306,8 @@ void Triangulation<1>::create_triangulation (const std::vector > &v, Assert (vertices.size() == 0, ExcTriangulationNotEmpty()); Assert (levels.size() == 0, ExcTriangulationNotEmpty()); + Assert (faces == NULL, ExcTriangulationNotEmpty()); + // check that no forbidden arrays // are used Assert (subcelldata.check_consistency(dim), ExcInternalError()); @@ -294,8 +325,7 @@ void Triangulation<1>::create_triangulation (const std::vector > &v, levels.push_back (new internal::Triangulation::TriaLevel); levels[0]->internal::Triangulation::TriaLevel<0> ::reserve_space (cells.size(), dim); - levels[0]->internal::Triangulation::TriaLevel<1> - ::reserve_space (cells.size()); + levels[0]->lines.reserve_space (cells.size()); // make up cells raw_line_iterator next_free_line = begin_raw_line (); @@ -445,6 +475,7 @@ void Triangulation<2>::create_triangulation (const std::vector > &v, Assert (vertices.size() == 0, ExcTriangulationNotEmpty()); Assert (levels.size() == 0, ExcTriangulationNotEmpty()); + Assert (faces == NULL, ExcTriangulationNotEmpty()); // check that no forbidden arrays // are used Assert (subcelldata.check_consistency(dim), ExcInternalError()); @@ -577,12 +608,11 @@ void Triangulation<2>::create_triangulation (const std::vector > &v, // reserve enough space levels.push_back (new internal::Triangulation::TriaLevel); + faces = new internal::Triangulation::TriaFaces; levels[0]->internal::Triangulation::TriaLevel<0> ::reserve_space (cells.size(), dim); - levels[0]->internal::Triangulation::TriaLevel<1> - ::reserve_space (needed_lines.size()); - levels[0]->internal::Triangulation::TriaLevel<2> - ::reserve_space (cells.size()); + faces->lines.reserve_space (needed_lines.size()); + levels[0]->quads.reserve_space (cells.size()); // make up lines if (true) @@ -868,6 +898,7 @@ Triangulation<3>::create_triangulation (const std::vector > &v, Assert (vertices.size() == 0, ExcTriangulationNotEmpty()); Assert (levels.size() == 0, ExcTriangulationNotEmpty()); + Assert (faces == NULL, ExcTriangulationNotEmpty()); // check that no forbidden arrays // are used Assert (subcelldata.check_consistency(dim), ExcInternalError()); @@ -1006,10 +1037,10 @@ Triangulation<3>::create_triangulation (const std::vector > &v, // for the lines // reserve enough space levels.push_back (new internal::Triangulation::TriaLevel); + faces = new internal::Triangulation::TriaFaces; levels[0]->internal::Triangulation::TriaLevel<0> ::reserve_space (cells.size(), dim); - levels[0]->internal::Triangulation::TriaLevel<1> - ::reserve_space (needed_lines.size()); + faces->lines.reserve_space (needed_lines.size()); // make up lines if (true) @@ -1144,8 +1175,7 @@ Triangulation<3>::create_triangulation (const std::vector > &v, // the arrays of the Triangulation // // first reserve enough space - levels[0]->internal::Triangulation::TriaLevel<2> - ::reserve_space (needed_quads.size()); + faces->quads.reserve_space (needed_quads.size()); if (true) { @@ -1167,8 +1197,7 @@ Triangulation<3>::create_triangulation (const std::vector > &v, ///////////////////////////////// // finally create the cells - levels[0]->internal::Triangulation::TriaLevel<3> - ::reserve_space (cells.size()); + levels[0]->hexes.reserve_space (cells.size()); // store for each quad index the // adjacent cells @@ -2739,7 +2768,7 @@ Triangulation<1>::last_active (const unsigned int level) const template <> Triangulation<1>::raw_face_iterator -Triangulation<1>::begin_raw_face (const unsigned int) const +Triangulation<1>::begin_raw_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -2749,7 +2778,7 @@ Triangulation<1>::begin_raw_face (const unsigned int) const template <> Triangulation<1>::face_iterator -Triangulation<1>::begin_face (const unsigned int) const +Triangulation<1>::begin_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -2759,7 +2788,7 @@ Triangulation<1>::begin_face (const unsigned int) const template <> Triangulation<1>::active_face_iterator -Triangulation<1>::begin_active_face (const unsigned int) const +Triangulation<1>::begin_active_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -2787,16 +2816,6 @@ Triangulation<1>::last_raw_face () const -template <> -Triangulation<1>::raw_face_iterator -Triangulation<1>::last_raw_face (const unsigned int) const -{ - Assert (false, ExcImpossibleInDim(1)); - return 0; -} - - - template <> Triangulation<1>::face_iterator Triangulation<1>::last_face () const @@ -2807,16 +2826,6 @@ Triangulation<1>::last_face () const -template <> -Triangulation<1>::face_iterator -Triangulation<1>::last_face (const unsigned int) const -{ - Assert (false, ExcImpossibleInDim(1)); - return 0; -} - - - template <> Triangulation<1>::active_face_iterator Triangulation<1>::last_active_face () const @@ -2827,16 +2836,6 @@ Triangulation<1>::last_active_face () const -template <> -Triangulation<1>::active_face_iterator -Triangulation<1>::last_active_face (const unsigned int) const -{ - Assert (false, ExcImpossibleInDim(1)); - return 0; -} - - - template <> Triangulation<1>::raw_quad_iterator Triangulation<1>::begin_raw_quad (const unsigned int) const @@ -3114,27 +3113,27 @@ Triangulation<2>::last_active (const unsigned int level) const template <> Triangulation<2>::raw_face_iterator -Triangulation<2>::begin_raw_face (const unsigned int level) const +Triangulation<2>::begin_raw_face () const { - return begin_raw_line (level); + return begin_raw_line (); } template <> Triangulation<2>::face_iterator -Triangulation<2>::begin_face (const unsigned int level) const +Triangulation<2>::begin_face () const { - return begin_line (level); + return begin_line (); } template <> Triangulation<2>::active_face_iterator -Triangulation<2>::begin_active_face (const unsigned int level) const +Triangulation<2>::begin_active_face () const { - return begin_active_line (level); + return begin_active_line (); } @@ -3157,15 +3156,6 @@ Triangulation<2>::last_raw_face () const -template <> -Triangulation<2>::raw_face_iterator -Triangulation<2>::last_raw_face (const unsigned int level) const -{ - return last_raw_line (level); -} - - - template <> Triangulation<2>::face_iterator Triangulation<2>::last_face () const @@ -3175,15 +3165,6 @@ Triangulation<2>::last_face () const -template <> -Triangulation<2>::face_iterator -Triangulation<2>::last_face (const unsigned int level) const -{ - return last_line (level); -} - - - template <> Triangulation<2>::active_face_iterator Triangulation<2>::last_active_face () const @@ -3193,15 +3174,6 @@ Triangulation<2>::last_active_face () const -template <> -Triangulation<2>::active_face_iterator -Triangulation<2>::last_active_face (const unsigned int level) const -{ - return last_active_line (level); -} - - - template <> Triangulation<2>::raw_hex_iterator Triangulation<2>::begin_raw_hex (const unsigned int) const @@ -3379,27 +3351,27 @@ Triangulation<3>::last_active (const unsigned int level) const template <> Triangulation<3>::raw_face_iterator -Triangulation<3>::begin_raw_face (const unsigned int level) const +Triangulation<3>::begin_raw_face () const { - return begin_raw_quad (level); + return begin_raw_quad (); } template <> Triangulation<3>::face_iterator -Triangulation<3>::begin_face (const unsigned int level) const +Triangulation<3>::begin_face () const { - return begin_quad (level); + return begin_quad (); } template <> Triangulation<3>::active_face_iterator -Triangulation<3>::begin_active_face (const unsigned int level) const +Triangulation<3>::begin_active_face () const { - return begin_active_quad (level); + return begin_active_quad (); } @@ -3422,15 +3394,6 @@ Triangulation<3>::last_raw_face () const -template <> -Triangulation<3>::raw_face_iterator -Triangulation<3>::last_raw_face (const unsigned int level) const -{ - return last_raw_quad (level); -} - - - template <> Triangulation<3>::face_iterator Triangulation<3>::last_face () const @@ -3440,15 +3403,6 @@ Triangulation<3>::last_face () const -template <> -Triangulation<3>::face_iterator -Triangulation<3>::last_face (const unsigned int level) const -{ - return last_quad (level); -} - - - template <> Triangulation<3>::active_face_iterator Triangulation<3>::last_active_face () const @@ -3457,28 +3411,31 @@ Triangulation<3>::last_active_face () const } - -template <> -Triangulation<3>::active_face_iterator -Triangulation<3>::last_active_face (const unsigned int level) const -{ - return last_active_quad (level); -} - - #endif template typename Triangulation::raw_line_iterator Triangulation::begin_raw_line (const unsigned int level) const +{ + Assert (level == 0, ExcFacesHaveNoLevel()); + return raw_line_iterator (const_cast*>(this), + 0, + 0); +} + + + +template <> +Triangulation<1>::raw_line_iterator +Triangulation<1>::begin_raw_line (const unsigned int level) const { Assert (levellines.lines.size() == 0) + + if (levels[level]->lines.cells.size() == 0) return end_line (); - - return raw_line_iterator (const_cast*>(this), + + return raw_line_iterator (const_cast*>(this), level, 0); } @@ -3488,13 +3445,27 @@ Triangulation::begin_raw_line (const unsigned int level) const template typename Triangulation::raw_quad_iterator Triangulation::begin_raw_quad (const unsigned int level) const +{ + Assert (dim>=2,ExcImpossibleInDim(dim)); + Assert (dim<3 || level == 0, ExcFacesHaveNoLevel()) + + return raw_quad_iterator (const_cast*>(this), + 0, + 0); +} + + + +template <> +Triangulation<2>::raw_quad_iterator +Triangulation<2>::begin_raw_quad (const unsigned int level) const { Assert (levelquads.quads.size() == 0) + if (levels[level]->quads.cells.size() == 0) return end_quad(); - return raw_quad_iterator (const_cast*>(this), + return raw_quad_iterator (const_cast*>(this), level, 0); } @@ -3507,7 +3478,7 @@ Triangulation::begin_raw_hex (const unsigned int level) const { Assert (levelhexes.hexes.size() == 0) + if (levels[level]->hexes.cells.size() == 0) return end_hex(); return raw_hex_iterator (const_cast*>(this), @@ -3649,29 +3620,52 @@ Triangulation::end_hex () const template typename Triangulation::raw_line_iterator Triangulation::last_raw_line (const unsigned int level) const +{ + Assert (level == 0, ExcFacesHaveNoLevel()); + + return raw_line_iterator (const_cast*>(this), + 0, + faces->lines.cells.size()-1); + +} + + +template <> +Triangulation<1>::raw_line_iterator +Triangulation<1>::last_raw_line (const unsigned int level) const { Assert (levellines.lines.size() != 0, + Assert (levels[level]->lines.cells.size() != 0, ExcEmptyLevel (level)); - - return raw_line_iterator (const_cast*>(this), + + return raw_line_iterator (const_cast*>(this), level, - levels[level]->lines.lines.size()-1); + levels[level]->lines.cells.size()-1); } template typename Triangulation::raw_quad_iterator Triangulation::last_raw_quad (const unsigned int level) const +{ + Assert (level == 0, ExcFacesHaveNoLevel()); + return raw_quad_iterator (const_cast*>(this), + 0, + faces->quads.cells.size()-1); +} + + +template <> +Triangulation<2>::raw_quad_iterator +Triangulation<2>::last_raw_quad (const unsigned int level) const { Assert (levelquads.quads.size() != 0, + Assert (levels[level]->quads.cells.size() != 0, ExcEmptyLevel (level)); - - return raw_quad_iterator (const_cast*>(this), + return raw_quad_iterator (const_cast*>(this), level, - levels[level]->quads.quads.size()-1); + levels[level]->quads.cells.size()-1); } @@ -3681,12 +3675,12 @@ Triangulation::last_raw_hex (const unsigned int level) const { Assert (levelhexes.hexes.size() != 0, + Assert (levels[level]->hexes.cells.size() != 0, ExcEmptyLevel (level)); return raw_hex_iterator (const_cast*>(this), level, - levels[level]->hexes.hexes.size()-1); + levels[level]->hexes.cells.size()-1); } @@ -3694,7 +3688,10 @@ template typename Triangulation::raw_line_iterator Triangulation::last_raw_line () const { - return last_raw_line (levels.size()-1); + if (dim == 1) + return last_raw_line (levels.size()-1); + else + return last_raw_line (0); } @@ -3702,7 +3699,10 @@ template typename Triangulation::raw_quad_iterator Triangulation::last_raw_quad () const { - return last_raw_quad (levels.size()-1); + if (dim == 2) + return last_raw_quad (levels.size()-1); + else + return last_raw_quad (0); } @@ -3718,7 +3718,7 @@ template typename Triangulation::line_iterator Triangulation::last_line (const unsigned int level) const { - // level is checked in begin_raw + // level is checked in last_raw raw_line_iterator ri = last_raw_line(level); if (ri->used()==true) return ri; @@ -3733,7 +3733,7 @@ template typename Triangulation::quad_iterator Triangulation::last_quad (const unsigned int level) const { - // level is checked in begin_raw + // level is checked in last_raw raw_quad_iterator ri = last_raw_quad(level); if (ri->used()==true) return ri; @@ -3748,7 +3748,7 @@ template typename Triangulation::hex_iterator Triangulation::last_hex (const unsigned int level) const { - // level is checked in begin_raw + // level is checked in last_raw raw_hex_iterator ri = last_raw_hex(level); if (ri->used()==true) return ri; @@ -3763,7 +3763,10 @@ template typename Triangulation::line_iterator Triangulation::last_line () const { - return last_line (levels.size()-1); + if (dim == 1) + return last_line (levels.size()-1); + else + return last_line (0); } @@ -3771,7 +3774,10 @@ template typename Triangulation::quad_iterator Triangulation::last_quad () const { - return last_quad (levels.size()-1); + if (dim == 2) + return last_quad (levels.size()-1); + else + return last_quad (0); } @@ -3787,7 +3793,7 @@ template typename Triangulation::active_line_iterator Triangulation::last_active_line (const unsigned int level) const { - // level is checked in begin_raw + // level is checked in last_raw line_iterator i = last_line(level); if (i->has_children()==false) return i; @@ -3802,7 +3808,7 @@ template typename Triangulation::active_quad_iterator Triangulation::last_active_quad (const unsigned int level) const { - // level is checked in begin_raw + // level is checked in last_raw quad_iterator i = last_quad(level); if (i->has_children()==false) return i; @@ -3817,7 +3823,7 @@ template typename Triangulation::active_hex_iterator Triangulation::last_active_hex (const unsigned int level) const { - // level is checked in begin_raw + // level is checked in last_raw hex_iterator i = last_hex(level); if (i->has_children()==false) return i; @@ -3832,7 +3838,10 @@ template typename Triangulation::active_line_iterator Triangulation::last_active_line () const { - return last_active_line (levels.size()-1); + if (dim == 1) + return last_active_line (levels.size()-1); + else + return last_active_line (0); } @@ -3840,7 +3849,10 @@ template typename Triangulation::active_quad_iterator Triangulation::last_active_quad () const { - return last_active_quad (levels.size()-1); + if (dim == 2) + return last_active_quad (levels.size()-1); + else + return last_active_quad (0); } @@ -3884,31 +3896,17 @@ Triangulation::end_active (const unsigned int level) const template typename Triangulation::raw_face_iterator -Triangulation::end_raw_face (const unsigned int level) const -{ - return (level == levels.size()-1 ? - end_face() : - begin_raw_face (level+1)); -} - - -template -typename Triangulation::face_iterator -Triangulation::end_face (const unsigned int level) const +Triangulation::end_raw_face () const { - return (level == levels.size()-1 ? - face_iterator(end_face()) : - begin_face (level+1)); + return end_face(); } template typename Triangulation::active_face_iterator -Triangulation::end_active_face (const unsigned int level) const +Triangulation::end_active_face () const { - return (level == levels.size()-1 ? - active_face_iterator(end_face()) : - begin_active_face (level+1)); + return active_face_iterator(end_face()); } @@ -3916,9 +3914,13 @@ template typename Triangulation::raw_line_iterator Triangulation::end_raw_line (const unsigned int level) const { - return (level == levels.size()-1 ? - end_line() : - begin_raw_line (level+1)); + Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel()); + if (dim == 1) + return (level == levels.size()-1 ? + end_line() : + begin_raw_line (level+1)); + else + return end_line(); } @@ -3926,9 +3928,13 @@ template typename Triangulation::line_iterator Triangulation::end_line (const unsigned int level) const { - return (level == levels.size()-1 ? - line_iterator(end_line()) : - begin_line (level+1)); + Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel()); + if (dim == 1) + return (level == levels.size()-1 ? + line_iterator(end_line()) : + begin_line (level+1)); + else + return line_iterator(end_line()); } @@ -3936,9 +3942,13 @@ template typename Triangulation::active_line_iterator Triangulation::end_active_line (const unsigned int level) const { - return (level == levels.size()-1 ? - active_line_iterator(end_line()) : - begin_active_line (level+1)); + Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel()); + if (dim == 1) + return (level == levels.size()-1 ? + active_line_iterator(end_line()) : + begin_active_line (level+1)); + else + return active_line_iterator(end_line()); } @@ -3946,9 +3956,13 @@ template typename Triangulation::raw_quad_iterator Triangulation::end_raw_quad (const unsigned int level) const { - return (level == levels.size()-1 ? - end_quad() : - begin_raw_quad (level+1)); + Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel()); + if (dim == 2) + return (level == levels.size()-1 ? + end_quad() : + begin_raw_quad (level+1)); + else + return end_quad(); } @@ -3956,9 +3970,14 @@ template typename Triangulation::quad_iterator Triangulation::end_quad (const unsigned int level) const { - return (level == levels.size()-1 ? - quad_iterator(end_quad()) : - begin_quad (level+1)); + Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel()); + if (dim == 2) + return (level == levels.size()-1 ? + quad_iterator(end_quad()) : + begin_quad (level+1)); + else + return quad_iterator(end_quad()); + } @@ -3966,9 +3985,13 @@ template typename Triangulation::active_quad_iterator Triangulation::end_active_quad (const unsigned int level) const { - return (level == levels.size()-1 ? - active_quad_iterator(end_quad()) : - begin_active_quad (level+1)); + Assert(dim == 2 || level == 0, ExcFacesHaveNoLevel()); + if (dim == 2) + return (level == levels.size()-1 ? + active_quad_iterator(end_quad()) : + begin_active_quad (level+1)); + else + return active_quad_iterator(end_quad()); } @@ -4024,43 +4047,20 @@ unsigned int Triangulation::n_active_cells () const template unsigned int Triangulation::n_faces () const -{ - unsigned int n=0; - for (unsigned int l=0; l -unsigned int Triangulation::n_active_faces () const -{ - unsigned int n=0; - for (unsigned int l=0; l -unsigned int -Triangulation::n_faces(unsigned int l) const { Assert (dim<=3, ExcNotImplemented()); - if (dim==2) return n_lines(l); - if (dim==3) return n_quads(l); + if (dim==2) return n_lines(); + if (dim==3) return n_quads(); return 0; } - template -unsigned int -Triangulation::n_active_faces(unsigned int l) const +unsigned int Triangulation::n_active_faces () const { Assert (dim<=3, ExcNotImplemented()); - if (dim==2) return n_active_lines(l); - if (dim==3) return n_active_quads(l); + if (dim==2) return n_active_lines(); + if (dim==3) return n_active_quads(); return 0; } @@ -4150,11 +4150,38 @@ unsigned int Triangulation::n_lines () const } -template -unsigned int Triangulation::n_raw_lines (const unsigned int level) const +#if deal_II_dimension == 1 + +template <> +unsigned int Triangulation<1>::n_raw_lines (const unsigned int level) const { Assert(level < n_levels(), ExcIndexRange(level,0,n_levels())); - return levels[level]->lines.lines.size(); + return levels[level]->lines.cells.size(); +} + + +template <> +unsigned int Triangulation<1>::n_raw_lines () const +{ + Assert(false, ExcNotImplemented()); + return 0; +} + +#endif + + +template +unsigned int Triangulation::n_raw_lines (const unsigned int) const +{ + Assert(false, ExcFacesHaveNoLevel()); + return 0; +} + + +template +unsigned int Triangulation::n_raw_lines () const +{ + return faces->lines.cells.size(); } @@ -4163,7 +4190,7 @@ unsigned int Triangulation::n_lines (const unsigned int level) const { Assert (level < number_cache.n_lines_level.size(), ExcIndexRange (level, 0, number_cache.n_lines_level.size())); - + Assert (dim == 1, ExcFacesHaveNoLevel()); return number_cache.n_lines_level[level]; } @@ -4180,6 +4207,7 @@ unsigned int Triangulation::n_active_lines (const unsigned int level) const { Assert (level < number_cache.n_lines_level.size(), ExcIndexRange (level, 0, number_cache.n_lines_level.size())); + Assert (dim == 1, ExcFacesHaveNoLevel()); return number_cache.n_active_lines_level[level]; } @@ -4244,19 +4272,48 @@ unsigned int Triangulation::n_quads (const unsigned int level) const { Assert (level < number_cache.n_quads_level.size(), ExcIndexRange (level, 0, number_cache.n_quads_level.size())); + Assert (dim == 2, ExcFacesHaveNoLevel()); return number_cache.n_quads_level[level]; } template -unsigned int Triangulation::n_raw_quads (const unsigned int level) const +unsigned int Triangulation::n_raw_quads (const unsigned int) const +{ + Assert (dim <3, ExcFacesHaveNoLevel()); + Assert (dim >2, ExcImpossibleInDim(dim)); + if (dim>2) + return n_raw_quads(); + else + return 0; +} + +#if deal_II_dimension == 2 +template <> +unsigned int Triangulation<2>::n_raw_quads (const unsigned int level) const { Assert(level < n_levels(), ExcIndexRange(level,0,n_levels())); - return levels[level]->quads.quads.size(); + return levels[level]->quads.cells.size(); +} +#endif + +template <> +unsigned int Triangulation<3>::n_raw_quads () const +{ + return faces->quads.cells.size(); } +template +unsigned int Triangulation::n_raw_quads () const +{ + Assert (false, ExcNotImplemented()); + return 0; +} + + + template unsigned int Triangulation::n_active_quads () const { @@ -4269,6 +4326,7 @@ unsigned int Triangulation::n_active_quads (const unsigned int level) const { Assert (level < number_cache.n_quads_level.size(), ExcIndexRange (level, 0, number_cache.n_quads_level.size())); + Assert (dim == 2, ExcFacesHaveNoLevel()); return number_cache.n_active_quads_level[level]; } @@ -4340,7 +4398,7 @@ template unsigned int Triangulation::n_raw_hexs (const unsigned int level) const { Assert(level < n_levels(), ExcIndexRange(level,0,n_levels())); - return levels[level]->hexes.hexes.size(); + return levels[level]->hexes.cells.size(); } @@ -4506,6 +4564,9 @@ Triangulation::clear_despite_subscriptions() delete levels[i]; levels.clear (); + delete faces; + faces = NULL; + vertices.clear (); vertices_used.clear (); @@ -4585,9 +4646,8 @@ Triangulation<1>::execute_refinement () // reserve space for // 2*flagged_cells new lines on // the next higher level - levels[level+1]-> - internal::Triangulation::TriaLevel<1> - ::reserve_space (GeometryInfo<1>::children_per_cell*flagged_cells); + levels[level+1]->lines. + reserve_space (GeometryInfo<1>::children_per_cell*flagged_cells); needed_vertices += flagged_cells; } @@ -4758,7 +4818,7 @@ Triangulation<1>::execute_refinement () #ifdef DEBUG for (unsigned int level=0; levelmonitor_memory (1); + levels[level]->lines.monitor_memory (1); // check whether really all // refinement flags are reset (also @@ -4822,6 +4882,7 @@ Triangulation<2>::execute_refinement () // - there are, but prepare_refinement // added another empty level unsigned int needed_vertices = 0; + unsigned int needed_lines = 0; for (int level=levels.size()-2; level>=0; --level) { // count number of flagged @@ -4830,7 +4891,6 @@ Triangulation<2>::execute_refinement () // vertices and new lines will // be needed unsigned int flagged_cells = 0; - unsigned int needed_lines = 0; active_cell_iterator cell = begin_active(level), endc = begin_active(level+1); for (; cell!=endc; ++cell) @@ -4867,15 +4927,6 @@ Triangulation<2>::execute_refinement () } } - // now count the lines which - // were flagged for refinement - for (line_iterator line=begin_line(level); line!=end_line(level); ++line) - if (line->user_flag_set()) - { - Assert (line->has_children() == false, ExcInternalError()); - needed_lines += 2; - needed_vertices += 1; - } // count number of used cells @@ -4895,20 +4946,30 @@ Triangulation<2>::execute_refinement () levels[level+1]-> internal::Triangulation::TriaLevel<0> ::reserve_space (used_cells+4*flagged_cells, 2); - // reserve space for - // needed_lines new lines - levels[level+1]-> - internal::Triangulation::TriaLevel<1> - ::reserve_space (needed_lines); + // reserve space for // 4*flagged_cells // new quads on the next higher // level - levels[level+1]-> - internal::Triangulation::TriaLevel<2> - ::reserve_space (4*flagged_cells); + levels[level+1]->quads. + reserve_space (4*flagged_cells); } + // now count the lines which + // were flagged for refinement + for (line_iterator line=begin_line(); line!=end_line(); ++line) + if (line->user_flag_set()) + { + Assert (line->has_children() == false, ExcInternalError()); + needed_lines += 2; + needed_vertices += 1; + } + + // reserve space for + // needed_lines new lines + faces->lines. + reserve_space (needed_lines); + // add to needed vertices how many // vertices are already in use needed_vertices += std::count_if (vertices_used.begin(), vertices_used.end(), @@ -4934,17 +4995,15 @@ Triangulation<2>::execute_refinement () unsigned int next_unused_vertex = 0; // first for lines - for (unsigned int level=0; level!=levels.size()-1; ++level) + // + // only active objects can be + // refined further + if (true) { - // only active objects can be - // refined further; remember - // that we won't operate on the - // finest level, so - // begin_*(level+1) is allowed - active_line_iterator line = begin_active_line(level), - endl = begin_active_line(level+1); - raw_line_iterator next_unused_line = begin_raw_line (level+1); - + active_line_iterator line = begin_active_line(), + endl = end_line(); + raw_line_iterator next_unused_line = begin_raw_line (); + for (; line!=endl; ++line) if (line->user_flag_set()) { @@ -5028,7 +5087,7 @@ Triangulation<2>::execute_refinement () active_cell_iterator cell = begin_active(level), endc = begin_active(level+1); - raw_line_iterator next_unused_line = begin_raw_line (level+1); + raw_line_iterator next_unused_line = begin_raw_line (); raw_cell_iterator next_unused_cell = begin_raw (level+1); for (; cell!=endc; ++cell) @@ -5445,7 +5504,7 @@ Triangulation<2>::execute_refinement () #ifdef DEBUG for (unsigned int level=0; levelmonitor_memory (2); + levels[level]->quads.monitor_memory (2); // check whether really all // refinement flags are reset (also @@ -5519,7 +5578,10 @@ Triangulation<3>::execute_refinement () // added another empty level which // then is the highest level unsigned int needed_vertices = 0; - for (int level=levels.size()-2; level>=0; --level) + unsigned int needed_lines = 0; + unsigned int needed_quads = 0; + int level; + for (level=levels.size()-2; level>=0; --level) { // count number of flagged // cells on this level and @@ -5527,8 +5589,7 @@ Triangulation<3>::execute_refinement () // vertices and new lines will // be needed unsigned int flagged_cells = 0; - unsigned int needed_lines = 0; - unsigned int needed_quads = 0; + active_cell_iterator acell = begin_active(level), aendc = begin_active(level+1); @@ -5574,27 +5635,6 @@ Triangulation<3>::execute_refinement () } } - // now count the quads and - // lines which were flagged for - // refinement - for (quad_iterator quad=begin_quad(level); quad!=end_quad(level); ++quad) - if (quad->user_flag_set()) - { - Assert (quad->has_children() == false, ExcInternalError()); - needed_quads += 4; - needed_lines += 4; - needed_vertices += 1; - } - - for (line_iterator line=begin_line(level); line!=end_line(level); ++line) - if (line->user_flag_set()) - { - Assert (line->has_children() == false, ExcInternalError()); - needed_lines += 2; - needed_vertices += 1; - } - - // count number of used cells on // the next higher level const unsigned int used_cells @@ -5612,25 +5652,43 @@ Triangulation<3>::execute_refinement () levels[level+1]-> internal::Triangulation::TriaLevel<0> ::reserve_space (used_cells+8*flagged_cells, 3); - // reserve space for - // needed_lines new lines - levels[level+1]-> - internal::Triangulation::TriaLevel<1> - ::reserve_space (needed_lines); - // reserve space for - // needed_quads new quads - levels[level+1]-> - internal::Triangulation::TriaLevel<2> - ::reserve_space (needed_quads); // reserve space for // 8*flagged_cells // new hexes on the next higher // level - levels[level+1]-> - internal::Triangulation::TriaLevel<3> - ::reserve_space (8*flagged_cells); + levels[level+1]->hexes. + reserve_space (8*flagged_cells); } + // now count the quads and + // lines which were flagged for + // refinement + for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad) + if (quad->user_flag_set()) + { + Assert (quad->has_children() == false, ExcInternalError()); + needed_quads += 4; + needed_lines += 4; + needed_vertices += 1; + } + + for (line_iterator line=begin_line(); line!=end_line(); ++line) + if (line->user_flag_set()) + { + Assert (line->has_children() == false, ExcInternalError()); + needed_lines += 2; + needed_vertices += 1; + } + + // reserve space for + // needed_lines new lines + faces->lines. + reserve_space (needed_lines); + // reserve space for + // needed_quads new quads + faces->quads. + reserve_space (needed_quads); + // add to needed vertices how many // vertices are already in use needed_vertices += std::count_if (vertices_used.begin(), vertices_used.end(), @@ -5688,16 +5746,14 @@ Triangulation<3>::execute_refinement () unsigned int next_unused_vertex = 0; // first for lines - for (unsigned int level=0; level!=levels.size()-1; ++level) + // only active objects can be + // refined further; + if (true) { - // only active objects can be - // refined further; remember - // that we won't operate on the - // finest level, so - // begin_*(level+1) is allowed - active_line_iterator line = begin_active_line(level), - endl = begin_active_line(level+1); - raw_line_iterator next_unused_line = begin_raw_line (level+1); + active_line_iterator line = begin_active_line(), + endl = end_line(); + raw_line_iterator next_unused_line = begin_raw_line (); + for (; line!=endl; ++line) if (line->user_flag_set()) @@ -5779,18 +5835,16 @@ Triangulation<3>::execute_refinement () /////////////////////////////////////// // now refine marked quads /////////////////////////////////////// - for (unsigned int level=0; level!=levels.size()-1; ++level) + // + // only active objects can be + // refined further; + if (true) { - // only active objects can be - // refined further; remember - // that we won't operate on the - // finest level, so - // begin_*(level+1) is allowed - active_quad_iterator quad = begin_active_quad(level), - endq = begin_active_quad(level+1); - raw_line_iterator next_unused_line = begin_raw_line (level+1); - raw_quad_iterator next_unused_quad = begin_raw_quad (level+1); - + active_quad_iterator quad = begin_active_quad(), + endq = end_quad(); + raw_line_iterator next_unused_line = begin_raw_line (); + raw_quad_iterator next_unused_quad = begin_raw_quad (); + for (; quad!=endq; ++quad) if (quad->user_flag_set()) { @@ -6033,8 +6087,8 @@ Triangulation<3>::execute_refinement () // begin_*(level+1) is allowed active_hex_iterator hex = begin_active_hex(level), endh = begin_active_hex(level+1); - raw_line_iterator next_unused_line = begin_raw_line (level+1); - raw_quad_iterator next_unused_quad = begin_raw_quad (level+1); + raw_line_iterator next_unused_line = begin_raw_line (); + raw_quad_iterator next_unused_quad = begin_raw_quad (); raw_hex_iterator next_unused_hex = begin_raw_hex (level+1); for (; hex!=endh; ++hex) @@ -7037,7 +7091,7 @@ Triangulation<3>::execute_refinement () #ifdef DEBUG for (unsigned int level=0; levelmonitor_memory (3); + levels[level]->hexes.monitor_memory (3); // check whether really all // refinement flags are reset (also @@ -8876,6 +8930,8 @@ Triangulation::memory_consumption () const mem += sizeof(boundary); mem += sizeof(smooth_grid); mem += MemoryConsumption::memory_consumption (number_cache); + mem += MemoryConsumption::memory_consumption (faces); + mem += MemoryConsumption::memory_consumption (*faces); return mem; } @@ -8883,8 +8939,8 @@ Triangulation::memory_consumption () const -template -void Triangulation::update_number_cache_lines () +template <> +void Triangulation<1>::update_number_cache_lines () { /////////////////////////////////// // update the number of lines @@ -8896,7 +8952,7 @@ void Triangulation::update_number_cache_lines () { // count lines on this level number_cache.n_lines_level[level] = 0; - if (levels[level]->lines.lines.size() != 0) + if (levels[level]->lines.cells.size() != 0) { line_iterator line = begin_line (level), endc = (level == levels.size()-1 ? @@ -8918,7 +8974,7 @@ void Triangulation::update_number_cache_lines () { // count lines on this level number_cache.n_active_lines_level[level] = 0; - if (levels[level]->lines.lines.size() != 0) + if (levels[level]->lines.cells.size() != 0) { active_line_iterator line = begin_active_line (level), endc = end_active_line (level); @@ -8932,6 +8988,34 @@ void Triangulation::update_number_cache_lines () } +template +void Triangulation::update_number_cache_lines () +{ + /////////////////////////////////// + // update the number of lines + // as @p dim>1, there are no levels + // here to take care of. + number_cache.n_lines = 0; + if (faces->lines.cells.size() != 0) + { + line_iterator line = begin_line (), + endc = end_line(); + for (; line!=endc; ++line) + ++number_cache.n_lines; + } + // do the update for the number of + // active lines as well + number_cache.n_active_lines = 0; + if (faces->lines.cells.size() != 0) + { + active_line_iterator line = begin_active_line (), + endc = end_line (); + for (; line!=endc; ++line) + ++number_cache.n_active_lines; + } +} + + #if deal_II_dimension == 1 template <> @@ -8942,10 +9026,10 @@ void Triangulation<1>::update_number_cache_quads () #endif -#if deal_II_dimension >= 2 +#if deal_II_dimension == 2 -template -void Triangulation::update_number_cache_quads () +template <> +void Triangulation<2>::update_number_cache_quads () { /////////////////////////////////// // update the number of quads @@ -8957,7 +9041,7 @@ void Triangulation::update_number_cache_quads () { // count quads on this level number_cache.n_quads_level[level] = 0; - if (levels[level]->quads.quads.size() != 0) + if (levels[level]->quads.cells.size() != 0) { quad_iterator quad = begin_quad (level), endc = (level == levels.size()-1 ? @@ -8979,7 +9063,7 @@ void Triangulation::update_number_cache_quads () { // count quads on this level number_cache.n_active_quads_level[level] = 0; - if (levels[level]->quads.quads.size() != 0) + if (levels[level]->quads.cells.size() != 0) { active_quad_iterator quad = begin_active_quad (level), endc = end_active_quad (level); @@ -8995,6 +9079,40 @@ void Triangulation::update_number_cache_quads () #endif +#if deal_II_dimension > 2 + +template +void Triangulation::update_number_cache_quads () +{ + /////////////////////////////////// + // update the number of quads + // as @p dim>2, there are no levels + // here to take care of. + number_cache.n_quads = 0; + if (faces->quads.cells.size() != 0) + { + quad_iterator quad = begin_quad (), + endc = end_quad(); + for (; quad!=endc; ++quad) + ++number_cache.n_quads; + } + + // do the update for the number + // of active quads as well + number_cache.n_active_quads = 0; + + if (faces->quads.cells.size() != 0) + { + active_quad_iterator quad = begin_active_quad (), + endc = end_quad (); + for (; quad!=endc; ++quad) + ++number_cache.n_active_quads; + } +} + +#endif + + #if deal_II_dimension == 1 template <> @@ -9016,7 +9134,7 @@ void Triangulation<2>::update_number_cache_hexes () #endif -#if deal_II_dimension >= 3 +#if deal_II_dimension == 3 template void Triangulation::update_number_cache_hexes () @@ -9031,7 +9149,7 @@ void Triangulation::update_number_cache_hexes () { // count hexes on this level number_cache.n_hexes_level[level] = 0; - if (levels[level]->hexes.hexes.size() != 0) + if (levels[level]->hexes.cells.size() != 0) { hex_iterator hex = begin_hex (level), endc = (level == levels.size()-1 ? @@ -9053,7 +9171,7 @@ void Triangulation::update_number_cache_hexes () { // count hexes on this level number_cache.n_active_hexes_level[level] = 0; - if (levels[level]->hexes.hexes.size() != 0) + if (levels[level]->hexes.cells.size() != 0) { active_hex_iterator hex = begin_active_hex (level), endc = end_active_hex (level); diff --git a/deal.II/deal.II/source/grid/tria_accessor.cc b/deal.II/deal.II/source/grid/tria_accessor.cc index 55bffa0dfa..301f7d738b 100644 --- a/deal.II/deal.II/source/grid/tria_accessor.cc +++ b/deal.II/deal.II/source/grid/tria_accessor.cc @@ -32,9 +32,19 @@ template void TriaObjectAccessor<1, dim>:: set (const internal::Triangulation::Line &line) const +{ + this->tria->faces->lines.cells[this->present_index] = line; +} + + + +template <> +void +TriaObjectAccessor<1, 1>:: +set (const internal::Triangulation::Line &line) const { this->tria->levels[this->present_level] - ->lines.lines[this->present_index] = line; + ->lines.cells[this->present_index] = line; } @@ -43,7 +53,16 @@ template int TriaObjectAccessor<1, dim>::vertex_index (const unsigned int i) const { Assert (i<2, ExcIndexRange(i,0,2)); - return this->tria->levels[this->present_level]->lines.lines[this->present_index].vertex (i); + return this->tria->faces->lines.cells[this->present_index].vertex (i); +} + + + +template <> +int TriaObjectAccessor<1, 1>::vertex_index (const unsigned int i) const +{ + Assert (i<2, ExcIndexRange(i,0,2)); + return this->tria->levels[this->present_level]->lines.cells[this->present_index].vertex (i); } @@ -62,6 +81,16 @@ void TriaObjectAccessor<1, dim>::set_used_flag () const { Assert (this->state() == IteratorState::valid, typename TriaAccessor::ExcDereferenceInvalidObject()); + this->tria->faces->lines.used[this->present_index] = true; +} + + + +template <> +void TriaObjectAccessor<1, 1>::set_used_flag () const +{ const int dim =1; + Assert (this->state() == IteratorState::valid, + TriaAccessor::ExcDereferenceInvalidObject()); this->tria->levels[this->present_level]->lines.used[this->present_index] = true; } @@ -72,6 +101,17 @@ void TriaObjectAccessor<1, dim>::clear_used_flag () const { Assert (this->state() == IteratorState::valid, typename TriaAccessor::ExcDereferenceInvalidObject()); + this->tria->faces->lines.used[this->present_index] = false; +} + + + +template <> +void TriaObjectAccessor<1, 1>::clear_used_flag () const +{ + const int dim=1; + Assert (this->state() == IteratorState::valid, + TriaAccessor::ExcDereferenceInvalidObject()); this->tria->levels[this->present_level]->lines.used[this->present_index] = false; } @@ -105,6 +145,16 @@ template void TriaObjectAccessor<1, dim>::set_user_pointer (void *p) const { Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + this->tria->faces->lines.user_pointers[this->present_index] = p; +} + + + +template <> +void TriaObjectAccessor<1, 1>::set_user_pointer (void *p) const +{ + const int dim=1; + Assert (used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->lines.user_pointers[this->present_index] = p; } @@ -114,6 +164,16 @@ template void TriaObjectAccessor<1, dim>::clear_user_pointer () const { Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + this->tria->faces->lines.user_pointers[this->present_index] = 0; +} + + + +template <> +void TriaObjectAccessor<1, 1>::clear_user_pointer () const +{ + const int dim=1; + Assert (used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->lines.user_pointers[this->present_index] = 0; } @@ -123,6 +183,16 @@ template void * TriaObjectAccessor<1, dim>::user_pointer () const { Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + return this->tria->faces->lines.user_pointers[this->present_index]; +} + + + +template <> +void * TriaObjectAccessor<1, 1>::user_pointer () const +{ + const int dim=1; + Assert (used(), TriaAccessor::ExcCellNotUsed()); return this->tria->levels[this->present_level]->lines.user_pointers[this->present_index]; } @@ -162,6 +232,20 @@ void TriaObjectAccessor<1, dim>::set_children (const int index) const (!has_children() && (index>=0)), typename TriaAccessor::ExcCantSetChildren(index)); + this->tria->faces->lines.children[this->present_index] = index; +} + + + +template <> +void TriaObjectAccessor<1, 1>::set_children (const int index) const +{ + const int dim=1; + Assert (used(), TriaAccessor::ExcCellNotUsed()); + Assert ((index==-1) || + (!has_children() && (index>=0)), + TriaAccessor::ExcCantSetChildren(index)); + this->tria->levels[this->present_level]->lines.children[this->present_index] = index; } @@ -181,7 +265,16 @@ unsigned char TriaObjectAccessor<1, dim>::boundary_indicator () const Assert (dim>=2, ExcImpossibleInDim(dim)); Assert (used(), typename TriaAccessor::ExcCellNotUsed()); - return this->tria->levels[this->present_level]->lines.material_id[this->present_index]; + return this->tria->faces->lines.material_id[this->present_index]; +} + + + +template <> +unsigned char TriaObjectAccessor<1, 1>::boundary_indicator () const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; } @@ -192,11 +285,20 @@ void TriaObjectAccessor<1, dim>::set_boundary_indicator (const unsigned char bou Assert (dim>=2, ExcImpossibleInDim(dim)); Assert (used(), typename TriaAccessor::ExcCellNotUsed()); - this->tria->levels[this->present_level]->lines.material_id[this->present_index] = boundary_ind; + this->tria->faces->lines.material_id[this->present_index] = boundary_ind; } +template <> +void TriaObjectAccessor<1, 1>::set_boundary_indicator (const unsigned char) const +{ + Assert (false, ExcImpossibleInDim(1)); +} + + + + template bool TriaObjectAccessor<1, dim>::at_boundary () const { @@ -261,9 +363,19 @@ template void TriaObjectAccessor<2, dim>:: set (const internal::Triangulation::Quad &quad) const +{ + this->tria->faces->quads.cells[this->present_index] = quad; +} + + + +template <> +void +TriaObjectAccessor<2, 2>:: +set (const internal::Triangulation::Quad &quad) const { this->tria->levels[this->present_level] - ->quads.quads[this->present_index] = quad; + ->quads.cells[this->present_index] = quad; } @@ -293,6 +405,18 @@ TriaObjectAccessor<2, dim>::set_used_flag () const { Assert (this->state() == IteratorState::valid, typename TriaAccessor::ExcDereferenceInvalidObject()); + this->tria->faces->quads.used[this->present_index] = true; +} + + + +template <> +void +TriaObjectAccessor<2, 2>::set_used_flag () const +{ + const int dim=2; + Assert (this->state() == IteratorState::valid, + TriaAccessor::ExcDereferenceInvalidObject()); this->tria->levels[this->present_level]->quads.used[this->present_index] = true; } @@ -303,6 +427,17 @@ void TriaObjectAccessor<2, dim>::clear_used_flag () const { Assert (this->state() == IteratorState::valid, typename TriaAccessor::ExcDereferenceInvalidObject()); + this->tria->faces->quads.used[this->present_index] = false; +} + + + +template <> +void TriaObjectAccessor<2, 2>::clear_used_flag () const +{ + const int dim=2; + Assert (this->state() == IteratorState::valid, + TriaAccessor::ExcDereferenceInvalidObject()); this->tria->levels[this->present_level]->quads.used[this->present_index] = false; } @@ -336,6 +471,16 @@ template void TriaObjectAccessor<2, dim>::set_user_pointer (void *p) const { Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + this->tria->faces->quads.user_pointers[this->present_index] = p; +} + + + +template <> +void TriaObjectAccessor<2, 2>::set_user_pointer (void *p) const +{ + const int dim=2; + Assert (used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->quads.user_pointers[this->present_index] = p; } @@ -345,6 +490,16 @@ template void TriaObjectAccessor<2, dim>::clear_user_pointer () const { Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + this->tria->faces->quads.user_pointers[this->present_index] = 0; +} + + + +template <> +void TriaObjectAccessor<2, 2>::clear_user_pointer () const +{ + const int dim=2; + Assert (used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->quads.user_pointers[this->present_index] = 0; } @@ -354,6 +509,16 @@ template void * TriaObjectAccessor<2, dim>::user_pointer () const { Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + return this->tria->faces->quads.user_pointers[this->present_index]; +} + + + +template <> +void * TriaObjectAccessor<2, 2>::user_pointer () const +{ + const int dim=2; + Assert (used(), TriaAccessor::ExcCellNotUsed()); return this->tria->levels[this->present_level]->quads.user_pointers[this->present_index]; } @@ -394,6 +559,21 @@ void TriaObjectAccessor<2, dim>::set_children (const int index) const (!has_children() && (index>=0)), typename TriaAccessor::ExcCantSetChildren(index)); + this->tria->faces->quads.children[this->present_index] = index; +} + + + +template <> +void TriaObjectAccessor<2, 2>::set_children (const int index) const +{ + const int dim=2; + Assert (used(), + TriaAccessor::ExcCellNotUsed()); + Assert ((index==-1) || + (!has_children() && (index>=0)), + TriaAccessor::ExcCantSetChildren(index)); + this->tria->levels[this->present_level]->quads.children[this->present_index] = index; } @@ -410,21 +590,36 @@ void TriaObjectAccessor<2, dim>::clear_children () const template unsigned char TriaObjectAccessor<2, dim>::boundary_indicator () const { - Assert (dim>=3, ExcImpossibleInDim(dim)); - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + Assert (false, ExcImpossibleInDim(dim)); + return 255; +} - return this->tria->levels[this->present_level]->quads.material_id[this->present_index]; + + +template <> +unsigned char TriaObjectAccessor<2, 3>::boundary_indicator () const +{ + Assert (used(), TriaAccessor<3>::ExcCellNotUsed()); + + return this->tria->faces->quads.material_id[this->present_index]; } template -void TriaObjectAccessor<2, dim>::set_boundary_indicator (const unsigned char boundary_ind) const +void TriaObjectAccessor<2, dim>::set_boundary_indicator (const unsigned char) const { - Assert (dim>=3, ExcImpossibleInDim(dim)); - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + Assert (false, ExcImpossibleInDim(dim)); +} + + - this->tria->levels[this->present_level]->quads.material_id[this->present_index] = boundary_ind; +template <> +void TriaObjectAccessor<2, 3>::set_boundary_indicator (const unsigned char boundary_ind) const +{ + Assert (used(), TriaAccessor<3>::ExcCellNotUsed()); + + this->tria->faces->quads.material_id[this->present_index] = boundary_ind; } @@ -670,13 +865,13 @@ unsigned int TriaObjectAccessor<2, dim>::number_of_children () const /*------------------------ Functions: TriaObjectAccessor ---------------------------*/ -template +template <> void -TriaObjectAccessor<3, dim>:: +TriaObjectAccessor<3, 3>:: set (const internal::Triangulation::Hexahedron &hex) const { this->tria->levels[this->present_level] - ->hexes.hexes[this->present_index] = hex; + ->hexes.cells[this->present_index] = hex; } @@ -723,21 +918,23 @@ TriaObjectAccessor<3, dim>::vertex (const unsigned int i) const -template -void TriaObjectAccessor<3, dim>::set_used_flag () const +template <> +void TriaObjectAccessor<3, 3>::set_used_flag () const { + const int dim=3; Assert (this->state() == IteratorState::valid, - typename TriaAccessor::ExcDereferenceInvalidObject()); + TriaAccessor::ExcDereferenceInvalidObject()); this->tria->levels[this->present_level]->hexes.used[this->present_index] = true; } -template -void TriaObjectAccessor<3, dim>::clear_used_flag () const +template <> +void TriaObjectAccessor<3, 3>::clear_used_flag () const { + const int dim=3; Assert (this->state() == IteratorState::valid, - typename TriaAccessor::ExcDereferenceInvalidObject()); + TriaAccessor::ExcDereferenceInvalidObject()); this->tria->levels[this->present_level]->hexes.used[this->present_index] = false; } @@ -767,28 +964,31 @@ void TriaObjectAccessor<3, dim>::recursively_clear_user_flag () const -template -void TriaObjectAccessor<3, dim>::set_user_pointer (void *p) const +template <> +void TriaObjectAccessor<3, 3>::set_user_pointer (void *p) const { - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + const int dim=3; + Assert (used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->hexes.user_pointers[this->present_index] = p; } -template -void TriaObjectAccessor<3, dim>::clear_user_pointer () const +template <> +void TriaObjectAccessor<3, 3>::clear_user_pointer () const { - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + const int dim=3; + Assert (used(), TriaAccessor::ExcCellNotUsed()); this->tria->levels[this->present_level]->hexes.user_pointers[this->present_index] = 0; } -template -void * TriaObjectAccessor<3, dim>::user_pointer () const +template <> +void * TriaObjectAccessor<3, 3>::user_pointer () const { - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + const int dim=3; + Assert (used(), TriaAccessor::ExcCellNotUsed()); return this->tria->levels[this->present_level]->hexes.user_pointers[this->present_index]; } @@ -820,13 +1020,14 @@ TriaObjectAccessor<3, dim>::recursively_clear_user_pointer () const -template -void TriaObjectAccessor<3, dim>::set_children (const int index) const +template <> +void TriaObjectAccessor<3, 3>::set_children (const int index) const { - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + const int dim=3; + Assert (used(), TriaAccessor::ExcCellNotUsed()); Assert ((index==-1) || (!has_children() && (index>=0)), - typename TriaAccessor::ExcCantSetChildren(index)); + TriaAccessor::ExcCantSetChildren(index)); this->tria->levels[this->present_level]->hexes.children[this->present_index] = index; } @@ -844,21 +1045,16 @@ void TriaObjectAccessor<3, dim>::clear_children () const template unsigned char TriaObjectAccessor<3, dim>::boundary_indicator () const { - Assert (dim<4, ExcImpossibleInDim(dim)); - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); - - return this->tria->levels[this->present_level]->hexes.material_id[this->present_index]; + Assert (false, ExcImpossibleInDim(dim)); + return 255; } template -void TriaObjectAccessor<3, dim>::set_boundary_indicator (const unsigned char boundary_ind) const +void TriaObjectAccessor<3, dim>::set_boundary_indicator (const unsigned char) const { - Assert (dim<4, ExcImpossibleInDim(dim)); - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); - - this->tria->levels[this->present_level]->hexes.material_id[this->present_index] = boundary_ind; + Assert (false, ExcImpossibleInDim(dim)); } @@ -1604,13 +1800,14 @@ unsigned int TriaObjectAccessor<3, dim>::number_of_children () const -template +template <> void -TriaObjectAccessor<3, dim>:: +TriaObjectAccessor<3, 3>:: set_face_orientation (const unsigned int face, const bool orientation) const { - Assert (used(), typename TriaAccessor::ExcCellNotUsed()); + const int dim=3; + Assert (used(), TriaAccessor::ExcCellNotUsed()); Assert (face::faces_per_cell, ExcIndexRange (face, 0, GeometryInfo<3>::faces_per_cell)); Assert (this->present_index * GeometryInfo<3>::faces_per_cell + face diff --git a/deal.II/deal.II/source/grid/tria_faces.cc b/deal.II/deal.II/source/grid/tria_faces.cc new file mode 100644 index 0000000000..3ff66a6404 --- /dev/null +++ b/deal.II/deal.II/source/grid/tria_faces.cc @@ -0,0 +1,43 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + +#include +#include + + +namespace internal +{ + namespace Triangulation + { + unsigned int + TriaFaces<1>::memory_consumption () const + { + return 0; + } + + + unsigned int + TriaFaces<2>::memory_consumption () const + { + return MemoryConsumption::memory_consumption (lines); + } + + + unsigned int + TriaFaces<3>::memory_consumption () const + { + return (MemoryConsumption::memory_consumption (quads) + + MemoryConsumption::memory_consumption (lines) ); + } + } +} diff --git a/deal.II/deal.II/source/grid/tria_objects.cc b/deal.II/deal.II/source/grid/tria_objects.cc new file mode 100644 index 0000000000..96afe61310 --- /dev/null +++ b/deal.II/deal.II/source/grid/tria_objects.cc @@ -0,0 +1,340 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include + +#include +#include + + +namespace internal +{ + namespace Triangulation + { + + template<> + void + TriaObjects::reserve_space (const unsigned int new_lines) + { + const unsigned int new_size = new_lines + + std::count_if (used.begin(), + used.end(), + std::bind2nd (std::equal_to(), true)); + + // only allocate space if necessary + if (new_size>cells.size()) + { + cells.reserve (new_size); + cells.insert (cells.end(), + new_size-cells.size(), + Line()); + + used.reserve (new_size); + used.insert (used.end(), + new_size-used.size(), + false); + + user_flags.reserve (new_size); + user_flags.insert (user_flags.end(), + new_size-user_flags.size(), + false); + + children.reserve (new_size); + children.insert (children.end(), + new_size-children.size(), + -1); + + material_id.reserve (new_size); + material_id.insert (material_id.end(), + new_size-material_id.size(), + 255); + + user_pointers.reserve (new_size); + user_pointers.insert (user_pointers.end(), + new_size-user_pointers.size(), + 0); + }; + } + + + template<> + void + TriaObjects::reserve_space (const unsigned int new_quads) + { + const unsigned int new_size = new_quads + + std::count_if (used.begin(), + used.end(), + std::bind2nd (std::equal_to(), true)); + + // see above... + if (new_size>cells.size()) + { + cells.reserve (new_size); + cells.insert (cells.end(), + new_size-cells.size(), + Quad()); + + used.reserve (new_size); + used.insert (used.end(), + new_size-used.size(), + false); + + user_flags.reserve (new_size); + user_flags.insert (user_flags.end(), + new_size-user_flags.size(), + false); + + children.reserve (new_size); + children.insert (children.end(), + new_size-children.size(), + -1); + + material_id.reserve (new_size); + material_id.insert (material_id.end(), + new_size-material_id.size(), + 255); + + user_pointers.reserve (new_size); + user_pointers.insert (user_pointers.end(), + new_size-user_pointers.size(), + 0); + }; + } + + + void + TriaObjectsHex::reserve_space (const unsigned int new_hexes) + { + const unsigned int new_size = new_hexes + + std::count_if (used.begin(), + used.end(), + std::bind2nd (std::equal_to(), true)); + + // see above... + if (new_size>cells.size()) + { + cells.reserve (new_size); + cells.insert (cells.end(), + new_size-cells.size(), + Hexahedron()); + + used.reserve (new_size); + used.insert (used.end(), + new_size-used.size(), + false); + + user_flags.reserve (new_size); + user_flags.insert (user_flags.end(), + new_size-user_flags.size(), + false); + + children.reserve (new_size); + children.insert (children.end(), + new_size-children.size(), + -1); + + material_id.reserve (new_size); + material_id.insert (material_id.end(), + new_size-material_id.size(), + 255); + + user_pointers.reserve (new_size); + user_pointers.insert (user_pointers.end(), + new_size-user_pointers.size(), + 0); + + face_orientations.reserve (new_size * GeometryInfo<3>::faces_per_cell); + face_orientations.insert (face_orientations.end(), + new_size * GeometryInfo<3>::faces_per_cell + - face_orientations.size(), + true); + }; + } + + + template<> + void + TriaObjects::monitor_memory (const unsigned int) const + { + // check that we have not allocated + // too much memory. note that bool + // vectors allocate their memory in + // chunks of whole integers, so + // they may over-allocate by up to + // as many elements as an integer + // has bits + Assert (cells.size() == cells.capacity() || + cells.size() + void + TriaObjects::monitor_memory (const unsigned int) const + { + // check that we have not allocated + // too much memory. note that bool + // vectors allocate their memory in + // chunks of whole integers, so + // they may over-allocate by up to + // as many elements as an integer + // has bits + Assert (cells.size() == cells.capacity() || + cells.size()::faces_per_cell + == face_orientations.size(), + ExcMemoryInexact (cells.size() * GeometryInfo<3>::faces_per_cell, + face_orientations.size())); + } + + + template + void + TriaObjects::clear() + { + cells.clear(); + children.clear(); + used.clear(); + user_flags.clear(); + material_id.clear(); + user_pointers.clear(); + } + + + void + TriaObjectsHex::clear() + { + TriaObjects::clear(); + face_orientations.clear(); + } + + + template + unsigned int + TriaObjects::memory_consumption () const + { + return (MemoryConsumption::memory_consumption (cells) + + MemoryConsumption::memory_consumption (children) + + MemoryConsumption::memory_consumption (used) + + MemoryConsumption::memory_consumption (user_flags) + + MemoryConsumption::memory_consumption (material_id) + + MemoryConsumption::memory_consumption (user_pointers)); + } + + + unsigned int + TriaObjectsHex::memory_consumption () const + { + return (MemoryConsumption::memory_consumption (face_orientations) + + this->TriaObjects::memory_consumption() ); + } + + // explicit instantiations + + template class TriaObjects; + +#if deal_II_dimension >=2 + template class TriaObjects; +#endif + + } +} diff --git a/deal.II/deal.II/source/multigrid/mg_dof_accessor.cc b/deal.II/deal.II/source/multigrid/mg_dof_accessor.cc index d74ee6bec4..943ab81ee9 100644 --- a/deal.II/deal.II/source/multigrid/mg_dof_accessor.cc +++ b/deal.II/deal.II/source/multigrid/mg_dof_accessor.cc @@ -126,12 +126,11 @@ template unsigned int MGDoFAccessor::mg_dof_index (const unsigned int i) const { - return this->mg_dof_handler->mg_levels[this->present_level] - ->get_dof_index(*this->dof_handler, - this->present_index, - 0, - i, - internal::StructuralDimension()); + return this->mg_dof_handler + ->template get_dof_index(this->present_level, + this->present_index, + 0, + i); } @@ -139,13 +138,12 @@ template void MGDoFAccessor::set_mg_dof_index (const unsigned int i, const unsigned int index) const { - this->mg_dof_handler->mg_levels[this->present_level] - ->set_dof_index(*this->dof_handler, - this->present_index, - 0, - i, - index, - internal::StructuralDimension()); + this->mg_dof_handler + ->template set_dof_index(this->present_level, + this->present_index, + 0, + i, + index); } @@ -154,8 +152,14 @@ template TriaIterator > MGDoFAccessor::child (const unsigned int i) const { + int next_level; + if (structdim==dim) + next_level=this->present_level+1; + else + next_level=0; + TriaIterator > q (this->tria, - this->present_level+1, + next_level, this->child_index (i), this->mg_dof_handler); @@ -360,7 +364,7 @@ MGDoFObjectAccessor<2, dim>::line (const unsigned int i) const return TriaIterator > ( this->tria, - this->present_level, + 0, this->line_index (i), this->mg_dof_handler ); @@ -467,7 +471,7 @@ MGDoFObjectAccessor<3, dim>::line (const unsigned int i) const return TriaIterator > ( this->tria, - this->present_level, + 0, this->line_index (i), this->mg_dof_handler ); @@ -478,12 +482,12 @@ template TriaIterator > MGDoFObjectAccessor<3, dim>::quad (const unsigned int i) const { - Assert (i<12, ExcIndexRange (i, 0, 6)); + Assert (i<6, ExcIndexRange (i, 0, 6)); return TriaIterator > ( this->tria, - this->present_level, + 0, this->quad_index (i), this->mg_dof_handler ); diff --git a/deal.II/deal.II/source/multigrid/mg_dof_handler.cc b/deal.II/deal.II/source/multigrid/mg_dof_handler.cc index fad5041070..d538bda48e 100644 --- a/deal.II/deal.II/source/multigrid/mg_dof_handler.cc +++ b/deal.II/deal.II/source/multigrid/mg_dof_handler.cc @@ -13,6 +13,7 @@ #include +#include #include #include #include @@ -109,7 +110,8 @@ const unsigned int MGDoFHandler::dimension; template MGDoFHandler::MGDoFHandler (const Triangulation &tria) : - DoFHandler (tria) + DoFHandler (tria), + mg_faces (NULL) {} @@ -204,7 +206,7 @@ MGDoFHandler<1>::last_active (const unsigned int level) const template <> internal::MGDoFHandler::Iterators<1>::raw_face_iterator -MGDoFHandler<1>::begin_raw_face (const unsigned int) const +MGDoFHandler<1>::begin_raw_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -213,7 +215,7 @@ MGDoFHandler<1>::begin_raw_face (const unsigned int) const template <> internal::MGDoFHandler::Iterators<1>::face_iterator -MGDoFHandler<1>::begin_face (const unsigned int) const +MGDoFHandler<1>::begin_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -222,7 +224,7 @@ MGDoFHandler<1>::begin_face (const unsigned int) const template <> internal::MGDoFHandler::Iterators<1>::active_face_iterator -MGDoFHandler<1>::begin_active_face (const unsigned int) const +MGDoFHandler<1>::begin_active_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -240,7 +242,7 @@ MGDoFHandler<1>::end_face () const template <> internal::MGDoFHandler::Iterators<1>::raw_face_iterator -MGDoFHandler<1>::last_raw_face () const +MGDoFHandler<1>::end_raw_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -248,8 +250,8 @@ MGDoFHandler<1>::last_raw_face () const template <> -internal::MGDoFHandler::Iterators<1>::raw_face_iterator -MGDoFHandler<1>::last_raw_face (const unsigned int) const +internal::MGDoFHandler::Iterators<1>::active_face_iterator +MGDoFHandler<1>::end_active_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -257,8 +259,8 @@ MGDoFHandler<1>::last_raw_face (const unsigned int) const template <> -internal::MGDoFHandler::Iterators<1>::face_iterator -MGDoFHandler<1>::last_face () const +internal::MGDoFHandler::Iterators<1>::raw_face_iterator +MGDoFHandler<1>::last_raw_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -267,7 +269,7 @@ MGDoFHandler<1>::last_face () const template <> internal::MGDoFHandler::Iterators<1>::face_iterator -MGDoFHandler<1>::last_face (const unsigned int) const +MGDoFHandler<1>::last_face () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -284,8 +286,26 @@ MGDoFHandler<1>::last_active_face () const template <> -internal::MGDoFHandler::Iterators<1>::active_face_iterator -MGDoFHandler<1>::last_active_face (const unsigned int) const +MGDoFHandler<1>::raw_quad_iterator +MGDoFHandler<1>::begin_raw_quad (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + +template <> +MGDoFHandler<1>::quad_iterator +MGDoFHandler<1>::begin_quad (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + +template <> +MGDoFHandler<1>::active_quad_iterator +MGDoFHandler<1>::begin_active_quad (const unsigned int) const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -294,7 +314,7 @@ MGDoFHandler<1>::last_active_face (const unsigned int) const template <> MGDoFHandler<1>::raw_quad_iterator -MGDoFHandler<1>::begin_raw_quad (const unsigned int) const +MGDoFHandler<1>::end_quad () const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -303,7 +323,7 @@ MGDoFHandler<1>::begin_raw_quad (const unsigned int) const template <> MGDoFHandler<1>::quad_iterator -MGDoFHandler<1>::begin_quad (const unsigned int) const +MGDoFHandler<1>::end_quad (const unsigned int) const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -311,8 +331,8 @@ MGDoFHandler<1>::begin_quad (const unsigned int) const template <> -MGDoFHandler<1>::active_quad_iterator -MGDoFHandler<1>::begin_active_quad (const unsigned int) const +MGDoFHandler<1>::raw_quad_iterator +MGDoFHandler<1>::end_raw_quad (const unsigned int) const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -320,8 +340,8 @@ MGDoFHandler<1>::begin_active_quad (const unsigned int) const template <> -MGDoFHandler<1>::raw_quad_iterator -MGDoFHandler<1>::end_quad () const +MGDoFHandler<1>::active_quad_iterator +MGDoFHandler<1>::end_active_quad (const unsigned int) const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -419,8 +439,8 @@ MGDoFHandler<1>::end_hex () const template <> -MGDoFHandler<1>::raw_hex_iterator -MGDoFHandler<1>::last_raw_hex (const unsigned int) const +MGDoFHandler<1>::hex_iterator +MGDoFHandler<1>::end_hex (const unsigned int) const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -428,8 +448,8 @@ MGDoFHandler<1>::last_raw_hex (const unsigned int) const template <> -MGDoFHandler<1>::hex_iterator -MGDoFHandler<1>::last_hex (const unsigned int) const +MGDoFHandler<1>::raw_hex_iterator +MGDoFHandler<1>::end_raw_hex (const unsigned int) const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -438,7 +458,16 @@ MGDoFHandler<1>::last_hex (const unsigned int) const template <> MGDoFHandler<1>::active_hex_iterator -MGDoFHandler<1>::last_active_hex (const unsigned int) const +MGDoFHandler<1>::end_active_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + +template <> +MGDoFHandler<1>::raw_hex_iterator +MGDoFHandler<1>::last_raw_hex (const unsigned int) const { Assert (false, ExcImpossibleInDim(1)); return 0; @@ -454,6 +483,15 @@ MGDoFHandler<1>::last_raw_hex () const } +template <> +MGDoFHandler<1>::hex_iterator +MGDoFHandler<1>::last_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + template <> MGDoFHandler<1>::hex_iterator MGDoFHandler<1>::last_hex () const @@ -463,6 +501,15 @@ MGDoFHandler<1>::last_hex () const } +template <> +MGDoFHandler<1>::active_hex_iterator +MGDoFHandler<1>::last_active_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(1)); + return 0; +} + + template <> MGDoFHandler<1>::active_hex_iterator MGDoFHandler<1>::last_active_hex () const @@ -558,25 +605,25 @@ MGDoFHandler<2>::last_active (const unsigned int level) const template <> internal::MGDoFHandler::Iterators<2>::raw_face_iterator -MGDoFHandler<2>::begin_raw_face (const unsigned int level) const +MGDoFHandler<2>::begin_raw_face () const { - return begin_raw_line (level); + return begin_raw_line (); } template <> internal::MGDoFHandler::Iterators<2>::face_iterator -MGDoFHandler<2>::begin_face (const unsigned int level) const +MGDoFHandler<2>::begin_face () const { - return begin_line (level); + return begin_line (); } template <> internal::MGDoFHandler::Iterators<2>::active_face_iterator -MGDoFHandler<2>::begin_active_face (const unsigned int level) const +MGDoFHandler<2>::begin_active_face () const { - return begin_active_line (level); + return begin_active_line (); } @@ -590,33 +637,33 @@ MGDoFHandler<2>::end_face () const template <> internal::MGDoFHandler::Iterators<2>::raw_face_iterator -MGDoFHandler<2>::last_raw_face () const +MGDoFHandler<2>::end_raw_face () const { - return last_raw_line (); + return end_line (); } template <> -internal::MGDoFHandler::Iterators<2>::raw_face_iterator -MGDoFHandler<2>::last_raw_face (const unsigned int level) const +internal::MGDoFHandler::Iterators<2>::active_face_iterator +MGDoFHandler<2>::end_active_face () const { - return last_raw_line (level); + return end_line (); } template <> -internal::MGDoFHandler::Iterators<2>::face_iterator -MGDoFHandler<2>::last_face () const +internal::MGDoFHandler::Iterators<2>::raw_face_iterator +MGDoFHandler<2>::last_raw_face () const { - return last_line (); + return last_raw_line (); } template <> internal::MGDoFHandler::Iterators<2>::face_iterator -MGDoFHandler<2>::last_face (const unsigned int level) const +MGDoFHandler<2>::last_face () const { - return last_line (level); + return last_line (); } @@ -628,14 +675,6 @@ MGDoFHandler<2>::last_active_face () const } -template <> -internal::MGDoFHandler::Iterators<2>::active_face_iterator -MGDoFHandler<2>::last_active_face (const unsigned int level) const -{ - return last_active_line (level); -} - - template <> MGDoFHandler<2>::raw_hex_iterator MGDoFHandler<2>::begin_raw_hex (const unsigned int) const @@ -673,8 +712,8 @@ MGDoFHandler<2>::end_hex () const template <> -MGDoFHandler<2>::raw_hex_iterator -MGDoFHandler<2>::last_raw_hex (const unsigned int) const +MGDoFHandler<2>::hex_iterator +MGDoFHandler<2>::end_hex (const unsigned int) const { Assert (false, ExcImpossibleInDim(2)); return 0; @@ -682,8 +721,8 @@ MGDoFHandler<2>::last_raw_hex (const unsigned int) const template <> -MGDoFHandler<2>::hex_iterator -MGDoFHandler<2>::last_hex (const unsigned int) const +MGDoFHandler<2>::raw_hex_iterator +MGDoFHandler<2>::end_raw_hex (const unsigned int) const { Assert (false, ExcImpossibleInDim(2)); return 0; @@ -692,7 +731,16 @@ MGDoFHandler<2>::last_hex (const unsigned int) const template <> MGDoFHandler<2>::active_hex_iterator -MGDoFHandler<2>::last_active_hex (const unsigned int) const +MGDoFHandler<2>::end_active_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(2)); + return 0; +} + + +template <> +MGDoFHandler<2>::raw_hex_iterator +MGDoFHandler<2>::last_raw_hex (const unsigned int) const { Assert (false, ExcImpossibleInDim(2)); return 0; @@ -708,6 +756,15 @@ MGDoFHandler<2>::last_raw_hex () const } +template <> +MGDoFHandler<2>::hex_iterator +MGDoFHandler<2>::last_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(2)); + return 0; +} + + template <> MGDoFHandler<2>::hex_iterator MGDoFHandler<2>::last_hex () const @@ -717,6 +774,15 @@ MGDoFHandler<2>::last_hex () const } +template <> +MGDoFHandler<2>::active_hex_iterator +MGDoFHandler<2>::last_active_hex (const unsigned int) const +{ + Assert (false, ExcImpossibleInDim(2)); + return 0; +} + + template <> MGDoFHandler<2>::active_hex_iterator MGDoFHandler<2>::last_active_hex () const @@ -813,25 +879,25 @@ MGDoFHandler<3>::last_active (const unsigned int level) const template <> internal::MGDoFHandler::Iterators<3>::raw_face_iterator -MGDoFHandler<3>::begin_raw_face (const unsigned int level) const +MGDoFHandler<3>::begin_raw_face () const { - return begin_raw_quad (level); + return begin_raw_quad (); } template <> internal::MGDoFHandler::Iterators<3>::face_iterator -MGDoFHandler<3>::begin_face (const unsigned int level) const +MGDoFHandler<3>::begin_face () const { - return begin_quad (level); + return begin_quad (); } template <> internal::MGDoFHandler::Iterators<3>::active_face_iterator -MGDoFHandler<3>::begin_active_face (const unsigned int level) const +MGDoFHandler<3>::begin_active_face () const { - return begin_active_quad (level); + return begin_active_quad (); } @@ -845,33 +911,33 @@ MGDoFHandler<3>::end_face () const template <> internal::MGDoFHandler::Iterators<3>::raw_face_iterator -MGDoFHandler<3>::last_raw_face () const +MGDoFHandler<3>::end_raw_face () const { - return last_raw_quad (); + return end_quad (); } template <> -internal::MGDoFHandler::Iterators<3>::raw_face_iterator -MGDoFHandler<3>::last_raw_face (const unsigned int level) const +internal::MGDoFHandler::Iterators<3>::active_face_iterator +MGDoFHandler<3>::end_active_face () const { - return last_raw_quad (level); + return end_quad (); } template <> -internal::MGDoFHandler::Iterators<3>::face_iterator -MGDoFHandler<3>::last_face () const +internal::MGDoFHandler::Iterators<3>::raw_face_iterator +MGDoFHandler<3>::last_raw_face () const { - return last_quad (); + return last_raw_quad (); } template <> internal::MGDoFHandler::Iterators<3>::face_iterator -MGDoFHandler<3>::last_face (const unsigned int level) const +MGDoFHandler<3>::last_face () const { - return last_quad (level); + return last_quad (); } @@ -883,13 +949,6 @@ MGDoFHandler<3>::last_active_face () const } -template <> -internal::MGDoFHandler::Iterators<3>::active_face_iterator -MGDoFHandler<3>::last_active_face (const unsigned int level) const -{ - return last_active_quad (level); -} - #endif @@ -992,6 +1051,13 @@ MGDoFHandler::begin_active_hex (const unsigned int level) const } + + // We can't ask the respective tria->-function here, as + // that would include dereferencing a past-the-end iterator + // which is not allowed. Therefore we have to repeat the + // code from tria.cc + // This is valid for all functions whisch return past the + // end iterators, namely all functions end_*() template typename MGDoFHandler::raw_line_iterator MGDoFHandler::end_line () const @@ -1046,43 +1112,14 @@ MGDoFHandler::end_active (const unsigned int level) const } -template -typename internal::MGDoFHandler::Iterators::raw_face_iterator -MGDoFHandler::end_raw_face (const unsigned int level) const -{ - return (level == mg_levels.size()-1 ? - end_face() : - begin_raw_face (level+1)); -} - - -template -typename internal::MGDoFHandler::Iterators::face_iterator -MGDoFHandler::end_face (const unsigned int level) const -{ - return (level == mg_levels.size()-1 ? - face_iterator(end_face()) : - begin_face (level+1)); -} - - -template -typename internal::MGDoFHandler::Iterators::active_face_iterator -MGDoFHandler::end_active_face (const unsigned int level) const -{ - return (level == mg_levels.size()-1 ? - active_face_iterator(end_face()) : - begin_active_face (level+1)); -} - - template typename internal::MGDoFHandler::Iterators::raw_line_iterator MGDoFHandler::end_raw_line (const unsigned int level) const { - return (level == mg_levels.size()-1 ? - end_line() : - begin_raw_line (level+1)); + return raw_line_iterator(this->tria, + this->tria->end_raw_line(level)->level(), + this->tria->end_raw_line(level)->index(), + this); } @@ -1090,9 +1127,10 @@ template typename internal::MGDoFHandler::Iterators::line_iterator MGDoFHandler::end_line (const unsigned int level) const { - return (level == mg_levels.size()-1 ? - line_iterator(end_line()) : - begin_line (level+1)); + return line_iterator(this->tria, + this->tria->end_line(level)->level(), + this->tria->end_line(level)->index(), + this); } @@ -1100,9 +1138,10 @@ template typename internal::MGDoFHandler::Iterators::active_line_iterator MGDoFHandler::end_active_line (const unsigned int level) const { - return (level == mg_levels.size()-1 ? - active_line_iterator(end_line()) : - begin_active_line (level+1)); + return active_line_iterator(this->tria, + this->tria->end_active_line(level)->level(), + this->tria->end_active_line(level)->index(), + this); } @@ -1110,9 +1149,10 @@ template typename internal::MGDoFHandler::Iterators::raw_quad_iterator MGDoFHandler::end_raw_quad (const unsigned int level) const { - return (level == mg_levels.size()-1 ? - end_quad() : - begin_raw_quad (level+1)); + return raw_quad_iterator(this->tria, + this->tria->end_raw_quad(level)->level(), + this->tria->end_raw_quad(level)->index(), + this); } @@ -1120,9 +1160,10 @@ template typename internal::MGDoFHandler::Iterators::quad_iterator MGDoFHandler::end_quad (const unsigned int level) const { - return (level == mg_levels.size()-1 ? - quad_iterator(end_quad()) : - begin_quad (level+1)); + return quad_iterator(this->tria, + this->tria->end_quad(level)->level(), + this->tria->end_quad(level)->index(), + this); } @@ -1130,9 +1171,10 @@ template typename internal::MGDoFHandler::Iterators::active_quad_iterator MGDoFHandler::end_active_quad (const unsigned int level) const { - return (level == mg_levels.size()-1 ? - active_quad_iterator(end_quad()) : - begin_active_quad (level+1)); + return active_quad_iterator(this->tria, + this->tria->end_active_quad(level)->level(), + this->tria->end_active_quad(level)->index(), + this); } @@ -1140,9 +1182,10 @@ template typename internal::MGDoFHandler::Iterators::raw_hex_iterator MGDoFHandler::end_raw_hex (const unsigned int level) const { - return (level == mg_levels.size()-1 ? - end_hex() : - begin_raw_hex (level+1)); + return raw_hex_iterator(this->tria, + this->tria->end_raw_hex(level)->level(), + this->tria->end_raw_hex(level)->index(), + this); } @@ -1150,9 +1193,10 @@ template typename internal::MGDoFHandler::Iterators::hex_iterator MGDoFHandler::end_hex (const unsigned int level) const { - return (level == mg_levels.size()-1 ? - hex_iterator(end_hex()) : - begin_hex (level+1)); + return hex_iterator(this->tria, + this->tria->end_hex(level)->level(), + this->tria->end_hex(level)->index(), + this); } @@ -1160,9 +1204,10 @@ template typename internal::MGDoFHandler::Iterators::active_hex_iterator MGDoFHandler::end_active_hex (const unsigned int level) const { - return (level == mg_levels.size()-1 ? - active_hex_iterator(end_hex()) : - begin_active_hex (level+1)); + return active_hex_iterator(this->tria, + this->tria->end_active_hex(level)->level(), + this->tria->end_active_hex(level)->index(), + this); } @@ -1269,7 +1314,13 @@ template typename MGDoFHandler::raw_line_iterator MGDoFHandler::last_raw_line () const { - return last_raw_line (mg_levels.size()-1); + if (dim==1) + return last_raw_line (mg_levels.size()-1); + else + return raw_line_iterator (this->tria, + this->tria->last_raw_line()->level(), + this->tria->last_raw_line()->index(), + this); } @@ -1277,7 +1328,13 @@ template typename MGDoFHandler::raw_quad_iterator MGDoFHandler::last_raw_quad () const { - return last_raw_quad (mg_levels.size()-1); + if (dim == 2) + return last_raw_quad (mg_levels.size()-1); + else + return raw_quad_iterator (this->tria, + this->tria->last_raw_quad()->level(), + this->tria->last_raw_quad()->index(), + this); } @@ -1285,7 +1342,13 @@ template typename MGDoFHandler::raw_hex_iterator MGDoFHandler::last_raw_hex () const { - return last_raw_hex (mg_levels.size()-1); + if (dim==3) + return last_raw_hex (mg_levels.size()-1); + else + return raw_hex_iterator (this->tria, + this->tria->last_raw_hex()->level(), + this->tria->last_raw_hex()->index(), + this); } @@ -1293,7 +1356,13 @@ template typename MGDoFHandler::line_iterator MGDoFHandler::last_line () const { - return last_line (mg_levels.size()-1); + if (dim==1) + return last_line (mg_levels.size()-1); + else + return line_iterator (this->tria, + this->tria->last_line()->level(), + this->tria->last_line()->index(), + this); } @@ -1301,7 +1370,13 @@ template typename MGDoFHandler::quad_iterator MGDoFHandler::last_quad () const { - return last_quad (mg_levels.size()-1); + if (dim == 2) + return last_quad (mg_levels.size()-1); + else + return quad_iterator (this->tria, + this->tria->last_quad()->level(), + this->tria->last_quad()->index(), + this); } @@ -1309,7 +1384,13 @@ template typename MGDoFHandler::hex_iterator MGDoFHandler::last_hex () const { - return last_hex (mg_levels.size()-1); + if (dim==3) + return last_hex (mg_levels.size()-1); + else + return hex_iterator (this->tria, + this->tria->last_hex()->level(), + this->tria->last_hex()->index(), + this); } @@ -1317,7 +1398,13 @@ template typename MGDoFHandler::active_line_iterator MGDoFHandler::last_active_line () const { - return last_active_line (mg_levels.size()-1); + if (dim==1) + return last_active_line (mg_levels.size()-1); + else + return active_line_iterator (this->tria, + this->tria->last_active_line()->level(), + this->tria->last_active_line()->index(), + this); } @@ -1325,7 +1412,13 @@ template typename MGDoFHandler::active_quad_iterator MGDoFHandler::last_active_quad () const { - return last_active_quad (mg_levels.size()-1); + if (dim==2) + return last_active_quad (mg_levels.size()-1); + else + return active_quad_iterator (this->tria, + this->tria->last_active_quad()->level(), + this->tria->last_active_quad()->index(), + this); } @@ -1333,13 +1426,233 @@ template typename MGDoFHandler::active_hex_iterator MGDoFHandler::last_active_hex () const { - return last_active_hex (mg_levels.size()-1); + if (dim == 3) + return last_active_hex (mg_levels.size()-1); + else + return active_hex_iterator (this->tria, + this->tria->last_active_hex()->level(), + this->tria->last_active_hex()->index(), + this); } //--------------------------------------------------------------------------- +#if deal_II_dimension == 1 +template <> +template <> +unsigned int +MGDoFHandler<1>::get_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->mg_levels[obj_level]->lines. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +MGDoFHandler<1>::set_dof_index<1> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->mg_levels[obj_level]->lines. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} +#endif + +#if deal_II_dimension == 2 +template <> +template <> +unsigned int +MGDoFHandler<2>::get_dof_index<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->mg_faces->lines. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +MGDoFHandler<2>::set_dof_index<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->mg_faces->lines. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} + + +template <> +template <> +unsigned int +MGDoFHandler<2>::get_dof_index<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->mg_levels[obj_level]->quads. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +MGDoFHandler<2>::set_dof_index<2> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->mg_levels[obj_level]->quads. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} +#endif + +#if deal_II_dimension == 3 +template <> +template <> +unsigned int +MGDoFHandler<3>::get_dof_index<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->mg_faces->lines. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +MGDoFHandler<3>::set_dof_index<1> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->mg_faces->lines. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} + + +template <> +template <> +unsigned int +MGDoFHandler<3>::get_dof_index<2> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->mg_faces->quads. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +unsigned int +MGDoFHandler<3>::get_dof_index<3> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index) const +{ + return this->mg_levels[obj_level]->hexes. + get_dof_index (*this, + obj_index, + fe_index, + local_index); +} + + +template <> +template <> +void +MGDoFHandler<3>::set_dof_index<2> (const unsigned int , + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->mg_faces->quads. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} + + +template <> +template <> +void +MGDoFHandler<3>::set_dof_index<3> (const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int global_index) const +{ + this->mg_levels[obj_level]->hexes. + set_dof_index (*this, + obj_index, + fe_index, + local_index, + global_index); + +} +#endif + + template void MGDoFHandler::distribute_dofs (const FiniteElement &fe, const unsigned int offset) @@ -1593,8 +1906,8 @@ void MGDoFHandler<1>::renumber_dofs (const unsigned int level, new_numbers[i->get_index (level, d, this->selected_fe->dofs_per_vertex)]); - for (std::vector::iterator i=mg_levels[level]->line_dofs.begin(); - i!=mg_levels[level]->line_dofs.end(); ++i) + for (std::vector::iterator i=mg_levels[level]->lines.dofs.begin(); + i!=mg_levels[level]->lines.dofs.end(); ++i) { if (*i != DoFHandler<1>::invalid_dof_index) { @@ -1625,19 +1938,40 @@ void MGDoFHandler<2>::renumber_dofs (const unsigned int level, i->set_index (level, d, this->selected_fe->dofs_per_vertex, new_numbers[i->get_index (level, d, this->selected_fe->dofs_per_vertex)]); - - for (std::vector::iterator i=mg_levels[level]->line_dofs.begin(); - i!=mg_levels[level]->line_dofs.end(); ++i) + + if (this->selected_fe->dofs_per_line > 0) { - if (*i != DoFHandler<2>::invalid_dof_index) - { - Assert(*i user_flags; + this->tria->save_user_flags(user_flags); + const_cast &>(*(this->tria)).clear_user_flags (); + + // flag all lines adjacent to cells of the current + // level, as those lines logically belong to the same + // level as the cell, at least for for isotropic + // refinement + cell_iterator cell = begin(level), + endcell = end(level); + for ( ; cell != endcell; ++cell) + for (unsigned int line=0; line < GeometryInfo<2>::faces_per_cell; ++line) + cell->face(line)->set_user_flag(); + + line_iterator line = begin_line(), + endline = end_line(); + + for( ; line != endline; ++line) + if (line->user_flag_set()) + { + for (unsigned int d=0; dselected_fe->dofs_per_line; ++d) + line->set_mg_dof_index (d, new_numbers[line->mg_dof_index(d)]); + line->clear_user_flag(); + } + // finally, restore user flags + const_cast &>(*(this->tria)).load_user_flags (user_flags); } - for (std::vector::iterator i=mg_levels[level]->quad_dofs.begin(); - i!=mg_levels[level]->quad_dofs.end(); ++i) + for (std::vector::iterator i=mg_levels[level]->quads.dofs.begin(); + i!=mg_levels[level]->quads.dofs.end(); ++i) { if (*i != DoFHandler<2>::invalid_dof_index) { @@ -1668,29 +2002,76 @@ void MGDoFHandler<3>::renumber_dofs (const unsigned int level, i->set_index (level, d, this->selected_fe->dofs_per_vertex, new_numbers[i->get_index (level, d, this->selected_fe->dofs_per_vertex)]); - - for (std::vector::iterator i=mg_levels[level]->line_dofs.begin(); - i!=mg_levels[level]->line_dofs.end(); ++i) + + // LINE DoFs + if (this->selected_fe->dofs_per_line > 0) { - if (*i != DoFHandler<3>::invalid_dof_index) - { - Assert(*i user_flags; + this->tria->save_user_flags(user_flags); + const_cast &>(*(this->tria)).clear_user_flags (); + + // flag all lines adjacent to cells of the current + // level, as those lines logically belong to the same + // level as the cell, at least for for isotropic + // refinement + + cell_iterator cell = begin(level), + endcell = end(level); + for ( ; cell != endcell ; ++cell) + for (unsigned int line=0; line < GeometryInfo<3>::lines_per_cell; ++line) + cell->line(line)->set_user_flag(); + + + line_iterator line = begin_line(), + endline = end_line(); + + for( ; line != endline; ++line) + if (line->user_flag_set()) + { + for (unsigned int d=0; dselected_fe->dofs_per_line; ++d) + line->set_mg_dof_index (d, new_numbers[line->mg_dof_index(d)]); + line->clear_user_flag(); + } + // finally, restore user flags + const_cast &>(*(this->tria)).load_user_flags (user_flags); } - for (std::vector::iterator i=mg_levels[level]->quad_dofs.begin(); - i!=mg_levels[level]->quad_dofs.end(); ++i) + // QUAD DoFs + if (this->selected_fe->dofs_per_quad > 0) { - if (*i != DoFHandler<3>::invalid_dof_index) - { - Assert(*i user_flags; + this->tria->save_user_flags(user_flags); + const_cast &>(*(this->tria)).clear_user_flags (); + + // flag all quads adjacent to cells of the current + // level, as those lines logically belong to the same + // level as the cell, at least for for isotropic + // refinement + cell_iterator cell = begin(level), + endcell = end(level); + for ( ; cell != endcell ; ++cell) + for (unsigned int quad=0; quad < GeometryInfo<3>::faces_per_cell; ++quad) + cell->face(quad)->set_user_flag(); + + quad_iterator quad = begin_quad(), + endline = end_quad(); + + for( ; quad != endline; ++quad) + if (quad->user_flag_set()) + { + for (unsigned int d=0; dselected_fe->dofs_per_quad; ++d) + quad->set_mg_dof_index (d, new_numbers[quad->mg_dof_index(d)]); + quad->clear_user_flag(); + } + // finally, restore user flags + const_cast &>(*(this->tria)).load_user_flags (user_flags); } - for (std::vector::iterator i=mg_levels[level]->hex_dofs.begin(); - i!=mg_levels[level]->hex_dofs.end(); ++i) + //HEX DoFs + for (std::vector::iterator i=mg_levels[level]->hexes.dofs.begin(); + i!=mg_levels[level]->hexes.dofs.end(); ++i) { if (*i != DoFHandler<3>::invalid_dof_index) { @@ -1725,7 +2106,7 @@ void MGDoFHandler<1>::reserve_space () { { mg_levels.push_back (new internal::DoFHandler::DoFLevel<1>); - mg_levels.back()->line_dofs = std::vector(this->tria->n_raw_lines(i) * + mg_levels.back()->lines.dofs = std::vector(this->tria->n_raw_lines(i) * this->selected_fe->dofs_per_line, DoFHandler<1>::invalid_dof_index); }; @@ -1806,13 +2187,15 @@ void MGDoFHandler<2>::reserve_space () { { mg_levels.push_back (new internal::DoFHandler::DoFLevel<2>); - mg_levels.back()->line_dofs = std::vector (this->tria->n_raw_lines(i) * - this->selected_fe->dofs_per_line, - DoFHandler<2>::invalid_dof_index); - mg_levels.back()->quad_dofs = std::vector (this->tria->n_raw_quads(i) * + mg_levels.back()->quads.dofs = std::vector (this->tria->n_raw_quads(i) * this->selected_fe->dofs_per_quad, DoFHandler<2>::invalid_dof_index); }; + + mg_faces = new internal::DoFHandler::DoFFaces<2>; + mg_faces->lines.dofs = std::vector (this->tria->n_raw_lines() * + this->selected_fe->dofs_per_line, + DoFHandler<2>::invalid_dof_index); // now allocate space for the @@ -1895,19 +2278,18 @@ void MGDoFHandler<3>::reserve_space () { { mg_levels.push_back (new internal::DoFHandler::DoFLevel<3>); - mg_levels.back()->line_dofs - = std::vector (this->tria->n_raw_lines(i) * - this->selected_fe->dofs_per_line, - DoFHandler<3>::invalid_dof_index); - mg_levels.back()->quad_dofs - = std::vector (this->tria->n_raw_quads(i) * - this->selected_fe->dofs_per_quad, - DoFHandler<3>::invalid_dof_index); - mg_levels.back()->hex_dofs + mg_levels.back()->hexes.dofs = std::vector (this->tria->n_raw_hexs(i) * this->selected_fe->dofs_per_hex, DoFHandler<3>::invalid_dof_index); }; + mg_faces = new internal::DoFHandler::DoFFaces<3>; + mg_faces->lines.dofs = std::vector (this->tria->n_raw_lines() * + this->selected_fe->dofs_per_line, + DoFHandler<3>::invalid_dof_index); + mg_faces->quads.dofs = std::vector (this->tria->n_raw_quads() * + this->selected_fe->dofs_per_quad, + DoFHandler<3>::invalid_dof_index); // now allocate space for the @@ -1975,6 +2357,8 @@ void MGDoFHandler::clear_space () for (unsigned int i=0; i