]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Merge branch_faces_without_level to main branch.
authorhartmann <hartmann@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 13 Jun 2006 12:15:41 +0000 (12:15 +0000)
committerhartmann <hartmann@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 13 Jun 2006 12:15:41 +0000 (12:15 +0000)
git-svn-id: https://svn.dealii.org/trunk@13221 0785d39b-7218-0410-832d-ea1e28bc413d

37 files changed:
deal.II/deal.II/include/dofs/dof_accessor.templates.h
deal.II/deal.II/include/dofs/dof_faces.h [new file with mode: 0644]
deal.II/deal.II/include/dofs/dof_handler.h
deal.II/deal.II/include/dofs/dof_levels.h
deal.II/deal.II/include/dofs/dof_objects.h [new file with mode: 0644]
deal.II/deal.II/include/dofs/hp_dof_faces.h [new file with mode: 0644]
deal.II/deal.II/include/dofs/hp_dof_handler.h
deal.II/deal.II/include/dofs/hp_dof_levels.h
deal.II/deal.II/include/dofs/hp_dof_objects.h [new file with mode: 0644]
deal.II/deal.II/include/grid/tria.h
deal.II/deal.II/include/grid/tria_accessor.h
deal.II/deal.II/include/grid/tria_accessor.templates.h
deal.II/deal.II/include/grid/tria_faces.h [new file with mode: 0644]
deal.II/deal.II/include/grid/tria_iterator.h
deal.II/deal.II/include/grid/tria_iterator.templates.h
deal.II/deal.II/include/grid/tria_levels.h
deal.II/deal.II/include/grid/tria_objects.h [new file with mode: 0644]
deal.II/deal.II/include/multigrid/mg_dof_accessor.h
deal.II/deal.II/include/multigrid/mg_dof_handler.h
deal.II/deal.II/source/dofs/dof_accessor.cc
deal.II/deal.II/source/dofs/dof_faces.cc [new file with mode: 0644]
deal.II/deal.II/source/dofs/dof_handler.cc
deal.II/deal.II/source/dofs/dof_levels.all_dimensions.cc
deal.II/deal.II/source/dofs/dof_levels.cc
deal.II/deal.II/source/dofs/dof_objects.cc [new file with mode: 0644]
deal.II/deal.II/source/dofs/hp_dof_faces.cc [new file with mode: 0644]
deal.II/deal.II/source/dofs/hp_dof_handler.cc
deal.II/deal.II/source/dofs/hp_dof_levels.all_dimensions.cc
deal.II/deal.II/source/dofs/hp_dof_levels.cc
deal.II/deal.II/source/dofs/hp_dof_objects.cc [new file with mode: 0644]
deal.II/deal.II/source/grid/tria.all_dimensions.cc
deal.II/deal.II/source/grid/tria.cc
deal.II/deal.II/source/grid/tria_accessor.cc
deal.II/deal.II/source/grid/tria_faces.cc [new file with mode: 0644]
deal.II/deal.II/source/grid/tria_objects.cc [new file with mode: 0644]
deal.II/deal.II/source/multigrid/mg_dof_accessor.cc
deal.II/deal.II/source/multigrid/mg_dof_handler.cc

index 6086d32c87105eccbaa689c5f4f0b07f1de76a27..8cea838d5e12c542ee11359b9b60b8c9b8f3507a 100644 (file)
@@ -129,8 +129,14 @@ DoFAccessor<structdim,DH>::child (const unsigned int i) const
   Assert (static_cast<unsigned int>(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<DH::dimension,DoFObjectAccessor<structdim,DH> > q (this->tria,
-                                                                 this->present_level+1,
+                                                                 next_level,
                                                                  this->child_index (i),
                                                                  this->dof_handler);
 
@@ -183,18 +189,12 @@ unsigned int
 DoFAccessor<dim,DH>::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<dim>());
+                                  // access the respective DoF 
+  return this->dof_handler
+    ->template get_dof_index<dim> (this->present_level,
+                                  this->present_index,
+                                  fe_index,
+                                  i);
 }
 
 
@@ -206,19 +206,13 @@ DoFAccessor<dim,DH>::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<dim>());
+                                  // access the respective DoF
+  this->dof_handler
+    ->template set_dof_index<dim> (this->present_level,
+                                  this->present_index,
+                                  fe_index,
+                                  i,
+                                  index);
 }
 
 
@@ -228,16 +222,10 @@ inline
 unsigned int
 DoFAccessor<dim,DH>::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<DH::dimension> (*this->dof_handler,
-                                                   this->present_index,
-                                                   internal::StructuralDimension<dim>());
+                                  // access the respective DoF
+  return this->dof_handler
+    ->template n_active_fe_indices<dim> (this->present_level,
+                                        this->present_index);
 }
 
 
@@ -247,17 +235,11 @@ inline
 bool
 DoFAccessor<dim,DH>::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<DH::dimension> (*this->dof_handler,
-                                                  this->present_index,
-                                                  fe_index,
-                                                  internal::StructuralDimension<dim>());
+                                  // access the respective DoF
+  return this->dof_handler
+    ->template fe_index_is_active<dim> (this->present_level,
+                                       this->present_index,
+                                       fe_index);
 }
 
 
@@ -347,7 +329,7 @@ DoFObjectAccessor<2,DH>::line (const unsigned int i) const
   return TriaIterator<dim,DoFObjectAccessor<1,DH> >
     (
       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<dim,DoFObjectAccessor<1,DH> >
     (
       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<dim,DoFObjectAccessor<2,DH> >
     (
       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 (file)
index 0000000..d1e0a40
--- /dev/null
@@ -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 <base/config.h>
+#include <base/exceptions.h>
+#include <dofs/dof_objects.h>
+#include <vector>
+
+
+template <int> class DoFHandler;
+template <int> class MGDoFHandler;
+  
+namespace internal
+{
+/**
+ * A namespace for internal data structures of the DoFHandler group of classes.
+ *
+ * @ingroup dofs
+ */
+  namespace DoFHandler
+  {
+
+/**    
+ *
+ * <h4>DoFFaces</h4>
+ *
+ * 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<int dim>
+    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 <int> friend class ::DoFHandler;       
+       template <int> 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 <int> friend class ::DoFHandler;       
+       template <int> friend class ::MGDoFHandler;
+    };
+
+  }
+}
+#endif
index 8bed1d2e59ba3ebc67aeaaabc25aa50c3a0e5502..79d2363c7bc8f38104138b6ef8cbbafd192d0a48 100644 (file)
@@ -30,6 +30,7 @@ namespace internal
   namespace DoFHandler
   {
     template <int dim> class DoFLevel;
+    template <int dim> 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
-                                     * <tt>end()</tt>.
-                                     */
-    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
                                      * <tt>end()</tt>.
                                      */
-    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
                                      * <tt>end()</tt>.
                                      */
-    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 <int structdim>
+    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 <int structdim>
+    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 <int structdim>
+    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 <int structdim>
+    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<internal::DoFHandler::DoFLevel<dim>*>    levels;
 
+    internal::DoFHandler::DoFFaces<dim> * 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,
index 0001f692a3e31c6c431e89b2425aa31bf18fb3e6..37388b31417c340b6feea840791b75c50ca48bfe 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <base/config.h>
 #include <base/exceptions.h>
+#include <dofs/dof_objects.h>
 #include <vector>
 
 template <int> class DoFHandler;
@@ -24,17 +25,6 @@ template <int> 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 <int structdim>
-  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.
- *
- * <h3>Information for all DoFLevel classes</h3>
- *
- * The <tt>DoFLevel<N></tt> 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<dim>
- * 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
- * <tt>N*i...(N+1)*i-1</tt>. 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.
- *
+
+/**    
  *
  * <h4>DoFLevel@<0@></h4>
  *
@@ -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 <tt>DoFFaces</tt> classes.
+ *
  *
  * <h4>DoFLevel@<1@>, DoFLevel@<2@>, and DoFLevel@<3@> </h4>
  *
  * 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 <tt>DoFObjects</tt>.
+ * 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<dim> 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<dim> 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<structdim,spacedim>::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<unsigned int> 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 <int dim, int structdim>
-        unsigned int
-        n_active_fe_indices (const ::DoFHandler<dim> &dof_handler,
-                             const unsigned int       index,
-                             const StructuralDimension<structdim>) 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 <int dim, int structdim>
-        bool
-        fe_index_is_active (const ::DoFHandler<dim> &dof_handler,
-                            const unsigned int       index,
-                            const unsigned int       fe_index,
-                            const StructuralDimension<structdim>) 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<unsigned int> 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 <int dim>
-        void
-        set_dof_index (const ::DoFHandler<dim> &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 <int dim>
-        unsigned int
-        get_dof_index (const ::DoFHandler<dim> &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<unsigned int> 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 <int dim>
-        void
-        set_dof_index (const ::DoFHandler<dim> &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 <int dim>
-        unsigned int
-        get_dof_index (const ::DoFHandler<dim> &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<unsigned int> 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 <int dim>
-        void
-        set_dof_index (const ::DoFHandler<dim> &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 <int dim>
-        unsigned int
-        get_dof_index (const ::DoFHandler<dim> &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 <int> friend class ::MGDoFHandler;
     };
 
-
-// ----------- inline functions ---------------------
-
-    template <int dim, int structdim>
-    inline
-    unsigned int
-    DoFLevel<0>::n_active_fe_indices (const ::DoFHandler<dim> &,
-                                      const unsigned int,
-                                      const StructuralDimension<structdim>) const
-    {
-      return 1;
-    }
-
-
-    template <int dim, int structdim>
-    inline
-    bool
-    DoFLevel<0>::fe_index_is_active (const ::DoFHandler<dim> &,
-                                     const unsigned int,
-                                     const unsigned int fe_index,
-                                     const StructuralDimension<structdim>) 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 (file)
index 0000000..c4550c2
--- /dev/null
@@ -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 <base/config.h>
+#include <base/exceptions.h>
+#include <vector>
+
+template <int> class DoFHandler;
+
+namespace internal
+{
+/**
+ * A namespace for internal data structures of the DoFHandler group of classes.
+ *
+ * @ingroup dofs
+ */
+  namespace DoFHandler
+  {
+    template <int> class DoFLevel;
+    template <int> class DoFFaces;
+    
+
+/**
+ * Store the indices of the degrees of freedom which are located on
+ * objects of dimension @p dim. 
+ *
+ * <h3>Information for all DoFObjects classes</h3>
+ *
+ * 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 <int dim>
+    class DoFObjects{
+      public:
+                                         /**
+                                          * Store the global indices of
+                                          * the degrees of freedom.
+                                          */
+        std::vector<unsigned int> 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 <int spacedim>
+        void
+        set_dof_index (const ::DoFHandler<spacedim> &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<int spacedim>
+       unsigned int
+        get_dof_index (const ::DoFHandler<spacedim> &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 <int spacedim>
+        unsigned int
+        n_active_fe_indices (const ::DoFHandler<spacedim> &dof_handler,
+                             const unsigned int       index) const;
+
+                                         /**
+                                          * Similar to the function
+                                          * above. Assert that the
+                                          * given index is zero, and
+                                          * the return true.
+                                          */
+        template <int spacedim>
+        bool
+        fe_index_is_active (const ::DoFHandler<spacedim> &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 <int> friend class DoFLevel;
+       template <int> 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 (file)
index 0000000..1d3de9b
--- /dev/null
@@ -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 <base/config.h>
+#include <dofs/dof_levels.h>
+#include <dofs/hp_dof_objects.h>
+#include <fe/fe_collection.h>
+
+#include <vector>
+
+
+namespace hp
+{
+  template <int dim>
+  class FECollection;
+}
+
+
+namespace internal
+{
+  namespace hp
+  {
+
+/**    
+ *
+ * <h4>DoFFaces</h4>
+ *
+ * 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<int dim>
+    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 <int> 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 <int> 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 <int> friend class ::hp::DoFHandler;   
+    };
+    
+  } // namespace hp
+  
+} // namespace internal
+
+#endif
index 170c3b4d496813ae9b0e1e3a166661d0e4c6b89d..fe1c7afc12cdb97f6f1dde1303391cd17611bb51 100644 (file)
@@ -32,10 +32,8 @@ namespace internal
   namespace hp
   {
     template <int> class DoFLevel;
-    template <> class DoFLevel<0>;
-    template <> class DoFLevel<1>;
-    template <> class DoFLevel<2>;
-    template <> class DoFLevel<3>;
+    template <int> class DoFFaces;
+    template <int> 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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return an iterator which is the first
+                                       * iterator not on level. If @p level is
+                                       * the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return a raw iterator which is the first
+                                       * iterator not on level. If @p level is
+                                       * the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return an active iterator which is the
+                                       * first iterator not on level. If @p level
+                                       * is the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
-      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
-                                        * <tt>end()</tt>.
-                                        */
-      raw_face_iterator    end_raw_face (const unsigned int level) const;
+                                      /**
+                                       * Return a raw iterator past-the-end.
+                                       * This is the same as <tt>end_face()</tt>.
+                                       */
+      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
-                                        * <tt>end()</tt>.
-                                        */
-      active_face_iterator end_active_face (const unsigned int level) const;
+                                      /**
+                                       * Return an active iterator past-the-end.
+                                       * This is the same as <tt>end_face()</tt>.
+                                       */
+      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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return an iterator which is the first
+                                       * iterator not on level. If @p level is
+                                       * the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return a raw iterator which is the first
+                                       * iterator not on level. If @p level is
+                                       * the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return an active iterator which is the
+                                       * first iterator not on level. If @p level
+                                       * is the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return an iterator which is the first
+                                       * iterator not on level. If @p level is
+                                       * the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return a raw iterator which is the first
+                                       * iterator not on level. If @p level is
+                                       * the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return an active iterator which is the
+                                       * first iterator not on level. If @p level
+                                       * is the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return an iterator which is the first
+                                       * iterator not on level. If @p level is
+                                       * the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return a raw iterator which is the first
+                                       * iterator not on level. If @p level is
+                                       * the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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
-                                        * <tt>end()</tt>.
-                                        */
+                                      /**
+                                       * Return an active iterator which is the
+                                       * first iterator not on level. If @p level
+                                       * is the last level, then this returns
+                                       * <tt>end()</tt>.
+                                       */
       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 <int structdim>
+      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 <int structdim>
+      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 <int structdim>
+      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 <int structdim>
+      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<internal::hp::DoFLevel<dim>*>    levels;
+                                       /**
+                                        * Space to store the DoF
+                                        * numbers for the faces.
+                                        * Analogous to the
+                                        * <tt>faces</tt> pointer of
+                                        * the Triangulation objects.
+                                        */
+      internal::hp::DoFFaces<dim> * faces;
+      
 
                                        /**
                                         * Store the number of dofs
@@ -1157,13 +1156,15 @@ namespace hp
       template <class DH> 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 <int> friend class internal::hp::DoFLevel;
+      template <int> 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,
index c280692ab77d1e0636dedcd2091680e34a257622..c41533bc21563a46a6767a98ae6d54870e10c82f 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <base/config.h>
 #include <dofs/dof_levels.h>
+#include <dofs/hp_dof_objects.h>
 #include <fe/fe_collection.h>
 
 #include <vector>
@@ -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.
  *
  * 
  * <h4>Offset computations</h4>
@@ -61,9 +62,9 @@ namespace internal
  * dof_handler.get_fe().dofs_per_line</code>. 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 <code>line_dof_offsets[line_index]</code>
  * within the <code>line_dofs</code> 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
- * <code>line_dofs[line_dof_offsets[line_index]]</code> will denote
+ * <code>lines.dofs[lines.dof_offsets[line_index]]</code> 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<unsigned int> 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<unsigned int> line_dof_offsets;
-
-                                         /**
-                                          * Store the global indices of
-                                          * the degrees of freedom. See
-                                          * DoFLevel() for detailed
-                                          * information.
-                                          */
-        std::vector<unsigned int> 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 <int dim>
-        void
-        set_dof_index (const ::hp::DoFHandler<dim> &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 <int dim>
-        unsigned int
-        get_dof_index (const ::hp::DoFHandler<dim> &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 <int dim>
-        unsigned int
-        n_active_fe_indices (const ::hp::DoFHandler<dim> &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 <int dim>
-        bool
-        fe_index_is_active (const ::hp::DoFHandler<dim> &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<unsigned int> quad_dof_offsets;
-
-                                         /**
-                                          * Store the global indices of
-                                          * the degrees of freedom. See
-                                          * DoFLevel() for detailed
-                                          * information.
-                                          */
-        std::vector<unsigned int> 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 <int dim>
-        void
-        set_dof_index (const ::hp::DoFHandler<dim> &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 <int dim>
-        unsigned int
-        get_dof_index (const ::hp::DoFHandler<dim> &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 <int dim>
-        unsigned int
-        n_active_fe_indices (const ::hp::DoFHandler<dim> &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 <int dim>
-        bool
-        fe_index_is_active (const ::hp::DoFHandler<dim> &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<unsigned int> hex_dof_offsets;
-
-                                         /**
-                                          * Store the global indices of
-                                          * the degrees of freedom. See
-                                          * DoFLevel() for detailed
-                                          * information.
-                                          */
-        std::vector<unsigned int> 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 <int dim>
-        void
-        set_dof_index (const ::hp::DoFHandler<dim> &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 <int dim>
-        unsigned int
-        get_dof_index (const ::hp::DoFHandler<dim> &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 <int dim>
-        unsigned int
-        n_active_fe_indices (const ::hp::DoFHandler<dim> &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 <int dim>
-        bool
-        fe_index_is_active (const ::hp::DoFHandler<dim> &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 <int> 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 (file)
index 0000000..a3d6198
--- /dev/null
@@ -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 <base/config.h>
+#include <fe/fe_collection.h>
+
+#include <vector>
+
+
+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).
+ * 
+ * <h4>Offset computations</h4>
+ * 
+ * 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 <code>line_index *
+ * dof_handler.get_fe().dofs_per_line</code>. 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 <code>line_dof_offsets[line_index]</code>
+ * within the <code>line_dofs</code> array. 
+ *
+ *
+ * <h4>Multiple data sets per object</h4>
+ *
+ * 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
+ * <code>lines.dofs[lines.dof_offsets[line_index]]</code> 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<int dim>
+    class DoFObjects
+    {
+
+      private:
+
+                                         /**
+                                          * Store the start index for
+                                          * the degrees of freedom of each
+                                          * hex in the @p hex_dofs array.
+                                          */
+        std::vector<unsigned int> dof_offsets;
+
+                                         /**
+                                          * Store the global indices of
+                                          * the degrees of freedom. See
+                                          * DoFLevel() for detailed
+                                          * information.
+                                          */
+        std::vector<unsigned int> 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 <int spacedim>
+        void
+        set_dof_index (const ::hp::DoFHandler<spacedim> &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 <int spacedim>
+        unsigned int
+        get_dof_index (const ::hp::DoFHandler<spacedim> &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 <int spacedim>
+        unsigned int
+        n_active_fe_indices (const ::hp::DoFHandler<spacedim> &dof_handler,
+                             const unsigned int               obj_index) const;
+
+                                         /**
+                                          * Check whether a given
+                                          * finite element index is
+                                          * used on the present
+                                          * object or not.
+                                          */
+        template <int spacedim>
+        bool
+        fe_index_is_active (const ::hp::DoFHandler<spacedim> &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 <int> friend class ::hp::DoFHandler;
+    };
+  }
+}
+
+#endif
+
+
+
index 5f317678200034a9e27c67ff895282ac1344ed0d..201f409e7d7269d17290dd5c0aa8da1ab043628b 100644 (file)
@@ -31,6 +31,7 @@ namespace internal
   namespace Triangulation
   {
     template <int dim> class TriaLevel;
+    template <int dim> class TriaFaces;
   }
 }
 template <int dim> 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
-                                     * <tt>end()</tt>.
+                                     * Return a raw iterator which is past the end.
+                                     * This is the same as <tt>end()</tt> 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
-                                     * <tt>end()</tt>.
-                                     */
-    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
-                                     * <tt>end()</tt>.
+                                     * Return an active iterator which is past the end.
+                                     * This is the same as <tt>end()</tt> 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
+                                     * <tt>n_lines(level)</tt> cannot be called, only
+                                     * <tt>n_lines()</tt>, 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 <tt>n_lines(level)</tt> in two space
-                                     *  dimensions and so on.
-                                     */
-    unsigned int n_faces (const unsigned int level) const;
-
                                     /**
                                      *  Return total number of active faces.
                                      *  Maps to <tt>n_active_lines()</tt> 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 <tt>n_active_lines(level)</tt> 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<internal::Triangulation::TriaLevel<dim>*> 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<dim> * 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<dim>;
+    
 };
 
 
@@ -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;
index 0abcef35b35a0cfb89c0b40b8ff5fc3fe2c0aaac..383bbe1c8a275dd91660297884fd8e0dd6bf316f 100644 (file)
@@ -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<dim>
                                      *  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<dim>
                                      *  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<dim>
                                      *  iterator to the previous
                                      *  element.
                                      *
+                                     *  For cells only:
                                      *  The previous element is
                                      *  previous on this level if
                                      *  <tt>index>0</tt>. If the present
@@ -1054,8 +1072,11 @@ class TriaObjectAccessor<1, dim> :  public TriaAccessor<dim>
                                      *  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<dim>
                                      *  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<dim>
                                      *  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<dim>
                                      *  iterator to the previous
                                      *  element.
                                      *
+                                     *  For @p dim=1 only:
                                      *  The previous element is
                                      *  previous on this level if
                                      *  <tt>index>0</tt>. If the present
@@ -1397,8 +1423,7 @@ class TriaObjectAccessor<2, dim> :  public TriaAccessor<dim>
                                     /**
                                      * 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<dim>
                                      *  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<dim>
                                      *  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<dim>
                                      *  iterator to the previous
                                      *  element.
                                      *
+                                     *  For @p dim=2 only:
                                      *  The previous element is
                                      *  previous on this level if
                                      *  <tt>index>0</tt>. If the present
@@ -1912,9 +1942,8 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<dim>
 
                                     /**
                                      * 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<dim>
 
                                     /**
                                      * 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;
 
index 105f2bfc0e7a464dae4fff76f0b009f42acf5c66..34a0137ccbf4eb0ac0cb77449118f082f1eaa1a4 100644 (file)
@@ -17,6 +17,7 @@
 #include <base/config.h>
 #include <grid/tria.h>
 #include <grid/tria_levels.h>
+#include <grid/tria_faces.h>
 #include <grid/tria_iterator.h>
 #include <grid/tria_accessor.h>
 #include <grid/tria_iterator.templates.h>
@@ -105,7 +106,7 @@ TriaAccessor<dim>::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<dim>::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<dim>::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<dim>::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<dim>::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 <int dim>
 inline
 void
-TriaObjectAccessor<1,dim>::set_user_flag () const
+TriaObjectAccessor<1,dim>::set_user_flag () const 
 {
   Assert (this->used(), typename TriaAccessor<dim>::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<dim>::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<dim>::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<dim>::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 <int dim>
 inline
-TriaIterator<dim,TriaObjectAccessor<1,dim> >
-TriaObjectAccessor<1,dim>::child (const unsigned int i) const
+bool
+TriaObjectAccessor<1,dim>::has_children () const
 {
-  Assert (i<2, ExcIndexRange(i,0,2));
-  
-  TriaIterator<dim,TriaObjectAccessor<1,dim> >
-    q (this->tria, this->present_level+1, child_index (i));
-  
-  Assert ((q.state() == IteratorState::past_the_end) || q->used(),
-         typename TriaAccessor<dim>::ExcUnusedCellAsChild());
+  Assert (this->state() == IteratorState::valid,
+         typename TriaAccessor<dim>::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<dim>::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<dim>::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<dim>::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 <int dim>
 inline
-bool
-TriaObjectAccessor<1,dim>::has_children () const
+TriaIterator<dim,TriaObjectAccessor<1,dim> >
+TriaObjectAccessor<1,dim>::child (const unsigned int i) const
 {
-  Assert (this->state() == IteratorState::valid,
-         typename TriaAccessor<dim>::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<dim,TriaObjectAccessor<1,dim> >
+    q (this->tria, next_level, child_index (i));
+
+  Assert ((q.state() == IteratorState::past_the_end) || q->used(),
+         typename TriaAccessor<dim>::ExcUnusedCellAsChild());
+
+  return q;
 }
 
 
+
 template <int dim>
 inline
 unsigned int
@@ -234,6 +316,7 @@ TriaObjectAccessor<1,dim>::n_children () const
 }
 
 
+
 template <int dim>
 inline
 unsigned int
@@ -263,13 +346,29 @@ template <int dim>
 inline
 void
 TriaObjectAccessor<1,dim>::operator ++ ()
+{
+  ++this->present_index;
+                                  // is index still in the range of
+                                  // the vector?
+  if (this->present_index
+      >=
+      static_cast<int>(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<int>(this->tria->levels[this->present_level]->lines.lines.size()))
+        static_cast<int>(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 <int dim>
 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<dim>::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<dim>::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<dim>::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<dim>::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<dim>::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<dim>::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<dim>::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<dim>::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<dim,TriaObjectAccessor<1,dim> >
     (
       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 <int dim>
 inline
-TriaIterator<dim,TriaObjectAccessor<2,dim> >
-TriaObjectAccessor<2,dim>::child (const unsigned int i) const
+bool
+TriaObjectAccessor<2,dim>::has_children () const
 {
-  Assert (i<4, ExcIndexRange(i,0,4));
-  
-  TriaIterator<dim,TriaObjectAccessor<2,dim> >
-    q (this->tria, this->present_level+1, child_index (i));
-  
-  Assert ((q.state() == IteratorState::past_the_end) || q->used(),
-         typename TriaAccessor<dim>::ExcUnusedCellAsChild());
+  Assert (this->state() == IteratorState::valid,
+         typename TriaAccessor<dim>::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<dim>::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<dim>::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<dim>::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 <int dim>
 inline
-bool
-TriaObjectAccessor<2,dim>::has_children () const
+TriaIterator<dim,TriaObjectAccessor<2,dim> >
+TriaObjectAccessor<2,dim>::child (const unsigned int i) const
 {
-  Assert (this->state() == IteratorState::valid,
-         typename TriaAccessor<dim>::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<dim,TriaObjectAccessor<2,dim> >
+    q (this->tria, next_level, child_index (i));
+  
+  Assert ((q.state() == IteratorState::past_the_end) || q->used(),
+         typename TriaAccessor<dim>::ExcUnusedCellAsChild());
+
+  return q;
 }
 
 
+
 template <int dim>
 inline
 unsigned int
@@ -484,13 +684,29 @@ template <int dim>
 inline
 void
 TriaObjectAccessor<2,dim>::operator ++ ()
+{
+  ++this->present_index;
+                                  // is index still in the range of
+                                  // the vector?
+  if (this->present_index
+      >=
+      static_cast<int>(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<int>(this->tria->levels[this->present_level]->quads.quads.size()))
+        static_cast<int>(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 <int dim>
 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<dim> *parent,
 
 
 
-template <int dim>
+template <>
 inline
 bool
-TriaObjectAccessor<3,dim>::used () const
+TriaObjectAccessor<3,3>::used () const
 {
+  const int dim=3;
   Assert (this->state() == IteratorState::valid,
-         typename TriaAccessor<dim>::ExcDereferenceInvalidObject());
-  return this->tria->levels[this->present_level]->hexes.used[this->present_index];
+         TriaAccessor<dim>::ExcDereferenceInvalidObject());
+   return this->tria->levels[this->present_level]->hexes.used[this->present_index];
 }
 
 
 
-template <int dim>
+template <>
 inline
 bool
-TriaObjectAccessor<3,dim>::user_flag_set () const
+TriaObjectAccessor<3,3>::user_flag_set () const
 {
-  Assert (this->used(), typename TriaAccessor<dim>::ExcCellNotUsed());
-  return this->tria->levels[this->present_level]->hexes.user_flags[this->present_index];
+  const int dim=3;
+  Assert (this->used(), TriaAccessor<dim>::ExcCellNotUsed());
+    return this->tria->levels[this->present_level]->hexes.user_flags[this->present_index];
 }
 
 
 
-template <int dim>
+template <>
 inline
 void
-TriaObjectAccessor<3,dim>::set_user_flag () const
+TriaObjectAccessor<3,3>::set_user_flag () const
 {
-  Assert (this->used(), typename TriaAccessor<dim>::ExcCellNotUsed());
-  this->tria->levels[this->present_level]->hexes.user_flags[this->present_index] = true;
+  const int dim=3;
+  Assert (this->used(), TriaAccessor<dim>::ExcCellNotUsed());
+    this->tria->levels[this->present_level]->hexes.user_flags[this->present_index] = true;
 }
 
 
 
-template <int dim>
+template <>
 inline
-void TriaObjectAccessor<3,dim>::clear_user_flag () const
+void TriaObjectAccessor<3,3>::clear_user_flag () const
 {
-  Assert (this->used(), typename TriaAccessor<dim>::ExcCellNotUsed());
-  this->tria->levels[this->present_level]->hexes.user_flags[this->present_index] = false;
+  const int dim=3;
+  Assert (this->used(), TriaAccessor<dim>::ExcCellNotUsed());
+    this->tria->levels[this->present_level]->hexes.user_flags[this->present_index] = false;
 }
 
 
@@ -598,38 +831,13 @@ TriaIterator<dim,TriaObjectAccessor<1,dim> >
 TriaObjectAccessor<3,dim>::line (const unsigned int i) const
 {
   Assert (this->used(), typename TriaAccessor<dim>::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<dim,TriaObjectAccessor<1,dim> >
+    (
+      this->tria,
+      0,
+      line_index (i)
+    );
 }
 
 
@@ -644,7 +852,7 @@ TriaObjectAccessor<3,dim>::quad (const unsigned int i) const
     TriaIterator<dim,TriaObjectAccessor<2,dim> >
     (
       this->tria,
-      this->present_level,
+      0,
       quad_index (i)
     );
 }
@@ -692,57 +900,60 @@ TriaObjectAccessor<3,dim>::line_index (const unsigned int i) const
 
 
 
-template <int dim>
+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 <int dim>
+template <>
 inline
-TriaIterator<dim,TriaObjectAccessor<3,dim> >
-TriaObjectAccessor<3,dim>::child (const unsigned int i) const
+bool
+TriaObjectAccessor<3,3>::has_children () const
 {
-  Assert (i<8, ExcIndexRange(i,0,8));
-  
-  TriaIterator<dim,TriaObjectAccessor<3,dim> > q (this->tria, this->present_level+1, child_index (i));
-  
-  Assert ((q.state() == IteratorState::past_the_end) || q->used(),
-         typename TriaAccessor<dim>::ExcUnusedCellAsChild());
-
-  return q;
+  const int dim=3;
+  Assert (this->state() == IteratorState::valid,
+         TriaAccessor<dim>::ExcDereferenceInvalidObject());
+    return (this->tria->levels[this->present_level]->hexes.children[this->present_index] != -1);
 }
 
 
-
-template <int dim>
+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<dim>::ExcCellHasNoChildren());
-  return this->tria->levels[this->present_level]->hexes.children[this->present_index]+i;
+  Assert (has_children(), TriaAccessor<dim>::ExcCellHasNoChildren());
+    return this->tria->levels[this->present_level]->hexes.children[this->present_index]+i;
 }
 
 
 
-template <int dim>
+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<dim>::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<dim,TriaObjectAccessor<3,dim> > q (this->tria, this->present_level+1, child_index (i));
+  
+  Assert ((q.state() == IteratorState::past_the_end) || q->used(),
+         TriaAccessor<dim>::ExcUnusedCellAsChild());
+
+  return q;
 }
 
 
+
 template <int dim>
 inline
 unsigned int
@@ -777,78 +988,78 @@ TriaObjectAccessor<3,dim>::max_refinement_depth () const
 
 
 
-template <int dim>
+template <>
 inline
 bool
-TriaObjectAccessor<3, dim>::
+TriaObjectAccessor<3, 3>::
 face_orientation (const unsigned int face) const
 {
-  Assert (used(), typename TriaAccessor<dim>::ExcCellNotUsed());
+  const int dim=3;
+  Assert (used(), TriaAccessor<dim>::ExcCellNotUsed());
   Assert (face<GeometryInfo<3>::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 <int dim>
+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<int>(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<int>(this->tria->levels.size()))
-       {
-                                          // return with past the end pointer
-         this->present_level = this->present_index = -1;
-         return;
-       };
-    };
+    while (this->present_index
+          >=
+          static_cast<int>(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<int>(this->tria->levels.size()))
+         {
+                                            // return with past the end pointer
+           this->present_level = this->present_index = -1;
+           return;
+         }
+      }
 }
 
 
 
-template <int dim>
+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 (file)
index 0000000..247df64
--- /dev/null
@@ -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 <base/config.h>
+#include <grid/tria_line.h>
+#include <grid/tria_quad.h>
+#include <grid/tria_hex.h>
+#include <grid/tria_objects.h>
+
+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<int dim>
+    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 <tt>dim@>=1</tt>. In <tt>dim=1</tt> they are vertices,
+ * which are handled differently, so only for <tt>dim@>=2</tt> the use of TriaFaces
+ * is reasonable, for <tt>dim=1</tt> 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 <tt>dim=2</tt> the cells are quads, the faces accordingly are lines. 
+ * @ingroup grid
+ */
+    template<>
+    class TriaFaces<2>
+    {
+      public:
+                                        /**
+                                         *  The TriaObject containing the data of lines.
+                                         */
+       TriaObjects<Line> lines;
+
+      public:
+                                        /**
+                                          * Determine an estimate for the
+                                          * memory consumption (in bytes)
+                                          * of this object.
+                                          */
+        unsigned int memory_consumption () const;
+    };
+    
+/**
+ * In <tt>dim=3</tt> 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<Quad> quads;
+
+                                        /**
+                                         *  The TriaObject containing the data of lines.
+                                         */
+        TriaObjects<Line> lines;           
+
+      public:
+                                        /**
+                                          * Determine an estimate for the
+                                          * memory consumption (in bytes)
+                                          * of this object.
+                                          */
+        unsigned int memory_consumption () const;
+    };
+  }
+}
+#endif
index 35cc0849f59d5975ccfab1622e8c964d1dc1a746..a69633518bd16af00348a95e5a10dda2a56cf8b2 100644 (file)
@@ -318,9 +318,9 @@ class TriaRawIterator :
                                      *  explicitly for the different
                                      *  @p Pointees, to allow an
                                      *  <tt>iterator<1,TriangulationLevel<1>::LinesData></tt>
-                                     *  to point to <tt>tria->lines.lines[index]</tt> while
+                                     *  to point to <tt>tria->lines.cells[index]</tt> while
                                      *  for one dimension higher it has
-                                     *  to point to <tt>tria->quads.quads[index]</tt>.
+                                     *  to point to <tt>tria->quads.cells[index]</tt>.
                                      *
                                      *  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 <tt>index>0</tt>. 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<dim,Accessor>::TriaActiveIterator (const TriaRawIterator<dim,
 #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!
index 01bd8bdbe2d09f5778ee37378da67c79a20c1202..10a26299e2bfc6413175c7c1d7de2f00213d71e3 100644 (file)
@@ -260,7 +260,7 @@ TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaRawIterator<dim,
 #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!
@@ -279,7 +279,7 @@ TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaIterator<dim,Acc
 #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!
@@ -301,7 +301,7 @@ TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const Triangulation<dim> *
 #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<dim,Accessor>::operator = (const TriaRawIterator<dim,Accessor
 #ifdef DEBUG
                                   // do this like this, because:
                                   // if we write
-                                  // "Assert (IteratorState::past_the_end || used)"
+                                  // "Assert (IteratorState::past_the_end || !has_children())"
                                   // has_chidlren() is called anyway, even if
                                   // state==IteratorState::past_the_end, and will then
                                   // throw the exception!
@@ -349,7 +349,7 @@ TriaActiveIterator<dim,Accessor>::operator = (const TriaIterator<dim,Accessor> &
 #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!
index 2fe525e7e0508d6d48f49ee1c827bd2729136094..2a63aee2fd8856cafe3f3a1d5afef5dd8f0a4ff3 100644 (file)
@@ -20,6 +20,7 @@
 #include <grid/tria_quad.h>
 #include <grid/tria_hex.h>
 #include <base/point.h>
+#include <grid/tria_objects.h>
 
 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 <tt>TriaFaces</tt> 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<Line> 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<int>  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<bool> 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<bool> 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<unsigned char> 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<void*> user_pointers;
-        };
-    
       public:
-                                         /**
-                                          *  Data about the lines.
-                                          */
-        LinesData lines;
-
-                                         /**
-                                          *  Assert that enough space is
-                                          *  allocated to accomodate
-                                          *  <tt>new_lines</tt> new lines.
-                                          *  This function does not only
-                                          *  call
-                                          *  <tt>vector::reserve()</tt>,
-                                          *  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
-                                          *  <tt>TriaLevel<0>::reserve_space</tt>
-                                          *  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<Line> 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<tt><1></tt>.
-                                          */
-        struct QuadsData
-        {
-                                             /**
-                                              *  Same as for the @p lines array.
-                                              */
-            std::vector<Quad> 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<int>  children;
-
-                                             /**
-                                              *  Same as for
-                                              *  TriaLevel<1>::LinesData@p ::used.
-                                              */
-            std::vector<bool> used;
-
-                                             /**
-                                              *  Same as for
-                                              *  TriaLevel<1>::LinesData@p ::used.
-                                              */
-            std::vector<bool> 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<unsigned char> 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<void*> user_pointers;
-        };
-    
       public:
-                                         /**
-                                          *  Data about the quads.
-                                          */
-        QuadsData quads;
-
-                                         /**
-                                          *  Assert that enough space is
-                                          *  allocated to accomodate
-                                          *  <tt>new_quads</tt> new quads.
-                                          */
-        void reserve_space (const unsigned int new_quads);
+                                        /**
+                                         * The object containing the data on quads and
+                                         * related functions
+                                         */
+       TriaObjects<Quad> 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<Hexahedron> 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<int>  children;
-
-                                             /**
-                                              *  Same as for
-                                              *  TriaLevel<1>::LinesData@p ::used.
-                                              */
-            std::vector<bool> used;
-
-                                             /**
-                                              *  Same as for
-                                              *  TriaLevel<1>::LinesData@p ::used.
-                                              */
-            std::vector<bool> 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<unsigned char> 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<void*> 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
-                                              * <tt>6*n_cells</tt> elements,
-                                              * being the number of cells
-                                              * times the six faces each
-                                              * has.
-                                              */
-            std::vector<bool> 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
-                                          *  <tt>new_hexes</tt> 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 (file)
index 0000000..75f20c4
--- /dev/null
@@ -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 <base/config.h>
+#include <base/exceptions.h>
+#include <base/geometry_info.h>
+#include <grid/tria_line.h>
+#include <grid/tria_quad.h>
+#include <grid/tria_hex.h>
+#include <vector>
+
+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 <typename G>
+    class TriaObjects
+    {
+      public:
+                                        /**
+                                         *  Vector of the objects belonging to
+                                         *  this level. The index of the object
+                                         *  equals the index in this container. 
+                                         */
+       std::vector<G> 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<int>  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<bool> 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<bool> 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<unsigned char> 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<void*> user_pointers;
+
+                                         /**
+                                          *  Assert that enough space is
+                                          *  allocated to accomodate
+                                          *  <tt>new_objs</tt> new objects.
+                                          *  This function does not only call
+                                          *  <tt>vector::reserve()</tt>, 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<Hexahedron>
+    {
+      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
+                                         * <tt>6*n_cells</tt> elements,
+                                         * being the number of cells
+                                         * times the six faces each
+                                         * has.
+                                         */
+       std::vector<bool> face_orientations;
+
+                                         /**
+                                          *  Assert that enough space is
+                                          *  allocated to accomodate
+                                          *  <tt>new_objs</tt> new objects.
+                                          *  This function does not only call
+                                          *  <tt>vector::reserve()</tt>, 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
index 852023d4587411b166a0e4dc4e034becc66b1776..6b52bcc4ac58c2d77b87be95a071cc0d96eabfa3 100644 (file)
@@ -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
index 124a37e2dfd97e05f3216dfca4cd80a9e3cf78ad..fcccb47e01bff1bf3d09ec62ffcddf5033d3e47a 100644 (file)
@@ -275,37 +275,34 @@ class MGDoFHandler : public DoFHandler<dim>
                                     /*@{*/
                                     /**
                                      * 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<dim>
     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
-                                     * <tt>end()</tt>.
-                                     */
-    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
-                                     * <tt>end()</tt>.
-                                     */
-    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 <tt>end()</tt>.
+                                     * 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 
+                                     * <tt>end_face()</tt>.
                                      */
-    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 
+                                     * <tt>end_face()</tt>.
                                      */
-    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<dim>
                                      */
     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<dim>
                                      * @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<dim>
                                      */
     active_hex_iterator last_active_hex (const unsigned int level) const;
                                     /*@}*/
-    
+
                                     /*---------------------------------------*/
 
     
@@ -945,6 +906,26 @@ class MGDoFHandler : public DoFHandler<dim>
                                      */
     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 <int structdim>
+    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 <int structdim>
+    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<dim>
                                      * zero on each level.
                                      */
     std::vector<internal::DoFHandler::DoFLevel<dim>*>    mg_levels;
+    
+                                    /**
+                                     * Space to store the DoF numbers
+                                     * for the faces.
+                                     */
+    internal::DoFHandler::DoFFaces<dim> *                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 <>
index 7bee86dcbb71535320ed5811f6b76c2b0f618683..a042a436c110bb85c904de3955a847326c84e247 100644 (file)
@@ -19,7 +19,6 @@
 #include <lac/sparse_matrix.h>
 
 #include <dofs/dof_accessor.h>
-#include <dofs/dof_accessor.templates.h>
 #include <dofs/dof_handler.h>
 #include <dofs/dof_levels.h>
 #include <dofs/hp_dof_handler.h>
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 (file)
index 0000000..40497b0
--- /dev/null
@@ -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 <base/exceptions.h>
+#include <base/memory_consumption.h>
+#include <dofs/dof_faces.h>
+
+
+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) );
+    }
+    
+  }
+}
index 4ec8b943a5522e9e2d61f91c294bcf37cf2724e5..4ffd32a7f64867590b0ae9657cc34a70679ec686 100644 (file)
@@ -15,6 +15,7 @@
 #include <base/memory_consumption.h>
 #include <dofs/dof_handler.h>
 #include <dofs/dof_levels.h>
+#include <dofs/dof_faces.h>
 #include <dofs/dof_accessor.h>
 #include <grid/tria_accessor.h>
 #include <grid/tria_iterator.h>
@@ -42,6 +43,7 @@ template <int dim>
 DoFHandler<dim>::DoFHandler (const Triangulation<dim> &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<dim>::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 <int dim>
 typename DoFHandler<dim>::raw_line_iterator
 DoFHandler<dim>::end_line () const
@@ -980,43 +1044,14 @@ DoFHandler<dim>::end_active (const unsigned int level) const
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_face_iterator
-DoFHandler<dim>::end_raw_face (const unsigned int level) const
-{
-  return (level == levels.size()-1 ?
-         end_face() :
-         begin_raw_face (level+1));
-}
-
-
-template <int dim>
-typename DoFHandler<dim>::face_iterator
-DoFHandler<dim>::end_face (const unsigned int level) const
-{
-  return (level == levels.size()-1 ?
-         face_iterator(end_face()) :
-         begin_face (level+1));
-}
-
-
-template <int dim>
-typename DoFHandler<dim>::active_face_iterator
-DoFHandler<dim>::end_active_face (const unsigned int level) const
-{
-  return (level == levels.size()-1 ?
-         active_face_iterator(end_face()) :
-         begin_active_face (level+1));
-}
-
-
 template <int dim>
 typename DoFHandler<dim>::raw_line_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::line_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::active_line_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::raw_quad_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::quad_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::active_quad_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::raw_hex_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::hex_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::active_hex_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::raw_line_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::raw_quad_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::raw_hex_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::line_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::quad_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::hex_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::active_line_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::active_quad_iterator
 DoFHandler<dim>::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 <int dim>
 typename DoFHandler<dim>::active_hex_iterator
 DoFHandler<dim>::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<dim>::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<levels.size(); ++i)
     mem += MemoryConsumption::memory_consumption (*levels[i]);
+  mem += MemoryConsumption::memory_consumption (*faces);
   
   return mem;
 }
@@ -1688,8 +2114,8 @@ void DoFHandler<1>::renumber_dofs (const std::vector<unsigned int> &new_numbers)
              ExcInternalError ());
   
   for (unsigned int level=0; level<levels.size(); ++level) 
-    for (std::vector<unsigned int>::iterator i=levels[level]->line_dofs.begin();
-        i!=levels[level]->line_dofs.end(); ++i)
+    for (std::vector<unsigned int>::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<unsigned int> &new_numbers)
                                 selected_fe->dofs_per_vertex) == false,
              ExcInternalError ());
   
+  for (std::vector<unsigned int>::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<levels.size(); ++level) 
     {
-      for (std::vector<unsigned int>::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<unsigned int>::iterator i=levels[level]->quad_dofs.begin();
-          i!=levels[level]->quad_dofs.end(); ++i)
+      for (std::vector<unsigned int>::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<unsigned int> &new_numbers)
                                 selected_fe->dofs_per_vertex) == false,
              ExcInternalError ());
   
+  for (std::vector<unsigned int>::iterator i=faces->lines.dofs.begin();
+       i!=faces->lines.dofs.end(); ++i)
+    if (*i != invalid_dof_index)
+      *i = new_numbers[*i];
+  for (std::vector<unsigned int>::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<levels.size(); ++level) 
     {
-      for (std::vector<unsigned int>::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<unsigned int>::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<unsigned int>::iterator i=levels[level]->hex_dofs.begin();
-          i!=levels[level]->hex_dofs.end(); ++i)
+      for (std::vector<unsigned int>::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<unsigned int> (tria->n_raw_lines(i) *
-                                                           selected_fe->dofs_per_line,
-                                                           invalid_dof_index);
-      levels.back()->quad_dofs = std::vector<unsigned int> (tria->n_raw_quads(i) *
-                                                           selected_fe->dofs_per_quad,
-                                                           invalid_dof_index);
-      levels.back()->hex_dofs = std::vector<unsigned int> (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 <int dim>
-void DoFHandler<dim>::clear_space () {  
+void DoFHandler<dim>::clear_space () {
   for (unsigned int i=0; i<levels.size(); ++i)
     delete levels[i];
   levels.resize (0);
-
+    
+  delete faces;
+  faces = NULL;
+  
   std::vector<unsigned int> tmp;
   std::swap (vertex_dofs, tmp);
 }
index 6c0ecb7d3e51c9ea3a901a776f06645fd453853e..d32bc708ac740fd315bf70a45ae923d15c15dac0 100644 (file)
@@ -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
   }
   
 }
index 6d48cad48437d6ec3b049e73319cffc3f127d604..55cc1d76e36e0df2e48cfe5bdb73be88f19894d2 100644 (file)
-//---------------------------------------------------------------------------
-//    $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 <base/exceptions.h>
 #include <base/memory_consumption.h>
-#include <dofs/dof_levels.h>
+#include <dofs/dof_objects.h>
 #include <dofs/dof_handler.h>
 #include <fe/fe.h>
 
 
-//TODO[WB]: make a few of these functions inline
-
 namespace internal
 {
   namespace DoFHandler
   {
-    template <int dim>
-    unsigned int
-    DoFLevel<1>::
-    get_dof_index (const ::DoFHandler<dim> &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<dim>::default_fe_index,
-             ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
-      Assert (local_index<dof_handler.get_fe().dofs_per_line,
-             ExcIndexRange (local_index, 0, dof_handler.get_fe().dofs_per_line));
-      Assert (line_index * dof_handler.get_fe().dofs_per_line+local_index
-             <
-             line_dofs.size(),
-             ExcInternalError());
-      
-      return line_dofs[line_index * dof_handler.get_fe().dofs_per_line+local_index];
-    }
-
-
-
-    template <int dim>
-    void
-    DoFLevel<1>::
-    set_dof_index (const ::DoFHandler<dim> &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<dim>::default_fe_index,
-             ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
-      Assert (local_index<dof_handler.get_fe().dofs_per_line,
-             ExcIndexRange (local_index, 0, dof_handler.get_fe().dofs_per_line));
-      Assert (line_index * dof_handler.get_fe().dofs_per_line+local_index
-             <
-             line_dofs.size(),
-             ExcInternalError());
-      
-      line_dofs[line_index * dof_handler.get_fe().dofs_per_line+local_index] = global_index;
-    }
-
-
-
-    template <int dim>
-    unsigned int
-    DoFLevel<2>::
-    get_dof_index (const ::DoFHandler<dim> &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<dim>::default_fe_index,
-             ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
-      Assert (local_index<dof_handler.get_fe().dofs_per_quad,
-             ExcIndexRange (local_index, 0, dof_handler.get_fe().dofs_per_quad));
-      Assert (quad_index * dof_handler.get_fe().dofs_per_quad+local_index
-             <
-             quad_dofs.size(),
-             ExcInternalError());
-      
-      return quad_dofs[quad_index * dof_handler.get_fe().dofs_per_quad+local_index];
-    }
-
-
-
-    template <int dim>
-    void
-    DoFLevel<2>::
-    set_dof_index (const ::DoFHandler<dim> &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<dim>::default_fe_index,
-             ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
-      Assert (local_index<dof_handler.get_fe().dofs_per_quad,
-             ExcIndexRange (local_index, 0, dof_handler.get_fe().dofs_per_quad));
-      Assert (quad_index * dof_handler.get_fe().dofs_per_quad+local_index
-             <
-             quad_dofs.size(),
-             ExcInternalError());
-      
-      quad_dofs[quad_index * dof_handler.get_fe().dofs_per_quad+local_index] = global_index;
-    }
-
-
-
-    template <int dim>
-    unsigned int
-    DoFLevel<3>::
-    get_dof_index (const ::DoFHandler<dim> &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<dim>::default_fe_index,
-             ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
-      Assert (local_index<dof_handler.get_fe().dofs_per_hex,
-             ExcIndexRange (local_index, 0, dof_handler.get_fe().dofs_per_hex));
-      Assert (hex_index * dof_handler.get_fe().dofs_per_hex+local_index
-             <
-             hex_dofs.size(),
-             ExcInternalError());
-      
-      return hex_dofs[hex_index * dof_handler.get_fe().dofs_per_hex+local_index];
-    }
-
-
-
-    template <int dim>
-    void
-    DoFLevel<3>::
-    set_dof_index (const ::DoFHandler<dim> &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<dim>::default_fe_index,
-             ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
-      Assert (local_index<dof_handler.get_fe().dofs_per_hex,
-             ExcIndexRange (local_index, 0, dof_handler.get_fe().dofs_per_hex));
-      Assert (hex_index * dof_handler.get_fe().dofs_per_hex+local_index
-             <
-             hex_dofs.size(),
-             ExcInternalError());
-      
-      hex_dofs[hex_index * dof_handler.get_fe().dofs_per_hex+local_index] = global_index;
-    }
-    
-    
-
-// explicit instantiations
-    template
-    unsigned int
-    DoFLevel<1>::
-    get_dof_index (const ::DoFHandler<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &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 (file)
index 0000000..94058d1
--- /dev/null
@@ -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 <base/exceptions.h>
+#include <base/memory_consumption.h>
+#include <dofs/dof_objects.h>
+#include <dofs/dof_handler.h>
+#include <fe/fe.h>
+
+namespace internal
+{
+  namespace DoFHandler
+  {
+    template<int dim>
+    unsigned int
+    DoFObjects<dim>::memory_consumption () const
+    {
+      return (MemoryConsumption::memory_consumption (dofs));
+    }
+
+    template <int dim>
+    template <int spacedim>
+    inline
+    unsigned int
+    DoFObjects<dim>::n_active_fe_indices (const ::DoFHandler<spacedim> &,
+                                                   const unsigned) const
+    {
+      return 1;
+    }
+    
+
+    template <int dim>
+    template <int spacedim>
+    inline
+    bool
+    DoFObjects<dim>::fe_index_is_active (const ::DoFHandler<spacedim> &,
+                                                  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 <int dim>
+    template <int spacedim>
+    unsigned int
+    DoFObjects<dim>::
+    get_dof_index (const ::DoFHandler<spacedim> &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<spacedim>::default_fe_index,
+             ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
+      Assert (local_index<dofs_per_obj,
+             ExcIndexRange (local_index, 0, dofs_per_obj));
+      Assert (obj_index * dofs_per_obj+local_index
+             <
+             dofs.size(),
+             ExcInternalError());
+      
+      return dofs[obj_index * dofs_per_obj + local_index];
+    }
+
+
+    template <int dim>
+    template <int spacedim>
+    void
+    DoFObjects<dim>::
+    set_dof_index (const ::DoFHandler<spacedim> &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<spacedim>::default_fe_index,
+             ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
+      Assert (local_index<dofs_per_obj,
+             ExcIndexRange (local_index, 0, dof_handler.get_fe().dofs_per_line));
+      Assert (obj_index * dofs_per_obj+local_index
+             <
+             dofs.size(),
+             ExcInternalError());
+
+      dofs[obj_index * dofs_per_obj + local_index] = global_index;
+    }
+
+// explicit instantiations
+    template
+    unsigned int
+    DoFObjects<1>::
+    memory_consumption () const;
+    
+
+    template
+    unsigned int
+    DoFObjects<1>::
+    get_dof_index (const ::DoFHandler<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &,
+                        const unsigned) const;
+
+    template
+    bool
+    DoFObjects<1>::
+    fe_index_is_active (const ::DoFHandler<deal_II_dimension> &,
+                       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<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &,
+                        const unsigned) const;
+
+    template
+    bool
+    DoFObjects<2>::
+    fe_index_is_active (const ::DoFHandler<deal_II_dimension> &,
+                       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<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &,
+                        const unsigned) const;
+
+    template
+    bool
+    DoFObjects<3>::
+    fe_index_is_active (const ::DoFHandler<deal_II_dimension> &,
+                       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 (file)
index 0000000..b360130
--- /dev/null
@@ -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 <base/memory_consumption.h>
+#include <dofs/hp_dof_faces.h>
+
+
+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) );
+    }
+  }
+}
index 5672de40f82acc3c39fee9a577283e11021092eb..6aac25bf7f78fed8ee39f508ad24b47bf5e86a24 100644 (file)
@@ -14,7 +14,9 @@
 
 #include <base/memory_consumption.h>
 #include <dofs/hp_dof_handler.h>
+#include <dofs/hp_dof_objects.h>
 #include <dofs/hp_dof_levels.h>
+#include <dofs/hp_dof_faces.h>
 #include <dofs/dof_accessor.h>
 #include <grid/tria_accessor.h>
 #include <grid/tria_iterator.h>
@@ -46,6 +48,7 @@ namespace hp
   DoFHandler<dim>::DoFHandler (const Triangulation<dim> &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 <int dim>
   typename DoFHandler<dim>::raw_line_iterator
   DoFHandler<dim>::end_line () const
@@ -992,43 +1056,14 @@ namespace hp
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_face_iterator
-  DoFHandler<dim>::end_raw_face (const unsigned int level) const
-  {
-    return (level == levels.size()-1 ?
-            end_face() :
-            begin_raw_face (level+1));
-  }
-
-
-  template <int dim>
-  typename DoFHandler<dim>::face_iterator
-  DoFHandler<dim>::end_face (const unsigned int level) const
-  {
-    return (level == levels.size()-1 ?
-            face_iterator(end_face()) :
-            begin_face (level+1));
-  }
-
-
-  template <int dim>
-  typename DoFHandler<dim>::active_face_iterator
-  DoFHandler<dim>::end_active_face (const unsigned int level) const
-  {
-    return (level == levels.size()-1 ?
-            active_face_iterator(end_face()) :
-            begin_active_face (level+1));
-  }
-
-
   template <int dim>
   typename DoFHandler<dim>::raw_line_iterator
   DoFHandler<dim>::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<dim>::line_iterator
   DoFHandler<dim>::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<dim>::active_line_iterator
   DoFHandler<dim>::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<dim>::raw_quad_iterator
   DoFHandler<dim>::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<dim>::quad_iterator
   DoFHandler<dim>::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<dim>::active_quad_iterator
   DoFHandler<dim>::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<dim>::raw_hex_iterator
   DoFHandler<dim>::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<dim>::hex_iterator
   DoFHandler<dim>::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<dim>::active_hex_iterator
   DoFHandler<dim>::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<dim>::raw_line_iterator
   DoFHandler<dim>::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<dim>::raw_quad_iterator
   DoFHandler<dim>::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<dim>::raw_hex_iterator
   DoFHandler<dim>::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<dim>::line_iterator
   DoFHandler<dim>::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<dim>::quad_iterator
   DoFHandler<dim>::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<dim>::hex_iterator
   DoFHandler<dim>::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<dim>::active_line_iterator
   DoFHandler<dim>::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<dim>::active_quad_iterator
   DoFHandler<dim>::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<dim>::active_hex_iterator
   DoFHandler<dim>::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<levels.size(); ++i)
       mem += MemoryConsumption::memory_consumption (*levels[i]);
+    mem += MemoryConsumption::memory_consumption (*faces);
   
     return mem;
   }
@@ -1789,8 +2235,8 @@ namespace hp
         *i = new_numbers[*i];
   
     for (unsigned int level=0; level<levels.size(); ++level) 
-      for (std::vector<unsigned int>::iterator i=levels[level]->line_dofs.begin();
-           i!=levels[level]->line_dofs.end(); ++i)
+      for (std::vector<unsigned int>::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<levels.size(); ++level) 
       {
-        for (std::vector<unsigned int>::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<unsigned int>::iterator i=levels[level]->quad_dofs.begin();
-             i!=levels[level]->quad_dofs.end(); ++i)
+        for (std::vector<unsigned int>::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<unsigned int>::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<levels.size(); ++level) 
       {
-        for (std::vector<unsigned int>::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<unsigned int>::iterator i=levels[level]->quad_dofs.begin();
-             i!=levels[level]->quad_dofs.end(); ++i)
+        for (std::vector<unsigned int>::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<unsigned int>::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<unsigned int>::iterator i=faces->lines.dofs.begin();
+        i!=faces->lines.dofs.end(); ++i)
+      if (*i != invalid_dof_index)
+       *i = new_numbers[*i];
+    for (std::vector<unsigned int>::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; level<tria->n_levels(); ++level) 
       {
-        levels[level]->line_dof_offsets
+        levels[level]->lines.dof_offsets
           = std::vector<unsigned int> (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<unsigned int> (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<unsigned int>
-                (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; level<tria->n_levels(); ++level) 
       {
-        levels[level]->quad_dof_offsets
+        levels[level]->quads.dof_offsets
           = std::vector<unsigned int> (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<unsigned int> (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<unsigned int>
-                (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<unsigned int> 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<GeometryInfo<dim>::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; level<tria->n_levels(); ++level) 
-        {
-          levels[level]->line_dof_offsets
-            = std::vector<unsigned int> (tria->n_raw_lines(level),
-                                         invalid_dof_index);
-          levels[level]->line_dofs
-            = std::vector<unsigned int> (n_line_slots[level],
-                                         invalid_dof_index);        
-        }
-
+      faces->lines.dof_offsets
+       = std::vector<unsigned int> (tria->n_raw_lines(),
+                                    invalid_dof_index);
+      faces->lines.dofs
+       = std::vector<unsigned int> (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<Triangulation<dim>&>(*tria).clear_user_flags_line ();
 
-      std::vector<unsigned int> 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<GeometryInfo<dim>::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; level<tria->n_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<Triangulation<dim>&>(*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; level<tria->n_levels(); ++level) 
       {
-        levels[level]->hex_dof_offsets
+        levels[level]->hexes.dof_offsets
           = std::vector<unsigned int> (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<unsigned int> (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<unsigned int>
-                (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<Triangulation<dim>&>(*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<unsigned int> 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<GeometryInfo<dim>::faces_per_cell; ++face)
-          if (! cell->face(face)->user_flag_set())
-            {
+       for (unsigned int face=0; face<GeometryInfo<dim>::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; level<tria->n_levels(); ++level
+      if (true
         {
-          levels[level]->quad_dof_offsets
-            = std::vector<unsigned int> (tria->n_raw_quads(level),
+          faces->quads.dof_offsets
+            = std::vector<unsigned int> (tria->n_raw_quads(),
                                          invalid_dof_index);
-          levels[level]->quad_dofs
-            = std::vector<unsigned int> (n_quad_slots[level],
+          faces->quads.dofs
+            = std::vector<unsigned int> (n_quad_slots,
                                          invalid_dof_index);        
         }
 
@@ -2749,7 +3194,7 @@ namespace hp
                                        // the fe_index fields
       const_cast<Triangulation<dim>&>(*tria).clear_user_flags_quad ();
 
-      std::vector<unsigned int> 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<GeometryInfo<dim>::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; level<tria->n_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; level<tria->n_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<std::vector<bool> >
          line_fe_association (finite_elements->size(),
-                              std::vector<bool> (tria->n_raw_lines(level),
+                              std::vector<bool> (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<GeometryInfo<dim>::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<bool> line_is_used (tria->n_raw_lines(level), false);
-       for (unsigned int line=0; line<tria->n_raw_lines(level); ++line)
+       std::vector<bool> line_is_used (tria->n_raw_lines(), false);
+       for (unsigned int line=0; line<tria->n_raw_lines(); ++line)
          for (unsigned int fe=0; fe<finite_elements->size(); ++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; line<tria->n_raw_lines(level); ++line)
+       for (unsigned int line=0; line<tria->n_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; fe<finite_elements->size(); ++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; line<tria->n_raw_lines(level); ++line)
+       faces->lines.dofs.resize (line_slots_needed, invalid_dof_index);
+       for (unsigned int line=0; line<tria->n_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; fe<finite_elements->size(); ++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<levels.size(); ++i)
       delete levels[i];
     levels.resize (0);
+    delete faces;
+    faces = NULL;
 
     {
       std::vector<unsigned int> tmp;
index a2205358e15d9bccc9e2fe3430e4ed94b8c69571..8f5480aa74a00e966c525757d779b58dbc7b5976 100644 (file)
@@ -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
   }
 }
index 949e3ef9df5076257b36569389597f7792441d04..a733dc64b2fcb05d206d14aab317dd3d80128ce4 100644 (file)
 
 
 #include <base/memory_consumption.h>
-#include <dofs/hp_dof_levels.h>
-#include <dofs/hp_dof_handler.h>
 #include <fe/fe_collection.h>
 
-//TODO[WB]: make a few of these functions inline
-
-
 namespace internal
 {
   namespace hp
   {
-    template <int dim>
-    unsigned int
-    DoFLevel<1>::
-    get_dof_index (const ::hp::DoFHandler<dim> &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<dim>::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 <int dim>
-    void
-    DoFLevel<1>::
-    set_dof_index (const ::hp::DoFHandler<dim> &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<dim>::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 <int dim>
-    unsigned int
-    DoFLevel<1>::
-    n_active_fe_indices (const ::hp::DoFHandler<dim> &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 <int dim>
-    bool
-    DoFLevel<1>::
-    fe_index_is_active (const ::hp::DoFHandler<dim> &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<dim>::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 <int dim>
-    unsigned int
-    DoFLevel<2>::
-    get_dof_index (const ::hp::DoFHandler<dim> &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<dim>::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 <int dim>
-    void
-    DoFLevel<2>::
-    set_dof_index (const ::hp::DoFHandler<dim> &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<dim>::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 <int dim>
-    unsigned int
-    DoFLevel<2>::
-    n_active_fe_indices (const ::hp::DoFHandler<dim> &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 <int dim>
-    bool
-    DoFLevel<2>::
-    fe_index_is_active (const ::hp::DoFHandler<dim> &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<dim>::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 <int dim>
-    unsigned int
-    DoFLevel<3>::
-    get_dof_index (const ::hp::DoFHandler<dim> &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<dim>::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 <int dim>
-    void
-    DoFLevel<3>::
-    set_dof_index (const ::hp::DoFHandler<dim> &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<dim>::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 <int dim>
-    unsigned int
-    DoFLevel<3>::
-    n_active_fe_indices (const ::hp::DoFHandler<dim> &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 <int dim>
-    bool
-    DoFLevel<3>::
-    fe_index_is_active (const ::hp::DoFHandler<dim> &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<dim>::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<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &dof_handler,
-                         const unsigned int           line_index,
-                         internal::StructuralDimension<1> dummy) const;
-
-    template
-    bool
-    DoFLevel<1>::
-    fe_index_is_active (const ::hp::DoFHandler<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &dof_handler,
-                         const unsigned int           quad_index,
-                         internal::StructuralDimension<2> dummy) const;
-    
-
-    template
-    bool
-    DoFLevel<2>::
-    fe_index_is_active (const ::hp::DoFHandler<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &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<deal_II_dimension> &dof_handler,
-                         const unsigned int           hex_index,
-                         internal::StructuralDimension<3> dummy) const;
 
-    template
-    bool
-    DoFLevel<3>::
-    fe_index_is_active (const ::hp::DoFHandler<deal_II_dimension> &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 (file)
index 0000000..67eb1e6
--- /dev/null
@@ -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 <base/memory_consumption.h>
+#include <dofs/hp_dof_objects.h>
+#include <dofs/hp_dof_levels.h>
+#include <dofs/hp_dof_handler.h>
+
+
+namespace internal
+{
+  namespace hp
+  {
+    template <int structdim>
+    unsigned int
+    DoFObjects<structdim>::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
+  }
+}
index d07ec6ad8b5952a92cf862ff8f7dff444b9048a8..f9186abc37798db09a67119f86e4c7a7e35fceb0 100644 (file)
@@ -28,8 +28,6 @@
 #include <grid/tria_levels.h>
 #include <grid/tria_boundary.h>
 
-#include <algorithm>
-#include <functional>
 #include <numeric>
 
 
@@ -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<bool>(), 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()<DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("lines",
-                               lines.lines.size(), lines.lines.capacity()));
-      Assert (lines.children.size() == lines.children.capacity() ||
-              lines.children.size()<DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("children",
-                               lines.children.size(), lines.children.capacity()));
-      Assert (lines.used.size() <= lines.used.capacity() + sizeof(int)*8 ||
-              lines.used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("used",
-                               lines.used.size(), lines.used.capacity()));
-      Assert (lines.user_flags.size() <= lines.user_flags.capacity() + sizeof(int)*8 ||
-              lines.user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("user_flags",
-                               lines.user_flags.size(), lines.user_flags.capacity()));
-      Assert (lines.lines.size() == lines.used.size(),
-              ExcMemoryInexact (lines.lines.size(), lines.used.size()));
-      Assert (lines.lines.size() == lines.user_flags.size(),
-              ExcMemoryInexact (lines.lines.size(), lines.user_flags.size()));
-      Assert (lines.lines.size() == lines.children.size(),
-              ExcMemoryInexact (lines.lines.size(), lines.children.size()));
-      Assert (lines.lines.size() == lines.material_id.size(),
-              ExcMemoryInexact (lines.lines.size(), lines.material_id.size()));
-      Assert (lines.lines.size() == lines.user_pointers.size(),
-              ExcMemoryInexact (lines.lines.size(), lines.user_pointers.size()));
-
-      TriaLevel<0>::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<bool>(), 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()<DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("quads",
-                               quads.quads.size(), quads.quads.capacity()));
-      Assert (quads.children.size() == quads.children.capacity() ||
-              quads.children.size()<DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("children",
-                               quads.children.size(), quads.children.capacity()));
-      Assert (quads.used.size() <= quads.used.capacity() + sizeof(int)*8 ||
-              quads.used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("used",
-                               quads.used.size(), quads.used.capacity()));
-      Assert (quads.user_flags.size() <= quads.user_flags.capacity() + sizeof(int)*8 ||
-              quads.user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("user_flags",
-                               quads.user_flags.size(), quads.user_flags.capacity()));
-      Assert (quads.quads.size() == quads.used.size(),
-              ExcMemoryInexact (quads.quads.size(), quads.used.size()));
-      Assert (quads.quads.size() == quads.user_flags.size(),
-              ExcMemoryInexact (quads.quads.size(), quads.user_flags.size()));
-      Assert (quads.quads.size() == quads.children.size(),
-              ExcMemoryInexact (quads.quads.size(), quads.children.size()));
-      Assert (quads.quads.size() == quads.material_id.size(),
-              ExcMemoryInexact (quads.quads.size(), quads.material_id.size()));
-      Assert (quads.quads.size() == quads.user_pointers.size(),
-              ExcMemoryInexact (quads.quads.size(), quads.user_pointers.size()));
-
-      TriaLevel<1>::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<bool>(), 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()<DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("hexes",
-                               hexes.hexes.size(), hexes.hexes.capacity()));
-      Assert (hexes.children.size() == hexes.children.capacity() ||
-              hexes.children.size()<DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("children",
-                               hexes.children.size(), hexes.children.capacity()));
-      Assert (hexes.used.size() <= hexes.used.capacity() + sizeof(int)*8 ||
-              hexes.used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("used",
-                               hexes.used.size(), hexes.used.capacity()));
-      Assert (hexes.user_flags.size() <= hexes.user_flags.capacity() + sizeof(int)*8 ||
-              hexes.user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("user_flags",
-                               hexes.user_flags.size(), hexes.user_flags.capacity()));
-      Assert (hexes.hexes.size() == hexes.used.size(),
-              ExcMemoryInexact (hexes.hexes.size(), hexes.used.size()));
-      Assert (hexes.hexes.size() == hexes.user_flags.size(),
-              ExcMemoryInexact (hexes.hexes.size(), hexes.user_flags.size()));
-      Assert (hexes.hexes.size() == hexes.children.size(),
-              ExcMemoryInexact (hexes.hexes.size(), hexes.children.size()));
-      Assert (hexes.hexes.size() == hexes.material_id.size(),
-              ExcMemoryInexact (hexes.hexes.size(), hexes.material_id.size()));
-      Assert (hexes.hexes.size() == hexes.user_pointers.size(),
-              ExcMemoryInexact (hexes.hexes.size(), hexes.user_pointers.size()));
-      Assert (hexes.hexes.size() * GeometryInfo<3>::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));
     }
 
 
index 567a6f71e99954b65f052c69d6c471e983d6e70e..b21926db7b85af7ae021b5b05d4912f69b768982 100644 (file)
 //
 //---------------------------------------------------------------------------
 
-
 #include <base/memory_consumption.h>
 #include <grid/tria.h>
 #include <grid/tria_levels.h>
+#include <grid/tria_faces.h>
 #include <grid/tria_boundary.h>
 #include <grid/tria_accessor.h>
 #include <grid/tria_iterator.h>
@@ -51,6 +51,7 @@ Triangulation<dim>::dimension;
 template <int dim>
 Triangulation<dim>::Triangulation (const MeshSmoothing smooth_grid) :
                Subscriptor (),
+               faces(NULL),
                smooth_grid(smooth_grid)
 {
                                   // set default boundary for all
@@ -78,6 +79,7 @@ Triangulation<dim>::~Triangulation ()
   for (unsigned int i=0; i<levels.size(); ++i)
     delete levels[i];
   levels.clear ();
+  delete faces;
 }
 
 
@@ -174,6 +176,17 @@ Triangulation<1>::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<dim>::copy_triangulation (const Triangulation<dim> &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<dim>(*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<Point<1> >    &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<Point<1> >    &v,
   levels.push_back (new internal::Triangulation::TriaLevel<dim>);
   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<Point<2> >    &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<Point<2> >    &v,
        
                                   // reserve enough space
   levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+  faces = new internal::Triangulation::TriaFaces<dim>;
   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<Point<3> >    &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<Point<3> >    &v,
                                   // for the lines
                                   // reserve enough space
   levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+  faces = new internal::Triangulation::TriaFaces<dim>;
   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<Point<3> >    &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<Point<3> >    &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 <int dim>
 typename Triangulation<dim>::raw_line_iterator
 Triangulation<dim>::begin_raw_line (const unsigned int level) const
+{
+  Assert (level == 0, ExcFacesHaveNoLevel());
+  return raw_line_iterator (const_cast<Triangulation<dim>*>(this),
+                           0,
+                           0);
+}
+
+
+
+template <>
+Triangulation<1>::raw_line_iterator
+Triangulation<1>::begin_raw_line (const unsigned int level) const
 {
   Assert (level<levels.size(), ExcInvalidLevel(level));
-  
-  if (levels[level]->lines.lines.size() == 0)
+
+  if (levels[level]->lines.cells.size() == 0)
     return end_line ();
-  
-  return raw_line_iterator (const_cast<Triangulation<dim>*>(this),
+
+  return raw_line_iterator (const_cast<Triangulation<1>*>(this),
                            level,
                            0);
 }
@@ -3488,13 +3445,27 @@ Triangulation<dim>::begin_raw_line (const unsigned int level) const
 template <int dim>
 typename Triangulation<dim>::raw_quad_iterator
 Triangulation<dim>::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<Triangulation<dim>*>(this),
+                           0,
+                           0);
+}
+
+
+
+template <>
+Triangulation<2>::raw_quad_iterator
+Triangulation<2>::begin_raw_quad (const unsigned int level) const
 {
   Assert (level<levels.size(), ExcInvalidLevel(level));
 
-  if (levels[level]->quads.quads.size() == 0)
+  if (levels[level]->quads.cells.size() == 0)
     return end_quad();
   
-  return raw_quad_iterator (const_cast<Triangulation<dim>*>(this),
+  return raw_quad_iterator (const_cast<Triangulation<2>*>(this),
                            level,
                            0);
 }
@@ -3507,7 +3478,7 @@ Triangulation<dim>::begin_raw_hex (const unsigned int level) const
 {
   Assert (level<levels.size(), ExcInvalidLevel(level));
 
-  if (levels[level]->hexes.hexes.size() == 0)
+  if (levels[level]->hexes.cells.size() == 0)
     return end_hex();
   
   return raw_hex_iterator (const_cast<Triangulation<dim>*>(this),
@@ -3649,29 +3620,52 @@ Triangulation<dim>::end_hex () const
 template <int dim>
 typename Triangulation<dim>::raw_line_iterator
 Triangulation<dim>::last_raw_line (const unsigned int level) const
+{
+  Assert (level == 0, ExcFacesHaveNoLevel());
+
+  return raw_line_iterator (const_cast<Triangulation<dim>*>(this),
+                           0,
+                           faces->lines.cells.size()-1);
+  
+}
+
+
+template <>
+Triangulation<1>::raw_line_iterator
+Triangulation<1>::last_raw_line (const unsigned int level) const
 {
   Assert (level<levels.size(), ExcInvalidLevel(level));
-  Assert (levels[level]->lines.lines.size() != 0,
+  Assert (levels[level]->lines.cells.size() != 0,
          ExcEmptyLevel (level));
-  
-  return raw_line_iterator (const_cast<Triangulation<dim>*>(this),
+
+  return raw_line_iterator (const_cast<Triangulation<1>*>(this),
                            level,
-                           levels[level]->lines.lines.size()-1);
+                           levels[level]->lines.cells.size()-1);
 }
 
 
 template <int dim>
 typename Triangulation<dim>::raw_quad_iterator
 Triangulation<dim>::last_raw_quad (const unsigned int level) const
+{
+  Assert (level == 0, ExcFacesHaveNoLevel());
+  return raw_quad_iterator (const_cast<Triangulation<dim>*>(this),
+                           0,
+                           faces->quads.cells.size()-1);
+}
+
+
+template <>
+Triangulation<2>::raw_quad_iterator
+Triangulation<2>::last_raw_quad (const unsigned int level) const
 {
   Assert (level<levels.size(),
          ExcInvalidLevel(level));
-  Assert (levels[level]->quads.quads.size() != 0,
+  Assert (levels[level]->quads.cells.size() != 0,
          ExcEmptyLevel (level));
-
-  return raw_quad_iterator (const_cast<Triangulation<dim>*>(this),
+  return raw_quad_iterator (const_cast<Triangulation<2>*>(this),
                            level,
-                           levels[level]->quads.quads.size()-1);
+                           levels[level]->quads.cells.size()-1);
 }
 
 
@@ -3681,12 +3675,12 @@ Triangulation<dim>::last_raw_hex (const unsigned int level) const
 {
   Assert (level<levels.size(),
          ExcInvalidLevel(level));
-  Assert (levels[level]->hexes.hexes.size() != 0,
+  Assert (levels[level]->hexes.cells.size() != 0,
          ExcEmptyLevel (level));
 
   return raw_hex_iterator (const_cast<Triangulation<dim>*>(this),
                           level,
-                          levels[level]->hexes.hexes.size()-1);
+                          levels[level]->hexes.cells.size()-1);
 }
 
 
@@ -3694,7 +3688,10 @@ template <int dim>
 typename Triangulation<dim>::raw_line_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::raw_quad_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::line_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::quad_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::hex_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::line_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::quad_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::active_line_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::active_quad_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::active_hex_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::active_line_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::active_quad_iterator
 Triangulation<dim>::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<dim>::end_active (const unsigned int level) const
 
 template <int dim>
 typename Triangulation<dim>::raw_face_iterator
-Triangulation<dim>::end_raw_face (const unsigned int level) const
-{
-  return (level == levels.size()-1 ?
-         end_face() :
-         begin_raw_face (level+1));
-}
-
-
-template <int dim>
-typename Triangulation<dim>::face_iterator
-Triangulation<dim>::end_face (const unsigned int level) const
+Triangulation<dim>::end_raw_face () const
 {
-  return (level == levels.size()-1 ?
-         face_iterator(end_face()) :
-         begin_face (level+1));
+  return end_face();
 }
 
 
 template <int dim>
 typename Triangulation<dim>::active_face_iterator
-Triangulation<dim>::end_active_face (const unsigned int level) const
+Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::raw_line_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::line_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::active_line_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::raw_quad_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::quad_iterator
 Triangulation<dim>::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 <int dim>
 typename Triangulation<dim>::active_quad_iterator
 Triangulation<dim>::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<dim>::n_active_cells () const
 
 template <int dim>
 unsigned int Triangulation<dim>::n_faces () const
-{
-  unsigned int n=0;
-  for (unsigned int l=0; l<levels.size(); ++l)
-    n += n_faces (l);
-  return n;
-}
-
-
-template <int dim>
-unsigned int Triangulation<dim>::n_active_faces () const
-{
-  unsigned int n=0;
-  for (unsigned int l=0; l<levels.size(); ++l)
-    n += n_active_faces (l);
-  return n;
-}
-
-
-template <int dim>
-unsigned int
-Triangulation<dim>::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 <int dim>
-unsigned int
-Triangulation<dim>::n_active_faces(unsigned int l) const
+unsigned int Triangulation<dim>::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<dim>::n_lines () const
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::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 <int dim>
+unsigned int Triangulation<dim>::n_raw_lines (const unsigned int) const
+{
+  Assert(false, ExcFacesHaveNoLevel());
+  return 0;
+}
+
+
+template <int dim>
+unsigned int Triangulation<dim>::n_raw_lines () const
+{
+  return faces->lines.cells.size();
 }
 
 
@@ -4163,7 +4190,7 @@ unsigned int Triangulation<dim>::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<dim>::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<dim>::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 <int dim>
-unsigned int Triangulation<dim>::n_raw_quads (const unsigned int level) const
+unsigned int Triangulation<dim>::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 <int dim>
+unsigned int Triangulation<dim>::n_raw_quads () const
+{
+  Assert (false, ExcNotImplemented());
+  return 0;
+}
+
+
+
 template <int dim>
 unsigned int Triangulation<dim>::n_active_quads () const
 {
@@ -4269,6 +4326,7 @@ unsigned int Triangulation<dim>::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 <int dim>
 unsigned int Triangulation<dim>::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<dim>::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; level<levels.size(); ++level) 
-    levels[level]->monitor_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; level<levels.size(); ++level) 
-    levels[level]->monitor_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; level<levels.size(); ++level) 
-    levels[level]->monitor_memory (3);
+    levels[level]->hexes.monitor_memory (3);
 
                                   // check whether really all
                                   // refinement flags are reset (also
@@ -8876,6 +8930,8 @@ Triangulation<dim>::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<dim>::memory_consumption () const
   
 
 
-template <int dim>
-void Triangulation<dim>::update_number_cache_lines () 
+template <>
+void Triangulation<1>::update_number_cache_lines () 
 {
                                   ///////////////////////////////////
                                   // update the number of lines
@@ -8896,7 +8952,7 @@ void Triangulation<dim>::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<dim>::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<dim>::update_number_cache_lines ()
 }
 
 
+template <int dim>
+void Triangulation<dim>::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 <int dim>
-void Triangulation<dim>::update_number_cache_quads () 
+template <>
+void Triangulation<2>::update_number_cache_quads () 
 {
                                   ///////////////////////////////////
                                   // update the number of quads
@@ -8957,7 +9041,7 @@ void Triangulation<dim>::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<dim>::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<dim>::update_number_cache_quads ()
 #endif
 
 
+#if deal_II_dimension > 2
+
+template <int dim>
+void Triangulation<dim>::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 <int dim>
 void Triangulation<dim>::update_number_cache_hexes () 
@@ -9031,7 +9149,7 @@ void Triangulation<dim>::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<dim>::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);
index 55bffa0dfa78f7f4f8efa24a3281f81cab6f5a46..301f7d738bab921d083d25285ccba65bed8f8acb 100644 (file)
@@ -32,9 +32,19 @@ template <int dim>
 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 dim>
 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<dim>::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<dim>::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<dim>::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<dim>::ExcDereferenceInvalidObject());
   this->tria->levels[this->present_level]->lines.used[this->present_index] = false;
 }
 
@@ -105,6 +145,16 @@ template <int dim>
 void TriaObjectAccessor<1, dim>::set_user_pointer (void *p) const
 {
   Assert (used(), typename TriaAccessor<dim>::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<dim>::ExcCellNotUsed());
   this->tria->levels[this->present_level]->lines.user_pointers[this->present_index] = p;
 }
 
@@ -114,6 +164,16 @@ template <int dim>
 void TriaObjectAccessor<1, dim>::clear_user_pointer () const
 {
   Assert (used(), typename TriaAccessor<dim>::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<dim>::ExcCellNotUsed());
   this->tria->levels[this->present_level]->lines.user_pointers[this->present_index] = 0;
 }
 
@@ -123,6 +183,16 @@ template <int dim>
 void * TriaObjectAccessor<1, dim>::user_pointer () const
 {
   Assert (used(), typename TriaAccessor<dim>::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<dim>::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<dim>::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<dim>::ExcCellNotUsed());
+  Assert ((index==-1) ||
+         (!has_children() && (index>=0)),
+         TriaAccessor<dim>::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<dim>::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<dim>::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 <int dim>
 bool TriaObjectAccessor<1, dim>::at_boundary () const
 {
@@ -261,9 +363,19 @@ template <int dim>
 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<dim>::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<dim>::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<dim>::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<dim>::ExcDereferenceInvalidObject());
   this->tria->levels[this->present_level]->quads.used[this->present_index] = false;
 }
 
@@ -336,6 +471,16 @@ template <int dim>
 void TriaObjectAccessor<2, dim>::set_user_pointer (void *p) const
 {
   Assert (used(), typename TriaAccessor<dim>::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<dim>::ExcCellNotUsed());
   this->tria->levels[this->present_level]->quads.user_pointers[this->present_index] = p;
 }
 
@@ -345,6 +490,16 @@ template <int dim>
 void TriaObjectAccessor<2, dim>::clear_user_pointer () const
 {
   Assert (used(), typename TriaAccessor<dim>::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<dim>::ExcCellNotUsed());
   this->tria->levels[this->present_level]->quads.user_pointers[this->present_index] = 0;
 }
 
@@ -354,6 +509,16 @@ template <int dim>
 void * TriaObjectAccessor<2, dim>::user_pointer () const
 {
   Assert (used(), typename TriaAccessor<dim>::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<dim>::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<dim>::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<dim>::ExcCellNotUsed());
+  Assert ((index==-1) ||
+         (!has_children() && (index>=0)),
+         TriaAccessor<dim>::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 <int dim>
 unsigned char TriaObjectAccessor<2, dim>::boundary_indicator () const
 {
-  Assert (dim>=3, ExcImpossibleInDim(dim));
-  Assert (used(), typename TriaAccessor<dim>::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 <int dim>
-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<dim>::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 <int dim>
+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 <int dim>
-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<dim>::ExcDereferenceInvalidObject());
+         TriaAccessor<dim>::ExcDereferenceInvalidObject());
   this->tria->levels[this->present_level]->hexes.used[this->present_index] = true;
 }
 
 
 
-template <int dim>
-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<dim>::ExcDereferenceInvalidObject());
+         TriaAccessor<dim>::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 <int dim>
-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<dim>::ExcCellNotUsed());
+  const int dim=3;
+  Assert (used(), TriaAccessor<dim>::ExcCellNotUsed());
   this->tria->levels[this->present_level]->hexes.user_pointers[this->present_index] = p;
 }
 
 
 
-template <int dim>
-void TriaObjectAccessor<3, dim>::clear_user_pointer () const
+template <>
+void TriaObjectAccessor<3, 3>::clear_user_pointer () const
 {
-  Assert (used(), typename TriaAccessor<dim>::ExcCellNotUsed());
+  const int dim=3;
+  Assert (used(), TriaAccessor<dim>::ExcCellNotUsed());
   this->tria->levels[this->present_level]->hexes.user_pointers[this->present_index] = 0;
 }
 
 
 
-template <int dim>
-void * TriaObjectAccessor<3, dim>::user_pointer () const
+template <>
+void * TriaObjectAccessor<3, 3>::user_pointer () const
 {
-  Assert (used(), typename TriaAccessor<dim>::ExcCellNotUsed());
+  const int dim=3;
+  Assert (used(), TriaAccessor<dim>::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 <int dim>
-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<dim>::ExcCellNotUsed());
+  const int dim=3;
+  Assert (used(), TriaAccessor<dim>::ExcCellNotUsed());
   Assert ((index==-1) ||
          (!has_children() && (index>=0)),
-         typename TriaAccessor<dim>::ExcCantSetChildren(index));
+         TriaAccessor<dim>::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 <int dim>
 unsigned char TriaObjectAccessor<3, dim>::boundary_indicator () const
 {
-  Assert (dim<4, ExcImpossibleInDim(dim));
-  Assert (used(), typename TriaAccessor<dim>::ExcCellNotUsed());
-
-  return this->tria->levels[this->present_level]->hexes.material_id[this->present_index];
+  Assert (false, ExcImpossibleInDim(dim));
+  return 255;
 }
 
 
 
 template <int dim>
-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<dim>::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 <int dim>
+template <>
 void
-TriaObjectAccessor<3, dim>::
+TriaObjectAccessor<3, 3>::
 set_face_orientation (const unsigned int face,
                       const bool         orientation) const
 {
-  Assert (used(), typename TriaAccessor<dim>::ExcCellNotUsed());
+  const int dim=3;
+  Assert (used(), TriaAccessor<dim>::ExcCellNotUsed());
   Assert (face<GeometryInfo<3>::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 (file)
index 0000000..3ff66a6
--- /dev/null
@@ -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 <base/memory_consumption.h>
+#include <grid/tria_faces.h>
+
+
+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 (file)
index 0000000..96afe61
--- /dev/null
@@ -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 <base/memory_consumption.h>
+#include <grid/tria_objects.h>
+
+#include <algorithm>
+#include <functional>
+
+
+namespace internal
+{
+  namespace Triangulation
+  {
+    
+    template<>
+    void
+    TriaObjects<Line>::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<bool>(), 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<Quad>::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<bool>(), 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<bool>(), 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<Line>::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()<DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("lines",
+                               cells.size(), cells.capacity()));
+      Assert (children.size() == children.capacity() ||
+              children.size()<DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("children",
+                               children.size(), children.capacity()));
+      Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
+              used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("used",
+                               used.size(), used.capacity()));
+      Assert (user_flags.size() <= user_flags.capacity() + sizeof(int)*8 ||
+              user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("user_flags",
+                               user_flags.size(), user_flags.capacity()));
+      Assert (cells.size() == used.size(),
+              ExcMemoryInexact (cells.size(), used.size()));
+      Assert (cells.size() == user_flags.size(),
+              ExcMemoryInexact (cells.size(), user_flags.size()));
+      Assert (cells.size() == children.size(),
+              ExcMemoryInexact (cells.size(), children.size()));
+      Assert (cells.size() == material_id.size(),
+              ExcMemoryInexact (cells.size(), material_id.size()));
+      Assert (cells.size() == user_pointers.size(),
+              ExcMemoryInexact (cells.size(), user_pointers.size()));
+    }
+
+
+    template<>
+    void
+    TriaObjects<Quad>::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()<DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("quads",
+                               cells.size(), cells.capacity()));
+      Assert (children.size() == children.capacity() ||
+              children.size()<DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("children",
+                               children.size(), children.capacity()));
+      Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
+              used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("used",
+                               used.size(), used.capacity()));
+      Assert (user_flags.size() <= user_flags.capacity() + sizeof(int)*8 ||
+              user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("user_flags",
+                               user_flags.size(), user_flags.capacity()));
+      Assert (cells.size() == used.size(),
+              ExcMemoryInexact (cells.size(), used.size()));
+      Assert (cells.size() == user_flags.size(),
+              ExcMemoryInexact (cells.size(), user_flags.size()));
+      Assert (cells.size() == children.size(),
+              ExcMemoryInexact (cells.size(), children.size()));
+      Assert (cells.size() == material_id.size(),
+              ExcMemoryInexact (cells.size(), material_id.size()));
+      Assert (cells.size() == user_pointers.size(),
+              ExcMemoryInexact (cells.size(), user_pointers.size()));
+    }
+
+
+    void
+    TriaObjectsHex::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()<DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("hexes",
+                               cells.size(), cells.capacity()));
+      Assert (children.size() == children.capacity() ||
+              children.size()<DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("children",
+                               children.size(), children.capacity()));
+      Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
+              used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("used",
+                               used.size(), used.capacity()));
+      Assert (user_flags.size() <= user_flags.capacity() + sizeof(int)*8 ||
+              user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("user_flags",
+                               user_flags.size(), user_flags.capacity()));
+      Assert (cells.size() == used.size(),
+              ExcMemoryInexact (cells.size(), used.size()));
+      Assert (cells.size() == user_flags.size(),
+              ExcMemoryInexact (cells.size(), user_flags.size()));
+      Assert (cells.size() == children.size(),
+              ExcMemoryInexact (cells.size(), children.size()));
+      Assert (cells.size() == material_id.size(),
+              ExcMemoryInexact (cells.size(), material_id.size()));
+      Assert (cells.size() == user_pointers.size(),
+              ExcMemoryInexact (cells.size(), user_pointers.size()));
+      Assert (cells.size() * GeometryInfo<3>::faces_per_cell
+              == face_orientations.size(),
+              ExcMemoryInexact (cells.size() * GeometryInfo<3>::faces_per_cell,
+                                face_orientations.size()));
+    }
+
+
+    template <typename G>
+    void
+    TriaObjects<G>::clear()
+    {
+      cells.clear();
+      children.clear();
+      used.clear();
+      user_flags.clear();
+      material_id.clear();
+      user_pointers.clear();
+    }
+    
+
+    void
+    TriaObjectsHex::clear()
+    {
+      TriaObjects<Hexahedron>::clear();
+      face_orientations.clear();
+    }
+    
+    
+    template<typename G>
+    unsigned int
+    TriaObjects<G>::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<Hexahedron>::memory_consumption() );
+    }
+
+                                    // explicit instantiations
+
+    template class TriaObjects<Line>;
+
+#if deal_II_dimension >=2
+    template class TriaObjects<Quad>;
+#endif
+    
+  }
+}
index d74ee6bec4851c535fc042797b818615e898018c..943ab81ee90fb4e6ef60557ed083136e004ec46a 100644 (file)
@@ -126,12 +126,11 @@ template <int structdim, int dim>
 unsigned int
 MGDoFAccessor<structdim, dim>::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<structdim>());
+  return this->mg_dof_handler
+    ->template get_dof_index<structdim>(this->present_level,
+                                       this->present_index,
+                                       0,
+                                       i);
 }
 
 
@@ -139,13 +138,12 @@ template <int structdim, int dim>
 void MGDoFAccessor<structdim, dim>::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<structdim>());
+  this->mg_dof_handler
+    ->template set_dof_index<structdim>(this->present_level,
+                                       this->present_index,
+                                       0,
+                                       i,
+                                       index);
 }
 
 
@@ -154,8 +152,14 @@ template <int structdim, int dim>
 TriaIterator<dim,MGDoFObjectAccessor<structdim, dim> >
 MGDoFAccessor<structdim, dim>::child (const unsigned int i) const
 {
+  int next_level;
+  if (structdim==dim)
+    next_level=this->present_level+1;
+  else
+    next_level=0;
+  
   TriaIterator<dim,MGDoFObjectAccessor<structdim, dim> > 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<dim,MGDoFObjectAccessor<1, dim> >
     (
       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<dim,MGDoFObjectAccessor<1, dim> >
     (
       this->tria,
-      this->present_level,
+      0,
       this->line_index (i),
       this->mg_dof_handler
     );
@@ -478,12 +482,12 @@ template <int dim>
 TriaIterator<dim,MGDoFObjectAccessor<2, dim> >
 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<dim,MGDoFObjectAccessor<2, dim> >
     (
       this->tria,
-      this->present_level,
+      0,
       this->quad_index (i),
       this->mg_dof_handler
     );
index fad50410705e21d6387d069d4945c52db79caa33..d538bda48e09d1b10723aed69eaba9db855e7d15 100644 (file)
@@ -13,6 +13,7 @@
 
 
 #include <dofs/dof_levels.h>
+#include <dofs/dof_faces.h>
 #include <dofs/dof_constraints.h>
 #include <multigrid/mg_dof_handler.h>
 #include <multigrid/mg_dof_accessor.h>
@@ -109,7 +110,8 @@ const unsigned int MGDoFHandler<dim>::dimension;
 
 template <int dim>
 MGDoFHandler<dim>::MGDoFHandler (const Triangulation<dim> &tria) :
-               DoFHandler<dim> (tria)
+               DoFHandler<dim> (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<dim>::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 <int dim>
 typename MGDoFHandler<dim>::raw_line_iterator
 MGDoFHandler<dim>::end_line () const
@@ -1046,43 +1112,14 @@ MGDoFHandler<dim>::end_active (const unsigned int level) const
 }
 
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::raw_face_iterator
-MGDoFHandler<dim>::end_raw_face (const unsigned int level) const
-{
-  return (level == mg_levels.size()-1 ?
-         end_face() :
-         begin_raw_face (level+1));
-}
-
-
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::face_iterator
-MGDoFHandler<dim>::end_face (const unsigned int level) const
-{
-  return (level == mg_levels.size()-1 ?
-         face_iterator(end_face()) :
-         begin_face (level+1));
-}
-
-
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::active_face_iterator
-MGDoFHandler<dim>::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 <int dim>
 typename internal::MGDoFHandler::Iterators<dim>::raw_line_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename internal::MGDoFHandler::Iterators<dim>::line_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename internal::MGDoFHandler::Iterators<dim>::active_line_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename internal::MGDoFHandler::Iterators<dim>::raw_quad_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename internal::MGDoFHandler::Iterators<dim>::quad_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename internal::MGDoFHandler::Iterators<dim>::active_quad_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename internal::MGDoFHandler::Iterators<dim>::raw_hex_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename internal::MGDoFHandler::Iterators<dim>::hex_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename internal::MGDoFHandler::Iterators<dim>::active_hex_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename MGDoFHandler<dim>::raw_line_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename MGDoFHandler<dim>::raw_quad_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename MGDoFHandler<dim>::raw_hex_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename MGDoFHandler<dim>::line_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename MGDoFHandler<dim>::quad_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename MGDoFHandler<dim>::hex_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename MGDoFHandler<dim>::active_line_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename MGDoFHandler<dim>::active_quad_iterator
 MGDoFHandler<dim>::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 <int dim>
 typename MGDoFHandler<dim>::active_hex_iterator
 MGDoFHandler<dim>::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 <int dim>
 void MGDoFHandler<dim>::distribute_dofs (const FiniteElement<dim> &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<unsigned int>::iterator i=mg_levels[level]->line_dofs.begin();
-       i!=mg_levels[level]->line_dofs.end(); ++i) 
+  for (std::vector<unsigned int>::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<unsigned int>::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<new_numbers.size(), ExcInternalError());
-         *i = new_numbers[*i];
-       }
+                                      // save user flags as they will be modified
+      std::vector<bool> user_flags;
+      this->tria->save_user_flags(user_flags);
+      const_cast<Triangulation<2> &>(*(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; d<this->selected_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<Triangulation<2> &>(*(this->tria)).load_user_flags (user_flags);
     }
 
-  for (std::vector<unsigned int>::iterator i=mg_levels[level]->quad_dofs.begin();
-       i!=mg_levels[level]->quad_dofs.end(); ++i)
+  for (std::vector<unsigned int>::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<unsigned int>::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<new_numbers.size(), ExcInternalError());
-         *i = new_numbers[*i];
-       }
+                                      // save user flags as they will be modified
+      std::vector<bool> user_flags;
+      this->tria->save_user_flags(user_flags);
+      const_cast<Triangulation<3> &>(*(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; d<this->selected_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<Triangulation<3> &>(*(this->tria)).load_user_flags (user_flags);
     }
 
-  for (std::vector<unsigned int>::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<new_numbers.size(), ExcInternalError());
-         *i = new_numbers[*i];
-       }
+                                      // save user flags as they will be modified
+      std::vector<bool> user_flags;
+      this->tria->save_user_flags(user_flags);
+      const_cast<Triangulation<3> &>(*(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; d<this->selected_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<Triangulation<3> &>(*(this->tria)).load_user_flags (user_flags);
     }
 
-  for (std::vector<unsigned int>::iterator i=mg_levels[level]->hex_dofs.begin();
-       i!=mg_levels[level]->hex_dofs.end(); ++i)
+                                  //HEX DoFs
+  for (std::vector<unsigned int>::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<unsigned int>(this->tria->n_raw_lines(i) *
+      mg_levels.back()->lines.dofs = std::vector<unsigned int>(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<unsigned int> (this->tria->n_raw_lines(i) *
-                                                         this->selected_fe->dofs_per_line,
-                                                         DoFHandler<2>::invalid_dof_index);
-      mg_levels.back()->quad_dofs = std::vector<unsigned int> (this->tria->n_raw_quads(i) *
+      mg_levels.back()->quads.dofs = std::vector<unsigned int> (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<unsigned int> (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<unsigned int> (this->tria->n_raw_lines(i) *
-                                    this->selected_fe->dofs_per_line,
-                                    DoFHandler<3>::invalid_dof_index);
-      mg_levels.back()->quad_dofs
-       = std::vector<unsigned int> (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<unsigned int> (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<unsigned int> (this->tria->n_raw_lines() *
+                                                   this->selected_fe->dofs_per_line,
+                                                   DoFHandler<3>::invalid_dof_index);
+  mg_faces->quads.dofs = std::vector<unsigned int> (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<dim>::clear_space ()
   for (unsigned int i=0; i<mg_levels.size(); ++i)
     delete mg_levels[i];
   mg_levels.clear ();
+  delete mg_faces;
+  mg_faces=NULL;
 
                                   // also delete vector of vertex
                                   // indices

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.