From: Wolfgang Bangerth Date: Fri, 8 Jan 2010 18:37:59 +0000 (+0000) Subject: Move MGDoFHandler::distribute_dofs_on_cell into a class internal::MGDoFHandler::Imple... X-Git-Tag: v8.0.0~6655 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbb637aa62b7a43f688f26e4f1ed3464d55c6558;p=dealii.git Move MGDoFHandler::distribute_dofs_on_cell into a class internal::MGDoFHandler::Implementation in the same way this is done for ::DoFHandler. git-svn-id: https://svn.dealii.org/trunk@20337 0785d39b-7218-0410-832d-ea1e28bc413d --- 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 be3ed6c664..948ffc2d28 100644 --- a/deal.II/deal.II/include/multigrid/mg_dof_accessor.h +++ b/deal.II/deal.II/include/multigrid/mg_dof_accessor.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -24,6 +24,15 @@ template class MGDoFHandler; template class MGDoFAccessor; +namespace internal +{ + namespace MGDoFHandler + { + class Implementation; + } +} + + /*!@addtogroup mg */ /*@{*/ @@ -46,7 +55,7 @@ namespace internal * @author Wolfgang Bangerth, 1999 */ template - struct Inheritance + struct Inheritance { /** * Declaration of the @p typedef. @@ -123,7 +132,7 @@ namespace internal * since they are more secure to changes in the class naming and * template interface as well as providing easier typing (much less * complicated names!). - * + * * *

Inheritance

* @@ -151,7 +160,7 @@ class MGDoFAccessor : public internal::MGDoFAccessor::Inheritance::BaseClass BaseClass; @@ -167,7 +176,7 @@ class MGDoFAccessor : public internal::MGDoFAccessor::Inheritance Container; - + /** * @name Constructors */ @@ -221,7 +230,7 @@ class MGDoFAccessor : public internal::MGDoFAccessor::Inheritance - MGDoFAccessor (const MGDoFAccessor &); + MGDoFAccessor (const MGDoFAccessor &); /** * @} @@ -325,7 +334,7 @@ class MGDoFAccessor : public internal::MGDoFAccessor::Inheritance *mg_dof_handler; + MGDoFHandler *mg_dof_handler; /** * Reset the DoF handler pointer. @@ -374,6 +383,7 @@ class MGDoFAccessor : public internal::MGDoFAccessor::Inheritance friend class MGDoFHandler; + friend class internal::MGDoFHandler::Implementation; }; @@ -401,7 +411,7 @@ class MGDoFCellAccessor : public MGDoFAccessor { public: typedef MGDoFAccessor BaseClass; - + /** * Type of faces. */ @@ -414,7 +424,7 @@ class MGDoFCellAccessor : public MGDoFAccessor * iterator classes. */ typedef typename MGDoFAccessor::AccessorData AccessorData; - + /** * @name Constructors */ 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 9691220d56..164b271229 100644 --- a/deal.II/deal.II/include/multigrid/mg_dof_handler.h +++ b/deal.II/deal.II/include/multigrid/mg_dof_handler.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -37,7 +37,7 @@ DEAL_II_NAMESPACE_OPEN * This class has not yet been implemented for the use in the codimension * one case (spacedim != dim ). * -//TODO:[WB] Extend MGDoFHandler doc +//TODO:[WB] Extend MGDoFHandler doc * * @author Wolfgang Bangerth, 1998, 1999 */ @@ -83,7 +83,7 @@ class MGDoFHandler : public DoFHandler * Destructor */ virtual ~MGDoFHandler (); - + /** * Go through the triangulation * and distribute the degrees of @@ -132,9 +132,9 @@ class MGDoFHandler : public DoFHandler * name, see above. */ void renumber_dofs (const std::vector &new_numbers); - + /*--------------------------------------*/ - + /** * @name Cell iterator functions */ @@ -194,7 +194,7 @@ class MGDoFHandler : public DoFHandler * end(). */ cell_iterator end (const unsigned int level) const; - + /** * Return a raw iterator which is * the first iterator not on @@ -334,7 +334,7 @@ class MGDoFHandler : public DoFHandler * past-the-end or * before-the-beginning states. * - * This is the same as + * This is the same as * end_face(). */ raw_face_iterator end_raw_face () const; @@ -346,7 +346,7 @@ class MGDoFHandler : public DoFHandler * past-the-end or * before-the-beginning states. * - * This is the same as + * This is the same as * end_face(). */ active_face_iterator end_active_face () const; @@ -427,7 +427,7 @@ class MGDoFHandler : public DoFHandler * end(). */ line_iterator end_line (const unsigned int level) const; - + /** * Return a raw iterator which is * the first iterator not on @@ -485,7 +485,7 @@ class MGDoFHandler : public DoFHandler * @p level. */ active_line_iterator last_active_line (const unsigned int level) const; - /*@}*/ + /*@}*/ /*---------------------------------------*/ @@ -531,7 +531,7 @@ class MGDoFHandler : public DoFHandler * end(). */ quad_iterator end_quad (const unsigned int level) const; - + /** * Return a raw iterator which is * the first iterator not on @@ -635,7 +635,7 @@ class MGDoFHandler : public DoFHandler * end(). */ hex_iterator end_hex (const unsigned int level) const; - + /** * Return a raw iterator which is * the first iterator not on @@ -697,7 +697,7 @@ class MGDoFHandler : public DoFHandler /*---------------------------------------*/ - + /** * Return the number of degrees * of freedom on the specified @@ -716,7 +716,7 @@ class MGDoFHandler : public DoFHandler * name, see above. */ unsigned int n_dofs () const; - + /** * Determine an estimate for the * memory consumption (in bytes) @@ -751,7 +751,7 @@ class MGDoFHandler : public DoFHandler int, << "You tried to do something on level " << arg1 << ", but this level is empty."); - + private: /** @@ -782,7 +782,7 @@ class MGDoFHandler : public DoFHandler class MGVertexDoFs { public: - + /** * Constructor. This one is * empty because it is @@ -824,7 +824,7 @@ class MGDoFHandler : public DoFHandler * @p init is supposed to do. */ MGVertexDoFs & operator = (const MGVertexDoFs &vertex); - + /** * Set the index with number * @p dof_number of this @@ -846,7 +846,7 @@ class MGDoFHandler : public DoFHandler const unsigned int dof_number, const unsigned int dofs_per_vertex, const unsigned int index); - + /** * Return the index with * number @p dof_number of @@ -881,7 +881,7 @@ class MGDoFHandler : public DoFHandler * lives on. */ unsigned int get_finest_level () const; - + /** * Exception. */ @@ -893,7 +893,7 @@ class MGDoFHandler : public DoFHandler int, << "The given level number " << arg1 << " is outside " << "the range of levels this vertex lives on."); - + private: /** * Store the coarsest level @@ -921,29 +921,6 @@ class MGDoFHandler : public DoFHandler }; - /** - * Distribute dofs on the given - * cell, with new dofs starting - * with index - * @p next_free_dof. Return the - * next unused index number. The - * finite element used is the one - * given to @p distribute_dofs, - * which is copied to - * @p selected_fe. - * - * This function is excluded from - * the @p distribute_dofs - * function since it can not be - * implemented dimension - * independent. - * - * Note that unlike for the usual - * dofs, here all cells and not - * only active ones are allowed. - */ - 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. @@ -963,8 +940,8 @@ class MGDoFHandler : public DoFHandler const unsigned int fe_index, const unsigned int local_index, const unsigned int global_index) const; - - + + /** * Reserve enough space for the * MG dof indices for a given @@ -976,7 +953,7 @@ class MGDoFHandler : public DoFHandler * Free all used memory. */ void clear_space (); - + /** * Space to store the DoF numbers * for the different @@ -988,7 +965,7 @@ class MGDoFHandler : public DoFHandler * zero on each level. */ std::vector*> mg_levels; - + /** * Space to store the DoF numbers * for the faces. @@ -1003,7 +980,7 @@ class MGDoFHandler : public DoFHandler * and which are these levels. */ std::vector mg_vertex_dofs; - + /** * Vectors storing the number of * degrees of freedom on each @@ -1049,7 +1026,7 @@ void MGDoFHandler::MGVertexDoFs::set_index (const unsigned int le ExcInvalidLevel(level)); Assert (dof_number < dofs_per_vertex, ExcIndexRange(dof_number, 0, dofs_per_vertex)); - + indices[(level-coarsest_level)*dofs_per_vertex + dof_number] = index; } @@ -1064,7 +1041,7 @@ MGDoFHandler::MGVertexDoFs::get_index (const unsigned int level, ExcInvalidLevel(level)); Assert (dof_number < dofs_per_vertex, ExcIndexRange (dof_number, 0, dofs_per_vertex)); - + return indices[(level-coarsest_level)*dofs_per_vertex + dof_number]; } 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 7180299e2f..3bd542f484 100644 --- a/deal.II/deal.II/source/multigrid/mg_dof_handler.cc +++ b/deal.II/deal.II/source/multigrid/mg_dof_handler.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -35,6 +35,208 @@ DEAL_II_NAMESPACE_OPEN //make the general case happen it should undergo a similar transformation as //the ::DoFHandler class, i.e. much of the functions here that are dimension //dependent should be moved into a local Implementation class. +// Some of the following already goes in the right direction +namespace internal +{ + namespace MGDoFHandler + { + // access class + // dealii::MGDoFHandler instead + // of namespace + // internal::MGDoFHandler. same + // for dealii::DoFHandler + using dealii::MGDoFHandler; + using dealii::DoFHandler; + +/** + * A class with the same purpose as the similarly named class of the + * Triangulation class. See there for more information. + */ + struct Implementation + { + + /** + * Distribute dofs on the given + * cell, with new dofs starting + * with index + * @p next_free_dof. Return the + * next unused index number. + * + * This function is excluded from + * the @p distribute_dofs + * function since it can not be + * implemented dimension + * independent. + * + * Note that unlike for the usual + * dofs, here all cells and not + * only active ones are allowed. + */ + template + static + unsigned int + distribute_dofs_on_cell (typename MGDoFHandler<1,spacedim>::cell_iterator &cell, + unsigned int next_free_dof) + { + const unsigned int dim = 1; + + // distribute dofs of vertices + if (cell->get_fe().dofs_per_vertex > 0) + for (unsigned int v=0; v::vertices_per_cell; ++v) + { + typename MGDoFHandler::cell_iterator neighbor = cell->neighbor(v); + + if (neighbor.state() == IteratorState::valid) + { + // has neighbor already been processed? + if (neighbor->user_flag_set() && + (neighbor->level() == cell->level())) + // copy dofs if the neighbor is on + // the same level (only then are + // mg dofs the same) + { + if (v==0) + for (unsigned int d=0; dget_fe().dofs_per_vertex; ++d) + cell->set_mg_vertex_dof_index (cell->level(), 0, d, + neighbor->mg_vertex_dof_index (cell->level(), 1, d)); + else + for (unsigned int d=0; dget_fe().dofs_per_vertex; ++d) + cell->set_mg_vertex_dof_index (cell->level(), 1, d, + neighbor->mg_vertex_dof_index (cell->level(), 0, d)); + + // next neighbor + continue; + }; + }; + + // otherwise: create dofs newly + for (unsigned int d=0; dget_fe().dofs_per_vertex; ++d) + cell->set_mg_vertex_dof_index (cell->level(), v, d, next_free_dof++); + }; + + // dofs of line + if (cell->get_fe().dofs_per_line > 0) + for (unsigned int d=0; dget_fe().dofs_per_line; ++d) + cell->set_mg_dof_index (cell->level(), d, next_free_dof++); + + // note that this cell has been processed + cell->set_user_flag (); + + return next_free_dof; + } + + + template + static + unsigned int + distribute_dofs_on_cell (typename MGDoFHandler<2,spacedim>::cell_iterator &cell, + unsigned int next_free_dof) + { + const unsigned int dim = 2; + if (cell->get_fe().dofs_per_vertex > 0) + // number dofs on vertices + for (unsigned int vertex=0; vertex::vertices_per_cell; ++vertex) + // check whether dofs for this + // vertex have been distributed + // (only check the first dof) + if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) == DoFHandler<2>::invalid_dof_index) + for (unsigned int d=0; dget_fe().dofs_per_vertex; ++d) + cell->set_mg_vertex_dof_index (cell->level(), vertex, d, next_free_dof++); + + // for the four sides + if (cell->get_fe().dofs_per_line > 0) + for (unsigned int side=0; side::faces_per_cell; ++side) + { + typename MGDoFHandler::line_iterator line = cell->line(side); + + // distribute dofs if necessary: + // check whether line dof is already + // numbered (check only first dof) + if (line->mg_dof_index(cell->level(), 0) == DoFHandler<2>::invalid_dof_index) + // if not: distribute dofs + for (unsigned int d=0; dget_fe().dofs_per_line; ++d) + line->set_mg_dof_index (cell->level(), d, next_free_dof++); + }; + + + // dofs of quad + if (cell->get_fe().dofs_per_quad > 0) + for (unsigned int d=0; dget_fe().dofs_per_quad; ++d) + cell->set_mg_dof_index (cell->level(), d, next_free_dof++); + + + // note that this cell has been processed + cell->set_user_flag (); + + return next_free_dof; + } + + + template + static + unsigned int + distribute_dofs_on_cell (typename MGDoFHandler<3,spacedim>::cell_iterator &cell, + unsigned int next_free_dof) + { + const unsigned int dim = 3; + if (cell->get_fe().dofs_per_vertex > 0) + // number dofs on vertices + for (unsigned int vertex=0; vertex::vertices_per_cell; ++vertex) + // check whether dofs for this + // vertex have been distributed + // (only check the first dof) + if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) == DoFHandler<3>::invalid_dof_index) + for (unsigned int d=0; dget_fe().dofs_per_vertex; ++d) + cell->set_mg_vertex_dof_index (cell->level(), vertex, d, next_free_dof++); + + // for the lines + if (cell->get_fe().dofs_per_line > 0) + for (unsigned int l=0; l::lines_per_cell; ++l) + { + typename MGDoFHandler::line_iterator line = cell->line(l); + + // distribute dofs if necessary: + // check whether line dof is already + // numbered (check only first dof) + if (line->mg_dof_index(cell->level(), 0) == DoFHandler<3>::invalid_dof_index) + // if not: distribute dofs + for (unsigned int d=0; dget_fe().dofs_per_line; ++d) + line->set_mg_dof_index (cell->level(), d, next_free_dof++); + }; + + // for the quads + if (cell->get_fe().dofs_per_quad > 0) + for (unsigned int q=0; q::quads_per_cell; ++q) + { + typename MGDoFHandler::quad_iterator quad = cell->quad(q); + + // distribute dofs if necessary: + // check whether line dof is already + // numbered (check only first dof) + if (quad->mg_dof_index(cell->level(), 0) == DoFHandler<3>::invalid_dof_index) + // if not: distribute dofs + for (unsigned int d=0; dget_fe().dofs_per_quad; ++d) + quad->set_mg_dof_index (cell->level(), d, next_free_dof++); + }; + + + // dofs of cell + if (cell->get_fe().dofs_per_hex > 0) + for (unsigned int d=0; dget_fe().dofs_per_hex; ++d) + cell->set_mg_dof_index (cell->level(), d, next_free_dof++); + + + // note that this cell has + // been processed + cell->set_user_flag (); + + return next_free_dof; + } + }; + } +} + + /* ------------------------ MGVertexDoFs ----------------------------------- */ @@ -68,9 +270,9 @@ void MGDoFHandler::MGVertexDoFs::init (const unsigned int cl, // everything else alone if (cl > fl) return; - + const unsigned int n_levels = finest_level-coarsest_level + 1; - + indices = new unsigned int[n_levels * dofs_per_vertex]; Assert (indices != 0, ExcNoMemory ()); @@ -137,9 +339,9 @@ MGDoFHandler::memory_consumption() const unsigned int mem = DoFHandler::memory_consumption(); for (unsigned int l=0;lmemory_consumption(); - + mem += MemoryConsumption::memory_consumption(*mg_faces); - + for (unsigned int l=0;l::begin_raw_quad (const unsigned int level) const if (this->tria->n_raw_quads(level) == 0) return end_quad(); - + return raw_quad_iterator (this->tria, level, 0, @@ -792,11 +994,11 @@ MGDoFHandler::begin_raw_quad (const unsigned int level) const 0, this); } - - + + default: Assert (false, ExcNotImplemented()); - return raw_hex_iterator(); + return raw_hex_iterator(); } } @@ -859,7 +1061,7 @@ MGDoFHandler::end_quad (const unsigned int level) const quad_iterator(end_quad()) : begin_quad (level+1)); else - return quad_iterator(end_quad()); + return quad_iterator(end_quad()); } @@ -917,7 +1119,7 @@ MGDoFHandler::last_raw_quad (const unsigned int level) const default: Assert (false, ExcNotImplemented()); return raw_quad_iterator(); - } + } } @@ -1008,16 +1210,16 @@ MGDoFHandler::begin_raw_hex (const unsigned int level) const if (this->tria->n_raw_hexs(level) == 0) return end_hex(); - + return raw_hex_iterator (this->tria, level, 0, this); } - + default: Assert (false, ExcNotImplemented()); - return raw_hex_iterator(); + return raw_hex_iterator(); } } @@ -1160,7 +1362,7 @@ MGDoFHandler::last_hex () const } - + template typename MGDoFHandler::active_hex_iterator MGDoFHandler::last_active_hex (const unsigned int level) const @@ -1190,7 +1392,7 @@ MGDoFHandler::last_active_hex () const //--------------------------------------------------------------------------- -#if deal_II_dimension == 1 +#if deal_II_dimension == 1 template <> template <> unsigned int @@ -1222,7 +1424,7 @@ MGDoFHandler<1>::set_dof_index<1> (const unsigned int obj_level, fe_index, local_index, global_index); - + } #endif @@ -1258,7 +1460,7 @@ MGDoFHandler<2>::set_dof_index<1> (const unsigned int , fe_index, local_index, global_index); - + } @@ -1293,7 +1495,7 @@ MGDoFHandler<2>::set_dof_index<2> (const unsigned int obj_level, fe_index, local_index, global_index); - + } #endif @@ -1329,7 +1531,7 @@ MGDoFHandler<3>::set_dof_index<1> (const unsigned int , fe_index, local_index, global_index); - + } @@ -1380,7 +1582,7 @@ MGDoFHandler<3>::set_dof_index<2> (const unsigned int , fe_index, local_index, global_index); - + } @@ -1399,7 +1601,7 @@ MGDoFHandler<3>::set_dof_index<3> (const unsigned int obj_level, fe_index, local_index, global_index); - + } #endif @@ -1436,182 +1638,17 @@ void MGDoFHandler::distribute_dofs (const FiniteElement &>(*(this->tria)).load_user_flags(user_flags); -} - - -#if deal_II_dimension == 1 - -template <> -unsigned int -MGDoFHandler<1>::distribute_dofs_on_cell (cell_iterator &cell, - unsigned int next_free_dof) -{ - - // distribute dofs of vertices - if (this->selected_fe->dofs_per_vertex > 0) - for (unsigned int v=0; v::vertices_per_cell; ++v) - { - cell_iterator neighbor = cell->neighbor(v); - - if (neighbor.state() == IteratorState::valid) - { - // has neighbor already been processed? - if (neighbor->user_flag_set() && - (neighbor->level() == cell->level())) - // copy dofs if the neighbor is on - // the same level (only then are - // mg dofs the same) - { - if (v==0) - for (unsigned int d=0; dselected_fe->dofs_per_vertex; ++d) - cell->set_mg_vertex_dof_index (cell->level(), 0, d, - neighbor->mg_vertex_dof_index (cell->level(), 1, d)); - else - for (unsigned int d=0; dselected_fe->dofs_per_vertex; ++d) - cell->set_mg_vertex_dof_index (cell->level(), 1, d, - neighbor->mg_vertex_dof_index (cell->level(), 0, d)); - - // next neighbor - continue; - }; - }; - - // otherwise: create dofs newly - for (unsigned int d=0; dselected_fe->dofs_per_vertex; ++d) - cell->set_mg_vertex_dof_index (cell->level(), v, d, next_free_dof++); - }; - - // dofs of line - if (this->selected_fe->dofs_per_line > 0) - for (unsigned int d=0; dselected_fe->dofs_per_line; ++d) - cell->set_mg_dof_index (cell->level(), d, next_free_dof++); - - // note that this cell has been processed - cell->set_user_flag (); - - return next_free_dof; -} - -#endif - - -#if deal_II_dimension == 2 - -template <> -unsigned int -MGDoFHandler<2>::distribute_dofs_on_cell (cell_iterator &cell, - unsigned int next_free_dof) { - if (this->selected_fe->dofs_per_vertex > 0) - // number dofs on vertices - for (unsigned int vertex=0; vertex::vertices_per_cell; ++vertex) - // check whether dofs for this - // vertex have been distributed - // (only check the first dof) - if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) == DoFHandler<2>::invalid_dof_index) - for (unsigned int d=0; dselected_fe->dofs_per_vertex; ++d) - cell->set_mg_vertex_dof_index (cell->level(), vertex, d, next_free_dof++); - - // for the four sides - if (this->selected_fe->dofs_per_line > 0) - for (unsigned int side=0; side::faces_per_cell; ++side) - { - line_iterator line = cell->line(side); - - // distribute dofs if necessary: - // check whether line dof is already - // numbered (check only first dof) - if (line->mg_dof_index(cell->level(), 0) == DoFHandler<2>::invalid_dof_index) - // if not: distribute dofs - for (unsigned int d=0; dselected_fe->dofs_per_line; ++d) - line->set_mg_dof_index (cell->level(), d, next_free_dof++); - }; - - - // dofs of quad - if (this->selected_fe->dofs_per_quad > 0) - for (unsigned int d=0; dselected_fe->dofs_per_quad; ++d) - cell->set_mg_dof_index (cell->level(), d, next_free_dof++); - - - // note that this cell has been processed - cell->set_user_flag (); - - return next_free_dof; -} - -#endif - - -#if deal_II_dimension == 3 - -template <> -unsigned int -MGDoFHandler<3>::distribute_dofs_on_cell (cell_iterator &cell, - unsigned int next_free_dof) { - if (this->selected_fe->dofs_per_vertex > 0) - // number dofs on vertices - for (unsigned int vertex=0; vertex::vertices_per_cell; ++vertex) - // check whether dofs for this - // vertex have been distributed - // (only check the first dof) - if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) == DoFHandler<3>::invalid_dof_index) - for (unsigned int d=0; dselected_fe->dofs_per_vertex; ++d) - cell->set_mg_vertex_dof_index (cell->level(), vertex, d, next_free_dof++); - - // for the lines - if (this->selected_fe->dofs_per_line > 0) - for (unsigned int l=0; l::lines_per_cell; ++l) - { - line_iterator line = cell->line(l); - - // distribute dofs if necessary: - // check whether line dof is already - // numbered (check only first dof) - if (line->mg_dof_index(cell->level(), 0) == DoFHandler<3>::invalid_dof_index) - // if not: distribute dofs - for (unsigned int d=0; dselected_fe->dofs_per_line; ++d) - line->set_mg_dof_index (cell->level(), d, next_free_dof++); - }; - - // for the quads - if (this->selected_fe->dofs_per_quad > 0) - for (unsigned int q=0; q::quads_per_cell; ++q) - { - quad_iterator quad = cell->quad(q); - - // distribute dofs if necessary: - // check whether line dof is already - // numbered (check only first dof) - if (quad->mg_dof_index(cell->level(), 0) == DoFHandler<3>::invalid_dof_index) - // if not: distribute dofs - for (unsigned int d=0; dselected_fe->dofs_per_quad; ++d) - quad->set_mg_dof_index (cell->level(), d, next_free_dof++); - }; - - - // dofs of cell - if (this->selected_fe->dofs_per_hex > 0) - for (unsigned int d=0; dselected_fe->dofs_per_hex; ++d) - cell->set_mg_dof_index (cell->level(), d, next_free_dof++); + for (; cell != endc; ++cell) + next_free_dof = internal::MGDoFHandler::Implementation::distribute_dofs_on_cell (cell, next_free_dof); + mg_used_dofs[level] = next_free_dof; + } - // note that this cell has been processed - cell->set_user_flag (); - - return next_free_dof; + // finally restore the user flags + const_cast &>(*(this->tria)) + .load_user_flags(user_flags); } -#endif - - template void MGDoFHandler::clear () @@ -1621,14 +1658,14 @@ MGDoFHandler::clear () // let base class release its mem // as well - DoFHandler::clear (); + DoFHandler::clear (); } template unsigned int MGDoFHandler::n_dofs (const unsigned int level) const { Assert (level < mg_used_dofs.size(), ExcInvalidLevel(level)); - + return mg_used_dofs[level]; } @@ -1639,7 +1676,7 @@ template <> void MGDoFHandler<1>::renumber_dofs (const unsigned int level, const std::vector &new_numbers) { Assert (new_numbers.size() == n_dofs(level), DoFHandler<1>::ExcRenumberingIncomplete()); - + // note that we can not use cell iterators // in this function since then we would // renumber the dofs on the interface of @@ -1658,7 +1695,7 @@ void MGDoFHandler<1>::renumber_dofs (const unsigned int level, this->selected_fe->dofs_per_vertex)]); for (std::vector::iterator i=mg_levels[level]->lines.dofs.begin(); - i!=mg_levels[level]->lines.dofs.end(); ++i) + i!=mg_levels[level]->lines.dofs.end(); ++i) { if (*i != DoFHandler<1>::invalid_dof_index) { @@ -1676,9 +1713,9 @@ void MGDoFHandler<1>::renumber_dofs (const unsigned int level, template <> void MGDoFHandler<2>::renumber_dofs (const unsigned int level, const std::vector &new_numbers) { - Assert (new_numbers.size() == n_dofs(level), + Assert (new_numbers.size() == n_dofs(level), DoFHandler<2>::ExcRenumberingIncomplete()); - + for (std::vector::iterator i=mg_vertex_dofs.begin(); i!=mg_vertex_dofs.end(); ++i) // if the present vertex lives on @@ -1696,7 +1733,7 @@ void MGDoFHandler<2>::renumber_dofs (const unsigned int level, std::vector 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 @@ -1706,10 +1743,10 @@ void MGDoFHandler<2>::renumber_dofs (const unsigned int 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()) { @@ -1742,7 +1779,7 @@ void MGDoFHandler<3>::renumber_dofs (const unsigned int level, const std::vector &new_numbers) { Assert (new_numbers.size() == n_dofs(level), DoFHandler<3>::ExcRenumberingIncomplete()); - + for (std::vector::iterator i=mg_vertex_dofs.begin(); i!=mg_vertex_dofs.end(); ++i) // if the present vertex lives on @@ -1761,22 +1798,22 @@ void MGDoFHandler<3>::renumber_dofs (const unsigned int level, std::vector 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()) { @@ -1795,7 +1832,7 @@ void MGDoFHandler<3>::renumber_dofs (const unsigned int level, std::vector 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 @@ -1805,10 +1842,10 @@ void MGDoFHandler<3>::renumber_dofs (const unsigned int 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()) { @@ -1841,7 +1878,7 @@ template <> void MGDoFHandler<1>::reserve_space () { const unsigned int dim = 1; const unsigned int spacedim = 1; - + Assert (this->selected_fe != 0, DoFHandler::ExcNoFESelected()); Assert (this->tria->n_levels() > 0, DoFHandler::ExcInvalidTriangulation()); @@ -1851,10 +1888,10 @@ void MGDoFHandler<1>::reserve_space () { //////////////////////////// // CONSTRUCTION - + // first allocate space for the // lines on each level - for (unsigned int i=0; itria->n_levels(); ++i) + for (unsigned int i=0; itria->n_levels(); ++i) { mg_levels.push_back (new internal::DoFHandler::DoFLevel<1>); @@ -1899,7 +1936,7 @@ void MGDoFHandler<1>::reserve_space () { { Assert (min_level[vertex] < this->tria->n_levels(), ExcInternalError()); Assert (max_level[vertex] >= min_level[vertex], ExcInternalError()); - + mg_vertex_dofs[vertex].init (min_level[vertex], max_level[vertex], this->get_fe().dofs_per_vertex); @@ -1908,7 +1945,7 @@ void MGDoFHandler<1>::reserve_space () { { Assert (min_level[vertex] == this->tria->n_levels(), ExcInternalError()); Assert (max_level[vertex] == 0, ExcInternalError()); - + // reset to original state mg_vertex_dofs[vertex].init (1, 0, 0); } @@ -1923,20 +1960,20 @@ template <> void MGDoFHandler<2>::reserve_space () { const unsigned int dim = 2; const unsigned int spacedim = 2; - + Assert (this->selected_fe != 0, DoFHandler::ExcNoFESelected()); Assert (this->tria->n_levels() > 0, DoFHandler<2>::ExcInvalidTriangulation()); - + //////////////////////////// // DESTRUCTION clear_space (); //////////////////////////// // CONSTRUCTION - + // first allocate space for the // lines and quads on each level - for (unsigned int i=0; itria->n_levels(); ++i) + for (unsigned int i=0; itria->n_levels(); ++i) { mg_levels.push_back (new internal::DoFHandler::DoFLevel<2>); @@ -1944,7 +1981,7 @@ void MGDoFHandler<2>::reserve_space () { 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, @@ -2016,20 +2053,20 @@ void MGDoFHandler<3>::reserve_space () { const unsigned int dim = 3; const unsigned int spacedim = 3; - + Assert (this->selected_fe != 0, DoFHandler<3>::ExcNoFESelected()); Assert (this->tria->n_levels() > 0, DoFHandler<3>::ExcInvalidTriangulation()); - + //////////////////////////// // DESTRUCTION clear_space (); //////////////////////////// // CONSTRUCTION - + // first allocate space for the // lines and quads on each level - for (unsigned int i=0; itria->n_levels(); ++i) + for (unsigned int i=0; itria->n_levels(); ++i) { mg_levels.push_back (new internal::DoFHandler::DoFLevel<3>); @@ -2084,7 +2121,7 @@ void MGDoFHandler<3>::reserve_space () { { Assert (min_level[vertex] < this->tria->n_levels(), ExcInternalError()); Assert (max_level[vertex] >= min_level[vertex], ExcInternalError()); - + mg_vertex_dofs[vertex].init (min_level[vertex], max_level[vertex], this->get_fe().dofs_per_vertex); @@ -2093,7 +2130,7 @@ void MGDoFHandler<3>::reserve_space () { { Assert (min_level[vertex] == this->tria->n_levels(), ExcInternalError()); Assert (max_level[vertex] == 0, ExcInternalError()); - + // reset to original state mg_vertex_dofs[vertex].init (1, 0, 0); }