]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Merge branch_codimension_one.
authorbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Fri, 5 Dec 2008 22:27:44 +0000 (22:27 +0000)
committerbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Fri, 5 Dec 2008 22:27:44 +0000 (22:27 +0000)
git-svn-id: https://svn.dealii.org/trunk@17866 0785d39b-7218-0410-832d-ea1e28bc413d

143 files changed:
deal.II/base/include/base/geometry_info.h
deal.II/base/include/base/quadrature_lib.h
deal.II/base/include/base/tensor.h
deal.II/base/source/data_out_base.cc
deal.II/base/source/geometry_info.cc
deal.II/base/source/quadrature_lib.cc
deal.II/deal.II/Makefile
deal.II/deal.II/include/dofs/dof_accessor.h
deal.II/deal.II/include/dofs/dof_accessor.templates.h
deal.II/deal.II/include/dofs/dof_constraints.h
deal.II/deal.II/include/dofs/dof_faces.h
deal.II/deal.II/include/dofs/dof_handler.h
deal.II/deal.II/include/dofs/dof_iterator_selector.h
deal.II/deal.II/include/dofs/dof_levels.h
deal.II/deal.II/include/dofs/dof_objects.h
deal.II/deal.II/include/dofs/dof_tools.h
deal.II/deal.II/include/dofs/function_map.h
deal.II/deal.II/include/fe/fe.h
deal.II/deal.II/include/fe/fe_abf.h
deal.II/deal.II/include/fe/fe_base.h
deal.II/deal.II/include/fe/fe_dgp.h
deal.II/deal.II/include/fe/fe_dgp_monomial.h
deal.II/deal.II/include/fe/fe_dgp_nonparametric.h
deal.II/deal.II/include/fe/fe_dgq.h
deal.II/deal.II/include/fe/fe_nedelec.h
deal.II/deal.II/include/fe/fe_poly.h
deal.II/deal.II/include/fe/fe_poly.templates.h
deal.II/deal.II/include/fe/fe_poly_tensor.h
deal.II/deal.II/include/fe/fe_q.h
deal.II/deal.II/include/fe/fe_q_hierarchical.h
deal.II/deal.II/include/fe/fe_raviart_thomas.h
deal.II/deal.II/include/fe/fe_system.h
deal.II/deal.II/include/fe/fe_tools.h
deal.II/deal.II/include/fe/fe_update_flags.h
deal.II/deal.II/include/fe/fe_values.h
deal.II/deal.II/include/fe/mapping.h
deal.II/deal.II/include/fe/mapping_c1.h
deal.II/deal.II/include/fe/mapping_cartesian.h
deal.II/deal.II/include/fe/mapping_q.h
deal.II/deal.II/include/fe/mapping_q1.h
deal.II/deal.II/include/fe/mapping_q1_eulerian.h
deal.II/deal.II/include/fe/mapping_q_eulerian.h
deal.II/deal.II/include/grid/grid_generator.h
deal.II/deal.II/include/grid/grid_in.h
deal.II/deal.II/include/grid/grid_out.h
deal.II/deal.II/include/grid/grid_refinement.h
deal.II/deal.II/include/grid/grid_reordering.h
deal.II/deal.II/include/grid/grid_tools.h
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_boundary.h
deal.II/deal.II/include/grid/tria_boundary_lib.h
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_iterator_selector.h
deal.II/deal.II/include/grid/tria_objects.h
deal.II/deal.II/include/hp/dof_faces.h
deal.II/deal.II/include/hp/dof_handler.h
deal.II/deal.II/include/hp/dof_levels.h
deal.II/deal.II/include/hp/dof_objects.h
deal.II/deal.II/include/hp/fe_collection.h
deal.II/deal.II/include/hp/fe_values.h
deal.II/deal.II/include/hp/mapping_collection.h
deal.II/deal.II/include/multigrid/mg_dof_accessor.h
deal.II/deal.II/include/multigrid/mg_dof_handler.h
deal.II/deal.II/include/multigrid/mg_dof_iterator_selector.h
deal.II/deal.II/include/multigrid/mg_smoother.h
deal.II/deal.II/include/multigrid/mg_tools.h
deal.II/deal.II/include/multigrid/mg_transfer.h
deal.II/deal.II/include/multigrid/mg_transfer.templates.h
deal.II/deal.II/include/multigrid/mg_transfer_block.h
deal.II/deal.II/include/multigrid/mg_transfer_block.templates.h
deal.II/deal.II/include/multigrid/mg_transfer_component.h
deal.II/deal.II/include/multigrid/mg_transfer_component.templates.h
deal.II/deal.II/include/numerics/data_out.h
deal.II/deal.II/include/numerics/data_out_stack.h
deal.II/deal.II/include/numerics/derivative_approximation.h
deal.II/deal.II/include/numerics/error_estimator.h
deal.II/deal.II/include/numerics/matrices.h
deal.II/deal.II/include/numerics/time_dependent.h
deal.II/deal.II/include/numerics/vectors.h
deal.II/deal.II/include/numerics/vectors.templates.h
deal.II/deal.II/source/dofs/dof_accessor.cc
deal.II/deal.II/source/dofs/dof_accessor.inst.in
deal.II/deal.II/source/dofs/dof_handler.cc
deal.II/deal.II/source/dofs/dof_objects.cc
deal.II/deal.II/source/dofs/dof_tools.cc
deal.II/deal.II/source/fe/fe.cc
deal.II/deal.II/source/fe/fe_dgp.cc
deal.II/deal.II/source/fe/fe_dgp_nonparametric.cc
deal.II/deal.II/source/fe/fe_dgq.cc
deal.II/deal.II/source/fe/fe_nedelec.cc
deal.II/deal.II/source/fe/fe_poly.cc
deal.II/deal.II/source/fe/fe_poly_tensor.cc
deal.II/deal.II/source/fe/fe_q.cc
deal.II/deal.II/source/fe/fe_system.cc
deal.II/deal.II/source/fe/fe_tools.cc
deal.II/deal.II/source/fe/fe_values.cc
deal.II/deal.II/source/fe/fe_values.inst.in
deal.II/deal.II/source/fe/mapping.cc
deal.II/deal.II/source/fe/mapping_c1.cc
deal.II/deal.II/source/fe/mapping_cartesian.cc
deal.II/deal.II/source/fe/mapping_q.cc
deal.II/deal.II/source/fe/mapping_q1.cc
deal.II/deal.II/source/fe/mapping_q1_eulerian.cc
deal.II/deal.II/source/fe/mapping_q_eulerian.cc
deal.II/deal.II/source/grid/grid_generator.cc
deal.II/deal.II/source/grid/grid_in.cc
deal.II/deal.II/source/grid/grid_out.cc
deal.II/deal.II/source/grid/grid_refinement.cc
deal.II/deal.II/source/grid/grid_reordering.cc
deal.II/deal.II/source/grid/grid_tools.cc
deal.II/deal.II/source/grid/intergrid_map.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_boundary.cc
deal.II/deal.II/source/grid/tria_boundary_lib.cc
deal.II/deal.II/source/grid/tria_objects.cc
deal.II/deal.II/source/hp/dof_handler.cc
deal.II/deal.II/source/hp/fe_collection.cc
deal.II/deal.II/source/hp/fe_values.cc
deal.II/deal.II/source/hp/mapping_collection.cc
deal.II/deal.II/source/multigrid/mg_dof_accessor.cc
deal.II/deal.II/source/multigrid/mg_dof_handler.cc
deal.II/deal.II/source/multigrid/mg_dof_tools.cc
deal.II/deal.II/source/multigrid/mg_smoother.cc
deal.II/deal.II/source/multigrid/mg_transfer_block.cc
deal.II/deal.II/source/multigrid/mg_transfer_component.cc
deal.II/deal.II/source/multigrid/mg_transfer_prebuilt.cc
deal.II/deal.II/source/numerics/data_out.cc
deal.II/deal.II/source/numerics/data_out_stack.cc
deal.II/deal.II/source/numerics/derivative_approximation.cc
deal.II/deal.II/source/numerics/error_estimator.cc
deal.II/deal.II/source/numerics/matrices.cc
deal.II/deal.II/source/numerics/vectors.cc
deal.II/deal.II/source/numerics/vectors.inst.in
deal.II/doc/doxygen/headers/iterators.h
deal.II/doc/news/changes.h
deal.II/lac/include/lac/full_matrix.h
deal.II/lac/include/lac/full_matrix.templates.h
deal.II/lac/source/full_matrix.cc
deal.II/lac/source/full_matrix.inst.in

index 2296ee3df8c9b30e252ab609f1516dafd14b1f49..5bb41751229399c3bf458f1f170ba9ed680310f2 100644 (file)
@@ -810,6 +810,16 @@ struct GeometryInfo<0>
                                       */
     static const unsigned int max_children_per_face = 0;
 
+                                    /**
+                                     * Return the number of children
+                                     * of a cell (or face) refined
+                                     * with <tt>ref_case</tt>. Since
+                                     * we are concerned here with
+                                     * points, the number of children
+                                     * is equal to one.
+                                     */
+    static unsigned int n_children(const RefinementCase<0> &refinement_case);
+    
                                     /**
                                      * Number of vertices a cell has.
                                      */
@@ -1684,7 +1694,7 @@ struct GeometryInfo
                                      * entry.
                                      *
                                      * In the case of anisotropically refined
-                                     * cells and faces, the @p RefineCase of
+                                     * cells and faces, the @p RefinementCase of
                                      * the face, <tt>face_ref_case</tt>,
                                      * might have an influence on 
                                      * which child is behind which given
index 32f143b74e3fbb77a686467d6bb3ae2b7e527658..0606d258ea5973b9f50f96cb2e4101303a8ba50a 100644 (file)
@@ -306,6 +306,72 @@ class QWeddle : public Quadrature<dim>
     QWeddle ();
 };
 
+
+
+/**
+ * Gauss Quadrature Formula to integrate <tt>ln[(x-a)/(b-a)]*f(x)</tt> on the
+ * interval <tt>[a,b]</tt>, where f is a smooth function without
+ * singularities. See <tt>Numerical Recipes</tt> for more information.  The
+ * quadrature formula weights are chosen in order to integrate
+ * <tt>f(x)*ln[(x-a)/(b-a)]</tt> (that is, the argument of the logarithm goes
+ * linearly from 0 to 1 on the interval of integration). So, the only
+ * thing one can specify is the function <tt>f(x)</tt>. Using logarithm
+ * properties, one can add the integral of <tt>f(x)*ln(b-a)</tt> (calculated
+ * with QGauss class formulas) to the integral of <tt>f(x)*ln[(x-a)/(b-a)]</tt>
+ * to finally obtain the integral of <tt>f(x)*ln(x-a)</tt>.  It is also
+ * possible to integrate with weighting function <tt>ln[(b-x)/(b-a)]</tt> if
+ * revert is set to true.
+ * 
+ * It works up to <tt>n=12</tt>.
+ *
+//TODO: implement the calculation of points and weights as it is
+//described in Numerical Recipes, instead of passing them to set_*
+//functions, so that n can also be grater than 12.
+ *
+ */
+template <int dim>
+class QGaussLog : public Quadrature<dim>
+{
+  public:
+                                  /**
+                                   * Generate a formula with
+                                   * <tt>n</tt> quadrature points 
+                                   */
+  QGaussLog(const unsigned int n,
+            const bool revert=false);
+   
+  protected: 
+                                    /**  
+                                    * Sets the points of the
+                                    * quadrature formula.
+                                    */
+  std::vector<double>
+  set_quadrature_points(const unsigned int n) const;
+
+                                    /**  
+                                    * Sets the weights of the
+                                    * quadrature formula.
+                                    */
+  std::vector<double>
+  set_quadrature_weights(const unsigned int n) const;
+
+                                    /**  
+                                    * If the singularity is at the rightmost point 
+                                    * of the interval just revert the vectors
+                                    * of points and weights and everything 
+                                    * works.
+                                    */
+  void
+  revert_points_and_weights(std::vector<double> &p,
+                           std::vector<double> &w) const;
+
+};
+
+
+
+
+
+
 /*@}*/
 
 /* -------------- declaration of explicit specializations ------------- */
@@ -324,6 +390,11 @@ JacobiP(const long double, const int, const int, const unsigned int) const;
 template <>
 unsigned int 
 QGaussLobatto<1>::gamma(const unsigned int n) const;
+
+template <> void QGaussLog<1>::revert_points_and_weights(std::vector<double> &, std::vector<double> &) const;
+template <> std::vector<double> QGaussLog<1>::set_quadrature_points(const unsigned int) const;
+template <> std::vector<double> QGaussLog<1>::set_quadrature_weights(const unsigned int) const;
+
 template <> QGauss2<1>::QGauss2 ();
 template <> QGauss3<1>::QGauss3 ();
 template <> QGauss4<1>::QGauss4 ();
@@ -335,6 +406,10 @@ template <> QTrapez<1>::QTrapez ();
 template <> QSimpson<1>::QSimpson ();
 template <> QMilne<1>::QMilne ();
 template <> QWeddle<1>::QWeddle ();
+template <> QGaussLog<1>::QGaussLog (const unsigned int n, const bool revert);
+
+
+
 
 DEAL_II_NAMESPACE_CLOSE
 
index 59c192e4b379e068a6b985469a5941eaecfba51c..9ad9e4630860943d58688c2d03256785dce3856c 100644 (file)
@@ -230,10 +230,9 @@ class Tensor
     void clear ();
 
                                     /**
-                                     * Determine an estimate for
-                                     * the memory consumption (in
-                                     * bytes) of this
-                                     * object.
+                                     * Determine an estimate for the
+                                     * memory consumption (in bytes)
+                                     * of this object.
                                      */
     static unsigned int memory_consumption ();
 
index 2c8cf4dc593aab6fd53fcc0cb36efc5ea800637b..f2fff9e6f2b1839daefaa07aa8e7824b81d141d9 100644 (file)
@@ -2186,7 +2186,7 @@ void DataOutBase::write_gnuplot (const std::vector<Patch<dim,spacedim> > &patche
     {
       const unsigned int n_subdivisions = patch->n_subdivisions;
       const unsigned int n = n_subdivisions+1;
-                                      // Length of loops in all dimensons
+                                      // Length of loops in all dimensions
       const unsigned int n1 = (dim>0) ? n : 1;
       const unsigned int n2 = (dim>1) ? n : 1;
       const unsigned int n3 = (dim>2) ? n : 1;
index 2b5ffb638d3f1ac8f23acc2502791b88ee82e028..646b779dc73b0393b691d242c0a3b14bf549736f 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
+unsigned int
+GeometryInfo<0>::n_children(const RefinementCase<0> &)
+{
+  return 0;
+}
+
+
+
 template <int dim> const unsigned int GeometryInfo<dim>::max_children_per_cell;
 template <int dim> const unsigned int GeometryInfo<dim>::faces_per_cell;
 template <int dim> const unsigned int GeometryInfo<dim>::max_children_per_face;
index 72fd24800875876495c7cd9fb0ccdaf7b749d9b0..dbd291c40ea90c6a3c95be64e8f0f7ca64f9ad95 100644 (file)
@@ -627,6 +627,319 @@ QWeddle<1>::QWeddle ()
 }
 
 
+template <>
+QGaussLog<1>::QGaussLog(const unsigned int n,
+                        const bool revert) 
+                 : 
+                 Quadrature<1> (n)
+{
+
+  std::vector<double> p=set_quadrature_points(n);
+  std::vector<double> w=set_quadrature_weights(n);
+  
+  if (revert == true)
+      revert_points_and_weights(p,w);
+
+  for (unsigned int i=0; i<this->size(); ++i)
+    {
+      this->quadrature_points[i] = Point<1>(p[i]);
+      this->weights[i]           = w[i];
+    }
+
+}
+
+template <>
+std::vector<double>
+QGaussLog<1>::set_quadrature_points(const unsigned int n) const
+{
+  std::vector<double> points(n);
+
+  switch (n)
+    {    
+    case 1:
+      points[0] = 0.3333333333333333;
+      break; 
+
+    case 2:
+      points[0] = 0.1120088061669761;
+      points[1] = 0.6022769081187381;
+      break;   
+
+    case 3:
+      points[0] = 0.06389079308732544;
+      points[1] = 0.3689970637156184;
+      points[2] = 0.766880303938942;
+      break;
+
+    case 4:
+      points[0] = 0.04144848019938324;
+      points[1] = 0.2452749143206022;
+      points[2] = 0.5561654535602751;
+      points[3] = 0.848982394532986;
+      break;
+
+    case 5:
+      points[0] = 0.02913447215197205;
+      points[1] = 0.1739772133208974;
+      points[2] =  0.4117025202849029;
+      points[3] = 0.6773141745828183;
+      points[4] = 0.89477136103101;  
+      break;
+
+    case 6:
+      points[0] = 0.02163400584411693;
+      points[1] = 0.1295833911549506;
+      points[2] = 0.3140204499147661;
+      points[3] = 0.5386572173517997;
+      points[4] = 0.7569153373774084;
+      points[5] = 0.922668851372116;
+      break;
+
+
+    case 7:
+      points[0] = 0.0167193554082585;
+      points[1] = 0.100185677915675;
+      points[2] = 0.2462942462079286;
+      points[3] = 0.4334634932570557;
+      points[4] = 0.6323509880476823;
+      points[5] = 0.81111862674023;
+      points[6] = 0.940848166743287;
+      break;
+
+    case 8:
+      points[0] = 0.01332024416089244;
+      points[1] = 0.07975042901389491;
+      points[2] = 0.1978710293261864;
+      points[3] =   0.354153994351925;
+      points[4] =   0.5294585752348643;
+      points[5] = 0.7018145299391673;
+      points[6] = 0.849379320441094;
+      points[7] = 0.953326450056343;
+      break;
+
+    case 9:
+      points[0] = 0.01086933608417545;
+      points[1] = 0.06498366633800794;
+      points[2] = 0.1622293980238825;
+      points[3] = 0.2937499039716641;
+      points[4] = 0.4466318819056009;
+      points[5] = 0.6054816627755208;
+      points[6] = 0.7541101371585467;
+      points[7] = 0.877265828834263;
+      points[8] = 0.96225055941096;
+      break;
+
+    case 10:
+      points[0] = 0.00904263096219963;
+      points[1] = 0.05397126622250072;
+      points[2] =  0.1353118246392511;
+      points[3] = 0.2470524162871565;
+      points[4] = 0.3802125396092744;
+      points[5] = 0.5237923179723384;
+      points[6] = 0.6657752055148032;
+      points[7] = 0.7941904160147613;
+      points[8] = 0.898161091216429;
+      points[9] = 0.9688479887196;
+      break;
+
+
+    case 11:
+      points[0] = 0.007643941174637681;
+      points[1] = 0.04554182825657903;
+      points[2] = 0.1145222974551244;
+      points[3] = 0.2103785812270227;
+      points[4] = 0.3266955532217897;
+      points[5] = 0.4554532469286375;
+      points[6] = 0.5876483563573721;
+      points[7] = 0.7139638500230458;
+      points[8] = 0.825453217777127;
+      points[9] = 0.914193921640008;
+      points[10] = 0.973860256264123;
+      break;
+      
+    case 12:   
+      points[0] = 0.006548722279080035;
+      points[1] = 0.03894680956045022;
+      points[2] = 0.0981502631060046;
+      points[3] = 0.1811385815906331;
+      points[4] = 0.2832200676673157;
+      points[5] = 0.398434435164983;
+      points[6] = 0.5199526267791299;
+      points[7] = 0.6405109167754819;
+      points[8] = 0.7528650118926111;
+      points[9] = 0.850240024421055;
+      points[10] = 0.926749682988251;
+      points[11] = 0.977756129778486;
+      break;   
+
+    default:
+      Assert(false, ExcNotImplemented());
+      break;
+    }
+    
+  return points;
+}
+
+
+template <>
+std::vector<double>
+QGaussLog<1>::set_quadrature_weights(const unsigned int n) const
+{
+  std::vector<double> weights(n);
+
+  switch (n)
+    {    
+    case 1:
+      weights[0] = -1.0;
+      break; 
+    case 2:
+      weights[0] = -0.7185393190303845;
+      weights[1] = -0.2814606809696154;
+      break;
+
+    case 3:
+      weights[0] = -0.5134045522323634;
+      weights[1] = -0.3919800412014877;
+      weights[2] = -0.0946154065661483;
+      break;
+
+    case 4:
+      weights[0] =-0.3834640681451353;
+      weights[1] =-0.3868753177747627;
+      weights[2] =-0.1904351269501432;
+      weights[3] =-0.03922548712995894;
+      break;
+
+    case 5:
+      weights[0] =-0.2978934717828955;
+      weights[1] =-0.3497762265132236;
+      weights[2] =-0.234488290044052;
+      weights[3] =-0.0989304595166356;
+      weights[4] =-0.01891155214319462;
+      break;
+
+    case 6:
+      weights[0] = -0.2387636625785478;
+      weights[1] = -0.3082865732739458;
+      weights[2] = -0.2453174265632108;
+      weights[3] = -0.1420087565664786;
+      weights[4] = -0.05545462232488041;
+      weights[5] = -0.01016895869293513;
+      break;
+
+
+    case 7:
+      weights[0] = -0.1961693894252476;
+      weights[1] = -0.2703026442472726;
+      weights[2] = -0.239681873007687;
+      weights[3] = -0.1657757748104267;
+      weights[4] = -0.0889432271377365;
+      weights[5] = -0.03319430435645653;
+      weights[6] = -0.005932787015162054;
+      break;
+
+    case 8:
+      weights[0] = -0.164416604728002;
+      weights[1] = -0.2375256100233057;
+      weights[2] = -0.2268419844319134;
+      weights[3] = -0.1757540790060772;
+      weights[4] = -0.1129240302467932;
+      weights[5] = -0.05787221071771947;
+      weights[6] = -0.02097907374214317;
+      weights[7] = -0.003686407104036044;
+      break;
+
+    case 9:
+      weights[0] = -0.1400684387481339;
+      weights[1] = -0.2097722052010308;
+      weights[2] = -0.211427149896601;
+      weights[3] = -0.1771562339380667;
+      weights[4] = -0.1277992280331758;
+      weights[5] = -0.07847890261203835;
+      weights[6] = -0.0390225049841783;
+      weights[7] = -0.01386729555074604;
+      weights[8] = -0.002408041036090773;
+      break;
+
+    case 10:
+      weights[0] = -0.12095513195457;
+      weights[1] = -0.1863635425640733;
+      weights[2] = -0.1956608732777627;
+      weights[3] = -0.1735771421828997;
+      weights[4] = -0.135695672995467;
+      weights[5] = -0.0936467585378491;
+      weights[6] = -0.05578772735275126;
+      weights[7] = -0.02715981089692378;
+      weights[8] = -0.00951518260454442;
+      weights[9] = -0.001638157633217673;
+      break;
+
+
+    case 11:
+      weights[0] = -0.1056522560990997;
+      weights[1] = -0.1665716806006314;
+      weights[2] = -0.1805632182877528;
+      weights[3] = -0.1672787367737502;
+      weights[4] = -0.1386970574017174;
+      weights[5] = -0.1038334333650771;
+      weights[6] = -0.06953669788988512;
+      weights[7] = -0.04054160079499477;
+      weights[8] = -0.01943540249522013;
+      weights[9] = -0.006737429326043388;
+      weights[10] = -0.001152486965101561;      
+      break;
+      
+    case 12:   
+      weights[0] = -0.09319269144393;
+      weights[1] = -0.1497518275763289;
+      weights[2] = -0.166557454364573;
+      weights[3] = -0.1596335594369941;
+      weights[4] = -0.1384248318647479;
+      weights[5] = -0.1100165706360573;
+      weights[6] = -0.07996182177673273;
+      weights[7] = -0.0524069547809709;
+      weights[8] = -0.03007108900074863;
+      weights[9] = -0.01424924540252916;
+      weights[10] = -0.004899924710875609;
+      weights[11] = -0.000834029009809656;     
+      break;
+
+    default:
+      Assert(false, ExcNotImplemented());
+      break;  
+    }
+
+  return weights;
+
+}
+
+
+template <> 
+void
+QGaussLog<1>::revert_points_and_weights(std::vector<double> &p,
+                                       std::vector<double> &w) const
+{
+
+  double temp;
+  const unsigned int sz = this->size();
+
+  for (unsigned int i=0; i<sz/2; i++)
+    {
+      temp = p[sz-1-i];
+      p[sz-1-i] = p[i];
+      p[i]=temp;
+      
+      temp = w[sz-1-i];
+      w[sz-1-i]=w[i];
+      w[i]=temp;      
+    }
+
+}
+
+
+
 
 // construct the quadrature formulae in higher dimensions by
 // tensor product of lower dimensions
index 3981d1a0b4f843016ff8ec7b3c1e714a102cacc6..ee5847bf51d39b7c03d4861fc53253a7be8daea6 100644 (file)
@@ -14,6 +14,7 @@ include $D/common/Make.global_options
 # top level targets
 default: 2dg 2d
 all: 2dg 2d 3dg 3d 1dg 1d
+debug: 2dg 3dg 1dg
 
 
 1dg: $(LIBDIR)/libdeal_II_1d.g$(lib-suffix)
index 8c9cc193661b5ccedefe737cc201756eb79cb0c2..93404e8092fc1c30c1fe1adcb36555b8e2aea0ef 100644 (file)
@@ -27,14 +27,7 @@ template <typename number> class FullMatrix;
 template <typename number> class SparseMatrix;
 template <typename number> class Vector;
 
-template <int celldim, class DH> class DoFObjectAccessor;
-template <class DH> class DoFObjectAccessor<0,DH>;
-template <class DH> class DoFObjectAccessor<1,DH>;
-template <class DH> class DoFObjectAccessor<2,DH>;
-template <class DH> class DoFObjectAccessor<3,DH>;
-
-
-template <int dim, typename Accessor> class TriaRawIterator;
+template <typename Accessor> class TriaRawIterator;
 
 
 
@@ -44,60 +37,56 @@ template <int dim, typename Accessor> class TriaRawIterator;
 // inlining and thus faster code.
 
 
+namespace internal
+{
+  namespace DoFAccessor
+  {
 /**
  * This is a switch class which only declares a @p typedef. It is meant to
- * determine which class a DoFObjectAccessor class is to be derived
- * from. By default, <tt>DoFObjectAccessor<celldim,dim></tt> derives from
- * the @p typedef in the general <tt>DoFObjectAccessor_Inheritance<celldim,dim></tt>
- * class, which is <tt>TriaObjectAccessor<celldim,dim></tt>,
- * but if <tt>celldim==dim</tt>, then the specialization <tt>DoFObjectAccessor_Inheritance<dim,dim></tt>
- * is used which declares its local type to be <tt>CellAccessor<dim></tt>. Therefore,
- * the inheritance is automatically chosen to be from CellAccessor if the
- * object under consideration has full dimension, i.e. constitutes a cell.
+ * determine which class a DoFAccessor class is to be derived from. By
+ * default, <tt>DoFAccessor@<celldim,dim,spacedim@></tt> derives from the
+ * typedef in the general
+ * <tt>Inheritance@<celldim,dim,spacedim@></tt> class, which is
+ * <tt>TriaAccessor@<celldim,dim,spacedim@></tt>, but if
+ * <tt>celldim==dim</tt>, then the specialization
+ * <tt>Inheritance@<dim,dim,spacedim@></tt> is used which declares
+ * its local type to be <tt>CellAccessor@<dim,spacedim@></tt>. Therefore, the
+ * inheritance is automatically chosen to be from CellAccessor if the object
+ * under consideration has full dimension, i.e. constitutes a cell.
  *
  * @ingroup dofs
  * @ingroup Accessors 
  * @author Wolfgang Bangerth, 1999
  */
-template <int celldim, int dim>
-class DoFObjectAccessor_Inheritance 
-{
-  public:
-                                    /**
-                                     * Declaration of the @p typedef.
-                                     * See the full documentation for
-                                     * more information.
-                                     */
-    typedef TriaObjectAccessor<celldim,dim> BaseClass;
-};
+    template <int celldim, int dim, int spacedim>
+    struct Inheritance 
+    {
+                                        /**
+                                         * Declaration of the @p typedef.
+                                         * See the full documentation for
+                                         * more information.
+                                         */
+       typedef TriaAccessor<celldim,dim,spacedim> BaseClass;
+    };
 
 
 /**
- * This is a switch class which only declares a @p typedef. It is meant to
- * determine which class a DoFObjectAccessor class is to be derived
- * from. By default, <tt>DoFObjectAccessor<celldim,dim></tt> derives from
- * the @p typedef in the general <tt>DoFObjectAccessor_Inheritance<celldim,dim></tt>
- * class, which is <tt>TriaObjectAccessor<celldim,dim></tt>,
- * but if <tt>celldim==dim</tt>, then the specialization <tt>DoFObjectAccessor_Inheritance<dim,dim></tt>
- * is used which declares its local type to be <tt>CellAccessor<dim></tt>. Therefore,
- * the inheritance is automatically chosen to be from CellAccessor if the
- * object under consideration has full dimension, i.e. constitutes a cell.
- *
- * @ingroup dofs
- * @ingroup Accessors 
- * @author Wolfgang Bangerth, 1999
+ * This is the specialization of the general template used for the case where
+ * an object has full dimension, i.e. is a cell. See the general template for
+ * more details.
  */
-template <int dim>
-class DoFObjectAccessor_Inheritance<dim,dim>
-{
-  public:
-                                    /**
-                                     * Declaration of the @p typedef.
-                                     * See the full documentation for
-                                     * more information.
-                                     */
-    typedef CellAccessor<dim> BaseClass;
-};
+    template <int dim, int spacedim>
+    struct Inheritance<dim,dim,spacedim>
+    {
+                                        /**
+                                         * Declaration of the @p typedef.
+                                         * See the full documentation for
+                                         * more information.
+                                         */
+       typedef CellAccessor<dim,spacedim> BaseClass;
+    };
+  }
+}
 
 
 /* -------------------------------------------------------------------------- */
@@ -105,29 +94,26 @@ class DoFObjectAccessor_Inheritance<dim,dim>
 
 
 /**
- * Define the base class for accessors to the degrees of
- * freedom. Accessors are used to, well, access the data that pertains
- * to edges, faces, and cells of a triangulation. The concept is
+ * A class that gives access to the degrees of freedom stored in a DoFHandler
+ * or hp::DoFHandler object. Accessors are used to, well, access the data that
+ * pertains to edges, faces, and cells of a triangulation. The concept is
  * explained in more detail in connection to @ref Iterators.
  *
  * This class follows mainly the route laid out by the accessor library
- * declared in the triangulation library (TriaAccessor). It enables
- * the user to access the degrees of freedom on the lines (there are similar
- * versions for the DoFs on quads, etc), where the dimension of the underlying
- * triangulation does not really matter (i.e. this accessor works with the
- * lines in 1D-, 2D-, etc dimensions).
- *
- * The first template argument of this class refers to the structural
- * dimension of the thing accessed: it is 1 for lines, 2 for quads, or
- * 3 for hexes. The second argument denotes the type of DoF handler we
- * should work on. It can either be ::DoFHandler<dim> or
- * hp::DoFHandler<dim>. The space dimension of the object we are to
- * work on is automatically extracted from the DH template argument.
+ * declared in the triangulation library (TriaAccessor). It enables the user
+ * to access the degrees of freedom on lines, quads, or hexes. The first
+ * template argument of this class determines the dimensionality of the object
+ * under consideration: 1 for lines, 2 for quads, and 3 for hexes. From the
+ * second template argument we can deduce the dimensionality of the
+ * triangulation to which this object belongs as well as the dimensionality of
+ * the space in which it is embedded. The second argument also denotes the
+ * type of DoF handler we should work on. It can either be
+ * ::DoFHandler or hp::DoFHandler.
  *
  * Depending on whether the structural dimension of the object
- * accessed equals the space dimension on which the DoF handler object
+ * accessed equals the dimension on which the DoF handler object
  * operates, this class is derived from CellAccessor or
- * TriaObjectAccessor. This means that, for example accessors to quads
+ * TriaAccessor. This means that, for example accessors to quads
  * in 2d have access to all the mesh aspects of cells, whereas
  * accessors to quads in 3d can only access things that make sense for
  * faces.
@@ -150,28 +136,34 @@ class DoFObjectAccessor_Inheritance<dim,dim>
  * rather than lower-dimensional objects. In that case, inheritance is
  * from CellAccessor, to provide access to all the cell specific
  * information afforded by that class. Otherwise, i.e. for
- * lower-dimensional objects, inheritance is from TriaObjectAccessor.
- *
- * There are classes DoFObjectAccessor<1>, DoFObjectAccessor<2>, and
- * DoFObjectAccessor<3> derived from the present class that provide
- * things that are specific to objects of a particular
- * dimensionality. For example, DoFObjectAccessor<2> allows access to
- * the DoF iterators pointing to the lines that bound that
- * quadrilateral, which is obviously something that a line can't
- * do. Consequently, these few operations are declared in these
- * derived classes.
+ * lower-dimensional objects, inheritance is from TriaAccessor.
  *
- * In addition, there is a DoFCellAccessor class that provides the
+ * There is a DoFCellAccessor class that provides the
  * equivalent to the CellAccessor class.
  *
  * @ingroup dofs
  * @ingroup Accessors
- * @author Wolfgang Bangerth, 1998, 2006
+ * @author Wolfgang Bangerth, 1998, 2006, 2008
  */
 template <int structdim, class DH>
-class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimension>::BaseClass
+class DoFAccessor : public internal::DoFAccessor::Inheritance<structdim, DH::dimension, DH::space_dimension>::BaseClass
 {
   public:
+
+                                    /**
+                                     * A static variable that allows users of
+                                     * this class to discover the value of
+                                     * the second template argument.
+                                     */
+    static const unsigned int dimension=DH::dimension;
+
+                                    /**
+                                     * A static variable that allows users of
+                                     * this class to discover the value of
+                                     * the third template argument.
+                                     */
+    static const unsigned int space_dimension=DH::space_dimension;
+
                                     /**
                                      * Declare a typedef to the base
                                      * class to make accessing some
@@ -179,7 +171,7 @@ class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimensio
                                      * simpler.
                                      */
     typedef
-    typename DoFObjectAccessor_Inheritance<structdim, DH::dimension>::BaseClass
+    typename internal::DoFAccessor::Inheritance<structdim, dimension, space_dimension>::BaseClass
     BaseClass;
 
                                     /**
@@ -187,6 +179,13 @@ class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimensio
                                      */
     typedef DH AccessorData;
 
+                                    /**
+                                     * @name Constructors
+                                     */
+                                    /**
+                                     * @{
+                                     */
+    
                                     /**
                                      * Default constructor. Provides
                                      * an accessor that can't be
@@ -197,16 +196,48 @@ class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimensio
                                     /**
                                      * Constructor
                                      */
-    DoFAccessor (const Triangulation<DH::dimension> *tria,
+    DoFAccessor (const Triangulation<DH::dimension,DH::space_dimension> *tria,
                 const int                 level,
                 const int                 index,
                 const DH                 *local_data);
 
                                     /**
-                                     * Reset the DoF handler pointer.
+                                     * Conversion constructor. This
+                                     * constructor exists to make certain
+                                     * constructs simpler to write in
+                                     * dimension independent code. For
+                                     * example, it allows assigning a face
+                                     * iterator to a line iterator, an
+                                     * operation that is useful in 2d but
+                                     * doesn't make any sense in 3d. The
+                                     * constructor here exists for the
+                                     * purpose of making the code conform to
+                                     * C++ but it will unconditionally abort;
+                                     * in other words, assigning a face
+                                     * iterator to a line iterator is better
+                                     * put into an if-statement that checks
+                                     * that the dimension is two, and assign
+                                     * to a quad iterator in 3d (an operator
+                                     * that, without this constructor would
+                                     * be illegal if we happen to compile for
+                                     * 2d).
+                                     */
+    template <int structdim2, int dim2, int spacedim2>
+    DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &);
+
+                                    /**
+                                     * Another conversion operator
+                                     * between objects that don't
+                                     * make sense, just like the
+                                     * previous one.
                                      */
-    void set_dof_handler (DH *dh);
+    template <int dim2, class DH2>
+    DoFAccessor (const DoFAccessor<dim2, DH2> &);
 
+                                    /**
+                                     * @}
+                                     */
+    
                                     /**
                                      * Return a handle on the
                                      * DoFHandler object which we
@@ -227,17 +258,71 @@ class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimensio
                                      */
     void copy_from (const DoFAccessor<structdim, DH> &a);
 
+                                    /**
+                                     *  @name Accessing sub-objects
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
                                     /**
                                      * Return an iterator pointing to
                                      * the the @p c-th child.
                                      */
-    TriaIterator<DH::dimension,DoFObjectAccessor<structdim,DH> >
+    TriaIterator<DoFAccessor<structdim,DH> >
     child (const unsigned int c) const;
 
                                     /**
-                                     * Global DoF index of the <i>i</i>
-                                     * degree associated with the @p vertexth
-                                     * vertex of the present cell.
+                                     * Pointer to the @p ith line
+                                     * bounding this object.
+                                     */
+    typename internal::DoFHandler::Iterators<DH>::line_iterator
+    line (const unsigned int i) const;
+
+                                    /**
+                                     * Pointer to the @p ith quad
+                                     * bounding this object.
+                                     */
+    typename internal::DoFHandler::Iterators<DH>::quad_iterator
+    quad (const unsigned int i) const;
+
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Accessing the DoF indices of this object
+                                     */
+                                    /**
+                                     * @{
+                                     */
+    
+                                    /**
+                                     * Return the indices of the dofs of this
+                                     * object in the standard ordering: dofs
+                                     * on vertex 0, dofs on vertex 1, etc,
+                                     * dofs on line 0, dofs on line 1, etc,
+                                     * dofs on quad 0, etc.
+                                     *
+                                     * The vector has to have the
+                                     * right size before being passed
+                                     * to this function.
+                                     *
+                                     * This function is most often
+                                     * used on active objects (edges,
+                                     * faces, cells). It can be used
+                                     * on non-active objects as well
+                                     * (i.e. objects that have
+                                     * children), but only if the
+                                     * finite element under
+                                     * consideration has degrees of
+                                     * freedom exclusively on
+                                     * vertices. Otherwise, the
+                                     * function doesn't make much
+                                     * sense, since for example
+                                     * inactive edges do not have
+                                     * degrees of freedom associated
+                                     * with them at all.
                                      *
                                      * The last argument denotes the
                                      * finite element index. For the
@@ -269,15 +354,27 @@ class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimensio
                                      * freedom, and fe_index has to
                                      * match the result of
                                      * active_fe_index().
+                                     *
+                                     * For cells, there is only a
+                                     * single possible finite element
+                                     * index (namely the one for that
+                                     * cell, returned by
+                                     * <code>cell-@>active_fe_index</code>. Consequently,
+                                     * the derived DoFCellAccessor
+                                     * class has an overloaded
+                                     * version of this function that
+                                     * calls the present function
+                                     * with
+                                     * <code>cell-@>active_fe_index</code>
+                                     * as last argument.
                                      */
-    unsigned int vertex_dof_index (const unsigned int vertex,
-                                  const unsigned int i,
-                                  const unsigned int fe_index = DH::default_fe_index) const;
+    void get_dof_indices (std::vector<unsigned int> &dof_indices,
+                         const unsigned int fe_index = DH::default_fe_index) const;
 
                                     /**
-                                     * Set the global index of the <i>i</i>
-                                     * degree on the @p vertex-th vertex of
-                                     * the present cell to @p index.
+                                     * Global DoF index of the <i>i</i>
+                                     * degree associated with the @p vertexth
+                                     * vertex of the present cell.
                                      *
                                      * The last argument denotes the
                                      * finite element index. For the
@@ -310,10 +407,9 @@ class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimensio
                                      * match the result of
                                      * active_fe_index().
                                      */
-    void set_vertex_dof_index (const unsigned int vertex,
-                              const unsigned int i,
-                              const unsigned int index,
-                              const unsigned int fe_index = DH::default_fe_index) const;
+    unsigned int vertex_dof_index (const unsigned int vertex,
+                                  const unsigned int i,
+                                  const unsigned int fe_index = DH::default_fe_index) const;
 
                                     /**
                                      * Index of the <i>i</i>th degree
@@ -353,46 +449,17 @@ class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimensio
     unsigned int dof_index (const unsigned int i,
                            const unsigned int fe_index = DH::default_fe_index) const;
 
-                                    /**
-                                     * Set the index of the
-                                     * <i>i</i>th degree of freedom
-                                     * of this object to @p index.
-                                     *
-                                     * The last argument denotes the
-                                     * finite element index. For the
-                                     * standard ::DoFHandler class,
-                                     * this value must be equal to
-                                     * its default value since that
-                                     * class only supports the same
-                                     * finite element on all cells
-                                     * anyway.
-                                     *
-                                     * However, for hp objects
-                                     * (i.e. the hp::DoFHandler
-                                     * class), different finite
-                                     * element objects may be used on
-                                     * different cells. On faces
-                                     * between two cells, as well as
-                                     * vertices, there may therefore
-                                     * be two sets of degrees of
-                                     * freedom, one for each of the
-                                     * finite elements used on the
-                                     * adjacent cells. In order to
-                                     * specify which set of degrees
-                                     * of freedom to work on, the
-                                     * last argument is used to
-                                     * disambiguate. Finally, if this
-                                     * function is called for a cell
-                                     * object, there can only be a
-                                     * single set of degrees of
-                                     * freedom, and fe_index has to
-                                     * match the result of
-                                     * active_fe_index().
+                                    /**
+                                     * @}
                                      */
-    void set_dof_index (const unsigned int i,
-                       const unsigned int index,
-                       const unsigned int fe_index = DH::default_fe_index) const;
 
+                                    /**
+                                     *  @name Accessing the finite element associated with this object
+                                     */
+                                    /**
+                                     * @{
+                                     */
+    
                                      /**
                                       * Return the number of finite
                                       * elements that are active on a
@@ -461,8 +528,12 @@ class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimensio
                                      * i.e. <code>fe_index_is_active(fe_index)</code>
                                      * must return true.
                                      */
-    const FiniteElement<DH::dimension> &
+    const FiniteElement<DH::dimension,DH::space_dimension> &
     get_fe (const unsigned int fe_index) const;
+
+                                    /**
+                                     * @}
+                                     */
     
                                      /**
                                      * Exceptions for child classes
@@ -505,261 +576,31 @@ class DoFAccessor : public DoFObjectAccessor_Inheritance<structdim, DH::dimensio
 
   protected:    
 
-                                    /**
-                                     * Store the address of the DoFHandler object
-                                     * to be accessed.
-                                     */
-    DH *dof_handler;
-
-                                    /**
-                                     *  Compare for equality.            
-                                     */
-    bool operator == (const DoFAccessor &) const;
-       
-                                    /**
-                                     * Compare for inequality.
-                                     */
-    bool operator != (const DoFAccessor &) const;
-
-                                     /**
-                                      * Iterator classes need to be friends
-                                      * because they need to access operator==
-                                      * and operator!=.
-                                      */
-    template <int, typename> friend class TriaRawIterator;
-};
-
-
-/* -------------------------------------------------------------------------- */
-
-
-/**
- * Closure class. Unused, but necessary for some template constructs.
- * @ingroup dofs
- * @ingroup Accessors
- */
-template <class DH>
-class DoFObjectAccessor<0, DH> : public DoFAccessor<0, DH>
-{
-  public:
-                                    /**
-                                     * Extract dimension from DH.
-                                     */
-    static const unsigned int dim = DH::dimension;
-
-    typedef void AccessorData;
-
-                                    /**
-                                     * Constructor. Should never be called
-                                     * and thus throws an error.
-                                     */
-    DoFObjectAccessor (Triangulation<dim> *,
-                      const int,
-                      const int,
-                      const AccessorData *)
-      {
-       Assert (false, ExcInternalError());
-      }
-};
-
-
-
-/**
- * Grant access to those aspects of degrees of freedom located on
- * quads that are dimension specific. See the DoFAccessor class for
- * more information.
- *
- * @ingroup dofs
- * @ingroup Accessors
- * @author Wolfgang Bangerth, 1998, 2006
- */
-template <class DH>
-class DoFObjectAccessor<1, DH> : public DoFAccessor<1,DH>
-{
-  public:
-                                    /**
-                                     * Extract dimension from DH.
-                                     */
-    static const unsigned int dim = DH::dimension;
-    
-                                    /**
-                                     * Declare the data type that this accessor
-                                     * class expects to get passed from the
-                                     * iterator classes.
-                                     */
-    typedef DH AccessorData;
-
-                                    /**
-                                     * Declare base class as a local typedef
-                                     * for simpler access.
-                                     */
-    typedef DoFAccessor<1,DH> BaseClass;
-
-                                    /**
-                                     * Default constructor, unused thus
-                                     * not implemented.
-                                     */
-    DoFObjectAccessor ();
-    
-                                    /**
-                                     * Constructor. The @p local_data
-                                     * argument is assumed to be a pointer
-                                     * to a DoFHandler object.
-                                     */
-    DoFObjectAccessor (const Triangulation<DH::dimension> *tria,
-                      const int                 level,
-                      const int                 index,
-                      const AccessorData       *local_data);    
-
-                                    /**
-                                     * Return the indices of the dofs of this
-                                     * object in the standard ordering: dofs
-                                     * on vertex 0, dofs on vertex 1, etc,
-                                     * dofs on line 0, dofs on line 1, etc,
-                                     * dofs on quad 0, etc.
-                                     *
-                                     * The vector has to have the
-                                     * right size before being passed
-                                     * to this function.
-                                     *
-                                     * This function is most often
-                                     * used on active objects (edges,
-                                     * faces, cells). It can be used
-                                     * on non-active objects as well
-                                     * (i.e. objects that have
-                                     * children), but only if the
-                                     * finite element under
-                                     * consideration has degrees of
-                                     * freedom exclusively on
-                                     * vertices. Otherwise, the
-                                     * function doesn't make much
-                                     * sense, since for example
-                                     * inactive edges do not have
-                                     * degrees of freedom associated
-                                     * with them at all.
-                                     *
-                                     * The last argument denotes the
-                                     * finite element index. For the
-                                     * standard ::DoFHandler class,
-                                     * this value must be equal to
-                                     * its default value since that
-                                     * class only supports the same
-                                     * finite element on all cells
-                                     * anyway.
-                                     *
-                                     * However, for hp objects
-                                     * (i.e. the hp::DoFHandler
-                                     * class), different finite
-                                     * element objects may be used on
-                                     * different cells. On faces
-                                     * between two cells, as well as
-                                     * vertices, there may therefore
-                                     * be two sets of degrees of
-                                     * freedom, one for each of the
-                                     * finite elements used on the
-                                     * adjacent cells. In order to
-                                     * specify which set of degrees
-                                     * of freedom to work on, the
-                                     * last argument is used to
-                                     * disambiguate. Finally, if this
-                                     * function is called for a cell
-                                     * object, there can only be a
-                                     * single set of degrees of
-                                     * freedom, and fe_index has to
-                                     * match the result of
-                                     * active_fe_index().
-                                     *
-                                     * For cells, there is only a
-                                     * single possible finite element
-                                     * index (namely the one for that
-                                     * cell, returned by
-                                     * <code>cell-@>active_fe_index</code>. Consequently,
-                                     * the derived DoFCellAccessor
-                                     * class has an overloaded
-                                     * version of this function that
-                                     * calls the present function
-                                     * with
-                                     * <code>cell-@>active_fe_index</code>
-                                     * as last argument.
-                                     */
-    void get_dof_indices (std::vector<unsigned int> &dof_indices,
-                         const unsigned int fe_index = DH::default_fe_index) const;
-};
-
-
-/**
- * Grant access to those aspects of degrees of freedom located on
- * quads that are dimension specific. See the DoFAccessor class for
- * more information.
- *
- * @ingroup dofs
- * @ingroup Accessors
- * @author Wolfgang Bangerth, 1998, 2006
- */
-template <class DH>
-class DoFObjectAccessor<2, DH> : public DoFAccessor<2,DH>
-{
-  public:
-                                    /**
-                                     * Extract dimension from DH.
-                                     */
-    static const unsigned int dim = DH::dimension;
-
-                                    /**
-                                     * Declare the data type that this accessor
-                                     * class expects to get passed from the
-                                     * iterator classes.
-                                     */
-    typedef DH AccessorData;
-
-                                    /**
-                                     * Declare base class as a local typedef
-                                     * for simpler access.
-                                     */
-    typedef DoFAccessor<2,DH> BaseClass;
-    
-                                    /**
-                                     * Default constructor, unused thus
-                                     * not implemented.
-                                     */
-    DoFObjectAccessor ();
-
-                                    /**
-                                     * Constructor. The @p local_data
-                                     * argument is assumed to be a pointer
-                                     * to a DoFHandler object.
-                                     */
-    DoFObjectAccessor (const Triangulation<DH::dimension> *tria,
-                      const int                 level,
-                      const int                 index,
-                      const AccessorData       *local_data);
-    
-                                    /**
-                                     * Return the indices of the dofs of this
-                                     * object in the standard ordering: dofs
-                                     * on vertex 0, dofs on vertex 1, etc,
-                                     * dofs on line 0, dofs on line 1, etc,
-                                     * dofs on quad 0, etc.
-                                     *
-                                     * The vector has to have the
-                                     * right size before being passed
-                                     * to this function.
-                                     *
-                                     * This function is most often
-                                     * used on active objects (edges,
-                                     * faces, cells). It can be used
-                                     * on non-active objects as well
-                                     * (i.e. objects that have
-                                     * children), but only if the
-                                     * finite element under
-                                     * consideration has degrees of
-                                     * freedom exclusively on
-                                     * vertices. Otherwise, the
-                                     * function doesn't make much
-                                     * sense, since for example
-                                     * inactive edges do not have
-                                     * degrees of freedom associated
-                                     * with them at all.
+                                    /**
+                                     * Store the address of the DoFHandler object
+                                     * to be accessed.
+                                     */
+    DH *dof_handler;
+
+                                    /**
+                                     *  Compare for equality.            
+                                     */
+    bool operator == (const DoFAccessor &) const;
+       
+                                    /**
+                                     * Compare for inequality.
+                                     */
+    bool operator != (const DoFAccessor &) const;
+
+                                    /**
+                                     * Reset the DoF handler pointer.
+                                     */
+    void set_dof_handler (DH *dh);
+
+                                    /**
+                                     * Set the index of the
+                                     * <i>i</i>th degree of freedom
+                                     * of this object to @p index.
                                      *
                                      * The last argument denotes the
                                      * finite element index. For the
@@ -791,105 +632,15 @@ class DoFObjectAccessor<2, DH> : public DoFAccessor<2,DH>
                                      * freedom, and fe_index has to
                                      * match the result of
                                      * active_fe_index().
-                                     *
-                                     * For cells, there is only a
-                                     * single possible finite element
-                                     * index (namely the one for that
-                                     * cell, returned by
-                                     * <code>cell-@>active_fe_index</code>. Consequently,
-                                     * the derived DoFCellAccessor
-                                     * class has an overloaded
-                                     * version of this function that
-                                     * calls the present function
-                                     * with
-                                     * <code>cell-@>active_fe_index</code>
-                                     * as last argument.
-                                     */
-    void get_dof_indices (std::vector<unsigned int> &dof_indices,
-                         const unsigned int fe_index = DH::default_fe_index) const;
-
-                                    /**
-                                     *  Return a pointer to the @p ith line
-                                     *  bounding this @p Quad.
-                                     */
-    TriaIterator<DH::dimension,DoFObjectAccessor<1, DH> >
-    line (const unsigned int i) const;
-};
-
-
-/**
- * Grant access to those aspects of degrees of freedom located on
- * hexes that are dimension specific. See the DoFAccessor class for
- * more information.
- *
- * @ingroup dofs
- * @ingroup Accessors
- * @author Wolfgang Bangerth, 1998, 2006
- */
-template <class DH>
-class DoFObjectAccessor<3, DH> : public DoFAccessor<3,DH>
-{
-  public:
-                                    /**
-                                     * Extract dimension from DH.
-                                     */
-    static const unsigned int dim = DH::dimension;
-    
-                                    /**
-                                     * Declare the data type that this accessor
-                                     * class expects to get passed from the
-                                     * iterator classes.
                                      */
-    typedef DH AccessorData;
+    void set_dof_index (const unsigned int i,
+                       const unsigned int index,
+                       const unsigned int fe_index = DH::default_fe_index) const;
 
                                     /**
-                                     * Declare base class as a local typedef
-                                     * for simpler access.
-                                     */
-    typedef DoFAccessor<1,DH> BaseClass;
-    
-                                    /**
-                                     * Default constructor, unused thus
-                                     * not implemented.
-                                     */
-    DoFObjectAccessor ();
-
-                                    /**
-                                     * Constructor. The @p local_data
-                                     * argument is assumed to be a pointer
-                                     * to a DoFHandler object.
-                                     */
-    DoFObjectAccessor (const Triangulation<DH::dimension> *tria,
-                      const int                 level,
-                      const int                 index,
-                      const AccessorData       *local_data);
-    
-                                    /**
-                                     * Return the indices of the dofs of this
-                                     * object in the standard ordering: dofs
-                                     * on vertex 0, dofs on vertex 1, etc,
-                                     * dofs on line 0, dofs on line 1, etc,
-                                     * dofs on quad 0, etc.
-                                     *
-                                     * The vector has to have the
-                                     * right size before being passed
-                                     * to this function.
-                                     *
-                                     * This function is most often
-                                     * used on active objects (edges,
-                                     * faces, cells). It can be used
-                                     * on non-active objects as well
-                                     * (i.e. objects that have
-                                     * children), but only if the
-                                     * finite element under
-                                     * consideration has degrees of
-                                     * freedom exclusively on
-                                     * vertices. Otherwise, the
-                                     * function doesn't make much
-                                     * sense, since for example
-                                     * inactive edges do not have
-                                     * degrees of freedom associated
-                                     * with them at all.
+                                     * Set the global index of the <i>i</i>
+                                     * degree on the @p vertex-th vertex of
+                                     * the present cell to @p index.
                                      *
                                      * The last argument denotes the
                                      * finite element index. For the
@@ -921,52 +672,37 @@ class DoFObjectAccessor<3, DH> : public DoFAccessor<3,DH>
                                      * freedom, and fe_index has to
                                      * match the result of
                                      * active_fe_index().
-                                     *
-                                     * For cells, there is only a
-                                     * single possible finite element
-                                     * index (namely the one for that
-                                     * cell, returned by
-                                     * <code>cell-@>active_fe_index</code>. Consequently,
-                                     * the derived DoFCellAccessor
-                                     * class has an overloaded
-                                     * version of this function that
-                                     * calls the present function
-                                     * with
-                                     * <code>cell-@>active_fe_index</code>
-                                     * as last argument.
                                      */
-    void get_dof_indices (std::vector<unsigned int> &dof_indices,
-                         const unsigned int fe_index = DH::default_fe_index) const;
+    void set_vertex_dof_index (const unsigned int vertex,
+                              const unsigned int i,
+                              const unsigned int index,
+                              const unsigned int fe_index = DH::default_fe_index) const;
+    
+                                     /**
+                                      * Iterator classes need to be friends
+                                      * because they need to access operator==
+                                      * and operator!=.
+                                      */
+    template <typename> friend class TriaRawIterator;
 
-                                    /**
-                                     *  Return a pointer to the @p ith line
-                                     *  bounding this @p Hex.
-                                     */
-    TriaIterator<DH::dimension,DoFObjectAccessor<1, DH> >
-    line (const unsigned int i) const;
 
-                                    /**
-                                     *  Return a pointer to the @p ith quad
-                                     *  bounding this @p Hex.
+                                    /**
+                                     * Make the DoFHandler class a friend so
+                                     * that it can call the set_xxx()
+                                     * functions.
                                      */
-    TriaIterator<DH::dimension,DoFObjectAccessor<2, DH> >
-    quad (const unsigned int i) const;
+    template <int dim, int spacedim> friend class DoFHandler;
+    template <int dim, int spacedim> friend class hp::DoFHandler;
 };
 
 
+/* -------------------------------------------------------------------------- */
+
 
 /**
- * Grant access to the degrees of freedom on a cell. In fact, since all
- * access to the degrees of freedom has been enabled by the classes
- * <tt>DoFObjectAccessor<1, 1></tt> and <tt>DoFObjectAccessor<2, 2></tt> for the space dimension
- * one and two, respectively, this class only collects the pieces
- * together by deriving from the appropriate <tt>DoF*Accessor</tt> and the
- * right <tt>CellAccessor<dim></tt> and finally adding two functions which give
- * access to the neighbors and children as DoFCellAccessor objects
- * rather than CellAccessor objects (the latter function was inherited
- * from the <tt>CellAccessor<dim></tt> class).
+ * Grant access to the degrees of freedom on a cell.
  *
- * Note that since for the class we derive from, i.e. <tt>DoFObjectAccessor<dim,dim></tt>,
+ * Note that since for the class we derive from, i.e. <tt>DoFAccessor<dim></tt>,
  * the two template parameters are equal, the base class is actually derived from
  * CellAccessor, which makes the functions of this class available to the
  * DoFCellAccessor class as well.
@@ -976,13 +712,18 @@ class DoFObjectAccessor<3, DH> : public DoFAccessor<3,DH>
  * @author Wolfgang Bangerth, 1998
  */
 template <class DH>
-class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
+class DoFCellAccessor :  public DoFAccessor<DH::dimension,DH>
 {
   public:
                                     /**
                                      * Extract dimension from DH.
                                      */
     static const unsigned int dim = DH::dimension;
+
+                                    /**
+                                     * Extract space dimension from DH.
+                                     */
+    static const unsigned int spacedim = DH::space_dimension;
     
                                     /**
                                      * Declare the data type that
@@ -990,7 +731,7 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                      * get passed from the iterator
                                      * classes.
                                      */
-    typedef typename DoFObjectAccessor<DH::dimension,DH>::AccessorData AccessorData;
+    typedef typename DoFAccessor<DH::dimension,DH>::AccessorData AccessorData;
 
                                     /**
                                      * Declare a typedef to the base
@@ -998,16 +739,67 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                      * of the exception classes
                                      * simpler.
                                      */
-    typedef DoFObjectAccessor<DH::dimension,DH> BaseClass;
+    typedef DoFAccessor<DH::dimension,DH> BaseClass;
     
+                                    /**
+                                     * @name Constructors
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
                                     /**
                                      * Constructor
                                      */
-    DoFCellAccessor (const Triangulation<DH::dimension> *tria,
+    DoFCellAccessor (const Triangulation<DH::dimension,DH::space_dimension> *tria,
                     const int                 level,
                     const int                 index,
                     const AccessorData       *local_data);
 
+                                    /**
+                                     * Conversion constructor. This
+                                     * constructor exists to make certain
+                                     * constructs simpler to write in
+                                     * dimension independent code. For
+                                     * example, it allows assigning a face
+                                     * iterator to a line iterator, an
+                                     * operation that is useful in 2d but
+                                     * doesn't make any sense in 3d. The
+                                     * constructor here exists for the
+                                     * purpose of making the code conform to
+                                     * C++ but it will unconditionally abort;
+                                     * in other words, assigning a face
+                                     * iterator to a line iterator is better
+                                     * put into an if-statement that checks
+                                     * that the dimension is two, and assign
+                                     * to a quad iterator in 3d (an operator
+                                     * that, without this constructor would
+                                     * be illegal if we happen to compile for
+                                     * 2d).
+                                     */
+    template <int structdim2, int dim2, int spacedim2>
+    DoFCellAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &);
+
+                                    /**
+                                     * Another conversion operator
+                                     * between objects that don't
+                                     * make sense, just like the
+                                     * previous one.
+                                     */
+    template <int dim2, class DH2>
+    DoFCellAccessor (const DoFAccessor<dim2, DH2> &);
+
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Accessing sub-objects and neighbors
+                                     */
+                                    /**
+                                     * @{
+                                     */
+    
                                     /**
                                      * Return the @p ith neighbor as
                                      * a DoF cell iterator. This
@@ -1017,7 +809,7 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                      * without access to the DoF
                                      * data.
                                      */
-    TriaIterator<DH::dimension,DoFCellAccessor<DH> >
+    typename internal::DoFHandler::Iterators<DH>::cell_iterator
     neighbor (const unsigned int) const;
 
                                     /**
@@ -1029,7 +821,7 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                      * without access to the DoF
                                      * data.
                                      */
-    TriaIterator<DH::dimension,DoFCellAccessor<DH> >
+    typename internal::DoFHandler::Iterators<DH>::cell_iterator
     child (const unsigned int) const;
 
                                     /**
@@ -1037,10 +829,10 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                      * of this cell.
                                      *
                                      * This function is not implemented in
-                                     * 1D, and maps to DoFObjectAccessor<2,
+                                     * 1D, and maps to DoFAccessor<2,
                                      * dim>::line in 2D.
                                      */
-    TriaIterator<DH::dimension, DoFObjectAccessor<dim-1, DH> >
+    typename internal::DoFHandler::Iterators<DH>::face_iterator
     face (const unsigned int i) const;
 
                                      /**
@@ -1054,10 +846,21 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                      * access to the triangulation
                                      * data).
                                      */
-    TriaIterator<DH::dimension,DoFCellAccessor<DH> >
+    typename internal::DoFHandler::Iterators<DH>::cell_iterator
     neighbor_child_on_subface (const unsigned int face_no,
                                const unsigned int subface_no) const;
 
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Extracting values from global vectors
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
                                     /**
                                      * Return the values of the given vector
                                      * restricted to the dofs of this
@@ -1257,6 +1060,54 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
     void set_dof_values_by_interpolation (const Vector<number> &local_values,
                                          OutputVector         &values) const;
 
+                                    /**
+                                     * Distribute a local (cell
+                                     * based) vector to a global one
+                                     * by mapping the local numbering
+                                     * of the degrees of freedom to
+                                     * the global one and entering
+                                     * the local values into the
+                                     * global vector.
+                                     *
+                                     * The elements are
+                                     * <em>added</em> up to the
+                                     * elements in the global vector,
+                                     * rather than just set, since
+                                     * this is usually what one
+                                     * wants.
+                                     */
+    template <typename number, typename OutputVector>
+    void
+    distribute_local_to_global (const Vector<number> &local_source,
+                                OutputVector         &global_destination) const;
+
+                                    /**
+                                     * This function does much the
+                                     * same as the
+                                     * <tt>distribute_local_to_global(Vector,Vector)</tt>
+                                     * function, but operates on
+                                     * matrices instead of
+                                     * vectors. If the matrix type is
+                                     * a sparse matrix then it is
+                                     * supposed to have non-zero
+                                     * entry slots where required.
+                                     */
+    template <typename number, typename OutputMatrix>
+    void
+    distribute_local_to_global (const FullMatrix<number> &local_source,
+                                OutputMatrix             &global_destination) const;
+    
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Accessing the DoF indices of this object
+                                     */
+                                    /**
+                                     * @{
+                                     */
+    
                                     /**
                                      * Return the indices of the dofs of this
                                      * quad in the standard ordering: dofs
@@ -1304,6 +1155,17 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                      */
     void get_dof_indices (std::vector<unsigned int> &dof_indices) const;
 
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Accessing the finite element associated with this object
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
                                      /**
                                       * Return the finite element that
                                       * is used on the cell pointed to
@@ -1315,7 +1177,7 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                       * for hp DoF handlers, this may
                                       * change from cell to cell.
                                       */
-    const FiniteElement<DH::dimension> &
+    const FiniteElement<DH::dimension,DH::space_dimension> &
     get_fe () const;
 
                                      /**
@@ -1330,45 +1192,21 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                      *  this cell.
                                      */
     void set_active_fe_index (const unsigned int i);
-
                                     /**
-                                     * Distribute a local (cell
-                                     * based) vector to a global one
-                                     * by mapping the local numbering
-                                     * of the degrees of freedom to
-                                     * the global one and entering
-                                     * the local values into the
-                                     * global vector.
-                                     *
-                                     * The elements are
-                                     * <em>added</em> up to the
-                                     * elements in the global vector,
-                                     * rather than just set, since
-                                     * this is usually what one
-                                     * wants.
+                                     * @}
                                      */
-    template <typename number, typename OutputVector>
-    void
-    distribute_local_to_global (const Vector<number> &local_source,
-                                OutputVector         &global_destination) const;
-
+    
+  private:
                                     /**
-                                     * This function does much the
-                                     * same as the
-                                     * <tt>distribute_local_to_global(Vector,Vector)</tt>
-                                     * function, but operates on
-                                     * matrices instead of
-                                     * vectors. If the matrix type is
-                                     * a sparse matrix then it is
-                                     * supposed to have non-zero
-                                     * entry slots where required.
+                                     * Forward declaration of a class
+                                     * into which we put some
+                                     * parts of the implementation.
+                                     *
+                                     * See the .cc file for more
+                                     * information.
                                      */
-    template <typename number, typename OutputMatrix>
-    void
-    distribute_local_to_global (const FullMatrix<number> &local_source,
-                                OutputMatrix             &global_destination) const;
+    struct Implementation;    
     
-  private:
                                     /**
                                      * Update the cache in which we
                                      * store the dof indices of this
@@ -1382,74 +1220,10 @@ class DoFCellAccessor :  public DoFObjectAccessor<DH::dimension,DH>
                                      * update_cell_dof_indices_cache()
                                      * function
                                      */
-    template <int> friend class DoFHandler;
+    template <int dim, int spacedim> friend class DoFHandler;
 };
 
 
-/* -------------- declaration of explicit specializations ------------- */
-
-template <>
-TriaIterator<1, DoFObjectAccessor<0,DoFHandler<1> > >
-DoFCellAccessor<DoFHandler<1> >::face (const unsigned int) const;
-template <>
-TriaIterator<2, DoFObjectAccessor<1,DoFHandler<2> > >
-DoFCellAccessor<DoFHandler<2> >::face (const unsigned int i) const;
-template <>
-TriaIterator<3, DoFObjectAccessor<2,DoFHandler<3> > >
-DoFCellAccessor<DoFHandler<3> >::face (const unsigned int i) const;
-
-
-template <>
-const FiniteElement<1> &
-DoFCellAccessor<hp::DoFHandler<1> >::get_fe () const;
-template <>
-const FiniteElement<2> &
-DoFCellAccessor<hp::DoFHandler<2> >::get_fe () const;
-template <>
-const FiniteElement<3> &
-DoFCellAccessor<hp::DoFHandler<3> >::get_fe () const;
-
-template <>
-unsigned int
-DoFCellAccessor<hp::DoFHandler<1> >::active_fe_index () const;
-template <>
-unsigned int
-DoFCellAccessor<hp::DoFHandler<2> >::active_fe_index () const;
-template <>
-unsigned int
-DoFCellAccessor<hp::DoFHandler<3> >::active_fe_index () const;
-
-template <>
-void
-DoFCellAccessor<hp::DoFHandler<1> >::set_active_fe_index (const unsigned int i);
-template <>
-void
-DoFCellAccessor<hp::DoFHandler<2> >::set_active_fe_index (const unsigned int i);
-template <>
-void
-DoFCellAccessor<hp::DoFHandler<3> >::set_active_fe_index (const unsigned int i);
-
-template <>
-void
-DoFCellAccessor<DoFHandler<1> >::update_cell_dof_indices_cache () const;
-template <>
-void
-DoFCellAccessor<DoFHandler<2> >::update_cell_dof_indices_cache () const;
-template <>
-void
-DoFCellAccessor<DoFHandler<3> >::update_cell_dof_indices_cache () const;
-
-template <>
-void
-DoFCellAccessor<hp::DoFHandler<1> >::update_cell_dof_indices_cache () const;
-template <>
-void
-DoFCellAccessor<hp::DoFHandler<2> >::update_cell_dof_indices_cache () const;
-template <>
-void
-DoFCellAccessor<hp::DoFHandler<3> >::update_cell_dof_indices_cache () const;
-
-
 DEAL_II_NAMESPACE_CLOSE
 
 // include more templates
index b78b44a424e485c6b76be31fb36dda7f7cf5c389..2407a84df186d579375acb0e56a7b7f9cf1cc6f7 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -31,12 +31,8 @@ DEAL_II_NAMESPACE_OPEN
 
 
 template <int structdim, class DH>
-DoFAccessor<structdim,DH>::DoFAccessor ()
-                :
-               DoFObjectAccessor_Inheritance<structdim, DH::dimension>::BaseClass (0,
-                                                                                   numbers::invalid_unsigned_int,
-                                                                                   numbers::invalid_unsigned_int),
-               dof_handler(0)
+DoFAccessor<structdim,DH>::
+DoFAccessor ()
 {
   Assert (false, ExcInvalidObject());
 }
@@ -45,19 +41,40 @@ DoFAccessor<structdim,DH>::DoFAccessor ()
 
 template <int structdim, class DH>
 inline
-DoFAccessor<structdim,DH>::DoFAccessor (const Triangulation<DH::dimension> *tria,
-                                       const int                 level,
-                                       const int                 index,
-                                       const DH                 *dof_handler)
+DoFAccessor<structdim,DH>::
+DoFAccessor (const Triangulation<DH::dimension,DH::space_dimension> *tria,
+            const int                 level,
+            const int                 index,
+            const DH                 *dof_handler)
                :
-               DoFObjectAccessor_Inheritance<structdim, DH::dimension>::BaseClass (tria,
-                                                                                   level,
-                                                                                   index),
+               internal::DoFAccessor::Inheritance<structdim,DH::dimension,DH::space_dimension>::BaseClass (tria,
+                                                                                                           level,
+                                                                                                           index),
                 dof_handler(const_cast<DH*>(dof_handler))
 {}
 
 
 
+template <int structdim, class DH>
+template <int structdim2, int dim2, int spacedim2>
+DoFAccessor<structdim,DH>::
+DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+{
+  Assert (false, ExcInvalidObject());
+}
+
+
+
+template <int structdim, class DH>
+template <int dim2, class DH2>
+DoFAccessor<structdim,DH>::
+DoFAccessor (const DoFAccessor<dim2, DH2> &)
+{
+  Assert (false, ExcInvalidObject());
+}
+
+
+
 template <int structdim, class DH>
 inline
 void
@@ -124,7 +141,7 @@ DoFAccessor<structdim,DH>::operator != (const DoFAccessor<structdim,DH> &a) cons
 
 template <int structdim, class DH>
 inline
-TriaIterator<DH::dimension,DoFObjectAccessor<structdim,DH> >
+TriaIterator<DoFAccessor<structdim,DH> >
 DoFAccessor<structdim,DH>::child (const unsigned int i) const
 {
   Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
@@ -136,11 +153,11 @@ DoFAccessor<structdim,DH>::child (const unsigned int i) const
   else
     next_level = 0;
   
-  TriaIterator<DH::dimension,DoFObjectAccessor<structdim,DH> > q (this->tria,
-                                                                 next_level,
-                                                                 this->child_index (i),
-                                                                 this->dof_handler);
-
+  TriaIterator<DoFAccessor<structdim,DH> > q (this->tria,
+                                             next_level,
+                                             this->child_index (i),
+                                             this->dof_handler);
+  
                                   // make sure that we either created
                                   // a past-the-end iterator or one
                                   // pointing to a used cell
@@ -259,200 +276,200 @@ DoFAccessor<dim,DH>::fe_index_is_active (const unsigned int fe_index) const
 
 
 
-template <int dim, class DH>
-inline
-const FiniteElement<DH::dimension> &
-DoFAccessor<dim,DH>::get_fe (const unsigned int fe_index) const
+namespace internal
 {
-  Assert (fe_index_is_active (fe_index) == true,
-         ExcMessage ("This function can only be called for active fe indices"));
-  
-  return this->dof_handler->get_fe()[fe_index];
-}
-
-
-
-template <>
-inline
-const FiniteElement<1> &
-DoFAccessor<1,dealii::DoFHandler<1> >::get_fe (const unsigned int fe_index) const
-{
-  Assert (fe_index_is_active (fe_index) == true,
-         ExcMessage ("This function can only be called for active fe indices"));  
-  return this->dof_handler->get_fe();
-}
-
-
-
-template <>
-inline
-const FiniteElement<2> &
-DoFAccessor<1,dealii::DoFHandler<2> >::get_fe (const unsigned int fe_index) const
-{
-  Assert (fe_index_is_active (fe_index) == true,
-         ExcMessage ("This function can only be called for active fe indices"));  
-  return this->dof_handler->get_fe();
-}
-
+  namespace DoFAccessor
+  {
+    template <int dim, int spacedim>
+    inline
+    const FiniteElement<dim,spacedim> &
+    get_fe (const FiniteElement<dim,spacedim> &fe,
+           const unsigned int)
+    {
+      return fe;
+    }
 
 
-template <>
-inline
-const FiniteElement<3> &
-DoFAccessor<1,dealii::DoFHandler<3> >::get_fe (const unsigned int fe_index) const
-{
-  Assert (fe_index_is_active (fe_index) == true,
-         ExcMessage ("This function can only be called for active fe indices"));  
-  return this->dof_handler->get_fe();
-}
-
-
-
-template <>
-inline
-const FiniteElement<2> &
-DoFAccessor<2,dealii::DoFHandler<2> >::get_fe (const unsigned int fe_index) const
-{
-  Assert (fe_index_is_active (fe_index) == true,
-         ExcMessage ("This function can only be called for active fe indices"));  
-  return this->dof_handler->get_fe();
+  
+    template <int dim, int spacedim>
+    inline
+    const FiniteElement<dim,spacedim> &
+    get_fe (const dealii::hp::FECollection<dim,spacedim> &fe,
+           const unsigned int                            index)
+    {
+      return fe[index];
+    }
+  }
 }
 
 
-
-template <>
+template <int dim, class DH>
 inline
-const FiniteElement<3> &
-DoFAccessor<2,dealii::DoFHandler<3> >::get_fe (const unsigned int fe_index) const
+const FiniteElement<DH::dimension,DH::space_dimension> &
+DoFAccessor<dim,DH>::get_fe (const unsigned int fe_index) const
 {
   Assert (fe_index_is_active (fe_index) == true,
-         ExcMessage ("This function can only be called for active fe indices"));  
-  return this->dof_handler->get_fe();
+         ExcMessage ("This function can only be called for active fe indices"));
+  
+  return internal::DoFAccessor::get_fe (this->dof_handler->get_fe(), fe_index);
 }
 
 
 
-template <>
-inline
-const FiniteElement<3> &
-DoFAccessor<3,dealii::DoFHandler<3> >::get_fe (const unsigned int fe_index) const
+namespace internal
 {
-  Assert (fe_index_is_active (fe_index) == true,
-         ExcMessage ("This function can only be called for active fe indices"));  
-  return this->dof_handler->get_fe();
+  namespace DoFAccessor
+  {
+    template <class DH>
+    void get_dof_indices (const dealii::DoFAccessor<1,DH>   &accessor,
+                         std::vector<unsigned int> &dof_indices,
+                         const unsigned int         fe_index)
+    {
+      const unsigned int dofs_per_vertex = accessor.get_fe(fe_index).dofs_per_vertex,
+                        dofs_per_line   = accessor.get_fe(fe_index).dofs_per_line;
+      std::vector<unsigned int>::iterator next = dof_indices.begin();
+      for (unsigned int vertex=0; vertex<2; ++vertex)
+       for (unsigned int d=0; d<dofs_per_vertex; ++d)
+         *next++ = accessor.vertex_dof_index(vertex,d,fe_index);
+      for (unsigned int d=0; d<dofs_per_line; ++d)
+       *next++ = accessor.dof_index(d,fe_index);
+    }
+
+
+    
+    template <class DH>
+    void get_dof_indices (const dealii::DoFAccessor<2,DH>   &accessor,
+                         std::vector<unsigned int> &dof_indices,
+                         const unsigned int         fe_index)
+    {
+      const unsigned int dofs_per_vertex = accessor.get_fe(fe_index).dofs_per_vertex,
+                        dofs_per_line   = accessor.get_fe(fe_index).dofs_per_line,
+                        dofs_per_quad   = accessor.get_fe(fe_index).dofs_per_quad;
+      std::vector<unsigned int>::iterator next = dof_indices.begin();
+      for (unsigned int vertex=0; vertex<4; ++vertex)
+       for (unsigned int d=0; d<dofs_per_vertex; ++d)
+         *next++ = accessor.vertex_dof_index(vertex,d,fe_index);
+                                      // now copy dof numbers from the line. for
+                                      // lines with the wrong orientation (which
+                                      // might occur in 3d), we have already made
+                                      // sure that we're ok by picking the correct
+                                      // vertices (this happens automatically in
+                                      // the vertex() function). however, if the
+                                      // line is in wrong orientation, we look at
+                                      // it in flipped orientation and we will have
+                                      // to adjust the shape function indices that
+                                      // we see to correspond to the correct
+                                      // (face-local) ordering.
+      for (unsigned int line=0; line<4; ++line)
+       for (unsigned int d=0; d<dofs_per_line; ++d)
+         *next++ = accessor.line(line)->dof_index(accessor.get_fe(fe_index).
+                                                  adjust_line_dof_index_for_line_orientation(d,
+                                                                                             accessor.line_orientation(line)),
+                                                  fe_index);
+      for (unsigned int d=0; d<dofs_per_quad; ++d)
+       *next++ = accessor.dof_index(d,fe_index);
+    }
+
+    
+
+    template <class DH>
+    void get_dof_indices (const dealii::DoFAccessor<3,DH>   &accessor,
+                         std::vector<unsigned int> &dof_indices,
+                         const unsigned int         fe_index)
+    {
+      const unsigned int dofs_per_vertex = accessor.get_fe(fe_index).dofs_per_vertex,
+                        dofs_per_line   = accessor.get_fe(fe_index).dofs_per_line,
+                        dofs_per_quad   = accessor.get_fe(fe_index).dofs_per_quad,
+                        dofs_per_hex    = accessor.get_fe(fe_index).dofs_per_hex;
+      std::vector<unsigned int>::iterator next = dof_indices.begin();
+      for (unsigned int vertex=0; vertex<8; ++vertex)
+       for (unsigned int d=0; d<dofs_per_vertex; ++d)
+         *next++ = accessor.vertex_dof_index(vertex,d,fe_index);
+                                      // now copy dof numbers from the line. for
+                                      // lines with the wrong orientation, we have
+                                      // already made sure that we're ok by picking
+                                      // the correct vertices (this happens
+                                      // automatically in the vertex()
+                                      // function). however, if the line is in
+                                      // wrong orientation, we look at it in
+                                      // flipped orientation and we will have to
+                                      // adjust the shape function indices that we
+                                      // see to correspond to the correct
+                                      // (cell-local) ordering.
+      for (unsigned int line=0; line<12; ++line)
+       for (unsigned int d=0; d<dofs_per_line; ++d)
+         *next++ = accessor.line(line)->dof_index(accessor.get_fe(fe_index).
+                                                  adjust_line_dof_index_for_line_orientation(d,
+                                                                                             accessor.line_orientation(line)),fe_index);
+                                      // now copy dof numbers from the face. for
+                                      // faces with the wrong orientation, we
+                                      // have already made sure that we're ok by
+                                      // picking the correct lines and vertices
+                                      // (this happens automatically in the
+                                      // line() and vertex() functions). however,
+                                      // if the face is in wrong orientation, we
+                                      // look at it in flipped orientation and we
+                                      // will have to adjust the shape function
+                                      // indices that we see to correspond to the
+                                      // correct (cell-local) ordering. The same
+                                      // applies, if the face_rotation or
+                                      // face_orientation is non-standard
+      for (unsigned int quad=0; quad<6; ++quad)
+       for (unsigned int d=0; d<dofs_per_quad; ++d)
+         *next++ = accessor.quad(quad)->dof_index(accessor.get_fe(fe_index).
+                                                  adjust_quad_dof_index_for_face_orientation(d,
+                                                                                             accessor.face_orientation(quad),
+                                                                                             accessor.face_flip(quad),
+                                                                                             accessor.face_rotation(quad)),
+                                                  fe_index);
+      for (unsigned int d=0; d<dofs_per_hex; ++d)
+       *next++ = accessor.dof_index(d,fe_index);
+    }
+  }
 }
 
-/*------------------------- Functions: DoFObjectAccessor<1,dim> -----------------------*/
-
 
-template <class DH>
-inline
-DoFObjectAccessor<1,DH>::
-DoFObjectAccessor (const Triangulation<DH::dimension> *tria,
-                   const int                 level,
-                   const int                 index,
-                   const AccessorData       *local_data)
-                :
-                DoFAccessor<1,DH> (tria, level, index, local_data)
-{}
-
-
-
-
-template <class DH>
+template <int structdim, class DH>
 inline
 void
-DoFObjectAccessor<1,DH>::get_dof_indices (std::vector<unsigned int> &dof_indices,
-                                         const unsigned int         fe_index) const
+DoFAccessor<structdim,DH>::get_dof_indices (std::vector<unsigned int> &dof_indices,
+                                           const unsigned int         fe_index) const
 {
   Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
           ExcMessage ("DoFHandler not initialized"));
 
-  Assert (this->dof_handler != 0, typename BaseClass::ExcInvalidObject());
-  Assert (&this->dof_handler->get_fe() != 0, typename BaseClass::ExcInvalidObject());
-  Assert (dof_indices.size() == (2*this->dof_handler->get_fe()[fe_index].dofs_per_vertex +
-                                this->dof_handler->get_fe()[fe_index].dofs_per_line),
-         typename BaseClass::ExcVectorDoesNotMatch());
-
-                                  // this function really only makes
-                                  // sense if either a) there are
-                                  // degrees of freedom defined on
-                                  // the present object, or b) the
-                                  // object is non-active objects but
-                                  // all degrees of freedom are
-                                  // located on vertices, since
-                                  // otherwise there are degrees of
-                                  // freedom on sub-objects which are
-                                  // not allocated for this
-                                  // non-active thing
-  Assert (this->fe_index_is_active (fe_index)
-         ||
-         (this->dof_handler->get_fe()[fe_index].dofs_per_cell ==
-          2*this->dof_handler->get_fe()[fe_index].dofs_per_vertex),
-         ExcInternalError());
-         
-  const unsigned int dofs_per_vertex = this->dof_handler->get_fe()[fe_index].dofs_per_vertex,
-                    dofs_per_line   = this->dof_handler->get_fe()[fe_index].dofs_per_line;
-  std::vector<unsigned int>::iterator next = dof_indices.begin();
-  for (unsigned int vertex=0; vertex<2; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next++ = this->vertex_dof_index(vertex,d,fe_index);
-  for (unsigned int d=0; d<dofs_per_line; ++d)
-    *next++ = this->dof_index(d,fe_index);
-}
-
-
-
-
-
-/*------------------------- Functions: DoFObjectAccessor<2,dim> -----------------------*/
-
-template <class DH>
-DoFObjectAccessor<2,DH>::
-DoFObjectAccessor (const Triangulation<DH::dimension> *tria,
-                   const int                 level,
-                   const int                 index,
-                   const AccessorData       *local_data)
-                :
-                DoFAccessor<2,DH> (tria, level, index, local_data)
-{}
-
-
-
-template <class DH>
-inline
-TriaIterator<DH::dimension,DoFObjectAccessor<1,DH> >
-DoFObjectAccessor<2,DH>::line (const unsigned int i) const
-{
-  Assert (i<4, ExcIndexRange (i, 0, 4));
+  Assert (this->dof_handler != 0, ExcInvalidObject());
+  Assert (&this->dof_handler->get_fe() != 0, ExcInvalidObject());
   Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
           ExcMessage ("DoFHandler not initialized"));
 
-  return TriaIterator<dim,DoFObjectAccessor<1,DH> >
-    (
-      this->tria,
-      0,
-      this->line_index (i),
-      this->dof_handler
-    );
-}
-
-
-
-template <class DH>
-inline
-void
-DoFObjectAccessor<2,DH>::get_dof_indices (std::vector<unsigned int> &dof_indices,
-                                         const unsigned int         fe_index) const
-{
-  Assert (this->dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (&this->dof_handler->get_fe() != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (dof_indices.size() == (4*this->dof_handler->get_fe()[fe_index].dofs_per_vertex +
-                                4*this->dof_handler->get_fe()[fe_index].dofs_per_line +
-                                this->dof_handler->get_fe()[fe_index].dofs_per_quad),
-         typename BaseClass::ExcVectorDoesNotMatch());
+  switch (structdim)
+    {
+      case 1:
+           Assert (dof_indices.size() ==
+                   (2*this->dof_handler->get_fe()[fe_index].dofs_per_vertex +
+                    this->dof_handler->get_fe()[fe_index].dofs_per_line),
+                   ExcVectorDoesNotMatch());
+           break;
+      case 2:
+           Assert (dof_indices.size() ==
+                   (4*this->dof_handler->get_fe()[fe_index].dofs_per_vertex +
+                    4*this->dof_handler->get_fe()[fe_index].dofs_per_line +
+                    this->dof_handler->get_fe()[fe_index].dofs_per_quad),
+                   ExcVectorDoesNotMatch());
+           break;
+      case 3:
+           Assert (dof_indices.size() ==
+                   (8*this->dof_handler->get_fe()[fe_index].dofs_per_vertex +
+                    12*this->dof_handler->get_fe()[fe_index].dofs_per_line +
+                    6*this->dof_handler->get_fe()[fe_index].dofs_per_quad +
+                    this->dof_handler->get_fe()[fe_index].dofs_per_hex),
+                   ExcVectorDoesNotMatch());
+           break;
+      default:
+           Assert (false, ExcNotImplemented());
+    }
+  
 
                                   // this function really only makes
                                   // sense if either a) there are
@@ -468,83 +485,50 @@ DoFObjectAccessor<2,DH>::get_dof_indices (std::vector<unsigned int> &dof_indices
   Assert (this->fe_index_is_active (fe_index)
          ||
          (this->dof_handler->get_fe()[fe_index].dofs_per_cell ==
-          4*this->dof_handler->get_fe()[fe_index].dofs_per_vertex),
+          GeometryInfo<structdim>::vertices_per_cell *
+          this->dof_handler->get_fe()[fe_index].dofs_per_vertex),
          ExcInternalError());
-         
-  Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-  
-  const unsigned int dofs_per_vertex = this->dof_handler->get_fe()[fe_index].dofs_per_vertex,
-                    dofs_per_line   = this->dof_handler->get_fe()[fe_index].dofs_per_line,
-                    dofs_per_quad   = this->dof_handler->get_fe()[fe_index].dofs_per_quad;
-  std::vector<unsigned int>::iterator next = dof_indices.begin();
-  for (unsigned int vertex=0; vertex<4; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next++ = this->vertex_dof_index(vertex,d,fe_index);
-                                  // now copy dof numbers from the line. for
-                                  // lines with the wrong orientation (which
-                                  // might occur in 3d), we have already made
-                                  // sure that we're ok by picking the correct
-                                  // vertices (this happens automatically in
-                                  // the vertex() function). however, if the
-                                  // line is in wrong orientation, we look at
-                                  // it in flipped orientation and we will have
-                                  // to adjust the shape function indices that
-                                  // we see to correspond to the correct
-                                  // (face-local) ordering.
-  for (unsigned int line=0; line<4; ++line)
-    for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next++ = this->line(line)->dof_index(this->dof_handler->get_fe()[fe_index].
-                                           adjust_line_dof_index_for_line_orientation(d,
-                                                                                      this->line_orientation(line)),fe_index);
-  for (unsigned int d=0; d<dofs_per_quad; ++d)
-    *next++ = this->dof_index(d,fe_index);
+
+                                  // now do the actual work
+  internal::DoFAccessor::get_dof_indices (*this, dof_indices, fe_index);
 }
 
 
 
-/*------------------------- Functions: DoFObjectAccessor<3,dim> -----------------------*/
 
-template <class DH>
-inline
-DoFObjectAccessor<3,DH>::
-DoFObjectAccessor (const Triangulation<DH::dimension> *tria,
-                   const int                 level,
-                   const int                 index,
-                   const AccessorData       *local_data)
-                :
-                DoFAccessor<3,DH> (tria, level, index, local_data)
-{}
 
-
-
-template <class DH>
+template <int structdim, class DH>
 inline
-TriaIterator<DH::dimension,DoFObjectAccessor<1,DH> >
-DoFObjectAccessor<3,DH>::line (const unsigned int i) const
+typename internal::DoFHandler::Iterators<DH>::line_iterator
+DoFAccessor<structdim,DH>::line (const unsigned int i) const
 {
-  TriaIterator<dim,TriaObjectAccessor<1,dim> > l = TriaObjectAccessor<3,DH::dimension>::line(i);
-  return TriaIterator<dim,DoFObjectAccessor<1,DH> >
+  Assert (structdim > 1, ExcImpossibleInDim(structdim));
+                                  // checking of 'i' happens in
+                                  // line_index(i)
+  
+  return typename internal::DoFHandler::Iterators<DH>::line_iterator
     (
       this->tria,
-      0,
-      l->index(),
+      0,  // only sub-objects are allowed, which have no level
+      this->line_index(i),
       this->dof_handler
     );
 }
 
 
-template <class DH>
+template <int structdim, class DH>
 inline
-TriaIterator<DH::dimension,DoFObjectAccessor<2,DH> >
-DoFObjectAccessor<3,DH>::quad (const unsigned int i) const
+typename internal::DoFHandler::Iterators<DH>::quad_iterator
+DoFAccessor<structdim,DH>::quad (const unsigned int i) const
 {
-  Assert (i<6, ExcIndexRange (i, 0, 6));
+  Assert (structdim > 2, ExcImpossibleInDim(structdim));
+                                  // checking of 'i' happens in
+                                  // quad_index(i)
 
-  return TriaIterator<dim,DoFObjectAccessor<2,DH> >
+  return typename internal::DoFHandler::Iterators<DH>::quad_iterator
     (
       this->tria,
-      0,
+      0,  // only sub-objects are allowed, which have no level
       this->quad_index (i),
       this->dof_handler
     );
@@ -552,119 +536,369 @@ DoFObjectAccessor<3,DH>::quad (const unsigned int i) const
 
 
 
-template <class DH>
-inline
-void
-DoFObjectAccessor<3,DH>::get_dof_indices (std::vector<unsigned int> &dof_indices,
-                                         const unsigned int         fe_index) const
-{
-  Assert (this->dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (&this->dof_handler->get_fe() != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (dof_indices.size() == (8*this->dof_handler->get_fe()[fe_index].dofs_per_vertex +
-                                12*this->dof_handler->get_fe()[fe_index].dofs_per_line +
-                                6*this->dof_handler->get_fe()[fe_index].dofs_per_quad +
-                                this->dof_handler->get_fe()[fe_index].dofs_per_hex),
-         typename BaseClass::ExcVectorDoesNotMatch());
-  Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
 
-                                  // this function really only makes
-                                  // sense if either a) there are
-                                  // degrees of freedom defined on
-                                  // the present object, or b) the
-                                  // object is non-active objects but
-                                  // all degrees of freedom are
-                                  // located on vertices, since
-                                  // otherwise there are degrees of
-                                  // freedom on sub-objects which are
-                                  // not allocated for this
-                                  // non-active thing
-  Assert (this->fe_index_is_active (fe_index)
-         ||
-         (this->dof_handler->get_fe()[fe_index].dofs_per_cell ==
-          8*this->dof_handler->get_fe()[fe_index].dofs_per_vertex),
-         ExcInternalError());
 
-  Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-  
-  const unsigned int dofs_per_vertex = this->dof_handler->get_fe()[fe_index].dofs_per_vertex,
-                    dofs_per_line   = this->dof_handler->get_fe()[fe_index].dofs_per_line,
-                    dofs_per_quad   = this->dof_handler->get_fe()[fe_index].dofs_per_quad,
-                    dofs_per_hex    = this->dof_handler->get_fe()[fe_index].dofs_per_hex;
-  std::vector<unsigned int>::iterator next = dof_indices.begin();
-  for (unsigned int vertex=0; vertex<8; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next++ = this->vertex_dof_index(vertex,d,fe_index);
-                                  // now copy dof numbers from the line. for
-                                  // lines with the wrong orientation, we have
-                                  // already made sure that we're ok by picking
-                                  // the correct vertices (this happens
-                                  // automatically in the vertex()
-                                  // function). however, if the line is in
-                                  // wrong orientation, we look at it in
-                                  // flipped orientation and we will have to
-                                  // adjust the shape function indices that we
-                                  // see to correspond to the correct
-                                  // (cell-local) ordering.
-  for (unsigned int line=0; line<12; ++line)
-    for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next++ = this->line(line)->dof_index(this->dof_handler->get_fe()[fe_index].
-                                           adjust_line_dof_index_for_line_orientation(d,
-                                                                                      this->line_orientation(line)),fe_index);
-                                  // now copy dof numbers from the face. for
-                                  // faces with the wrong orientation, we
-                                  // have already made sure that we're ok by
-                                  // picking the correct lines and vertices
-                                  // (this happens automatically in the
-                                  // line() and vertex() functions). however,
-                                  // if the face is in wrong orientation, we
-                                  // look at it in flipped orientation and we
-                                  // will have to adjust the shape function
-                                  // indices that we see to correspond to the
-                                  // correct (cell-local) ordering. The same
-                                  // applies, if the face_rotation or
-                                  // face_orientation is non-standard
-  for (unsigned int quad=0; quad<6; ++quad)
-    for (unsigned int d=0; d<dofs_per_quad; ++d)
-      *next++ = this->quad(quad)->dof_index(this->dof_handler->get_fe()[fe_index].
-                                             adjust_quad_dof_index_for_face_orientation(d,
-                                                                                        this->face_orientation(quad),
-                                                                                        this->face_flip(quad),
-                                                                                        this->face_rotation(quad)),fe_index);
-  for (unsigned int d=0; d<dofs_per_hex; ++d)
-    *next++ = this->dof_index(d,fe_index);
-}
+/*------------------------- Functions: DoFCellAccessor -----------------------*/
 
 
+/**
+ * A class with the same purpose as the similarly named class of the
+ * Triangulation class. See there for more information.
+ */
+template <class DH>
+struct DoFCellAccessor<DH>::Implementation
+{
+                                    /**
+                                     * Implement the updating of the
+                                     * cache. Currently not
+                                     * implemented for hp::DoFHandler
+                                     * objects.
+                                     */
+    template <int spacedim>
+    static
+    void
+    update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<1,spacedim> > &accessor)
+      {
+                                        // check as in documentation that
+                                        // cell is either active, or dofs
+                                        // are only in vertices. otherwise
+                                        // simply don't update the cache at
+                                        // all. the get_dof_indices
+                                        // function will then make sure we
+                                        // don't access the invalid data
+       if (accessor.has_children()
+           &&
+           (accessor.get_fe().dofs_per_cell !=
+            accessor.get_fe().dofs_per_vertex * GeometryInfo<1>::vertices_per_cell))
+         return;
+       
+       const unsigned int dofs_per_vertex = accessor.get_fe().dofs_per_vertex,
+                          dofs_per_line   = accessor.get_fe().dofs_per_line,
+                          dofs_per_cell   = accessor.get_fe().dofs_per_cell;
+       
+                                        // make sure the cache is at least
+                                        // as big as we need it when
+                                        // writing to the last element of
+                                        // this cell
+       Assert (accessor.present_index * dofs_per_cell + dofs_per_cell
+               <=
+               accessor.dof_handler->levels[accessor.present_level]
+               ->cell_dof_indices_cache.size(),
+               ExcInternalError());
+       
+       std::vector<unsigned int>::iterator next
+         = (accessor.dof_handler->levels[accessor.present_level]
+            ->cell_dof_indices_cache.begin() + accessor.present_index * dofs_per_cell);
+       
+       for (unsigned int vertex=0; vertex<2; ++vertex)
+         for (unsigned int d=0; d<dofs_per_vertex; ++d)
+           *next++ = accessor.vertex_dof_index(vertex,d);
+       for (unsigned int d=0; d<dofs_per_line; ++d)
+         *next++ = accessor.dof_index(d);
+      }
+
+
+
+    template <int spacedim>
+    static
+    void
+    update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<2,spacedim> > &accessor)
+      {
+                                        // check as in documentation that
+                                        // cell is either active, or dofs
+                                        // are only in vertices. otherwise
+                                        // simply don't update the cache at
+                                        // all. the get_dof_indices
+                                        // function will then make sure we
+                                        // don't access the invalid data
+       if (accessor.has_children()
+           &&
+           (accessor.get_fe().dofs_per_cell !=
+            accessor.get_fe().dofs_per_vertex * GeometryInfo<2>::vertices_per_cell))
+         return;
+  
+       const unsigned int dofs_per_vertex = accessor.get_fe().dofs_per_vertex,
+                          dofs_per_line   = accessor.get_fe().dofs_per_line,
+                          dofs_per_quad   = accessor.get_fe().dofs_per_quad,
+                          dofs_per_cell   = accessor.get_fe().dofs_per_cell;
+
+                                        // make sure the cache is at least
+                                        // as big as we need it when
+                                        // writing to the last element of
+                                        // this cell
+       Assert (accessor.present_index * dofs_per_cell + dofs_per_cell
+               <=
+               accessor.dof_handler->levels[accessor.present_level]
+               ->cell_dof_indices_cache.size(),
+               ExcInternalError());
+
+       std::vector<unsigned int>::iterator next
+         = (accessor.dof_handler->levels[accessor.present_level]
+            ->cell_dof_indices_cache.begin() + accessor.present_index * dofs_per_cell);
+
+       for (unsigned int vertex=0; vertex<4; ++vertex)
+         for (unsigned int d=0; d<dofs_per_vertex; ++d)
+           *next++ = accessor.vertex_dof_index(vertex,d);
+       for (unsigned int line=0; line<4; ++line)
+         for (unsigned int d=0; d<dofs_per_line; ++d)
+           *next++ = accessor.line(line)->dof_index(d);
+       for (unsigned int d=0; d<dofs_per_quad; ++d)
+         *next++ = accessor.dof_index(d);
+      }
+
+
+
+    template <int spacedim>
+    static
+    void
+    update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<3,spacedim> > &accessor)
+      {
+                                        // check as in documentation that
+                                        // cell is either active, or dofs
+                                        // are only in vertices. otherwise
+                                        // simply don't update the cache at
+                                        // all. the get_dof_indices
+                                        // function will then make sure we
+                                        // don't access the invalid data
+       if (accessor.has_children()
+           &&
+           (accessor.get_fe().dofs_per_cell !=
+            accessor.get_fe().dofs_per_vertex * GeometryInfo<3>::vertices_per_cell))
+         return;
+  
+       const unsigned int dofs_per_vertex = accessor.get_fe().dofs_per_vertex,
+                          dofs_per_line   = accessor.get_fe().dofs_per_line,
+                          dofs_per_quad   = accessor.get_fe().dofs_per_quad,
+                          dofs_per_hex    = accessor.get_fe().dofs_per_hex,
+                          dofs_per_cell   = accessor.get_fe().dofs_per_cell;
+
+                                        // make sure the cache is at least
+                                        // as big as we need it when
+                                        // writing to the last element of
+                                        // this cell
+       Assert (accessor.present_index * dofs_per_cell + dofs_per_cell
+               <=
+               accessor.dof_handler->levels[accessor.present_level]
+               ->cell_dof_indices_cache.size(),
+               ExcInternalError());
+
+       std::vector<unsigned int>::iterator next
+         = (accessor.dof_handler->levels[accessor.present_level]
+            ->cell_dof_indices_cache.begin() + accessor.present_index * dofs_per_cell);
+
+       for (unsigned int vertex=0; vertex<8; ++vertex)
+         for (unsigned int d=0; d<dofs_per_vertex; ++d)
+           *next++ = accessor.vertex_dof_index(vertex,d);
+                                        // now copy dof numbers from the line. for
+                                        // lines with the wrong orientation, we have
+                                        // already made sure that we're ok by picking
+                                        // the correct vertices (this happens
+                                        // automatically in the vertex()
+                                        // function). however, if the line is in
+                                        // wrong orientation, we look at it in
+                                        // flipped orientation and we will have to
+                                        // adjust the shape function indices that we
+                                        // see to correspond to the correct
+                                        // (cell-local) ordering.
+       for (unsigned int line=0; line<12; ++line)
+         for (unsigned int d=0; d<dofs_per_line; ++d)
+           *next++ = accessor.line(line)->dof_index(accessor.dof_handler->get_fe().
+                                                    adjust_line_dof_index_for_line_orientation(d,
+                                                                                               accessor.line_orientation(line)));
+                                        // now copy dof numbers from the face. for
+                                        // faces with the wrong orientation, we
+                                        // have already made sure that we're ok by
+                                        // picking the correct lines and vertices
+                                        // (this happens automatically in the
+                                        // line() and vertex() functions). however,
+                                        // if the face is in wrong orientation, we
+                                        // look at it in flipped orientation and we
+                                        // will have to adjust the shape function
+                                        // indices that we see to correspond to the
+                                        // correct (cell-local) ordering. The same
+                                        // applies, if the face_rotation or
+                                        // face_orientation is non-standard
+       for (unsigned int quad=0; quad<6; ++quad)
+         for (unsigned int d=0; d<dofs_per_quad; ++d)
+           *next++ = accessor.quad(quad)->dof_index(accessor.dof_handler->get_fe().
+                                                    adjust_quad_dof_index_for_face_orientation(d,
+                                                                                               accessor.face_orientation(quad),
+                                                                                               accessor.face_flip(quad),
+                                                                                               accessor.face_rotation(quad)));
+       for (unsigned int d=0; d<dofs_per_hex; ++d)
+         *next++ = accessor.dof_index(d);
+      }
+
+
+                                    // implementation for the case of
+                                    // hp::DoFHandler objects. it's
+                                    // not implemented there, for no
+                                    // space dimension
+    template <int dim, int spacedim>
+    static
+    void
+    update_cell_dof_indices_cache (const DoFCellAccessor<hp::DoFHandler<dim,spacedim> > &)
+      {
+//TODO[WB]: should implement a dof indices cache for hp as well
+  
+                                        // not implemented, but should also
+                                        // not be called
+       Assert (false, ExcNotImplemented());
+      }
+
+
+                                    /**
+                                     * A function that collects the
+                                     * global indices of degrees of
+                                     * freedom. This function works
+                                     * for ::DoFHandler and all
+                                     * template arguments and copies
+                                     * the data out of the cache that
+                                     * we hold for each cell.
+                                     */
+    template <int dim, int spacedim>
+    static
+    void
+    get_dof_indices (const DoFCellAccessor<DoFHandler<dim,spacedim> > &accessor,
+                    std::vector<unsigned int>                        &dof_indices)
+      {
+       Assert (dof_indices.size() == accessor.get_fe().dofs_per_cell,
+               typename BaseClass::ExcVectorDoesNotMatch());
+
+                                        // check as in documentation that
+                                        // cell is either active, or dofs
+                                        // are only in vertices
+       Assert (!accessor.has_children()
+               ||
+               (accessor.get_fe().dofs_per_cell ==
+                accessor.get_fe().dofs_per_vertex * GeometryInfo<dim>::vertices_per_cell),
+               ExcMessage ("Cell must either be active, or all DoFs must be in vertices"));
+  
+       unsigned int *cache = &accessor.dof_handler->levels[accessor.level()]
+                             ->cell_dof_indices_cache[accessor.present_index * accessor.get_fe().dofs_per_cell]; 
+       for (unsigned int i=0; i<accessor.get_fe().dofs_per_cell; ++i, ++cache)
+         dof_indices[i] = *cache;
+      }      
+
+                                    /**
+                                     * Same function as above except
+                                     * that it works for
+                                     * hp::DoFHandler objects that do
+                                     * not have a cache for the local
+                                     * DoF indices.
+                                     */
+    template <int dim, int spacedim>
+    static
+    void
+    get_dof_indices (const DoFCellAccessor<hp::DoFHandler<dim,spacedim> > &accessor,
+                    std::vector<unsigned int>                            &dof_indices)
+      {
+                                        // no caching for hp::DoFHandler implemented 
+       accessor.DoFAccessor<dim,hp::DoFHandler<dim,spacedim> >::get_dof_indices (dof_indices,
+                                                                                 accessor.active_fe_index());
+      }
+
+
+                                    /**
+                                     * Do what the active_fe_index
+                                     * function in the parent class
+                                     * is supposed to do.
+                                     */
+    template <int dim, int spacedim>
+    static
+    unsigned int
+    active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim> > &)
+    {
+                                      // ::DoFHandler only supports a
+                                      // single active fe with index
+                                      // zero
+      return 0;
+    }
+
+
+
+    template <int dim, int spacedim>
+    static
+    unsigned int
+    active_fe_index (const DoFCellAccessor<hp::DoFHandler<dim,spacedim> > &accessor)
+    {
+      Assert (static_cast<unsigned int>(accessor.level()) < accessor.dof_handler->levels.size(),
+             ExcMessage ("DoFHandler not initialized"));
+      Assert (static_cast<std::vector<unsigned int>::size_type>(accessor.present_index) <
+             accessor.dof_handler->levels[accessor.level()]->active_fe_indices.size (),
+             ExcIndexRange (accessor.present_index, 0,
+                            accessor.dof_handler->levels[accessor.level()]->active_fe_indices.size ()));
+      return accessor.dof_handler->levels[accessor.level()]
+       ->active_fe_indices[accessor.present_index];
+    }
+
+
+
+                                    /**
+                                     * Do what the
+                                     * set_active_fe_index function
+                                     * in the parent class is
+                                     * supposed to do.
+                                     */
+    template <int dim, int spacedim>
+    static
+    void
+    set_active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim> > &,
+                        const unsigned int                                i)
+    {
+                                      // ::DoFHandler only supports a
+                                      // single active fe with index
+                                      // zero
+      Assert (i == 0, typename BaseClass::ExcInvalidObject());
+    }
+
+
+
+    template <int dim, int spacedim>
+    static
+    void
+    set_active_fe_index (DoFCellAccessor<hp::DoFHandler<dim,spacedim> > &accessor,
+                        const unsigned int                              i)
+      {
+       Assert (accessor.dof_handler != 0,
+               typename BaseClass::ExcInvalidObject());
+       Assert (static_cast<unsigned int>(accessor.level()) <
+               accessor.dof_handler->levels.size(),
+               ExcMessage ("DoFHandler not initialized"));
+       Assert (static_cast<std::vector<unsigned int>::size_type>(accessor.present_index) <
+               accessor.dof_handler->levels[accessor.level()]->active_fe_indices.size (),
+               ExcIndexRange (accessor.present_index, 0,
+                              accessor.dof_handler->levels[accessor.level()]->active_fe_indices.size ()));
+       accessor.dof_handler->levels[accessor.level()]
+         ->active_fe_indices[accessor.present_index] = i;
+      }
+};
 
 
 
-/*------------------------- Functions: DoFCellAccessor -----------------------*/
 
 template <class DH>
 inline
 DoFCellAccessor<DH>::
-DoFCellAccessor (const Triangulation<DH::dimension> *tria,
+DoFCellAccessor (const Triangulation<DH::dimension,DH::space_dimension> *tria,
                  const int                 level,
                  const int                 index,
                  const AccessorData       *local_data)
                 :
-                DoFObjectAccessor<DH::dimension,DH> (tria,level,index,local_data)
+                DoFAccessor<DH::dimension,DH> (tria,level,index,local_data)
 {}
 
 
 template <class DH>
 inline
-TriaIterator<DH::dimension,DoFCellAccessor<DH> >
+typename internal::DoFHandler::Iterators<DH>::cell_iterator
 DoFCellAccessor<DH>::neighbor (const unsigned int i) const
 {
-  TriaIterator<dim,DoFCellAccessor<DH> > q (this->tria,
-                                           this->neighbor_level (i),
-                                           this->neighbor_index (i),
-                                           this->dof_handler);
+  typename internal::DoFHandler::Iterators<DH>::cell_iterator
+    q (this->tria,
+       this->neighbor_level (i),
+       this->neighbor_index (i),
+       this->dof_handler);
   
 #ifdef DEBUG
   if (q.state() != IteratorState::past_the_end)
@@ -676,13 +910,14 @@ DoFCellAccessor<DH>::neighbor (const unsigned int i) const
 
 template <class DH>
 inline
-TriaIterator<DH::dimension,DoFCellAccessor<DH> >
+typename internal::DoFHandler::Iterators<DH>::cell_iterator
 DoFCellAccessor<DH>::child (const unsigned int i) const
 {
-  TriaIterator<dim,DoFCellAccessor<DH> > q (this->tria,
-                                           this->level()+1,
-                                           this->child_index (i),
-                                           this->dof_handler);
+  typename internal::DoFHandler::Iterators<DH>::cell_iterator
+    q (this->tria,
+       this->level()+1,
+       this->child_index (i),
+       this->dof_handler);
   
 #ifdef DEBUG
   if (q.state() != IteratorState::past_the_end)
@@ -693,159 +928,58 @@ DoFCellAccessor<DH>::child (const unsigned int i) const
 
 
 
-template <>
-inline
-TriaIterator<1, DoFObjectAccessor<0,hp::DoFHandler<1> > >
-DoFCellAccessor<hp::DoFHandler<1> >::face (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return TriaIterator<1, DoFObjectAccessor<0,hp::DoFHandler<1> > >();
-}
-
-
-
-template <>
-inline
-TriaIterator<2, DoFObjectAccessor<1,hp::DoFHandler<2> > >
-DoFCellAccessor<hp::DoFHandler<2> >::face (const unsigned int i) const
-{
-  return this->line(i);
-}
-
-
-
-template <>
-inline
-TriaIterator<3, DoFObjectAccessor<2, hp::DoFHandler<3> > >
-DoFCellAccessor<hp::DoFHandler<3> >::face (const unsigned int i) const
-{
-  return this->quad(i);
-}
-
-
-
-template <>
-inline
-void
-DoFCellAccessor<DoFHandler<1> >::
-get_dof_indices (std::vector<unsigned int> &dof_indices) const
-{
-  Assert (dof_indices.size() == this->get_fe().dofs_per_cell,
-         BaseClass::ExcVectorDoesNotMatch());
-
-                                  // check as in documentation that
-                                  // cell is either active, or dofs
-                                  // are only in vertices
-  Assert (!this->has_children()
-         ||
-         (this->get_fe().dofs_per_cell ==
-          this->get_fe().dofs_per_vertex * GeometryInfo<1>::vertices_per_cell),
-         ExcMessage ("Cell must either be active, or all DoFs must be in vertices"));
-  
-  unsigned int *cache = &this->dof_handler->levels[this->level()]
-                       ->cell_dof_indices_cache[this->present_index * this->get_fe().dofs_per_cell]; 
-  for (unsigned int i=0; i<this->get_fe().dofs_per_cell; ++i, ++cache)
-    dof_indices[i] = *cache;
-}
-
-
-
-template <>
-inline
-void
-DoFCellAccessor<hp::DoFHandler<1> >::
-get_dof_indices (std::vector<unsigned int> &dof_indices) const
-{
-                                  // no caching for hp::DoFHandler implemented 
-  DoFObjectAccessor<dim,hp::DoFHandler<dim> >::get_dof_indices (dof_indices,
-                                                               this->active_fe_index());
-}
-
-
-template <>
-inline
-void
-DoFCellAccessor<DoFHandler<2> >::
-get_dof_indices (std::vector<unsigned int> &dof_indices) const
-{
-  Assert (dof_indices.size() == this->get_fe().dofs_per_cell,
-         BaseClass::ExcVectorDoesNotMatch());
-
-                                  // check as in documentation that
-                                  // cell is either active, or dofs
-                                  // are only in vertices
-  Assert (!this->has_children()
-         ||
-         (this->get_fe().dofs_per_cell ==
-          this->get_fe().dofs_per_vertex * GeometryInfo<2>::vertices_per_cell),
-         ExcMessage ("Cell must either be active, or all DoFs must be in vertices"));
-  
-  unsigned int *cache = &this->dof_handler->levels[this->level()]
-                       ->cell_dof_indices_cache[this->present_index * this->get_fe().dofs_per_cell]; 
-  for (unsigned int i=0; i<this->get_fe().dofs_per_cell; ++i, ++cache)
-    dof_indices[i] = *cache;
-}
-
-
-
-template <>
-inline
-void
-DoFCellAccessor<hp::DoFHandler<2> >::
-get_dof_indices (std::vector<unsigned int> &dof_indices) const
-{
-                                  // no caching for hp::DoFHandler implemented 
-  DoFObjectAccessor<dim,hp::DoFHandler<dim> >::get_dof_indices (dof_indices,
-                                                               this->active_fe_index());
-}
-
-
-
-template <>
-inline
-void
-DoFCellAccessor<DoFHandler<3> >::
-get_dof_indices (std::vector<unsigned int> &dof_indices) const
+template <class DH>
+typename internal::DoFHandler::Iterators<DH>::face_iterator
+DoFCellAccessor<DH>::face (const unsigned int i) const
 {
-  Assert (dof_indices.size() == this->get_fe().dofs_per_cell,
-         BaseClass::ExcVectorDoesNotMatch());
+  Assert (i<GeometryInfo<dim>::faces_per_cell, ExcIndexRange (i, 0, GeometryInfo<dim>::faces_per_cell));
+  Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
+          ExcMessage ("DoFHandler not initialized"));
 
-                                  // check as in documentation that
-                                  // cell is either active, or dofs
-                                  // are only in vertices
-  Assert (!this->has_children()
-         ||
-         (this->get_fe().dofs_per_cell ==
-          this->get_fe().dofs_per_vertex * GeometryInfo<3>::vertices_per_cell),
-         ExcMessage ("Cell must either be active, or all DoFs must be in vertices"));
-  
-  unsigned int *cache = &this->dof_handler->levels[this->level()]
-                       ->cell_dof_indices_cache[this->present_index * this->get_fe().dofs_per_cell]; 
-  for (unsigned int i=0; i<this->get_fe().dofs_per_cell; ++i, ++cache)
-    dof_indices[i] = *cache;
+  const unsigned int dim = DH::dimension;  
+  Assert (dim > 1, ExcImpossibleInDim(1));
+
+  switch (dim)
+    {
+      case 2:
+           return typename internal::DoFHandler::Iterators<DH>::face_iterator
+             (this->tria,
+              0,
+              this->line_index (i),
+              this->dof_handler);
+           
+      case 3:
+           return typename internal::DoFHandler::Iterators<DH>::face_iterator
+             (this->tria,
+              0,
+              this->quad_index (i),
+              this->dof_handler);
+           
+      default:
+           Assert (false, ExcNotImplemented());
+           return typename internal::DoFHandler::Iterators<DH>::face_iterator();
+    }
 }
 
 
 
-template <>
+template <class DH>
 inline
 void
-DoFCellAccessor<hp::DoFHandler<3> >::
+DoFCellAccessor<DH>::
 get_dof_indices (std::vector<unsigned int> &dof_indices) const
 {
-                                  // no caching for hp::DoFHandler implemented 
-  DoFObjectAccessor<dim,hp::DoFHandler<dim> >::get_dof_indices (dof_indices,
-                                                               this->active_fe_index());
+  Implementation::get_dof_indices (*this, dof_indices);
 }
 
 
 
 template <class DH>
 inline
-const FiniteElement<DH::dimension> &
+const FiniteElement<DH::dimension,DH::space_dimension> &
 DoFCellAccessor<DH>::get_fe () const
 {
-  return this->dof_handler->get_fe();
+  return internal::DoFAccessor::get_fe (this->dof_handler->get_fe(), active_fe_index());
 }
 
 
@@ -855,7 +989,7 @@ inline
 unsigned int
 DoFCellAccessor<DH>::active_fe_index () const
 {
-  return 0;
+  return Implementation::active_fe_index (*this);
 }
 
 
@@ -865,153 +999,11 @@ inline
 void
 DoFCellAccessor<DH>::set_active_fe_index (const unsigned int i)
 {
-  Assert (i == 0, typename BaseClass::BaseClass::ExcInvalidObject());
-}
-
-
-
-
-
-template <>
-inline
-const FiniteElement<1> &
-DoFCellAccessor<hp::DoFHandler<1> >::get_fe () const
-{
-  return this->dof_handler->get_fe()[active_fe_index ()];
-}
-
-
-
-template <>
-inline
-const FiniteElement<2> &
-DoFCellAccessor<hp::DoFHandler<2> >::get_fe () const
-{
-  return this->dof_handler->get_fe()[active_fe_index ()];
+  Implementation::set_active_fe_index (*this, i);
 }
 
 
 
-template <>
-inline
-const FiniteElement<3> &
-DoFCellAccessor<hp::DoFHandler<3> >::get_fe () const
-{
-  return this->dof_handler->get_fe()[active_fe_index ()];
-}
-
-
-
-template <>
-inline
-unsigned int
-DoFCellAccessor<hp::DoFHandler<1> >::active_fe_index () const
-{
-  Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-  Assert (static_cast<std::vector<unsigned int>::size_type>(this->present_index) <
-         this->dof_handler->levels[this->level()]->active_fe_indices.size (),
-         ExcIndexRange (this->present_index, 0,
-                        this->dof_handler->levels[this->level()]->active_fe_indices.size ()));
-  return this->dof_handler->levels[this->level()]
-    ->active_fe_indices[this->present_index];
-}
-
-
-
-template <>
-inline
-unsigned int
-DoFCellAccessor<hp::DoFHandler<2> >::active_fe_index () const
-{
-  Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-  Assert (static_cast<std::vector<unsigned int>::size_type>(this->present_index) <
-         this->dof_handler->levels[this->level()]->active_fe_indices.size (),
-         ExcIndexRange (this->present_index, 0,
-                        this->dof_handler->levels[this->level()]->active_fe_indices.size ()));
-  return this->dof_handler->levels[this->level()]
-    ->active_fe_indices[this->present_index];
-}
-
-
-
-template <>
-inline
-unsigned int
-DoFCellAccessor<hp::DoFHandler<3> >::active_fe_index () const
-{
-  Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-  Assert (static_cast<std::vector<unsigned int>::size_type>(this->present_index) <
-         this->dof_handler->levels[this->level()]->active_fe_indices.size (),
-         ExcIndexRange (this->present_index, 0,
-                        this->dof_handler->levels[this->level()]->active_fe_indices.size ()));
-  return this->dof_handler->levels[this->level()]
-    ->active_fe_indices[this->present_index];
-}
-
-
-
-template <>
-inline
-void
-DoFCellAccessor<hp::DoFHandler<1> >::set_active_fe_index (const unsigned int i)
-{
-  Assert (this->dof_handler != 0,
-          BaseClass::ExcInvalidObject());
-  Assert (static_cast<unsigned int>(this->level()) <
-          this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-  Assert (static_cast<std::vector<unsigned int>::size_type>(this->present_index) <
-         this->dof_handler->levels[this->level()]->active_fe_indices.size (),
-         ExcIndexRange (this->present_index, 0,
-                        this->dof_handler->levels[this->level()]->active_fe_indices.size ()));
-  this->dof_handler->levels[this->level()]
-    ->active_fe_indices[this->present_index] = i;
-}
-
-
-
-template <>
-inline
-void
-DoFCellAccessor<hp::DoFHandler<2> >::set_active_fe_index (const unsigned int i)
-{
-  Assert (this->dof_handler != 0,
-          BaseClass::ExcInvalidObject());
-  Assert (static_cast<unsigned int>(this->level()) <
-          this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-  Assert (static_cast<std::vector<unsigned int>::size_type>(this->present_index) <
-         this->dof_handler->levels[this->level()]->active_fe_indices.size (),
-         ExcIndexRange (this->present_index, 0,
-                        this->dof_handler->levels[this->level()]->active_fe_indices.size ()));
-  this->dof_handler->levels[this->level()]
-    ->active_fe_indices[this->present_index] = i;
-}
-
-
-
-template <>
-inline
-void
-DoFCellAccessor<hp::DoFHandler<3> >::set_active_fe_index (const unsigned int i)
-{
-  Assert (this->dof_handler != 0,
-          BaseClass::ExcInvalidObject());
-  Assert (static_cast<unsigned int>(this->level()) <
-          this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-  Assert (static_cast<std::vector<unsigned int>::size_type>(this->present_index) <
-         this->dof_handler->levels[this->level()]->active_fe_indices.size (),
-         ExcIndexRange (this->present_index, 0,
-                        this->dof_handler->levels[this->level()]->active_fe_indices.size ()));
-  this->dof_handler->levels[this->level()]
-    ->active_fe_indices[this->present_index] = i;
-}
-
-
 
 template <class DH>
 template <typename number, typename OutputVector>
index b6a757bf3a60486c2ef2e4fe8bcda643dbfd57fe..176092f490e95a5188e8fb9762a368e086eaaf74 100644 (file)
@@ -48,7 +48,7 @@ class BlockIndices;
  * $x_{i_1} = \sum_{j=2}^M a_{i_j} x_{i_j}$. In the context of adaptive finite
  * elements, such constraints appear most frequently as "hanging nodes". For
  * example, when using Q1 and Q2 elements (i.e. using
- * FE_Q&lt;dim&gt;(1) and FE_Q&lt;dim&gt;(2)) on the two
+ * FE_Q&lt;dim,spacedim&gt;(1) and FE_Q&lt;dim,spacedim&gt;(2)) on the two
  * marked cells of the mesh
  *
  * @image html hp-refinement-simple.png
index 658ef72767f46151e1ea1b3cc9eb24f76d01c78e..33e51963b58dc9051529b1a351737629f8051a2f 100644 (file)
@@ -21,8 +21,8 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int> class DoFHandler;
-template <int> class MGDoFHandler;
+template <int, int> class DoFHandler;
+template <int, int> class MGDoFHandler;
   
 namespace internal
 {
index 1f9ec0668ff1d1da02bf778089431176e8815cf9..cab7749455957157261c68bcf4c9b8d2ef0352e0 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -62,6 +62,13 @@ namespace internal
  * presented by the <tt>++</tt> and <tt>--</tt> operators is the same as that
  * for the corresponding triangulation iterators.
  *
+ * The <tt>spacedim</tt> parameter has to be used if one wants to
+ * solve problems in the boundary element method formulation or in an
+ * equivalent one, as it is explained in the Triangulation class. If
+ * not specified, this parameter takes the default value <tt>=dim</tt>
+ * so that this class can be used to solve problems in the finite
+ * element method formulation.
+ *
  * 
  * <h3>Distribution of indices for degrees of freedom</h3>
  *
@@ -104,10 +111,10 @@ namespace internal
  * @ingroup dofs
  * @author Wolfgang Bangerth, 1998
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 class DoFHandler  :  public Subscriptor
 {
-    typedef internal::DoFHandler::Iterators<DoFHandler<dim> > IteratorSelector;
+    typedef internal::DoFHandler::Iterators<DoFHandler<dim,spacedim> > IteratorSelector;
   public:
     typedef typename IteratorSelector::raw_line_iterator    raw_line_iterator;
     typedef typename IteratorSelector::line_iterator        line_iterator;
@@ -133,14 +140,20 @@ class DoFHandler  :  public Subscriptor
                                      * Alias the @p FunctionMap type
                                      * declared elsewhere.
                                      */
-    typedef typename dealii::FunctionMap<dim>::type FunctionMap;
+    typedef typename dealii::FunctionMap<spacedim>::type FunctionMap;
 
                                     /**
                                      * Make the dimension available
                                      * in function templates.
                                      */
     static const unsigned int dimension = dim;
-    
+
+                                    /**
+                                     * Make the space dimension available
+                                     * in function templates.
+                                     */
+    static const unsigned int space_dimension = spacedim;
+
                                     /**
                                      * When the arrays holding the
                                      * DoF indices are set up, but
@@ -184,8 +197,8 @@ class DoFHandler  :  public Subscriptor
                                      * Constructor. Take @p tria as the
                                      * triangulation to work on.
                                      */
-    DoFHandler (const Triangulation<dim> &tria);
-    
+    DoFHandler ( const Triangulation<dim,spacedim> &tria);    
+
                                     /**
                                      * Destructor.
                                      */
@@ -222,7 +235,7 @@ class DoFHandler  :  public Subscriptor
                                      * releases the lock of this
                                      * object to the finite element.
                                      */
-    virtual void distribute_dofs (const FiniteElement<dim> &fe,
+    virtual void distribute_dofs (const FiniteElement<dim,spacedim> &fe,
                                  const unsigned int        offset = 0);
 
                                     /**
@@ -898,14 +911,14 @@ class DoFHandler  :  public Subscriptor
                                      * the selected finite element
                                      * object.
                                      */
-    const FiniteElement<dim> & get_fe () const;
+    const FiniteElement<dim,spacedim> & get_fe () const;
 
                                     /**
                                      * Return a constant reference to
                                      * the triangulation underlying
                                      * this object.
                                      */
-    const Triangulation<dim> & get_tria () const;
+    const Triangulation<dim,spacedim> & get_tria () const;
     
                                     /**
                                      * Determine an estimate for the
@@ -954,6 +967,25 @@ class DoFHandler  :  public Subscriptor
                    int,
                    << "The given list of new dof indices is not consecutive: "
                    << "the index " << arg1 << " does not exist.");
+                                    /**
+                                     *  Exception
+                                     */
+    DeclException1 (ExcInvalidLevel,
+                   int,
+                   << "The given level " << arg1
+                   << " is not in the valid range!");
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcFacesHaveNoLevel);
+                                    /**
+                                     * The triangulation level you
+                                     * accessed is empty.
+                                     */
+    DeclException1 (ExcEmptyLevel,
+                   int,
+                   << "You tried to do something on level " << arg1
+                   << ", but this level is empty.");
 
   protected:
     
@@ -961,7 +993,7 @@ class DoFHandler  :  public Subscriptor
                                      * Address of the triangulation to
                                      * work on.
                                      */
-    SmartPointer<const Triangulation<dim> > tria;
+    SmartPointer<const Triangulation<dim,spacedim> > tria;
 
                                     /**
                                      * Store a pointer to the finite element
@@ -975,7 +1007,7 @@ class DoFHandler  :  public Subscriptor
                                      * function (this clears all data of
                                      * this object as well, though).
                                      */
-    SmartPointer<const FiniteElement<dim> > selected_fe;
+    SmartPointer<const FiniteElement<dim,spacedim> > selected_fe;
 
   private:
 
@@ -1001,38 +1033,10 @@ class DoFHandler  :  public Subscriptor
                                      */
     DoFHandler & operator = (const DoFHandler &);
 
-                                    /**
-                                     * Reserve enough space in the 
-                                     * <tt>levels[]</tt> objects to store the
-                                     * numbers of the degrees of freedom
-                                     * needed for the given element. The
-                                     * given element is that one which
-                                     * was selected when calling
-                                     * @p distribute_dofs the last time.
-                                     */
-    void reserve_space ();
-
                                     /**
                                      * Free all used memory.
                                      */
     void clear_space ();
-    
-                                    /**
-                                     * Distribute dofs on the given cell,
-                                     * with new dofs starting with index
-                                     * @p next_free_dof. Return the next
-                                     * unused index number. The finite
-                                     * element used is the one given to
-                                     * @p distribute_dofs, which is copied
-                                     * to @p selected_fe.
-                                     *
-                                     * This function is excluded from the
-                                     * @p distribute_dofs function since
-                                     * it can not be implemented dimension
-                                     * independent.
-                                     */
-    unsigned int distribute_dofs_on_cell (active_cell_iterator &cell,
-                                         unsigned int next_free_dof);
 
                                     /**
                                      * Set the @p local_index-th
@@ -1199,21 +1203,28 @@ class DoFHandler  :  public Subscriptor
                                      */
     std::vector<unsigned int>      vertex_dofs;
 
+                                    /**
+                                     * Forward declaration of a class
+                                     * into which we put significant
+                                     * parts of the implementation.
+                                     *
+                                     * See the .cc file for more
+                                     * information.
+                                     */
+    struct Implementation;    
     
                                     /*
                                      * Make accessor objects friends.
                                      */
     template <int structdim, class DH> friend class DoFAccessor;
 
-                                    /*
-                                     * Make accessor objects friends.
-                                     */
-    template <int dim1, class DH> friend class DoFObjectAccessor;
-
                                     /*
                                      * Same with cell accessor
                                      */
     template <class DH> friend class DoFCellAccessor;
+
+
+    friend class DoFHandler<dim,spacedim>::Implementation;
 };
 
 
@@ -1226,153 +1237,50 @@ class DoFHandler  :  public Subscriptor
 template <> unsigned int DoFHandler<1>::n_boundary_dofs () const;
 template <> unsigned int DoFHandler<1>::n_boundary_dofs (const FunctionMap &) const;
 template <> unsigned int DoFHandler<1>::n_boundary_dofs (const std::set<unsigned char> &) const;
-template <> unsigned int DoFHandler<1>::max_couplings_between_dofs () const;
-template <> unsigned int DoFHandler<1>::max_couplings_between_boundary_dofs () const;
-template <> unsigned int DoFHandler<2>::max_couplings_between_dofs () const;
-template <> unsigned int DoFHandler<2>::max_couplings_between_boundary_dofs () const;
-template <> unsigned int DoFHandler<3>::max_couplings_between_dofs () const;
-template <> unsigned int DoFHandler<3>::max_couplings_between_boundary_dofs () const;
-
-template <> DoFHandler<1>::raw_cell_iterator DoFHandler<1>::begin_raw (const unsigned int level) const;
-template <> DoFHandler<1>::cell_iterator DoFHandler<1>::begin (const unsigned int level) const;
-template <> DoFHandler<1>::active_cell_iterator DoFHandler<1>::begin_active (const unsigned int level) const;
-template <> DoFHandler<1>::raw_cell_iterator DoFHandler<1>::end () const;
-template <> DoFHandler<1>::raw_cell_iterator DoFHandler<1>::last_raw () const;
-template <> DoFHandler<1>::raw_cell_iterator DoFHandler<1>::last_raw (const unsigned int level) const;
-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;
-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>::face_iterator DoFHandler<1>::last_face () const;
-template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::last_active_face () 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;
-template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::end_quad () const;
-template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::last_raw_quad (const unsigned int) const;
-template <> DoFHandler<1>::quad_iterator DoFHandler<1>::last_quad (const unsigned int) const;
-template <> DoFHandler<1>::active_quad_iterator DoFHandler<1>::last_active_quad (const unsigned int) const;
-template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::last_raw_quad () const;
-template <> DoFHandler<1>::quad_iterator DoFHandler<1>::last_quad () const;
-template <> DoFHandler<1>::active_quad_iterator DoFHandler<1>::last_active_quad () const;
-template <> DoFHandler<1>::raw_hex_iterator DoFHandler<1>::begin_raw_hex (const unsigned int) const;
-template <> DoFHandler<1>::hex_iterator DoFHandler<1>::begin_hex (const unsigned int) const;
-template <> DoFHandler<1>::active_hex_iterator DoFHandler<1>::begin_active_hex (const unsigned int) const;
-template <> DoFHandler<1>::raw_hex_iterator DoFHandler<1>::end_hex () const;
-template <> DoFHandler<1>::raw_hex_iterator DoFHandler<1>::last_raw_hex (const unsigned int) const;
-template <> DoFHandler<1>::raw_hex_iterator DoFHandler<1>::last_raw_hex () const;
-template <> DoFHandler<1>::hex_iterator DoFHandler<1>::last_hex (const unsigned int) const;
-template <> DoFHandler<1>::hex_iterator DoFHandler<1>::last_hex () const;
-template <> DoFHandler<1>::active_hex_iterator DoFHandler<1>::last_active_hex (const unsigned int) const;
-template <> DoFHandler<1>::active_hex_iterator DoFHandler<1>::last_active_hex () const;
-template <> DoFHandler<2>::raw_cell_iterator DoFHandler<2>::begin_raw (const unsigned int level) const;
-template <> DoFHandler<2>::cell_iterator DoFHandler<2>::begin (const unsigned int level) const;
-template <> DoFHandler<2>::active_cell_iterator DoFHandler<2>::begin_active (const unsigned int level) const;
-template <> DoFHandler<2>::raw_cell_iterator DoFHandler<2>::end () const;
-template <> DoFHandler<2>::raw_cell_iterator DoFHandler<2>::last_raw () const;
-template <> DoFHandler<2>::raw_cell_iterator DoFHandler<2>::last_raw (const unsigned int level) const;
-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;
-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>::face_iterator DoFHandler<2>::last_face () const;
-template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::last_active_face () 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;
-template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::end_hex () const;
-template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::last_raw_hex (const unsigned int) const;
-template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::last_raw_hex () const;
-template <> DoFHandler<2>::hex_iterator DoFHandler<2>::last_hex (const unsigned int) const;
-template <> DoFHandler<2>::hex_iterator DoFHandler<2>::last_hex () const;
-template <> DoFHandler<2>::active_hex_iterator DoFHandler<2>::last_active_hex (const unsigned int) const;
-template <> DoFHandler<2>::active_hex_iterator DoFHandler<2>::last_active_hex () const;
-template <> DoFHandler<3>::raw_cell_iterator DoFHandler<3>::begin_raw (const unsigned int level) const;
-template <> DoFHandler<3>::cell_iterator DoFHandler<3>::begin (const unsigned int level) const;
-template <> DoFHandler<3>::active_cell_iterator DoFHandler<3>::begin_active (const unsigned int level) const;
-template <> DoFHandler<3>::raw_cell_iterator DoFHandler<3>::end () const;
-template <> DoFHandler<3>::raw_cell_iterator DoFHandler<3>::last_raw () const;
-template <> DoFHandler<3>::raw_cell_iterator DoFHandler<3>::last_raw (const unsigned int level) const;
-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;
-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>::face_iterator DoFHandler<3>::last_face () const;
-template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::last_active_face () const;
-
-template <>
-unsigned int DoFHandler<1>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                                    unsigned int          next_free_dof);
-template <>
-unsigned int DoFHandler<2>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                                    unsigned int          next_free_dof);
-template <>
-unsigned int DoFHandler<3>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                                    unsigned int          next_free_dof);
-template <> void DoFHandler<1>::renumber_dofs (const std::vector<unsigned int> &new_numbers);
-template <> void DoFHandler<2>::renumber_dofs (const std::vector<unsigned int> &new_numbers);
-template <> void DoFHandler<3>::renumber_dofs (const std::vector<unsigned int> &new_numbers);
-template <> void DoFHandler<1>::reserve_space ();
-template <> void DoFHandler<2>::reserve_space ();
-template <> void DoFHandler<3>::reserve_space ();
+
 
 /* ----------------------- Inline functions ---------------------------------- */
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 unsigned int
-DoFHandler<dim>::n_dofs () const
+DoFHandler<dim,spacedim>::n_dofs () const
 {
   return used_dofs;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const FiniteElement<dim> &
-DoFHandler<dim>::get_fe () const
+const FiniteElement<dim,spacedim> &
+DoFHandler<dim,spacedim>::get_fe () const
 {
   Assert(selected_fe!=0, ExcNoFESelected());
   return *selected_fe;
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const Triangulation<dim> &
-DoFHandler<dim>::get_tria () const
+const Triangulation<dim,spacedim> &
+DoFHandler<dim,spacedim>::get_tria () const
 {
   return *tria;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 unsigned int
-DoFHandler<dim>::
+DoFHandler<dim,spacedim>::
 get_vertex_dof_index (const unsigned int vertex_index,
                      const unsigned int fe_index,
                      const unsigned int local_index) const
 {
-  Assert (fe_index == DoFHandler<dim>::default_fe_index,
+  Assert ((fe_index == DoFHandler<dim,spacedim>::default_fe_index),
          ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
   Assert (selected_fe != 0,
          ExcMessage ("No finite element collection is associated with "
@@ -1386,16 +1294,16 @@ get_vertex_dof_index (const unsigned int vertex_index,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 void
-DoFHandler<dim>::
+DoFHandler<dim,spacedim>::
 set_vertex_dof_index (const unsigned int vertex_index,
                      const unsigned int fe_index,
                      const unsigned int local_index,
                      const unsigned int global_index)
 {
-  Assert (fe_index == DoFHandler<dim>::default_fe_index,
+  Assert ((fe_index == DoFHandler<dim,spacedim>::default_fe_index),
          ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
   Assert (selected_fe != 0,
          ExcMessage ("No finite element collection is associated with "
@@ -1409,11 +1317,11 @@ set_vertex_dof_index (const unsigned int vertex_index,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <int structdim>
 inline
 bool
-DoFHandler<dim>::fe_index_is_active (const unsigned int,
+DoFHandler<dim,spacedim>::fe_index_is_active (const unsigned int,
                                     const unsigned int,
                                     const unsigned int fe_index) const
 {
@@ -1422,11 +1330,11 @@ DoFHandler<dim>::fe_index_is_active (const unsigned int,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <int structdim>
 inline
 unsigned int
-DoFHandler<dim>::n_active_fe_indices (const unsigned int obj_level,
+DoFHandler<dim,spacedim>::n_active_fe_indices (const unsigned int obj_level,
                                      const unsigned int obj_index) const
 {
                                   // check that the object we look at is in
@@ -1462,11 +1370,11 @@ DoFHandler<dim>::n_active_fe_indices (const unsigned int obj_level,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <int structdim>
 inline
 unsigned int
-DoFHandler<dim>::nth_active_fe_index (const unsigned int obj_level,
+DoFHandler<dim,spacedim>::nth_active_fe_index (const unsigned int obj_level,
                                      const unsigned int obj_index,
                                      const unsigned int n) const
 {
index b764033bae55f7f19dbb603d8ceb107441e89528..807b19bdadabdabce729fb0b9cf4befe265876ba 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2007 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
 #ifndef __deal2__dof_iterators_h
 #define __deal2__dof_iterators_h
 
-//TODO: Rename this file to dof_iterators.h
-//TODO: Can we avoid the specializations?
-
-// To consider for the second TODO:
-//  1. Define accessors for unreasonable dimensions
-//  2. Can cell_iterator and quad_iterator in 2D be different (or hex
-//     in 3D)?
-
 #include <base/config.h>
 
+
 DEAL_II_NAMESPACE_OPEN
 
+template <int, int, int> class InvalidAccessor;
+
 template <int structdim, class DH> class DoFAccessor;
 template <class DH> class DoFCellAccessor;
 
-template <int celldim, class DH> class DoFObjectAccessor;
-template <class DH> class DoFObjectAccessor<0,DH>;
-template <class DH> class DoFObjectAccessor<1,DH>;
-template <class DH> class DoFObjectAccessor<2,DH>;
-template <class DH> class DoFObjectAccessor<3,DH>;
-
-template <int dim> class FiniteElement;
-template <int dim, typename Accessor> class TriaRawIterator;
-template <int dim, typename Accessor> class TriaIterator;
-template <int dim, typename Accessor> class TriaActiveIterator;
-template <int dim> class Triangulation;
-template <int dim> class DoFHandler;
+template <int dim, int spacedim> class FiniteElement;
+template <typename Accessor> class TriaRawIterator;
+template <typename Accessor> class TriaIterator;
+template <typename Accessor> class TriaActiveIterator;
+template <int dim, int spacedim> class Triangulation;
+template <int dim, int spacedim> class DoFHandler;
 
 
 namespace internal
 {
   namespace DoFHandler
   {
-/**
- * A pseudo class defining the iterator types used by DoFHandler and
- * hp::DoFHandler.  The typedefs in this class are synonymous with
- * those in the handler classes, such that this class can be used in
- * order to avoid including the complete header files of the handler.
- *
- * The class template is not used, but only its specializations with
- * respect to the dimension. These differ from the template in two
- * points: first, the iterator to objects of the same dimension as the
- * handler is aliased to the #cell_iterator. Second, #face_iterator is
- * aliased to objects of codimension one.
- *
- *
- * @warning This raw iterators are not normally used in application
- * programs.
- *
- * @ingroup dofs
- * @ingroup Accessors
- * @author W. Bangerth, G. Kanschat,  O. Kayser-Herold, 1998, 2003, 2006
- */
     template <class DH>
-    struct Iterators
-    {
-                                         /// The dof handler class.
-        typedef DH DoFHandler_type;
-                                         /// The topological dimension of the dof handler.
-        static const unsigned int dim = DH::dimension;
-    
-                                         /// Iterator for raw lines.
-        typedef TriaRawIterator<dim, DoFObjectAccessor<1, DH> > raw_line_iterator;
-                                         /// Iterator for usual lines.
-        typedef TriaIterator<dim, DoFObjectAccessor<1, DH> > line_iterator;
-                                         /// Iterator for active lines.
-        typedef TriaActiveIterator<dim, DoFObjectAccessor<1, DH> > active_line_iterator;
-                                         /// Iterator for raw quadrilaterals
-        typedef TriaRawIterator<dim, DoFObjectAccessor<2, DH> > raw_quad_iterator;
-                                         /// Iterator for quadrilaterals
-        typedef TriaIterator<dim ,DoFObjectAccessor<2, DH> > quad_iterator;
-                                         /// Iterator for active quadrilaterals
-        typedef TriaActiveIterator<dim ,DoFObjectAccessor<2, DH> > active_quad_iterator;
-                                         /// Iterator for raw hexahedra
-        typedef TriaRawIterator<dim ,DoFObjectAccessor<3, DH> > raw_hex_iterator;
-                                         /// Iterator for hexahedra
-        typedef TriaIterator<dim ,DoFObjectAccessor<3, DH> > hex_iterator;
-                                         /// Iterator for active hexahedra
-        typedef TriaActiveIterator<dim ,DoFObjectAccessor<3, DH> > active_hex_iterator;
-                                         /// Iterator for raw cells
-        typedef TriaRawIterator<dim, DoFCellAccessor<DH> > raw_cell_iterator;
-                                         /// Iterator for cells
-        typedef TriaIterator<dim, DoFCellAccessor<DH> > cell_iterator;
-                                         /// Iterator for active cells
-        typedef TriaActiveIterator<dim, DoFCellAccessor<DH> > active_cell_iterator;
-                                         /// Iterator for raw faces
-        typedef TriaRawIterator<dim ,DoFObjectAccessor<dim-1, DH> > raw_face_iterator;
-                                         /// Iterator for faces
-        typedef TriaIterator<dim ,DoFObjectAccessor<dim-1, DH> > face_iterator;
-                                         /// Iterator for active faces
-        typedef TriaActiveIterator<dim ,DoFObjectAccessor<dim-1, DH> > active_face_iterator;
-    };
-
+    struct Iterators;
 
 
 /**
- * Define some types for the DoF handling in one dimension.
+ * Define some types for DoF handling in one dimension.
  *
  * The types have the same meaning as those declared in
- * internal::Triangulation::Iterators<2>, only the treatment of templates is a
- * little more complicated since the @p DoFAccessor classes want a
- * template template argument.
+ * internal::Triangulation::Iterators<1,spacedim>, only the treatment of
+ * templates is a little more complicated. See the @ref Iterators module
+ * for more information.
  *
- * @author Wolfgang Bangerth, Oliver Kayser-Herold, 1998, 2003
+ * @author Wolfgang Bangerth, Oliver Kayser-Herold, 1998, 2003, 2008
  */
-    template <template <int> class DH>
-    struct Iterators<DH<1> >
+    template <template <int, int> class DH, int spacedim>
+    struct Iterators<DH<1, spacedim> >
     {
-        typedef DH<1> DoFHandler_type;
+        typedef DH<1,spacedim> DoFHandler_type;
     
-        typedef TriaRawIterator<1,DoFCellAccessor<DoFHandler_type> >    raw_line_iterator;
-        typedef TriaIterator<1,DoFCellAccessor<DoFHandler_type> >       line_iterator;
-        typedef TriaActiveIterator<1,DoFCellAccessor<DoFHandler_type> > active_line_iterator;
+        typedef TriaRawIterator<DoFCellAccessor<DoFHandler_type> >    raw_line_iterator;
+        typedef TriaIterator<DoFCellAccessor<DoFHandler_type> >       line_iterator;
+        typedef TriaActiveIterator<DoFCellAccessor<DoFHandler_type> > active_line_iterator;
     
-        typedef void * raw_quad_iterator;
-        typedef void * quad_iterator;
-        typedef void * active_quad_iterator;
-    
-        typedef void * raw_hex_iterator;
-        typedef void * hex_iterator;
-        typedef void * active_hex_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<2,1,spacedim> > raw_quad_iterator;
+        typedef TriaIterator      <InvalidAccessor<2,1,spacedim> > quad_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<2,1,spacedim> > active_quad_iterator;
+
+        typedef TriaRawIterator   <InvalidAccessor<3,1,spacedim> > raw_hex_iterator;
+        typedef TriaIterator      <InvalidAccessor<3,1,spacedim> > hex_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<3,1,spacedim> > active_hex_iterator;
     
         typedef raw_line_iterator    raw_cell_iterator;
         typedef line_iterator        cell_iterator;
         typedef active_line_iterator active_cell_iterator;
     
-        typedef void * raw_face_iterator;
-        typedef void * face_iterator;
-        typedef void * active_face_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<0,1,spacedim> > raw_face_iterator;
+        typedef TriaIterator      <InvalidAccessor<0,1,spacedim> > face_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<0,1,spacedim> > active_face_iterator;
     };
 
 
 
+
 /**
- * Define some types for the DoF handling in two dimensions.
+ * Define some types for DoF handling in two dimensions.
  *
  * The types have the same meaning as those declared in
- * internal::Triangulation::Iterators<2>, only the treatment of templates is a
- * little more complicated since the @p DoFAccessor classes want a
- * template template argument.
+ * internal::Triangulation::Iterators<2,spacedim>, only the treatment of
+ * templates is a little more complicated. See the @ref Iterators module
+ * for more information.
  *
- * @author Wolfgang Bangerth, Oliver Kayser-Herold, 1998, 2003
+ * @author Wolfgang Bangerth, Oliver Kayser-Herold, 1998, 2003, 2008
  */
-    template <template <int> class DH>
-    struct Iterators<DH<2> >
+    template <template <int, int> class DH, int spacedim>
+    struct Iterators<DH<2, spacedim> >
     {
-        typedef DH<2> DoFHandler_type;
+        typedef DH<2,spacedim> DoFHandler_type;
     
-        typedef TriaRawIterator<2,DoFObjectAccessor<1, DoFHandler_type> >    raw_line_iterator;
-        typedef TriaIterator<2,DoFObjectAccessor<1, DoFHandler_type> >       line_iterator;
-        typedef TriaActiveIterator<2,DoFObjectAccessor<1, DoFHandler_type> > active_line_iterator;
+        typedef TriaRawIterator<DoFAccessor<1, DoFHandler_type> >    raw_line_iterator;
+        typedef TriaIterator<DoFAccessor<1, DoFHandler_type> >       line_iterator;
+        typedef TriaActiveIterator<DoFAccessor<1, DoFHandler_type> > active_line_iterator;
     
-        typedef TriaRawIterator<2,DoFCellAccessor<DoFHandler_type> >         raw_quad_iterator;
-        typedef TriaIterator<2,DoFCellAccessor<DoFHandler_type> >            quad_iterator;
-        typedef TriaActiveIterator<2,DoFCellAccessor<DoFHandler_type> >      active_quad_iterator;
+        typedef TriaRawIterator<DoFCellAccessor<DoFHandler_type> >         raw_quad_iterator;
+        typedef TriaIterator<DoFCellAccessor<DoFHandler_type> >            quad_iterator;
+        typedef TriaActiveIterator<DoFCellAccessor<DoFHandler_type> >      active_quad_iterator;
     
-        typedef void * raw_hex_iterator;
-        typedef void * hex_iterator;
-        typedef void * active_hex_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<3,2,spacedim> > raw_hex_iterator;
+        typedef TriaIterator      <InvalidAccessor<3,2,spacedim> > hex_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<3,2,spacedim> > active_hex_iterator;
     
         typedef raw_quad_iterator    raw_cell_iterator;
         typedef quad_iterator        cell_iterator;
@@ -184,32 +116,33 @@ namespace internal
 
 
 
+
 /**
- * Define some types for the DoF handling in two dimensions.
+ * Define some types for DoF handling in three dimensions.
  *
  * The types have the same meaning as those declared in
- * internal::Triangulation::Iterators<3>, only the treatment of templates is a
- * little more complicated since the @p DoFAccessor classes want a
- * template template argument.
+ * internal::Triangulation::Iterators<3,spacedim>, only the treatment of
+ * templates is a little more complicated. See the @ref Iterators module
+ * for more information.
  *
- * @author Wolfgang Bangerth, Oliver Kayser-Herold, 1998, 2003
+ * @author Wolfgang Bangerth, Oliver Kayser-Herold, 1998, 2003, 2008
  */
-    template <template <int> class DH>
-    struct Iterators<DH<3> >
+    template <template <int, int> class DH, int spacedim>
+    struct Iterators<DH<3, spacedim> >
     {
-        typedef DH<3> DoFHandler_type;
+        typedef DH<3, spacedim> DoFHandler_type;
       
-        typedef TriaRawIterator<3,DoFObjectAccessor<1, DoFHandler_type> >    raw_line_iterator;
-        typedef TriaIterator<3,DoFObjectAccessor<1, DoFHandler_type> >       line_iterator;
-        typedef TriaActiveIterator<3,DoFObjectAccessor<1, DoFHandler_type> > active_line_iterator;
+        typedef TriaRawIterator<DoFAccessor<1, DoFHandler_type> >    raw_line_iterator;
+        typedef TriaIterator<DoFAccessor<1, DoFHandler_type> >       line_iterator;
+        typedef TriaActiveIterator<DoFAccessor<1, DoFHandler_type> > active_line_iterator;
       
-        typedef TriaRawIterator<3,DoFObjectAccessor<2, DoFHandler_type> >    raw_quad_iterator;
-        typedef TriaIterator<3,DoFObjectAccessor<2, DoFHandler_type> >       quad_iterator;
-        typedef TriaActiveIterator<3,DoFObjectAccessor<2, DoFHandler_type> > active_quad_iterator;
+        typedef TriaRawIterator<DoFAccessor<2, DoFHandler_type> >    raw_quad_iterator;
+        typedef TriaIterator<DoFAccessor<2, DoFHandler_type> >       quad_iterator;
+        typedef TriaActiveIterator<DoFAccessor<2, DoFHandler_type> > active_quad_iterator;
       
-        typedef TriaRawIterator<3,DoFCellAccessor<DoFHandler_type> >         raw_hex_iterator;
-        typedef TriaIterator<3,DoFCellAccessor<DoFHandler_type> >            hex_iterator;
-        typedef TriaActiveIterator<3,DoFCellAccessor<DoFHandler_type> >      active_hex_iterator;
+        typedef TriaRawIterator<DoFCellAccessor<DoFHandler_type> >         raw_hex_iterator;
+        typedef TriaIterator<DoFCellAccessor<DoFHandler_type> >            hex_iterator;
+        typedef TriaActiveIterator<DoFCellAccessor<DoFHandler_type> >      active_hex_iterator;
       
         typedef raw_hex_iterator    raw_cell_iterator;
         typedef hex_iterator        cell_iterator;
index a488f52fcda69a390535426bc57f06fb7df6f992..498bee8e4a82721a7f9e36b621bf8a06861ea981 100644 (file)
@@ -21,8 +21,8 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int> class DoFHandler;
-template <int> class MGDoFHandler;
+template <int, int> class DoFHandler;
+template <int, int> class MGDoFHandler;
 
 
 namespace internal
@@ -152,8 +152,8 @@ namespace internal
                                           * resize arrays as
                                           * necessary.
                                           */
-        template <int> friend class dealii::DoFHandler;
-        template <int> friend class dealii::MGDoFHandler;
+        template <int, int> friend class dealii::DoFHandler;
+        template <int, int> friend class dealii::MGDoFHandler;
     };
 
 
@@ -189,8 +189,8 @@ namespace internal
                                           * resize arrays as
                                           * necessary.
                                           */
-        template <int> friend class dealii::DoFHandler;
-        template <int> friend class dealii::MGDoFHandler;
+        template <int, int> friend class dealii::DoFHandler;
+        template <int, int> friend class dealii::MGDoFHandler;
     };
 
 
@@ -227,8 +227,8 @@ namespace internal
                                           * resize arrays as
                                           * necessary.
                                           */
-        template <int> friend class dealii::DoFHandler;
-        template <int> friend class dealii::MGDoFHandler;
+        template <int, int> friend class dealii::DoFHandler;
+        template <int, int> friend class dealii::MGDoFHandler;
     };
 
   }
index d9125523e8cb8b33a06f373958000ba0dc9b8297..918f0dd38f28f6e7bef676f3381a34e24e6a55bb 100644 (file)
@@ -20,7 +20,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int> class DoFHandler;
+template <int, int> class DoFHandler;
 
 namespace internal
 {
@@ -94,9 +94,9 @@ namespace internal
                                           * class hierarchy between hp
                                           * and non-hp classes.
                                           */
-       template <int spacedim>
+       template <int dh_dim, int spacedim>
         void
-        set_dof_index (const dealii::DoFHandler<spacedim> &dof_handler,
+        set_dof_index (const dealii::DoFHandler<dh_dim,spacedim> &dof_handler,
                       const unsigned int       obj_index,
                       const unsigned int       fe_index,
                       const unsigned int       local_index,
@@ -127,9 +127,9 @@ namespace internal
                                           * class hierarchy between hp
                                           * and non-hp classes.
                                           */
-       template <int spacedim>
+       template <int dh_dim, int spacedim>
        unsigned int
-        get_dof_index (const dealii::DoFHandler<spacedim> &dof_handler,
+        get_dof_index (const dealii::DoFHandler<dh_dim,spacedim> &dof_handler,
                       const unsigned int       obj_index,
                       const unsigned int       fe_index,
                       const unsigned int       local_index) const;
@@ -142,9 +142,9 @@ namespace internal
                                           * functions in the classes
                                           * internal::hp::DoFObjects 
                                           */
-        template <int spacedim>
+        template <int dh_dim, int spacedim>
         unsigned int
-        n_active_fe_indices (const dealii::DoFHandler<spacedim> &dof_handler,
+        n_active_fe_indices (const dealii::DoFHandler<dh_dim,spacedim> &dof_handler,
                              const unsigned int       index) const;
 
                                          /**
@@ -153,9 +153,9 @@ namespace internal
                                           * given index is zero, and
                                           * then return true.
                                           */
-        template <int spacedim>
+        template <int dh_dim, int spacedim>
         bool
-        fe_index_is_active (const dealii::DoFHandler<spacedim> &dof_handler,
+        fe_index_is_active (const dealii::DoFHandler<dh_dim,spacedim> &dof_handler,
                             const unsigned int       index,
                             const unsigned int       fe_index) const;
 
@@ -181,10 +181,10 @@ namespace internal
 // --------------------- template and inline functions ------------------
 
     template <int dim>
-    template <int spacedim>
+    template <int dh_dim, int spacedim>
     inline
     unsigned int
-    DoFObjects<dim>::n_active_fe_indices (const dealii::DoFHandler<spacedim> &,
+    DoFObjects<dim>::n_active_fe_indices (const dealii::DoFHandler<dh_dim,spacedim> &,
                                          const unsigned) const
     {
       return 1;
@@ -193,10 +193,10 @@ namespace internal
 
     
     template <int dim>
-    template <int spacedim>
+    template <int dh_dim, int spacedim>
     inline
     bool
-    DoFObjects<dim>::fe_index_is_active (const dealii::DoFHandler<spacedim> &,
+    DoFObjects<dim>::fe_index_is_active (const dealii::DoFHandler<dh_dim,spacedim> &,
                                         const unsigned int,
                                         const unsigned int fe_index) const
     {
@@ -209,16 +209,16 @@ namespace internal
     
 
     template <int dim>
-    template <int spacedim>
+    template <int dh_dim, int spacedim>
     inline
     unsigned int
     DoFObjects<dim>::
-    get_dof_index (const dealii::DoFHandler<spacedim> &dof_handler,
+    get_dof_index (const dealii::DoFHandler<dh_dim,spacedim> &dof_handler,
                   const unsigned int       obj_index,
                   const unsigned int       fe_index,
                   const unsigned int       local_index) const
     {
-      Assert (fe_index == dealii::DoFHandler<spacedim>::default_fe_index,
+      Assert ((fe_index == dealii::DoFHandler<dh_dim,spacedim>::default_fe_index),
              ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
       Assert (local_index<dof_handler.get_fe().template n_dofs_per_object<dim>(),
              ExcIndexRange (local_index, 0, dof_handler.get_fe().template n_dofs_per_object<dim>()));
index 40e901b07909a11a18859130cfc125d63a68d080..f10f963d2340256dc5afd389dd430d208f605a4b 100644 (file)
@@ -31,16 +31,16 @@ class SparsityPattern;
 template <typename number> class Vector;
 template <int dim> class Function;
 template <int dim> class Point;
-template <int dim> class FiniteElement;
-template <int dim> class DoFHandler;
+template <int dim, int spacedim> class FiniteElement;
+template <int dim, int spacedim> class DoFHandler;
 namespace hp
 {
-  template <int dim> class DoFHandler;
+  template <int dim, int spacedim> class DoFHandler;
 }
-template <int dim> class MGDoFHandler;
+template <int dim, int spacedim> class MGDoFHandler;
 class ConstraintMatrix;
 template <class GridClass> class InterGridMap;
-template <int dim> class Mapping;
+template <int dim, int spacedim> class Mapping;
 
 
 //TODO: map_support_points_to_dofs should generate a multimap, rather than just a map, since several dofs may be located at the same support point
@@ -208,13 +208,13 @@ class DoFTools
                                      * Maximal number of degrees of
                                      * freedom on a cell.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    max_dofs_per_cell (const DoFHandler<dim> &dh);
+    max_dofs_per_cell (const DoFHandler<dim,spacedim> &dh);
     
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    max_dofs_per_cell (const hp::DoFHandler<dim> &dh);
+    max_dofs_per_cell (const hp::DoFHandler<dim,spacedim> &dh);
     
     
                                     /**
@@ -226,9 +226,9 @@ class DoFTools
                                      * uniform interface to query this
                                      * property.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    max_dofs_per_face (const DoFHandler<dim> &dh);
+    max_dofs_per_face (const DoFHandler<dim,spacedim> &dh);
 
                                     /**
                                      * Maximal number of degrees of
@@ -239,9 +239,9 @@ class DoFTools
                                      * uniform interface to query this
                                      * property.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    max_dofs_per_face (const hp::DoFHandler<dim> &dh);
+    max_dofs_per_face (const hp::DoFHandler<dim,spacedim> &dh);
     
                                     /**
                                      * Maximal number of degrees of
@@ -252,9 +252,9 @@ class DoFTools
                                      * uniform interface to query this
                                      * property.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    max_dofs_per_vertex (const DoFHandler<dim> &dh);
+    max_dofs_per_vertex (const DoFHandler<dim,spacedim> &dh);
     
                                     /**
                                      * Maximal number of degrees of
@@ -265,9 +265,9 @@ class DoFTools
                                      * uniform interface to query this
                                      * property.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    max_dofs_per_vertex (const hp::DoFHandler<dim> &dh);
+    max_dofs_per_vertex (const hp::DoFHandler<dim,spacedim> &dh);
     
                                     /**
                                      * Number of vector components in the
@@ -279,9 +279,9 @@ class DoFTools
                                      * uniform interface to query this
                                      * property.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    n_components (const DoFHandler<dim> &dh);
+    n_components (const DoFHandler<dim,spacedim> &dh);
     
                                     /**
                                      * Number of vector components in the
@@ -293,9 +293,9 @@ class DoFTools
                                      * uniform interface to query this
                                      * property.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    n_components (const hp::DoFHandler<dim> &dh);
+    n_components (const hp::DoFHandler<dim,spacedim> &dh);
     
                                     /**
                                      * Find out whether the FiniteElement
@@ -307,9 +307,9 @@ class DoFTools
                                      * uniform interface to query this
                                      * property.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    fe_is_primitive (const DoFHandler<dim> &dh);
+    fe_is_primitive (const DoFHandler<dim,spacedim> &dh);
     
                                     /**
                                      * Find out whether the FiniteElement
@@ -321,9 +321,9 @@ class DoFTools
                                      * uniform interface to query this
                                      * property.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    fe_is_primitive (const hp::DoFHandler<dim> &dh);
+    fe_is_primitive (const hp::DoFHandler<dim,spacedim> &dh);
     
                                     /**
                                      * @}
@@ -685,7 +685,7 @@ class DoFTools
     template <class DH, class SparsityPattern>
     static void
     make_boundary_sparsity_pattern (const DH &dof,
-                                   const typename FunctionMap<DH::dimension>::type &boundary_indicators,
+                                   const typename FunctionMap<DH::space_dimension>::type &boundary_indicators,
                                    const std::vector<unsigned int> &dof_to_boundary_mapping,
                                    SparsityPattern    &sparsity);
 
@@ -931,9 +931,9 @@ class DoFTools
                                      * this non-primitive base
                                      * element.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    extract_dofs (const DoFHandler<dim>   &dof_handler,
+    extract_dofs (const DoFHandler<dim,spacedim>   &dof_handler,
                  const std::vector<bool> &select,
                  std::vector<bool>       &selected_dofs,
                  const bool               blocks = false);
@@ -942,9 +942,9 @@ class DoFTools
                                      * The same function as above,
                                      * but for a hp::DoFHandler.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    extract_dofs (const hp::DoFHandler<dim>   &dof_handler,
+    extract_dofs (const hp::DoFHandler<dim,spacedim>   &dof_handler,
                  const std::vector<bool> &select,
                  std::vector<bool>       &selected_dofs,
                  const bool               blocks = false);
@@ -954,10 +954,10 @@ class DoFTools
                                      * extract_dofs() for one level
                                      * of a multi-grid DoF numbering.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
     extract_level_dofs (const unsigned int       level,
-                       const MGDoFHandler<dim> &dof,
+                       const MGDoFHandler<dim,spacedim> &dof,
                        const std::vector<bool> &select,
                        std::vector<bool>       &selected_dofs,
                        const bool               blocks = false);
@@ -1031,25 +1031,10 @@ class DoFTools
                                      * contents of this array or
                                      * overwritten.
                                      */
+    template <int dim, int spacedim>
     static void
-    extract_hanging_node_dofs (const DoFHandler<1> &dof_handler,
-                              std::vector<bool>   &selected_dofs);
-
-                                    /**
-                                     * Declaration of same function
-                                     * for different space dimension.
-                                     */
-    static void
-    extract_hanging_node_dofs (const DoFHandler<2> &dof_handler,
-                              std::vector<bool>   &selected_dofs);
-
-                                    /**
-                                     * Declaration of same function
-                                     * for different space dimension.
-                                     */
-    static void
-    extract_hanging_node_dofs (const DoFHandler<3> &dof_handler,
-                              std::vector<bool>   &selected_dofs);
+    extract_hanging_node_dofs (const DoFHandler<dim,spacedim> &dof_handler,
+                              std::vector<bool>              &selected_dofs);
                                     //@}
     
                                     /**
@@ -1327,9 +1312,9 @@ class DoFTools
                                      * targetted by target_components
                                      * are left untouched.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    count_dofs_per_component (const DoFHandler<dim>&     dof_handler,
+    count_dofs_per_component (const DoFHandler<dim,spacedim>&     dof_handler,
                              std::vector<unsigned int>& dofs_per_component,
                              const bool vector_valued_once = false,
                              std::vector<unsigned int>  target_component
@@ -1350,9 +1335,9 @@ class DoFTools
                                      * function. If this is not the
                                      * case, an assertion is thrown.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    count_dofs_per_block (const DoFHandler<dim>&     dof_handler,
+    count_dofs_per_block (const DoFHandler<dim,spacedim>&     dof_handler,
                          std::vector<unsigned int>& dofs_per_block,
                          std::vector<unsigned int>  target_block
                          = std::vector<unsigned int>());
@@ -1365,9 +1350,9 @@ class DoFTools
                                      * compatibility with older
                                      * versions only.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    count_dofs_per_component (const DoFHandler<dim>&     dof_handler,
+    count_dofs_per_component (const DoFHandler<dim,spacedim>&     dof_handler,
                              std::vector<unsigned int>& dofs_per_component,
                              std::vector<unsigned int>  target_component);
     
@@ -1585,13 +1570,13 @@ class DoFTools
                                      * only need one object of this
                                      * type.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    compute_intergrid_constraints (const DoFHandler<dim>              &coarse_grid,
+    compute_intergrid_constraints (const DoFHandler<dim,spacedim>              &coarse_grid,
                                   const unsigned int                  coarse_component,
-                                  const DoFHandler<dim>              &fine_grid,
+                                  const DoFHandler<dim,spacedim>              &fine_grid,
                                   const unsigned int                  fine_component,
-                                  const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+                                  const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
                                   ConstraintMatrix                   &constraints);
 
 
@@ -1618,13 +1603,13 @@ class DoFTools
                                      * SparsityPattern ad
                                      * SparseMatrix classes.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    compute_intergrid_transfer_representation (const DoFHandler<dim>              &coarse_grid,
+    compute_intergrid_transfer_representation (const DoFHandler<dim,spacedim>              &coarse_grid,
                                               const unsigned int                  coarse_component,
-                                              const DoFHandler<dim>              &fine_grid,
+                                              const DoFHandler<dim,spacedim>              &fine_grid,
                                               const unsigned int                  fine_component,
-                                              const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+                                              const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
                                               std::vector<std::map<unsigned int, float> > &transfer_representation);
     
                                     /**
@@ -1693,10 +1678,10 @@ class DoFTools
                                      * length of as many elements as
                                      * there are degrees of freedom.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    map_dofs_to_support_points (const Mapping<dim>       &mapping,
-                               const DoFHandler<dim>    &dof_handler,
+    map_dofs_to_support_points (const Mapping<dim,spacedim>       &mapping,
+                               const DoFHandler<dim,spacedim>    &dof_handler,
                                std::vector<Point<dim> > &support_points);
 
                                     /**
@@ -1728,7 +1713,7 @@ class DoFTools
                                      */
     template <class DH, class Comp>
     static void
-    map_support_points_to_dofs (const Mapping<DH::dimension> &mapping,
+    map_support_points_to_dofs (const Mapping<DH::dimension, DH::space_dimension> &mapping,
                                const DH                     &dof_handler,
                                std::map<Point<DH::dimension>, unsigned int, Comp> &point_to_index_map);
 
@@ -1747,9 +1732,9 @@ class DoFTools
                                      * initialized to the correct
                                      * length inside this function.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    convert_couplings_to_blocks (const hp::DoFHandler<dim>& dof_handler,
+    convert_couplings_to_blocks (const hp::DoFHandler<dim,spacedim>& dof_handler,
                                 const Table<2, Coupling>& table_by_component,
                                 std::vector<Table<2,Coupling> >& tables_by_block);
 
@@ -1757,11 +1742,11 @@ class DoFTools
                                      * Make a constraint matrix with 
                                      * zero boundary values.
                                      */
-    template <int dim, template <int> class DH> 
-      static void 
-      make_zero_boundary_constraints (const DH<dim>           &dof,  
-                                     ConstraintMatrix        &zero_boundary_constraints,    
-                                     const std::vector<bool> &component_mask_=std::vector<bool>());
+    template <int dim, int spacedim, template <int, int> class DH> 
+    static void 
+    make_zero_boundary_constraints (const DH<dim,spacedim> &dof,  
+                                   ConstraintMatrix        &zero_boundary_constraints,    
+                                   const std::vector<bool> &component_mask_=std::vector<bool>());
 
                                     /**
                                      * Map a coupling table from the
@@ -1778,9 +1763,9 @@ class DoFTools
                                      * initialized to the correct
                                      * length inside this function.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    convert_couplings_to_blocks (const DoFHandler<dim>& dof_handler,
+    convert_couplings_to_blocks (const DoFHandler<dim,spacedim>& dof_handler,
                                 const Table<2, Coupling>& table_by_component,
                                 std::vector<Table<2,Coupling> >& tables_by_block);
     
@@ -1838,13 +1823,13 @@ class DoFTools
                                      * function for a thorough
                                      * description of how it works.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    compute_intergrid_weights_1 (const DoFHandler<dim>              &coarse_grid,
+    compute_intergrid_weights_1 (const DoFHandler<dim,spacedim>              &coarse_grid,
                                 const unsigned int                  coarse_component,
-                                const DoFHandler<dim>              &fine_grid,
+                                const DoFHandler<dim,spacedim>              &fine_grid,
                                 const unsigned int                  fine_component,
-                                const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+                                const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
                                 std::vector<std::map<unsigned int, float> > &weights,
                                 std::vector<int>                   &weight_mapping);
     
@@ -1855,11 +1840,11 @@ class DoFTools
                                      * function for a thorough
                                      * description of how it works.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    compute_intergrid_weights_2 (const DoFHandler<dim>              &coarse_grid,
+    compute_intergrid_weights_2 (const DoFHandler<dim,spacedim>              &coarse_grid,
                                 const unsigned int                  coarse_component,
-                                const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+                                const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
                                 const std::vector<Vector<double> > &parameter_dofs,
                                 const std::vector<int>             &weight_mapping,
                                 std::vector<std::map<unsigned int, float> > &weights);
@@ -1874,26 +1859,26 @@ class DoFTools
                                      * then worked on in parallel, if
                                      * multithreading is available.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    compute_intergrid_weights_3 (const DoFHandler<dim>              &coarse_grid,
+    compute_intergrid_weights_3 (const DoFHandler<dim,spacedim>              &coarse_grid,
                                 const unsigned int                  coarse_component,
-                                const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+                                const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
                                 const std::vector<Vector<double> > &parameter_dofs,
                                 const std::vector<int>             &weight_mapping,
                                 std::vector<std::map<unsigned int, float> > &weights,
-                                const typename DoFHandler<dim>::active_cell_iterator &begin,
-                                const typename DoFHandler<dim>::active_cell_iterator &end);
+                                const typename DoFHandler<dim,spacedim>::active_cell_iterator &begin,
+                                const typename DoFHandler<dim,spacedim>::active_cell_iterator &end);
 
                                     /**
                                      * Compute coupling of dofs from
                                      * coupling of components.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void compute_dof_couplings (
       Table<2,Coupling>& dof_couplings,
       const Table<2,Coupling>& component_couplings,
-      const FiniteElement<dim>& fe);
+      const FiniteElement<dim,spacedim>& fe);
 
     friend class MGTools;
 };
@@ -1904,7 +1889,7 @@ class DoFTools
 
 template <>
 void
-DoFTools::map_dof_to_boundary_indices (const DoFHandler<1>       &dof_handler,
+DoFTools::map_dof_to_boundary_indices (const DoFHandler<1,1>       &dof_handler,
                                        std::vector<unsigned int> &mapping);
 
 
@@ -1948,82 +1933,82 @@ DoFTools::Coupling operator | (const DoFTools::Coupling c1,
 
 // ---------------------- inline and template functions --------------------
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::max_dofs_per_cell (const DoFHandler<dim> &dh)
+DoFTools::max_dofs_per_cell (const DoFHandler<dim,spacedim> &dh)
 {
   return dh.get_fe().dofs_per_cell;
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::max_dofs_per_face (const DoFHandler<dim> &dh) 
+DoFTools::max_dofs_per_face (const DoFHandler<dim,spacedim> &dh) 
 {
   return dh.get_fe().dofs_per_face;
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::max_dofs_per_vertex (const DoFHandler<dim> &dh) 
+DoFTools::max_dofs_per_vertex (const DoFHandler<dim,spacedim> &dh) 
 {
   return dh.get_fe().dofs_per_vertex;
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::n_components (const DoFHandler<dim> &dh) 
+DoFTools::n_components (const DoFHandler<dim,spacedim> &dh) 
 {
   return dh.get_fe().n_components();
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::fe_is_primitive (const DoFHandler<dim> &dh) 
+DoFTools::fe_is_primitive (const DoFHandler<dim,spacedim> &dh) 
 {
   return dh.get_fe().is_primitive();
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::max_dofs_per_cell (const hp::DoFHandler<dim> &dh) 
+DoFTools::max_dofs_per_cell (const hp::DoFHandler<dim,spacedim> &dh) 
 {
   return dh.get_fe().max_dofs_per_cell ();
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::max_dofs_per_face (const hp::DoFHandler<dim> &dh) 
+DoFTools::max_dofs_per_face (const hp::DoFHandler<dim,spacedim> &dh) 
 {
   return dh.get_fe().max_dofs_per_face ();
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::max_dofs_per_vertex (const hp::DoFHandler<dim> &dh) 
+DoFTools::max_dofs_per_vertex (const hp::DoFHandler<dim,spacedim> &dh) 
 {
   return dh.get_fe().max_dofs_per_vertex ();
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::n_components (const hp::DoFHandler<dim> &dh) 
+DoFTools::n_components (const hp::DoFHandler<dim,spacedim> &dh) 
 {
   return dh.get_fe()[0].n_components();
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline unsigned int
-DoFTools::fe_is_primitive (const hp::DoFHandler<dim> &dh) 
+DoFTools::fe_is_primitive (const hp::DoFHandler<dim,spacedim> &dh) 
 {
   return dh.get_fe()[0].is_primitive();
 }
@@ -2058,7 +2043,7 @@ DoFTools::make_sparsity_pattern (
 template <class DH, class Comp>
 void
 DoFTools::map_support_points_to_dofs (
-  const Mapping<DH::dimension> &mapping,
+  const Mapping<DH::dimension,DH::space_dimension> &mapping,
   const DH                     &dof_handler,
   std::map<Point<DH::dimension>, unsigned int, Comp> &point_to_index_map)
 {
index 91bbfab6d5f7f262166d82f47a91e269623e437b..dc37ddf2e9a81263d8a877cdcefe25d72a06c87e 100644 (file)
@@ -18,7 +18,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class Function;
+template <int spacedim> class Function;
 
 
 
index 5af016f8916bdc381841e1ebd683301a60c28772..8be920321733e460a334a055a7c1f27051871275 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class FEValuesData;
-template <int dim> class FEValuesBase;
-template <int dim> class FEValues;
-template <int dim> class FEFaceValues;
-template <int dim> class FESubfaceValues;
-template <int dim> class FESystem;
-template <class POLY, int dim> class FE_PolyTensor;
+template <int dim, int spacedim> class FEValuesData;
+template <int dim, int spacedim> class FEValuesBase;
+template <int dim, int spacedim> class FEValues;
+template <int dim, int spacedim>   class FEFaceValues;
+template <int dim, int spacedim>   class FESubfaceValues;
+template <int dim, int spacedim>   class FESystem;
+template <class POLY, int dim, int spacedim> class FE_PolyTensor;
 namespace hp
 {
-  template <int dim> class FECollection;
+  template <int dim, int spacedim>   class FECollection;
 }
 
 
@@ -63,6 +63,13 @@ namespace hp
  * under consideration here is hanging nodes constraints and grid
  * transfer, respectively.
  *
+ * The <tt>spacedim</tt> parameter has to be used if one wants to
+ * solve problems in the boundary element method formulation or in an
+ * equivalent one, as it is explained in the Triangulation class. If
+ * not specified, this parameter takes the default value <tt>=dim</tt>
+ * so that this class can be used to solve problems in the finite
+ * element method formulation.
+ *
  * <h3>Components and blocks</h3>
  *
  * For vector valued elements shape functions may have nonzero entries
@@ -118,7 +125,7 @@ namespace hp
  * <h3>Notes on the implementation of derived classes</h3>
  *
  * The following sections list the information to be provided by
- * derived classes, depending on the space dimension. They are
+ * derived classes, depending on the dimension. They are
  * followed by a list of functions helping to generate these values.
  *
  * <h4>Finite elements in one dimension</h4>
@@ -248,7 +255,7 @@ namespace hp
  *
  * Construction of a finite element and computation of the matrices
  * described above may be a tedious task, in particular if it has to
- * be performed for several space dimensions. Therefore, some
+ * be performed for several dimensions. Therefore, some
  * functions in FETools have been provided to help with these tasks.
  *
  * <h5>Computing the correct basis from "raw" basis functions</h5>
@@ -326,7 +333,7 @@ namespace hp
  * 
  * @author Wolfgang Bangerth, Guido Kanschat, Ralf Hartmann, 1998, 2000, 2001, 2005
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 class FiniteElement : public Subscriptor,
                      public FiniteElementData<dim>
 {
@@ -343,7 +350,7 @@ class FiniteElement : public Subscriptor,
                                    *
                                    * @author Guido Kanschat, 2001
                                    */
-  class InternalDataBase : public Mapping<dim>::InternalDataBase
+  class InternalDataBase : public Mapping<dim,spacedim>::InternalDataBase
     {
       public:      
                                         /**
@@ -360,8 +367,8 @@ class FiniteElement : public Subscriptor,
                                          * finite differencing of
                                          * gradients.
                                          */
-       void initialize_2nd (const FiniteElement<dim> *element,
-                            const Mapping<dim>       &mapping,
+       void initialize_2nd (const FiniteElement<dim,spacedim> *element,
+                            const Mapping<dim,spacedim>       &mapping,
                             const Quadrature<dim>    &quadrature);
        
                                         /**
@@ -377,7 +384,7 @@ class FiniteElement : public Subscriptor,
                                          * entries in lower dimensions
                                          * are missing.
                                          */
-       std::vector<FEValues<dim>*> differences;
+       std::vector<FEValues<dim,spacedim>*> differences;
     };
 
   public:
@@ -401,7 +408,7 @@ class FiniteElement : public Subscriptor,
                                      * element. The general
                                      * convention is that this is the
                                      * class name, followed by the
-                                     * space dimension in angle
+                                     * dimension in angle
                                      * brackets, and the polynomial
                                      * degree and whatever else is
                                      * necessary in parentheses. For
@@ -458,7 +465,7 @@ class FiniteElement : public Subscriptor,
                                      * the present finite element
                                      * anyway).
                                      */
-    const FiniteElement<dim> & operator[] (const unsigned int fe_index) const;
+    const FiniteElement<dim,spacedim> & operator[] (const unsigned int fe_index) const;
     
                                     /**
                                      * @name Shape function access
@@ -900,7 +907,7 @@ class FiniteElement : public Subscriptor,
                                      * unrefined cell.
                                      * 
                                      * The matrix is obviously empty
-                                     * in only one space dimension,
+                                     * in only one dimension,
                                      * since there are no constraints
                                      * then.
                                      *
@@ -1016,7 +1023,7 @@ class FiniteElement : public Subscriptor,
                                      * ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_interpolation_matrix (const FiniteElement<dim> &source,
+    get_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                              FullMatrix<double>       &matrix) const;
                                     //@}
 
@@ -1048,7 +1055,7 @@ class FiniteElement : public Subscriptor,
                                      * ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_face_interpolation_matrix (const FiniteElement<dim> &source,
+    get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                   FullMatrix<double>       &matrix) const;
     
 
@@ -1074,7 +1081,7 @@ class FiniteElement : public Subscriptor,
                                      * ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_subface_interpolation_matrix (const FiniteElement<dim> &source,
+    get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                      const unsigned int        subface,
                                      FullMatrix<double>       &matrix) const;
                                     //@}
@@ -1116,7 +1123,7 @@ class FiniteElement : public Subscriptor,
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -1127,7 +1134,7 @@ class FiniteElement : public Subscriptor,
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_line_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -1138,7 +1145,7 @@ class FiniteElement : public Subscriptor,
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_quad_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_quad_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Return whether this element dominates
@@ -1154,7 +1161,7 @@ class FiniteElement : public Subscriptor,
                                      */
     virtual
     FiniteElementDomination::Domination
-    compare_for_face_domination (const FiniteElement<dim> &fe_other) const;
+    compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const;
     
                                     //@}
     
@@ -1175,7 +1182,7 @@ class FiniteElement : public Subscriptor,
                                      * #restriction and
                                      * #prolongation.
                                      */
-    bool operator == (const FiniteElement<dim> &) const;
+    bool operator == (const FiniteElement<dim,spacedim> &) const;
 
                                     /**
                                      * @name Index computations
@@ -1442,7 +1449,7 @@ class FiniteElement : public Subscriptor,
                                      * @p this.
                                      */
     virtual
-    const FiniteElement<dim> &
+    const FiniteElement<dim,spacedim> &
     base_element (const unsigned int index) const = 0;
 
                                      /**
@@ -2074,7 +2081,7 @@ class FiniteElement : public Subscriptor,
                                      * derived class.
                                      *
                                      * This field is obviously
-                                     * useless in one space dimension
+                                     * useless in one dimension
                                      * and has there a zero size.
                                      */
     FullMatrix<double> interface_constraints;
@@ -2204,12 +2211,12 @@ class FiniteElement : public Subscriptor,
                                      * finite differences of
                                      * gradients.
                                      */
-    void compute_2nd (const Mapping<dim>                      &mapping,
-                     const typename Triangulation<dim>::cell_iterator    &cell,
+    void compute_2nd (const Mapping<dim,spacedim>                      &mapping,
+                     const typename Triangulation<dim,spacedim>::cell_iterator    &cell,
                      const unsigned int                       offset,
-                     typename Mapping<dim>::InternalDataBase &mapping_internal,
+                     typename Mapping<dim,spacedim>::InternalDataBase &mapping_internal,
                      InternalDataBase                        &fe_internal,
-                     FEValuesData<dim>                       &data) const;
+                     FEValuesData<dim,spacedim>                       &data) const;
 
                                     /**
                                      * Given the pattern of nonzero
@@ -2294,7 +2301,7 @@ class FiniteElement : public Subscriptor,
                                      * knowing their exact type. They
                                      * do so through this function.
                                      */
-    virtual FiniteElement<dim> *clone() const = 0;    
+    virtual FiniteElement<dim,spacedim> *clone() const = 0;    
     
   private:
                                     /**
@@ -2530,9 +2537,9 @@ class FiniteElement : public Subscriptor,
                                      * includes destruction when it
                                      * is no more needed).
                                      */
-    virtual typename Mapping<dim>::InternalDataBase*
+    virtual typename Mapping<dim,spacedim>::InternalDataBase*
     get_data (const UpdateFlags      flags,
-             const Mapping<dim>    &mapping,
+             const Mapping<dim,spacedim>    &mapping,
              const Quadrature<dim> &quadrature) const = 0;
 
                                     /**
@@ -2547,9 +2554,9 @@ class FiniteElement : public Subscriptor,
                                      * includes destruction when it
                                      * is no more needed).
                                      */
-    virtual typename Mapping<dim>::InternalDataBase*
+    virtual typename Mapping<dim,spacedim>::InternalDataBase*
     get_face_data (const UpdateFlags        flags,
-                  const Mapping<dim>      &mapping,
+                  const Mapping<dim,spacedim>      &mapping,
                   const Quadrature<dim-1> &quadrature) const;
 
                                     /**
@@ -2564,9 +2571,9 @@ class FiniteElement : public Subscriptor,
                                      * includes destruction when it
                                      * is no more needed).
                                      */
-    virtual typename Mapping<dim>::InternalDataBase*
+    virtual typename Mapping<dim,spacedim>::InternalDataBase*
     get_subface_data (const UpdateFlags        flags,
-                     const Mapping<dim>      &mapping,
+                     const Mapping<dim,spacedim>      &mapping,
                      const Quadrature<dim-1> &quadrature) const;
 
                                     /**
@@ -2581,12 +2588,12 @@ class FiniteElement : public Subscriptor,
                                      * called for the same cell first!
                                      */                                      
     virtual void
-    fill_fe_values (const Mapping<dim>                   &mapping,
-                   const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_values (const Mapping<dim,spacedim>                   &mapping,
+                   const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                    const Quadrature<dim>                &quadrature,
-                   typename Mapping<dim>::InternalDataBase       &mapping_internal,
-                   typename Mapping<dim>::InternalDataBase       &fe_internal,
-                   FEValuesData<dim>                    &data) const = 0;
+                   typename Mapping<dim,spacedim>::InternalDataBase       &mapping_internal,
+                   typename Mapping<dim,spacedim>::InternalDataBase       &fe_internal,
+                   FEValuesData<dim,spacedim>                    &data) const = 0;
     
                                     /**
                                      * Fill the fields of
@@ -2600,13 +2607,13 @@ class FiniteElement : public Subscriptor,
                                      * called for the same cell first!
                                      */                                      
     virtual void
-    fill_fe_face_values (const Mapping<dim>                   &mapping,
-                        const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_face_values (const Mapping<dim,spacedim>                   &mapping,
+                        const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                         const unsigned int                    face_no,
                         const Quadrature<dim-1>              &quadrature,
-                        typename Mapping<dim>::InternalDataBase       &mapping_internal,
-                        typename Mapping<dim>::InternalDataBase       &fe_internal,
-                        FEValuesData<dim>                    &data) const = 0;
+                        typename Mapping<dim,spacedim>::InternalDataBase       &mapping_internal,
+                        typename Mapping<dim,spacedim>::InternalDataBase       &fe_internal,
+                        FEValuesData<dim,spacedim>                    &data) const = 0;
     
                                     /**
                                      * Fill the fields of
@@ -2620,33 +2627,34 @@ class FiniteElement : public Subscriptor,
                                      * called for the same cell first!
                                      */                                      
     virtual void
-    fill_fe_subface_values (const Mapping<dim>                   &mapping,
-                           const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const Mapping<dim,spacedim>                   &mapping,
+                           const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int                    face_no,
                            const unsigned int                    sub_no,
                            const Quadrature<dim-1>              &quadrature,
-                           typename Mapping<dim>::InternalDataBase &mapping_internal,
-                           typename Mapping<dim>::InternalDataBase &fe_internal,
-                           FEValuesData<dim>                    &data) const = 0;
+                           typename Mapping<dim,spacedim>::InternalDataBase &mapping_internal,
+                           typename Mapping<dim,spacedim>::InternalDataBase &fe_internal,
+                           FEValuesData<dim,spacedim>                    &data) const = 0;
 
     friend class InternalDataBase;
-    friend class FEValuesBase<dim>;
-    friend class FEValues<dim>;
-    friend class FEFaceValues<dim>;
-    friend class FESubfaceValues<dim>;
-    template <int dim_> friend class FESystem;
-    template <class POLY, int dim_> friend class FE_PolyTensor;
-    friend class hp::FECollection<dim>;
+    friend class FEValuesBase<dim,spacedim>;
+    friend class FEValues<dim,spacedim>;
+    friend class FEFaceValues<dim,spacedim>;
+    friend class FESubfaceValues<dim,spacedim>;
+    template <int, int > friend class FESystem;
+    template <class POLY, int dim_, int spacedim_> friend class FE_PolyTensor;
+    friend class hp::FECollection<dim,spacedim>;
+
 };
 
 
 //----------------------------------------------------------------------//
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const FiniteElement<dim> &
-FiniteElement<dim>::operator[] (const unsigned int fe_index) const
+const FiniteElement<dim,spacedim> &
+FiniteElement<dim,spacedim>::operator[] (const unsigned int fe_index) const
 {
   Assert (fe_index == 0,
          ExcMessage ("A fe_index of zero is the only index allowed here"));
@@ -2655,24 +2663,24 @@ FiniteElement<dim>::operator[] (const unsigned int fe_index) const
 
 
 
-template <int dim>  
+template <int dim, int spacedim>  
 inline
 std::pair<unsigned int,unsigned int>
-FiniteElement<dim>::system_to_component_index (const unsigned int index) const
+FiniteElement<dim,spacedim>::system_to_component_index (const unsigned int index) const
 {
   Assert (index < system_to_component_table.size(),
         ExcIndexRange(index, 0, system_to_component_table.size()));
   Assert (is_primitive (index),
-         typename FiniteElement<dim>::ExcShapeFunctionNotPrimitive(index));
+         ( typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(index)) );
   return system_to_component_table[index];
 }
 
 
 
-template <int dim>  
+template <int dim, int spacedim>  
 inline
 unsigned int
-FiniteElement<dim>::component_to_system_index (const unsigned int component,
+FiniteElement<dim,spacedim>::component_to_system_index (const unsigned int component,
                                                    const unsigned int index) const
 {
    std::vector< std::pair<unsigned int, unsigned int> >::const_iterator
@@ -2685,10 +2693,10 @@ FiniteElement<dim>::component_to_system_index (const unsigned int component,
 
 
 
-template <int dim>  
+template <int dim, int spacedim>  
 inline
 std::pair<unsigned int,unsigned int>
-FiniteElement<dim>::face_system_to_component_index (const unsigned int index) const
+FiniteElement<dim,spacedim>::face_system_to_component_index (const unsigned int index) const
 {
   Assert(index < face_system_to_component_table.size(),
         ExcIndexRange(index, 0, face_system_to_component_table.size()));
@@ -2707,17 +2715,17 @@ FiniteElement<dim>::face_system_to_component_index (const unsigned int index) co
                                    // in 1d, the face index is equal
                                    // to the cell index
   Assert (is_primitive(this->face_to_equivalent_cell_index(index)),
-          typename FiniteElement<dim>::ExcShapeFunctionNotPrimitive(index));
+          (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(index)) );
 
   return face_system_to_component_table[index];
 }
 
 
 
-template <int dim>  
+template <int dim, int spacedim>  
 inline
 std::pair<std::pair<unsigned int,unsigned int>,unsigned int>
-FiniteElement<dim>::system_to_base_index (const unsigned int index) const
+FiniteElement<dim,spacedim>::system_to_base_index (const unsigned int index) const
 {
   Assert (index < system_to_base_table.size(),
         ExcIndexRange(index, 0, system_to_base_table.size()));
@@ -2727,10 +2735,10 @@ FiniteElement<dim>::system_to_base_index (const unsigned int index) const
 
 
 
-template <int dim>  
+template <int dim, int spacedim>  
 inline
 std::pair<std::pair<unsigned int,unsigned int>,unsigned int>
-FiniteElement<dim>::face_system_to_base_index (const unsigned int index) const
+FiniteElement<dim,spacedim>::face_system_to_base_index (const unsigned int index) const
 {
   Assert(index < face_system_to_base_table.size(),
         ExcIndexRange(index, 0, face_system_to_base_table.size()));
@@ -2739,10 +2747,10 @@ FiniteElement<dim>::face_system_to_base_index (const unsigned int index) const
 
 
 
-template <int dim>  
+template <int dim, int spacedim>  
 inline
 unsigned int
-FiniteElement<dim>::first_block_of_base (const unsigned int index) const
+FiniteElement<dim,spacedim>::first_block_of_base (const unsigned int index) const
 {
   Assert(index < first_block_of_base_table.size(),
         ExcIndexRange(index, 0, first_block_of_base_table.size()));
@@ -2752,10 +2760,10 @@ FiniteElement<dim>::first_block_of_base (const unsigned int index) const
 
 
 
-template <int dim>  
+template <int dim, int spacedim>  
 inline
 std::pair<unsigned int,unsigned int>
-FiniteElement<dim>::component_to_base_index (const unsigned int index) const
+FiniteElement<dim,spacedim>::component_to_base_index (const unsigned int index) const
 {
   Assert(index < component_to_base_table.size(),
         ExcIndexRange(index, 0, component_to_base_table.size()));
@@ -2765,10 +2773,10 @@ FiniteElement<dim>::component_to_base_index (const unsigned int index) const
 
 
 
-template <int dim>  
+template <int dim, int spacedim>  
 inline
 std::pair<unsigned int,unsigned int>
-FiniteElement<dim>::block_to_base_index (const unsigned int index) const
+FiniteElement<dim,spacedim>::block_to_base_index (const unsigned int index) const
 {
   Assert(index < this->n_blocks(),
         ExcIndexRange(index, 0, this->n_blocks()));
@@ -2783,10 +2791,10 @@ FiniteElement<dim>::block_to_base_index (const unsigned int index) const
 
 
 
-template <int dim>  
+template <int dim, int spacedim>  
 inline
 std::pair<unsigned int,unsigned int>
-FiniteElement<dim>::system_to_block_index (const unsigned int index) const
+FiniteElement<dim,spacedim>::system_to_block_index (const unsigned int index) const
 {
   Assert (index < this->dofs_per_cell,
          ExcIndexRange(index, 0, this->dofs_per_cell));
@@ -2801,10 +2809,10 @@ FiniteElement<dim>::system_to_block_index (const unsigned int index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 bool
-FiniteElement<dim>::restriction_is_additive (const unsigned int index) const
+FiniteElement<dim,spacedim>::restriction_is_additive (const unsigned int index) const
 {
   Assert(index < this->dofs_per_cell,
         ExcIndexRange(index, 0, this->dofs_per_cell));
@@ -2813,10 +2821,10 @@ FiniteElement<dim>::restriction_is_additive (const unsigned int index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 const std::vector<bool> &
-FiniteElement<dim>::get_nonzero_components (const unsigned int i) const
+FiniteElement<dim,spacedim>::get_nonzero_components (const unsigned int i) const
 {
   Assert (i < this->dofs_per_cell, ExcIndexRange (i, 0, this->dofs_per_cell));
   return nonzero_components[i];
@@ -2824,10 +2832,10 @@ FiniteElement<dim>::get_nonzero_components (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 unsigned int
-FiniteElement<dim>::n_nonzero_components (const unsigned int i) const
+FiniteElement<dim,spacedim>::n_nonzero_components (const unsigned int i) const
 {
   Assert (i < this->dofs_per_cell, ExcIndexRange (i, 0, this->dofs_per_cell));
   return n_nonzero_components_table[i];
@@ -2835,10 +2843,10 @@ FiniteElement<dim>::n_nonzero_components (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 bool
-FiniteElement<dim>::is_primitive (const unsigned int i) const
+FiniteElement<dim,spacedim>::is_primitive (const unsigned int i) const
 {
   Assert (i < this->dofs_per_cell, ExcIndexRange (i, 0, this->dofs_per_cell));
 
@@ -2861,10 +2869,10 @@ FiniteElement<dim>::is_primitive (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 bool
-FiniteElement<dim>::is_primitive () const
+FiniteElement<dim,spacedim>::is_primitive () const
 {
   return cached_primitivity;
 }
index f79a17ba107f0261ce7c8c622563e7c8f6326238..6b9266c8e3dcd66fe4734ab0cb8f394ca663ef8a 100644 (file)
@@ -26,7 +26,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MappingQ;
+template <int dim, int spacedim> class MappingQ;
 
 
 /*!@addtogroup fe */
@@ -48,6 +48,9 @@ template <int dim> class MappingQ;
  * authors propose the ABF elements, which are implemented in this
  * module.
  *
+ * This class is not implemented for the codimension one case
+ * (<tt>spacedim != dim</tt>).
+ *
  * @todo Even if this element is implemented for two and three space
  * dimensions, the definition of the node values relies on
  * consistently oriented faces in 3D. Therefore, care should be taken
index bec4e3cc44faf436b951fee0b8491b0416b38f40..7b1dc1762136b01874eee1d4e6aca3018c8a955a 100644 (file)
@@ -30,7 +30,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template<int dim> class FESystem;
+template<int dim, int spacedim> class FESystem;
 
 
 /**
index c1775e82b1cb540fb58cc14c02c775a9d4c8024c..000ff5e9ea26e78721659b0cd291cddcddc6b3ec 100644 (file)
@@ -19,7 +19,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MappingQ;
+template <int dim, int spacedim> class MappingQ;
 
 /*!@addtogroup fe */
 /*@{*/
@@ -47,6 +47,11 @@ template <int dim> class MappingQ;
  * basis functions, refer to PolynomialSpace, remebering that the
  * Legendre polynomials are ordered by ascending degree.
  *
+ * This class if partially implemented for the codimension one case
+ * (<tt>spacedim != dim </tt>), since no passage of information
+ * between meshes of different refinement level is possible because
+ * the embedding and projection matrices are not computed in the class
+ * constructor.
  *
  * <h3>Transformation properties</h3>
  *
@@ -82,8 +87,8 @@ template <int dim> class MappingQ;
  * 
  * @author Guido Kanschat, 2001, 2002, Ralf Hartmann 2004
  */
-template <int dim>
-class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
+template <int dim, int spacedim=dim>
+class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim,spacedim>
 {
   public:
                                     /**
@@ -148,7 +153,7 @@ class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const;
+      hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -163,7 +168,7 @@ class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_line_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -178,7 +183,7 @@ class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_quad_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_quad_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                      /**
                                       * Return whether this element
@@ -208,7 +213,7 @@ class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
                                      */
     virtual
     FiniteElementDomination::Domination
-    compare_for_face_domination (const FiniteElement<dim> &fe_other) const;
+    compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const;
     
                                     /**
                                      * @}
@@ -233,10 +238,10 @@ class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
                                      * interpolation from a given
                                      * element, then they must throw
                                      * an exception of type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented.
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_face_interpolation_matrix (const FiniteElement<dim> &source,
+    get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                   FullMatrix<double>       &matrix) const;    
 
                                     /**
@@ -258,10 +263,10 @@ class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
                                      * interpolation from a given
                                      * element, then they must throw
                                      * an exception of type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented.
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_subface_interpolation_matrix (const FiniteElement<dim> &source,
+    get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                      const unsigned int        subface,
                                      FullMatrix<double>       &matrix) const;
 
@@ -331,7 +336,7 @@ class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
                                      * This function is needed by the
                                      * constructors of @p FESystem.
                                      */
-    virtual FiniteElement<dim> *clone() const;
+    virtual FiniteElement<dim,spacedim> *clone() const;
 
   private:
     
@@ -372,6 +377,24 @@ const double * const FE_DGP<3>::Matrices::projection_matrices[][GeometryInfo<3>:
 
 template <>
 const unsigned int FE_DGP<3>::Matrices::n_projection_matrices;
+
+//codimension 1
+#if deal_II_dimension != 3
+template <>
+const double * const FE_DGP<1,2>::Matrices::projection_matrices[][GeometryInfo<1>::max_children_per_cell];
+
+template <>
+const unsigned int FE_DGP<1,2>::Matrices::n_projection_matrices;
+
+template <>
+const double * const FE_DGP<2,3>::Matrices::projection_matrices[][GeometryInfo<2>::max_children_per_cell];
+
+template <>
+const unsigned int FE_DGP<2,3>::Matrices::n_projection_matrices;
+
+#endif
+
+
 #endif
 
 #endif // DOXYGEN
index 1e4bfa689ba31971ea363fd69a011c6fca367474..3aeeb7e2db5cee7b8545117d8ecbea9db99e24e5 100644 (file)
@@ -19,7 +19,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MappingQ;
+template <int dim, int spacedim> class MappingQ;
 
 
 /*!@addtogroup fe */
@@ -47,6 +47,8 @@ template <int dim> class MappingQ;
  * usually have a worse condition number than the ones originating
  * from the FE_DGP element.
  *
+ * This class is not implemented for the codimension one case
+ * (<tt>spacedim != dim</tt>).
  *
  * <h3>Transformation properties</h3>
  *
index 3f3e94928a9e129e8e0b8a528bc12e704f65f373..41e92926eb207194a2455101d27fd28ba00610c9 100644 (file)
@@ -21,7 +21,7 @@
 DEAL_II_NAMESPACE_OPEN
 
 template <int dim> class PolynomialSpace;
-template <int dim> class MappingQ;
+template <int dim, int spacedim> class MappingQ;
 
 
 /*!@addtogroup fe */
@@ -45,10 +45,13 @@ template <int dim> class MappingQ;
  * The purpose of this class is experimental, therefore the
  * implementation will remain incomplete.
  *
+ * Besides, this class is not implemented for the codimension one case
+ * (<tt>spacedim != dim</tt>).
+ *
  * @author Guido Kanschat, 2002
  */
-template <int dim>
-class FE_DGPNonparametric : public FiniteElement<dim>
+template <int dim, int spacedim=dim>
+class FE_DGPNonparametric : public FiniteElement<dim,spacedim>
 {
   public:
                                     /**
@@ -194,7 +197,7 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      * @p this, and all other
                                      * indices throw an error.
                                      */
-    virtual const FiniteElement<dim> &
+    virtual const FiniteElement<dim,spacedim> &
     base_element (const unsigned int index) const;
 
                                      /**
@@ -226,10 +229,10 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      * interpolation from a given
                                      * element, then they must throw
                                      * an exception of type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented.
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_face_interpolation_matrix (const FiniteElement<dim> &source,
+    get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                   FullMatrix<double>       &matrix) const;    
 
                                     /**
@@ -251,10 +254,10 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      * interpolation from a given
                                      * element, then they must throw
                                      * an exception of type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented.
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_subface_interpolation_matrix (const FiniteElement<dim> &source,
+    get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                      const unsigned int        subface,
                                      FullMatrix<double>       &matrix) const;
 
@@ -303,7 +306,7 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -318,7 +321,7 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_line_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -333,7 +336,7 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_quad_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_quad_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                      /**
                                       * Return whether this element
@@ -364,7 +367,7 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      */
     virtual
     FiniteElementDomination::Domination
-    compare_for_face_domination (const FiniteElement<dim> &fe_other) const;
+    compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * @}
@@ -456,7 +459,7 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      * This function is needed by the
                                      * constructors of @p FESystem.
                                      */
-    virtual FiniteElement<dim> *clone() const;
+    virtual FiniteElement<dim,spacedim> *clone() const;
   
                                     /**
                                      * Prepare internal data
@@ -464,9 +467,9 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      * independent of the cell.
                                      */
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_data (const UpdateFlags,
-             const Mapping<dim>& mapping,
+             const Mapping<dim,spacedim>& mapping,
              const Quadrature<dim>& quadrature) const ;
 
                                     /**
@@ -475,12 +478,12 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      * FiniteElement.
                                      */
     virtual void
-    fill_fe_values (const Mapping<dim> &mapping,
-                   const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_values (const Mapping<dim,spacedim> &mapping,
+                   const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                    const Quadrature<dim>                &quadrature,
-                   typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                   typename Mapping<dim>::InternalDataBase      &fe_internal,
-                   FEValuesData<dim>& data) const;
+                   typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                   typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                   FEValuesData<dim,spacedim>& data) const;
     
                                     /**
                                      * Implementation of the same
@@ -488,13 +491,13 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      * FiniteElement.
                                      */
     virtual void
-    fill_fe_face_values (const Mapping<dim> &mapping,
-                        const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_face_values (const Mapping<dim,spacedim> &mapping,
+                        const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                         const unsigned int                    face_no,
                         const Quadrature<dim-1>                &quadrature,
-                        typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                        typename Mapping<dim>::InternalDataBase      &fe_internal,
-                        FEValuesData<dim>& data) const ;
+                        typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                        typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                        FEValuesData<dim,spacedim>& data) const ;
     
                                     /**
                                      * Implementation of the same
@@ -502,14 +505,14 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      * FiniteElement.
                                      */
     virtual void
-    fill_fe_subface_values (const Mapping<dim> &mapping,
-                           const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const Mapping<dim,spacedim> &mapping,
+                           const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int                    face_no,
                            const unsigned int                    sub_no,
                            const Quadrature<dim-1>                &quadrature,
-                           typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                           typename Mapping<dim>::InternalDataBase      &fe_internal,
-                           FEValuesData<dim>& data) const ;
+                           typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                           typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                           FEValuesData<dim,spacedim>& data) const ;
 
   private:
     
@@ -584,7 +587,7 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                      * see the documentation of the
                                      * base class.
                                      */
-    class InternalData : public FiniteElement<dim>::InternalDataBase
+    class InternalData : public FiniteElement<dim,spacedim>::InternalDataBase
     {
       public:
                                       // have some scratch arrays
@@ -596,14 +599,15 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                     /**
                                      * Allow access from other dimensions.
                                      */
-    template <int dim1> friend class FE_DGPNonparametric;
+    template <int, int> friend class FE_DGPNonparametric;
 
                                     /**
                                      * Allows @p MappingQ class to
                                      * access to build_renumbering
                                      * function.
                                      */
-    friend class MappingQ<dim>;
+    template <int, int> friend class MappingQ;
+//    friend class MappingQ<dim>;
 };
 
 /*@}*/
@@ -614,40 +618,40 @@ class FE_DGPNonparametric : public FiniteElement<dim>
 // compiler allows us to do that (the standard says we must)
 #ifndef DEAL_II_MEMBER_VAR_SPECIALIZATION_BUG
 template <> 
-const double * const FE_DGPNonparametric<1>::Matrices::embedding[][GeometryInfo<1>::max_children_per_cell];
+const double * const FE_DGPNonparametric<1,1>::Matrices::embedding[][GeometryInfo<1>::max_children_per_cell];
 
 template <>
-const unsigned int FE_DGPNonparametric<1>::Matrices::n_embedding_matrices;
+const unsigned int FE_DGPNonparametric<1,1>::Matrices::n_embedding_matrices;
 
 template <>
-const double * const FE_DGPNonparametric<1>::Matrices::projection_matrices[][GeometryInfo<1>::max_children_per_cell];
+const double * const FE_DGPNonparametric<1,1>::Matrices::projection_matrices[][GeometryInfo<1>::max_children_per_cell];
 
 template <>
-const unsigned int FE_DGPNonparametric<1>::Matrices::n_projection_matrices;
+const unsigned int FE_DGPNonparametric<1,1>::Matrices::n_projection_matrices;
 
 template <> 
-const double * const FE_DGPNonparametric<2>::Matrices::embedding[][GeometryInfo<2>::max_children_per_cell];
+const double * const FE_DGPNonparametric<2,2>::Matrices::embedding[][GeometryInfo<2>::max_children_per_cell];
 
 template <>
-const unsigned int FE_DGPNonparametric<2>::Matrices::n_embedding_matrices;
+const unsigned int FE_DGPNonparametric<2,2>::Matrices::n_embedding_matrices;
 
 template <>
-const double * const FE_DGPNonparametric<2>::Matrices::projection_matrices[][GeometryInfo<2>::max_children_per_cell];
+const double * const FE_DGPNonparametric<2,2>::Matrices::projection_matrices[][GeometryInfo<2>::max_children_per_cell];
 
 template <>
-const unsigned int FE_DGPNonparametric<2>::Matrices::n_projection_matrices;
+const unsigned int FE_DGPNonparametric<2,2>::Matrices::n_projection_matrices;
 
 template <> 
-const double * const FE_DGPNonparametric<3>::Matrices::embedding[][GeometryInfo<3>::max_children_per_cell];
+const double * const FE_DGPNonparametric<3,3>::Matrices::embedding[][GeometryInfo<3>::max_children_per_cell];
 
 template <>
-const unsigned int FE_DGPNonparametric<3>::Matrices::n_embedding_matrices;
+const unsigned int FE_DGPNonparametric<3,3>::Matrices::n_embedding_matrices;
 
 template <>
-const double * const FE_DGPNonparametric<3>::Matrices::projection_matrices[][GeometryInfo<3>::max_children_per_cell];
+const double * const FE_DGPNonparametric<3,3>::Matrices::projection_matrices[][GeometryInfo<3>::max_children_per_cell];
 
 template <>
-const unsigned int FE_DGPNonparametric<3>::Matrices::n_projection_matrices;
+const unsigned int FE_DGPNonparametric<3,3>::Matrices::n_projection_matrices;
 #endif
 
 #endif // DOXYGEN
index bb097bd87dbb770101bdd694820a8ae72203475e..a50375e7af0043cef331abac7d903715e99aa84f 100644 (file)
@@ -22,7 +22,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MappingQ;
+template <int dim, int spacedim> class MappingQ;
 template <int dim> class Quadrature;
 
 /*!@addtogroup fe */
@@ -71,11 +71,16 @@ template <int dim> class Quadrature;
  * on the surface of the cell, they are logically in the interior
  * since there are no continuity requirements for these shape
  * functions across cell boundaries.
+ * This class if partially implemented for the codimension one case
+ * (<tt>spacedim != dim </tt>), since no passage of information
+ * between meshes of different refinement level is possible because
+ * the embedding and projection matrices are not computed in the class
+ * constructor.
  *
  * @author Ralf Hartmann, Guido Kanschat 2001, 2004
  */
-template <int dim>
-class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
+template <int dim, int spacedim=dim>
+class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>, dim, spacedim>
 {
   public:
                                     /**
@@ -119,7 +124,7 @@ class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * is thrown.
                                      */
     virtual void
-    get_interpolation_matrix (const FiniteElement<dim> &source,
+    get_interpolation_matrix (const FiniteElement<dim, spacedim> &source,
                              FullMatrix<double>           &matrix) const;
     
                                     /**
@@ -144,7 +149,7 @@ class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * FiniteElement<dim>::ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_face_interpolation_matrix (const FiniteElement<dim> &source,
+    get_face_interpolation_matrix (const FiniteElement<dim, spacedim> &source,
                                   FullMatrix<double>       &matrix) const;    
 
                                     /**
@@ -169,7 +174,7 @@ class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * FiniteElement<dim>::ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_subface_interpolation_matrix (const FiniteElement<dim> &source,
+    get_subface_interpolation_matrix (const FiniteElement<dim, spacedim> &source,
                                      const unsigned int        subface,
                                      FullMatrix<double>       &matrix) const;
 
@@ -218,7 +223,7 @@ class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_vertex_dof_identities (const FiniteElement<dim, spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -233,7 +238,7 @@ class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_line_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_line_dof_identities (const FiniteElement<dim, spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -248,7 +253,7 @@ class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_quad_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_quad_dof_identities (const FiniteElement<dim, spacedim> &fe_other) const;
 
                                      /**
                                       * Return whether this element
@@ -278,7 +283,7 @@ class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      */
     virtual
     FiniteElementDomination::Domination
-    compare_for_face_domination (const FiniteElement<dim> &fe_other) const;
+    compare_for_face_domination (const FiniteElement<dim, spacedim> &fe_other) const;
 
                                     /**
                                      * @}
@@ -338,7 +343,7 @@ class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * This function is needed by the
                                      * constructors of @p FESystem.
                                      */
-    virtual FiniteElement<dim> *clone() const;
+    virtual FiniteElement<dim, spacedim> *clone() const;
 
   private:
                                     /**
@@ -385,14 +390,14 @@ class FE_DGQ : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                     /**
                                      * Allow access from other dimensions.
                                      */
-    template <int dim1> friend class FE_DGQ;
+    template <int dim1, int spacedim1> friend class FE_DGQ;
 
                                     /**
                                      * Allows @p MappingQ class to
                                      * access to build_renumbering
                                      * function.
                                      */
-    template <int dim1> friend class MappingQ;
+    template <int dim1, int spacedim1> friend class MappingQ;
 };
 
 
index 6568e5cfa635d9bcdc5937f52d396558a8e25654..62cc2404f57772a22a99dabe6d6d5c53df1d2a5c 100644 (file)
@@ -19,7 +19,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MappingQ;
+template <int dim, int spacedim> class MappingQ;
 
 
 /*!@addtogroup fe */
@@ -36,6 +36,9 @@ template <int dim> class MappingQ;
  * element and its properties, see the report by Anna Schneebeli that
  * is linked from the general documentation page of the library.
  *
+ * This class has not yet been implemented for the codimension one case
+ * (<tt>spacedim != dim</tt>).
+ *
  *
  * <h3>Restriction on transformations</h3>
  *
@@ -180,8 +183,8 @@ template <int dim> class MappingQ;
  *
  * @author Wolfgang Bangerth, Anna Schneebeli, 2002, 2003
  */
-template <int dim>
-class FE_Nedelec : public FiniteElement<dim>
+template <int dim, int spacedim=dim>
+class FE_Nedelec : public FiniteElement<dim,spacedim>
 {
   public:
                                     /**
@@ -269,7 +272,7 @@ class FE_Nedelec : public FiniteElement<dim>
                                      * @p this, and all other
                                      * indices throw an error.
                                      */
-    virtual const FiniteElement<dim> &
+    virtual const FiniteElement<dim,spacedim> &
     base_element (const unsigned int index) const;
 
                                      /**
@@ -390,7 +393,7 @@ class FE_Nedelec : public FiniteElement<dim>
                                      * This function is needed by the
                                      * constructors of @p FESystem.
                                      */
-    virtual FiniteElement<dim> * clone() const;
+    virtual FiniteElement<dim,spacedim> * clone() const;
   
                                     /**
                                      * Prepare internal data
@@ -398,9 +401,9 @@ class FE_Nedelec : public FiniteElement<dim>
                                      * independent of the cell.
                                      */
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_data (const UpdateFlags,
-             const Mapping<dim>& mapping,
+             const Mapping<dim,spacedim>& mapping,
              const Quadrature<dim>& quadrature) const ;
 
                                     /**
@@ -409,12 +412,12 @@ class FE_Nedelec : public FiniteElement<dim>
                                      * FiniteElement.
                                      */
     virtual void
-    fill_fe_values (const Mapping<dim> &mapping,
-                   const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_values (const Mapping<dim,spacedim> &mapping,
+                   const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                    const Quadrature<dim>                &quadrature,
-                   typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                   typename Mapping<dim>::InternalDataBase      &fe_internal,
-                   FEValuesData<dim>& data) const;
+                   typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                   typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                   FEValuesData<dim,spacedim>& data) const;
     
                                     /**
                                      * Implementation of the same
@@ -422,13 +425,13 @@ class FE_Nedelec : public FiniteElement<dim>
                                      * FiniteElement.
                                      */
     virtual void
-    fill_fe_face_values (const Mapping<dim> &mapping,
-                        const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_face_values (const Mapping<dim,spacedim> &mapping,
+                        const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                         const unsigned int                    face_no,
                         const Quadrature<dim-1>                &quadrature,
-                        typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                        typename Mapping<dim>::InternalDataBase      &fe_internal,
-                        FEValuesData<dim>& data) const ;
+                        typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                        typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                        FEValuesData<dim,spacedim>& data) const ;
     
                                     /**
                                      * Implementation of the same
@@ -436,14 +439,14 @@ class FE_Nedelec : public FiniteElement<dim>
                                      * FiniteElement.
                                      */
     virtual void
-    fill_fe_subface_values (const Mapping<dim> &mapping,
-                           const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const Mapping<dim,spacedim> &mapping,
+                           const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int                    face_no,
                            const unsigned int                    sub_no,
                            const Quadrature<dim-1>                &quadrature,
-                           typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                           typename Mapping<dim>::InternalDataBase      &fe_internal,
-                           FEValuesData<dim>& data) const ;
+                           typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                           typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                           FEValuesData<dim,spacedim>& data) const ;
 
   private:
     
@@ -551,7 +554,7 @@ class FE_Nedelec : public FiniteElement<dim>
                                      * see the documentation of the
                                      * base class.
                                      */
-    class InternalData : public FiniteElement<dim>::InternalDataBase
+    class InternalData : public FiniteElement<dim,spacedim>::InternalDataBase
     {
       public:
                                         /**
@@ -604,7 +607,7 @@ class FE_Nedelec : public FiniteElement<dim>
                                      * Allow access from other
                                      * dimensions.
                                      */
-    template <int dim1> friend class FE_Nedelec;
+    template <int , int> friend class FE_Nedelec;
 };
 
 /*@}*/
@@ -615,59 +618,59 @@ class FE_Nedelec : public FiniteElement<dim>
 /* -------------- declaration of explicit specializations ------------- */
 
 template <>
-void FE_Nedelec<1>::initialize_unit_face_support_points ();
+void FE_Nedelec<1,1>::initialize_unit_face_support_points ();
 
 template <>
 double
-FE_Nedelec<1>::shape_value_component (const unsigned int ,
+FE_Nedelec<1,1>::shape_value_component (const unsigned int ,
                                       const Point<1>    &,
                                       const unsigned int ) const;
 
 template <>
 double
-FE_Nedelec<2>::shape_value_component (const unsigned int ,
+FE_Nedelec<2,2>::shape_value_component (const unsigned int ,
                                       const Point<2>    &,
                                       const unsigned int ) const;
 
 template <>
 double
-FE_Nedelec<3>::shape_value_component (const unsigned int ,
+FE_Nedelec<3,3>::shape_value_component (const unsigned int ,
                                       const Point<3>    &,
                                       const unsigned int ) const;
 
 template <>
 Tensor<1,1>
-FE_Nedelec<1>::shape_grad_component (const unsigned int ,
+FE_Nedelec<1,1>::shape_grad_component (const unsigned int ,
                                      const Point<1>    &,
                                      const unsigned int ) const;
 
 template <>
 Tensor<1,2>
-FE_Nedelec<2>::shape_grad_component (const unsigned int ,
+FE_Nedelec<2,2>::shape_grad_component (const unsigned int ,
                                      const Point<2>    &,
                                      const unsigned int ) const;
 
 template <>
 Tensor<1,3>
-FE_Nedelec<3>::shape_grad_component (const unsigned int ,
+FE_Nedelec<3,3>::shape_grad_component (const unsigned int ,
                                      const Point<3>    &,
                                      const unsigned int ) const;
 
 template <>
 Tensor<2,1>
-FE_Nedelec<1>::shape_grad_grad_component (const unsigned int ,
+FE_Nedelec<1,1>::shape_grad_grad_component (const unsigned int ,
                                           const Point<1>    &,
                                           const unsigned int ) const;
 
 template <>
 Tensor<2,2>
-FE_Nedelec<2>::shape_grad_grad_component (const unsigned int ,
+FE_Nedelec<2,2>::shape_grad_grad_component (const unsigned int ,
                                           const Point<2>    &,
                                           const unsigned int ) const;
 
 template <>
 Tensor<2,3>
-FE_Nedelec<3>::shape_grad_grad_component (const unsigned int ,
+FE_Nedelec<3,3>::shape_grad_grad_component (const unsigned int ,
                                           const Point<3>    &,
                                           const unsigned int ) const;
 
@@ -678,42 +681,42 @@ FE_Nedelec<3>::shape_grad_grad_component (const unsigned int ,
 #ifndef DEAL_II_MEMBER_VAR_SPECIALIZATION_BUG
 template <> 
 const double * const 
-FE_Nedelec<1>::Matrices::embedding[][GeometryInfo<1>::max_children_per_cell];
+FE_Nedelec<1,1>::Matrices::embedding[][GeometryInfo<1>::max_children_per_cell];
 
 template <>
-const unsigned int FE_Nedelec<1>::Matrices::n_embedding_matrices;
+const unsigned int FE_Nedelec<1,1>::Matrices::n_embedding_matrices;
 
 template <>
-const double * const FE_Nedelec<1>::Matrices::constraint_matrices[];
+const double * const FE_Nedelec<1,1>::Matrices::constraint_matrices[];
 
 template <>
-const unsigned int FE_Nedelec<1>::Matrices::n_constraint_matrices;
+const unsigned int FE_Nedelec<1,1>::Matrices::n_constraint_matrices;
 
 template <> 
 const double * const 
-FE_Nedelec<2>::Matrices::embedding[][GeometryInfo<2>::max_children_per_cell];
+FE_Nedelec<2,2>::Matrices::embedding[][GeometryInfo<2>::max_children_per_cell];
 
 template <>
-const unsigned int FE_Nedelec<2>::Matrices::n_embedding_matrices;
+const unsigned int FE_Nedelec<2,2>::Matrices::n_embedding_matrices;
 
 template <>
-const double * const FE_Nedelec<2>::Matrices::constraint_matrices[];
+const double * const FE_Nedelec<2,2>::Matrices::constraint_matrices[];
 
 template <>
-const unsigned int FE_Nedelec<2>::Matrices::n_constraint_matrices;
+const unsigned int FE_Nedelec<2,2>::Matrices::n_constraint_matrices;
 
 template <> 
 const double * const 
-FE_Nedelec<3>::Matrices::embedding[][GeometryInfo<3>::max_children_per_cell];
+FE_Nedelec<3,3>::Matrices::embedding[][GeometryInfo<3>::max_children_per_cell];
 
 template <>
-const unsigned int FE_Nedelec<3>::Matrices::n_embedding_matrices;
+const unsigned int FE_Nedelec<3,3>::Matrices::n_embedding_matrices;
 
 template <>
-const double * const FE_Nedelec<3>::Matrices::constraint_matrices[];
+const double * const FE_Nedelec<3,3>::Matrices::constraint_matrices[];
 
 template <>
-const unsigned int FE_Nedelec<3>::Matrices::n_constraint_matrices;
+const unsigned int FE_Nedelec<3,3>::Matrices::n_constraint_matrices;
 
 #endif
 #endif // DOXYGEN
index 78f9d1ec86879b8c93309e01eeb35803c36166c4..ed1b4652ff850cb3e642e4b4554901483d1b4fee 100644 (file)
@@ -61,8 +61,8 @@ DEAL_II_NAMESPACE_OPEN
  *
  * @author Ralf Hartmann 2004
  **/
-template <class POLY, int dim/*=POLY::dim*/>
-class FE_Poly : public FiniteElement<dim>
+template <class POLY, int dim/*=POLY::dim*/, int spacedim=dim>
+class FE_Poly : public FiniteElement<dim,spacedim>
 {
   public:
                                     /**
@@ -195,7 +195,7 @@ class FE_Poly : public FiniteElement<dim>
                                      * <tt>this</tt>, and all other
                                      * indices throw an error.
                                      */
-    virtual const FiniteElement<dim> &
+    virtual const FiniteElement<dim,spacedim> &
     base_element (const unsigned int index) const;
 
                                      /**
@@ -212,37 +212,37 @@ class FE_Poly : public FiniteElement<dim>
   protected:
       
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_data (const UpdateFlags,
-             const Mapping<dim>& mapping,
+             const Mapping<dim,spacedim>& mapping,
              const Quadrature<dim>& quadrature) const ;
 
     virtual void
-    fill_fe_values (const Mapping<dim> &mapping,
-                   const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_values (const Mapping<dim,spacedim> &mapping,
+                   const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                    const Quadrature<dim>                &quadrature,
-                   typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                   typename Mapping<dim>::InternalDataBase      &fe_internal,
-                   FEValuesData<dim>& data) const;
+                   typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                   typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                   FEValuesData<dim,spacedim>& data) const;
     
     virtual void
-    fill_fe_face_values (const Mapping<dim> &mapping,
-                        const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_face_values (const Mapping<dim,spacedim> &mapping,
+                        const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                         const unsigned int                    face_no,
                         const Quadrature<dim-1>                &quadrature,
-                        typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                        typename Mapping<dim>::InternalDataBase      &fe_internal,
-                        FEValuesData<dim>& data) const ;
+                        typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                        typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                        FEValuesData<dim,spacedim>& data) const ;
     
     virtual void
-    fill_fe_subface_values (const Mapping<dim> &mapping,
-                           const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const Mapping<dim,spacedim> &mapping,
+                           const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int                    face_no,
                            const unsigned int                    sub_no,
                            const Quadrature<dim-1>                &quadrature,
-                           typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                           typename Mapping<dim>::InternalDataBase      &fe_internal,
-                           FEValuesData<dim>& data) const ;
+                           typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                           typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                           FEValuesData<dim,spacedim>& data) const ;
 
     
                                     /**
@@ -338,7 +338,7 @@ class FE_Poly : public FiniteElement<dim>
                                      * see the documentation of the
                                      * base class.
                                      */
-    class InternalData : public FiniteElement<dim>::InternalDataBase
+    class InternalData : public FiniteElement<dim,spacedim>::InternalDataBase
     {
       public:
                                         /**
index e9a71d18e3e142eb8a15c25f9edfe64b4ee7c9ca..14c0c3ff3b13ac665835412689c75a3e4094b60f 100644 (file)
 //---------------------------------------------------------------------------
 
 #include <base/qprojector.h>
+#include <base/polynomial_space.h>
 #include <fe/fe_values.h>
 #include <fe/fe_poly.h>
 
+
 DEAL_II_NAMESPACE_OPEN
 
-template <class POLY, int dim>
-FE_Poly<POLY,dim>::FE_Poly (const POLY& poly_space,
+template <class POLY, int dim, int spacedim>
+FE_Poly<POLY,dim,spacedim>::FE_Poly (const POLY& poly_space,
                            const FiniteElementData<dim> &fe_data,
                            const std::vector<bool> &restriction_is_additive_flags,
                            const std::vector<std::vector<bool> > &nonzero_components):
-               FiniteElement<dim> (fe_data,
+               FiniteElement<dim,spacedim> (fe_data,
                                    restriction_is_additive_flags,
                                    nonzero_components),
                 poly_space(poly_space)
 {}
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 unsigned int
-FE_Poly<POLY,dim>::get_degree () const
+FE_Poly<POLY,dim,spacedim>::get_degree () const
 {
   return this->degree;
 }
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 double
-FE_Poly<POLY,dim>::shape_value (const unsigned int i,
+FE_Poly<POLY,dim,spacedim>::shape_value (const unsigned int i,
                                const Point<dim> &p) const
 {
   Assert (i<this->dofs_per_cell, ExcIndexRange(i,0,this->dofs_per_cell));
@@ -47,9 +49,9 @@ FE_Poly<POLY,dim>::shape_value (const unsigned int i,
 }
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 double
-FE_Poly<POLY,dim>::shape_value_component (const unsigned int i,
+FE_Poly<POLY,dim,spacedim>::shape_value_component (const unsigned int i,
                                           const Point<dim> &p,
                                           const unsigned int component) const
 {
@@ -60,9 +62,9 @@ FE_Poly<POLY,dim>::shape_value_component (const unsigned int i,
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 Tensor<1,dim>
-FE_Poly<POLY,dim>::shape_grad (const unsigned int i,
+FE_Poly<POLY,dim,spacedim>::shape_grad (const unsigned int i,
                                const Point<dim> &p) const
 {
   Assert (i<this->dofs_per_cell, ExcIndexRange(i,0,this->dofs_per_cell));
@@ -71,9 +73,9 @@ FE_Poly<POLY,dim>::shape_grad (const unsigned int i,
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 Tensor<1,dim>
-FE_Poly<POLY,dim>::shape_grad_component (const unsigned int i,
+FE_Poly<POLY,dim,spacedim>::shape_grad_component (const unsigned int i,
                                          const Point<dim> &p,
                                          const unsigned int component) const
 {
@@ -84,9 +86,9 @@ FE_Poly<POLY,dim>::shape_grad_component (const unsigned int i,
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 Tensor<2,dim>
-FE_Poly<POLY,dim>::shape_grad_grad (const unsigned int i,
+FE_Poly<POLY,dim,spacedim>::shape_grad_grad (const unsigned int i,
                                     const Point<dim> &p) const
 {
   Assert (i<this->dofs_per_cell, ExcIndexRange(i,0,this->dofs_per_cell));
@@ -95,9 +97,9 @@ FE_Poly<POLY,dim>::shape_grad_grad (const unsigned int i,
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 Tensor<2,dim>
-FE_Poly<POLY,dim>::shape_grad_grad_component (const unsigned int i,
+FE_Poly<POLY,dim,spacedim>::shape_grad_grad_component (const unsigned int i,
                                               const Point<dim> &p,
                                               const unsigned int component) const
 {
@@ -115,9 +117,9 @@ FE_Poly<POLY,dim>::shape_grad_grad_component (const unsigned int i,
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 UpdateFlags
-FE_Poly<POLY,dim>::update_once (const UpdateFlags flags) const
+FE_Poly<POLY,dim,spacedim>::update_once (const UpdateFlags flags) const
 {
                                   // for this kind of elements, only
                                   // the values can be precomputed
@@ -129,9 +131,9 @@ FE_Poly<POLY,dim>::update_once (const UpdateFlags flags) const
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 UpdateFlags
-FE_Poly<POLY,dim>::update_each (const UpdateFlags flags) const
+FE_Poly<POLY,dim,spacedim>::update_each (const UpdateFlags flags) const
 {
   UpdateFlags out = update_default;
 
@@ -139,7 +141,9 @@ FE_Poly<POLY,dim>::update_each (const UpdateFlags flags) const
     out |= update_gradients | update_covariant_transformation;
   if (flags & update_hessians)
     out |= update_hessians | update_covariant_transformation;
-
+  if (flags & update_cell_normal_vectors)
+    out |= update_cell_normal_vectors | update_JxW_values;
+  
   return out;
 }
 
@@ -149,10 +153,10 @@ FE_Poly<POLY,dim>::update_each (const UpdateFlags flags) const
 // Data field initialization
 //---------------------------------------------------------------------------
 
-template <class POLY, int dim>
-typename Mapping<dim>::InternalDataBase *
-FE_Poly<POLY,dim>::get_data (const UpdateFlags      update_flags,
-                            const Mapping<dim>    &mapping,
+template <class POLY, int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+FE_Poly<POLY,dim,spacedim>::get_data (const UpdateFlags      update_flags,
+                            const Mapping<dim,spacedim>    &mapping,
                             const Quadrature<dim> &quadrature) const
 {
                                   // generate a new data object and
@@ -230,23 +234,205 @@ FE_Poly<POLY,dim>::get_data (const UpdateFlags      update_flags,
 // Fill data of FEValues
 //---------------------------------------------------------------------------
 
-template <class POLY, int dim>
+
+//codimension 1
+template <>
 void
-FE_Poly<POLY,dim>::fill_fe_values (const Mapping<dim>                   &mapping,
-                                  const typename Triangulation<dim>::cell_iterator &cell,
-                                  const Quadrature<dim>                &quadrature,
-                                  typename Mapping<dim>::InternalDataBase &mapping_data,
-                                  typename Mapping<dim>::InternalDataBase &fedata,
-                                  FEValuesData<dim>                    &data) const
+FE_Poly<TensorProductPolynomials<1>,1,2>::fill_fe_values (const Mapping<1,2> &mapping,
+                                  const Triangulation<1,2>::cell_iterator   &/*cell*/,
+                                  const Quadrature<1>                       &quadrature,
+                                  Mapping<1,2>::InternalDataBase            &mapping_data,
+                                  Mapping<1,2>::InternalDataBase            &fedata,
+                                  FEValuesData<1,2>                         &data) const
+{
+                                  // convert data object to internal
+                                  // data for this class. fails with
+                                  // an exception if that is not
+                                  // possible 
+  InternalData &fe_data = dynamic_cast<InternalData &> (fedata);
+  
+  const UpdateFlags flags(fe_data.current_update_flags());
+  
+  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
+    {
+      if (flags & update_values)
+       for (unsigned int i=0; i<quadrature.size(); ++i)
+         data.shape_values(k,i) = fe_data.shape_values[k][i];
+      
+      if (flags & update_gradients)
+       {
+         Assert (data.shape_gradients[k].size() <=
+                 fe_data.shape_gradients[k].size(), 
+                 ExcInternalError()); 
+         mapping.transform_covariant(fe_data.shape_gradients[k], 0, 
+                                     data.shape_gradients[k], 
+                                     mapping_data); 
+       }
+    }
+  
+  //  const typename QProjector<1>::DataSetDescriptor dsd;
+  if (flags & update_hessians)
+    {
+      AssertThrow(false, ExcNotImplemented());
+/*       this->compute_2nd (mapping, cell, dsd.cell(), */
+/*                      mapping_data, fe_data, data); */
+    }
+}
+
+
+
+template <>
+void
+FE_Poly<TensorProductPolynomials<2>,2,3>::fill_fe_values (const Mapping<2,3> &mapping,
+                                  const Triangulation<2,3>::cell_iterator &/* cell */,
+                                  const Quadrature<2> &quadrature,
+                                  Mapping<2,3>::InternalDataBase & mapping_data,
+                                  Mapping<2,3>::InternalDataBase &fedata,
+                                  FEValuesData<2,3> &data) const
+{
+
+  InternalData &fe_data = dynamic_cast<InternalData &> (fedata);
+  
+  const UpdateFlags flags(fe_data.current_update_flags());
+  
+  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
+    {
+      if (flags & update_values)
+       for (unsigned int i=0; i<quadrature.size(); ++i)
+         data.shape_values(k,i) = fe_data.shape_values[k][i];     
+
+       if (flags & update_gradients)
+       {
+        Assert (data.shape_gradients[k].size() <=
+                fe_data.shape_gradients[k].size(), 
+                ExcInternalError());
+        mapping.transform_covariant(fe_data.shape_gradients[k], 0,
+                                    data.shape_gradients[k],
+                                    mapping_data);
+       }
+    }
+  
+/*   const QProjector<2>::DataSetDescriptor dsd; */
+  if (flags & update_hessians)
+    {
+      AssertThrow(false, ExcNotImplemented());
+/*       this->compute_2nd (mapping, cell, dsd.cell(), */
+/*                      mapping_data, fe_data, data); */
+    }
+
+}
+
+
+template <>
+void
+FE_Poly<PolynomialSpace<1>,1,2>::fill_fe_values (const Mapping<1,2> &/* mapping */,
+                                  const Triangulation<1,2>::cell_iterator   &/* cell */,
+                                  const Quadrature<1>                       &quadrature,
+                                  Mapping<1,2>::InternalDataBase            &/* mapping_data */,
+                                  Mapping<1,2>::InternalDataBase            &fedata,
+                                  FEValuesData<1,2>                         &data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
                                   // an exception if that is not
                                   // possible
+        
+
+  InternalData &fe_data = dynamic_cast<InternalData &> (fedata);
+  
+  const UpdateFlags flags(fe_data.current_update_flags());
+  
+  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
+    {
+      if (flags & update_values)
+       for (unsigned int i=0; i<quadrature.size(); ++i)
+         data.shape_values(k,i) = fe_data.shape_values[k][i];
+      
+      if (flags & update_gradients)
+       {
+         AssertThrow(false, ExcNotImplemented());
+/*       Assert (data.shape_gradients[k].size() */
+/*               fe_data.shape_gradients[k].size(), */
+/*               ExcInternalError()); */
+/*       mapping.transform_covariant(fe_data.shape_gradients[k], 0, */
+/*                                   data.shape_gradients[k], */
+/*                                   mapping_data); */
+       }
+    }
+  
+  //  const typename QProjector<1>::DataSetDescriptor dsd;
+  if (flags & update_hessians)
+    {
+      AssertThrow(false, ExcNotImplemented());
+/*       this->compute_2nd (mapping, cell, dsd.cell(), */
+/*                      mapping_data, fe_data, data); */
+    }
+}
+
+
+template <>
+void
+FE_Poly<PolynomialSpace<2>,2,3>::fill_fe_values (const Mapping<2,3> &/* mapping */,
+                                  const Triangulation<2,3>::cell_iterator &/* cell */,
+                                  const Quadrature<2> &quadrature,
+                                  Mapping<2,3>::InternalDataBase &/* mapping_data */,
+                                  Mapping<2,3>::InternalDataBase &fedata,
+                                  FEValuesData<2,3> &data) const
+{
+
   InternalData &fe_data = dynamic_cast<InternalData &> (fedata);
   
   const UpdateFlags flags(fe_data.current_update_flags());
+  
+  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
+    {
+      if (flags & update_values)
+       for (unsigned int i=0; i<quadrature.size(); ++i)
+         data.shape_values(k,i) = fe_data.shape_values[k][i];
+      
+
+       if (flags & update_gradients)
+       {
+         AssertThrow(false, ExcNotImplemented());
+/*       Assert (data.shape_gradients[k].size()  */
+/*               fe_data.shape_gradients[k].size(),  */
+/*               ExcInternalError());      */
+/*       mapping.transform_covariant(fe_data.shape_gradients[k], 0,  */
+/*                                   data.shape_gradients[k],  */
+/*                                   mapping_data);  */
+       }
+    }
+  
+/*   const QProjector<2>::DataSetDescriptor dsd; */
+  if (flags & update_hessians)
+    {
+      AssertThrow(false, ExcNotImplemented());
+/*       this->compute_2nd (mapping, cell, dsd.cell(), */
+/*                      mapping_data, fe_data, data); */
+    }
+
+}
+
+
+template <class POLY, int dim, int spacedim>
+void
+FE_Poly<POLY,dim,spacedim>::fill_fe_values (const Mapping<dim,spacedim>                   &mapping,
+                                  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                                  const Quadrature<dim>                &quadrature,
+                                  typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+                                  typename Mapping<dim,spacedim>::InternalDataBase &fedata,
+                                  FEValuesData<dim,spacedim>                    &data) const
+{
+                                  // convert data object to internal
+                                  // data for this class. fails with
+                                  // an exception if that is not
+                                  // possible
+        
 
+  InternalData &fe_data = dynamic_cast<InternalData &> (fedata);
+  
+  const UpdateFlags flags(fe_data.current_update_flags());
+  
   for (unsigned int k=0; k<this->dofs_per_cell; ++k)
     {
       if (flags & update_values)
@@ -259,28 +445,87 @@ FE_Poly<POLY,dim>::fill_fe_values (const Mapping<dim>                   &mapping
                  fe_data.shape_gradients[k].size(),
                  ExcInternalError());    
          mapping.transform_covariant(fe_data.shape_gradients[k], 0,
-                                      data.shape_gradients[k],
+                                     data.shape_gradients[k],
                                      mapping_data);
        }
     }
-
+  
   const typename QProjector<dim>::DataSetDescriptor dsd;
   if (flags & update_hessians)
     this->compute_2nd (mapping, cell, dsd.cell(),
                       mapping_data, fe_data, data);
 }
 
+//codimension 1
+
+template <>
+void
+FE_Poly<TensorProductPolynomials<1>,1,2>::fill_fe_face_values (const Mapping<1,2> &,
+                                                              const Triangulation<1,2>::cell_iterator &,
+                                                              const unsigned int,
+                                                              const Quadrature<0> &, 
+                                                              Mapping<1,2>::InternalDataBase &,
+                                                              Mapping<1,2>::InternalDataBase &,
+                                                              FEValuesData<1,2> &) const
+{
+  AssertThrow(false, ExcNotImplemented());
+}  
+
+
+template <>
+void
+FE_Poly<TensorProductPolynomials<2>,2,3>::fill_fe_face_values (const Mapping<2,3> &,
+                                                              const Triangulation<2,3>::cell_iterator &,
+                                                              const unsigned int,
+                                                              const Quadrature<1> &, 
+                                                              Mapping<2,3>::InternalDataBase &,
+                                                              Mapping<2,3>::InternalDataBase &,
+                                                              FEValuesData<2,3> &) const
+{
+  AssertThrow(false, ExcNotImplemented());
+}  
+
+
+
+template <>
+void
+FE_Poly<PolynomialSpace<1>,1,2>::fill_fe_face_values (const Mapping<1,2> &,
+                                                              const Triangulation<1,2>::cell_iterator &,
+                                                              const unsigned int,
+                                                              const Quadrature<0> &, 
+                                                              Mapping<1,2>::InternalDataBase &,
+                                                              Mapping<1,2>::InternalDataBase &,
+                                                              FEValuesData<1,2> &) const
+{
+  AssertThrow(false, ExcNotImplemented());
+}  
+
+
+template <>
+void
+FE_Poly<PolynomialSpace<2>,2,3>::fill_fe_face_values (const Mapping<2,3> &,
+                                                              const Triangulation<2,3>::cell_iterator &,
+                                                              const unsigned int,
+                                                              const Quadrature<1> &, 
+                                                              Mapping<2,3>::InternalDataBase &,
+                                                              Mapping<2,3>::InternalDataBase &,
+                                                              FEValuesData<2,3> &) const
+{
+  AssertThrow(false, ExcNotImplemented());
+}  
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 void
-FE_Poly<POLY,dim>::fill_fe_face_values (const Mapping<dim>                   &mapping,
-                               const typename Triangulation<dim>::cell_iterator &cell,
+FE_Poly<POLY,dim,spacedim>::fill_fe_face_values (const Mapping<dim,spacedim>                   &mapping,
+                               const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                const unsigned int                    face,
                                const Quadrature<dim-1>              &quadrature,
-                               typename Mapping<dim>::InternalDataBase       &mapping_data,
-                               typename Mapping<dim>::InternalDataBase       &fedata,
-                               FEValuesData<dim>                    &data) const
+                               typename Mapping<dim,spacedim>::InternalDataBase       &mapping_data,
+                               typename Mapping<dim,spacedim>::InternalDataBase       &fedata,
+                               FEValuesData<dim,spacedim>                    &data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -324,17 +569,79 @@ FE_Poly<POLY,dim>::fill_fe_face_values (const Mapping<dim>                   &ma
 }
 
 
+//codimension 1
+template <>
+void
+FE_Poly<TensorProductPolynomials<1>,1,2>::fill_fe_subface_values (const Mapping<1,2> &,
+                                                              const Triangulation<1,2>::cell_iterator &,
+                                                              const unsigned int,
+                                                              const unsigned int,        
+                                                              const Quadrature<0> &, 
+                                                              Mapping<1,2>::InternalDataBase &,
+                                                              Mapping<1,2>::InternalDataBase &,
+                                                              FEValuesData<1,2> &) const
+{
+  AssertThrow(false, ExcNotImplemented());
+}  
+
+
+template <>
+void
+FE_Poly<TensorProductPolynomials<2>,2,3>::fill_fe_subface_values (const Mapping<2,3> &,
+                                                              const Triangulation<2,3>::cell_iterator &,
+                                                              const unsigned int,
+                                                              const unsigned int,        
+                                                              const Quadrature<1> &, 
+                                                              Mapping<2,3>::InternalDataBase &,
+                                                              Mapping<2,3>::InternalDataBase &,
+                                                              FEValuesData<2,3> &) const
+{
+  AssertThrow(false, ExcNotImplemented());
+}  
+
+
+template <>
+void
+FE_Poly<PolynomialSpace<1>,1,2>::fill_fe_subface_values (const Mapping<1,2> &,
+                                                              const Triangulation<1,2>::cell_iterator &,
+                                                              const unsigned int,
+                                                              const unsigned int,        
+                                                              const Quadrature<0> &, 
+                                                              Mapping<1,2>::InternalDataBase &,
+                                                              Mapping<1,2>::InternalDataBase &,
+                                                              FEValuesData<1,2> &) const
+{
+  AssertThrow(false, ExcNotImplemented());
+}  
+
+
+template <>
+void
+FE_Poly<PolynomialSpace<2>,2,3>::fill_fe_subface_values (const Mapping<2,3> &,
+                                                              const Triangulation<2,3>::cell_iterator &,
+                                                              const unsigned int,
+                                                              const unsigned int,        
+                                                              const Quadrature<1> &, 
+                                                              Mapping<2,3>::InternalDataBase &,
+                                                              Mapping<2,3>::InternalDataBase &,
+                                                              FEValuesData<2,3> &) const
+{
+  AssertThrow(false, ExcNotImplemented());
+}  
+
+
+
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 void
-FE_Poly<POLY,dim>::fill_fe_subface_values (const Mapping<dim>                   &mapping,
-                                  const typename Triangulation<dim>::cell_iterator &cell,
+FE_Poly<POLY,dim,spacedim>::fill_fe_subface_values (const Mapping<dim,spacedim>                   &mapping,
+                                  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                   const unsigned int                    face,
                                   const unsigned int                    subface,
                                   const Quadrature<dim-1>              &quadrature,
-                                  typename Mapping<dim>::InternalDataBase       &mapping_data,
-                                  typename Mapping<dim>::InternalDataBase       &fedata,
-                                  FEValuesData<dim>                    &data) const
+                                  typename Mapping<dim,spacedim>::InternalDataBase       &mapping_data,
+                                  typename Mapping<dim,spacedim>::InternalDataBase       &fedata,
+                                  FEValuesData<dim,spacedim>                    &data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -380,18 +687,18 @@ FE_Poly<POLY,dim>::fill_fe_subface_values (const Mapping<dim>
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 unsigned int
-FE_Poly<POLY,dim>::n_base_elements () const
+FE_Poly<POLY,dim,spacedim>::n_base_elements () const
 {
   return 1;
 }
 
 
 
-template <class POLY, int dim>
-const FiniteElement<dim> &
-FE_Poly<POLY,dim>::base_element (const unsigned int index) const
+template <class POLY, int dim, int spacedim>
+const FiniteElement<dim,spacedim> &
+FE_Poly<POLY,dim,spacedim>::base_element (const unsigned int index) const
 {
   Assert (index==0, ExcIndexRange(index, 0, 1));
   return *this;
@@ -399,9 +706,9 @@ FE_Poly<POLY,dim>::base_element (const unsigned int index) const
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 unsigned int
-FE_Poly<POLY,dim>::element_multiplicity (const unsigned int index) const
+FE_Poly<POLY,dim,spacedim>::element_multiplicity (const unsigned int index) const
 {
   Assert (index==0, ExcIndexRange(index, 0, 1));
   return 1;
index 9a55a5569906b4301301ea1535ab97bc0b3847f4..6e44ccbd1f768aaaf880d56c73eb58ca4a088707 100644 (file)
@@ -48,6 +48,9 @@ DEAL_II_NAMESPACE_OPEN
  * vector valued polynomial classes. What's missing here in particular
  * is information on the topological location of the node values.
  *
+ * For more information on the template parameter <tt>spacedim</tt>,
+ * see the documentation for the class Triangulation.
+ *
  * <h3>Deriving classes</h3>
  *
  * Any derived class must decide on the polynomial space to use.  This
@@ -110,8 +113,8 @@ DEAL_II_NAMESPACE_OPEN
  *
  * @author Guido Kanschat, 2005
  **/
-template <class POLY, int dim>
-class FE_PolyTensor : public FiniteElement<dim>
+template <class POLY, int dim, int spacedim=dim>
+class FE_PolyTensor : public FiniteElement<dim,spacedim>
 {
   public:
                                     /**
@@ -179,7 +182,7 @@ class FE_PolyTensor : public FiniteElement<dim>
                                      * <tt>this</tt>, and all other
                                      * indices throw an error.
                                      */
-    virtual const FiniteElement<dim> &
+    virtual const FiniteElement<dim,spacedim> &
     base_element (const unsigned int index) const;
 
                                      /**
@@ -272,37 +275,37 @@ class FE_PolyTensor : public FiniteElement<dim>
     MappingType mapping_type;
     
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_data (const UpdateFlags,
-             const Mapping<dim>& mapping,
+             const Mapping<dim,spacedim>& mapping,
              const Quadrature<dim>& quadrature) const ;
 
     virtual void
-    fill_fe_values (const Mapping<dim> &mapping,
-                   const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_values (const Mapping<dim,spacedim> &mapping,
+                   const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                    const Quadrature<dim>                &quadrature,
-                   typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                   typename Mapping<dim>::InternalDataBase      &fe_internal,
-                   FEValuesData<dim>& data) const;
+                   typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                   typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                   FEValuesData<dim,spacedim>& data) const;
     
     virtual void
-    fill_fe_face_values (const Mapping<dim> &mapping,
-                        const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_face_values (const Mapping<dim,spacedim> &mapping,
+                        const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                         const unsigned int                    face_no,
                         const Quadrature<dim-1>                &quadrature,
-                        typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                        typename Mapping<dim>::InternalDataBase      &fe_internal,
-                        FEValuesData<dim>& data) const ;
+                        typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                        typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                        FEValuesData<dim,spacedim>& data) const ;
     
     virtual void
-    fill_fe_subface_values (const Mapping<dim> &mapping,
-                           const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const Mapping<dim,spacedim> &mapping,
+                           const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int                    face_no,
                            const unsigned int                    sub_no,
                            const Quadrature<dim-1>                &quadrature,
-                           typename Mapping<dim>::InternalDataBase      &mapping_internal,
-                           typename Mapping<dim>::InternalDataBase      &fe_internal,
-                           FEValuesData<dim>& data) const ;
+                           typename Mapping<dim,spacedim>::InternalDataBase      &mapping_internal,
+                           typename Mapping<dim,spacedim>::InternalDataBase      &fe_internal,
+                           FEValuesData<dim,spacedim>& data) const ;
 
                                     /**
                                      * Fields of cell-independent
@@ -319,7 +322,7 @@ class FE_PolyTensor : public FiniteElement<dim>
                                      * accessed by indices
                                      * <i>(i,k)</i>.
                                      */
-    class InternalData : public FiniteElement<dim>::InternalDataBase
+    class InternalData : public FiniteElement<dim,spacedim>::InternalDataBase
     {
       public:
                                         /**
index 35c147ff66d353a4561090c4d6c6866d3516795f..e140fdebbbe86a0d625cc3a50a4786ecd881e378 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -32,6 +32,10 @@ DEAL_II_NAMESPACE_OPEN
  * The standard constructor of this class takes the degree @p p of this finite
  * element. Alternatively, it can take a quadrature formula @p points defining
  * the support points of the Lagrange interpolation in one coordinate direction.
+ * 
+ * For more information about the <tt>spacedim</tt> template parameter
+ * check the documentation of FiniteElement or the one of
+ * Triangulation.
  *
  * <h3>Implementation</h3>
  *
@@ -236,8 +240,8 @@ DEAL_II_NAMESPACE_OPEN
  *
  * @author Wolfgang Bangerth, 1998, 2003; Guido Kanschat, 2001; Ralf Hartmann, 2001, 2004, 2005; Oliver Kayser-Herold, 2004; Katharina Kormann, 2008; Martin Kronbichler, 2008
  */
-template <int dim>
-class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
+template <int dim, int spacedim=dim>
+class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim,spacedim>
 {
   public:
                                     /**
@@ -282,11 +286,11 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * element is also a @p FE_Q
                                      * element. Otherwise, an
                                      * exception of type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented
                                      * is thrown.
                                      */
     virtual void
-    get_interpolation_matrix (const FiniteElement<dim> &source,
+    get_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                              FullMatrix<double>       &matrix) const;
 
     
@@ -309,10 +313,10 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * interpolation from a given
                                      * element, then they must throw
                                      * an exception of type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented.
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_face_interpolation_matrix (const FiniteElement<dim> &source,
+    get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                   FullMatrix<double>       &matrix) const;    
 
                                     /**
@@ -334,10 +338,10 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * interpolation from a given
                                      * element, then they must throw
                                      * an exception of type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented.
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented.
                                      */
     virtual void
-    get_subface_interpolation_matrix (const FiniteElement<dim> &source,
+    get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                      const unsigned int        subface,
                                      FullMatrix<double>       &matrix) const;
     
@@ -413,7 +417,7 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -424,7 +428,7 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_line_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -435,7 +439,7 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_quad_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_quad_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
     
                                     /**
                                      * Return whether this element dominates
@@ -451,7 +455,7 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      */
     virtual
     FiniteElementDomination::Domination
-    compare_for_face_domination (const FiniteElement<dim> &fe_other) const;
+    compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const;
                                     //@}
 
                                     /**
@@ -475,7 +479,7 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * This function is needed by the
                                      * constructors of @p FESystem.
                                      */
-    virtual FiniteElement<dim> * clone() const;
+    virtual FiniteElement<dim,spacedim> * clone() const;
     
   private:
     
@@ -509,14 +513,6 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      */
     void initialize_constraints ();
        
-                                            /**
-                                     * Initialize the hanging node
-                                     * constraints matrices. Called from the
-                                     * constructor in case the finite element
-                                     * is based on quadrature points.
-                                     */
-    void initialize_constraints (const Quadrature<1> &points);
-
                                     /**
                                      * Initialize the embedding
                                      * matrices. Called from the
@@ -584,6 +580,17 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * functions.
                                      */
     const std::vector<unsigned int> face_index_map;
+
+
+                                    /**
+                                     * Forward declaration of a class
+                                     * into which we put significant
+                                     * parts of the implementation.
+                                     *
+                                     * See the .cc file for more
+                                     * information.
+                                     */
+    struct Implementation;
     
                                     /**
                                      * Allow access from other
@@ -594,7 +601,9 @@ class FE_Q : public FE_Poly<TensorProductPolynomials<dim>,dim>
                                      * for the faces of the finite
                                      * element of dimension dim+1.
                                      */
-    template <int dim1> friend class FE_Q;
+    template <int, int> friend class FE_Q;
+
+    friend class FE_Q<dim,spacedim>::Implementation;
 };
 
 
@@ -610,14 +619,17 @@ template <>
 std::vector<unsigned int>
 FE_Q<1>::face_lexicographic_to_hierarchic_numbering (const unsigned int);
 
-template <>
-void FE_Q<1>::initialize_constraints (const Quadrature<1>&);
+
+#if deal_II_dimension != 3
 
 template <>
-void FE_Q<2>::initialize_constraints (const Quadrature<1>&);
+void FE_Q<1,2>::initialize_unit_face_support_points ();
 
 template <>
-void FE_Q<3>::initialize_constraints (const Quadrature<1>&);
+std::vector<unsigned int>
+FE_Q<1,2>::face_lexicographic_to_hierarchic_numbering (const unsigned int);
+
+#endif
 
 
 DEAL_II_NAMESPACE_CLOSE
index 1367ec6eccfb6abb7757439387521ce0cd980645..00b88c7c2a82ef59cefc88b5e0dcb91b7e9232df 100644 (file)
@@ -19,7 +19,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MappingQ;
+template <int dim, int spacedim> class MappingQ;
 
 
 /*!@addtogroup fe */
@@ -54,6 +54,9 @@ template <int dim> class MappingQ;
  * The constructor of this class takes the degree @p p of this finite
  * element.
  *
+ * This class is not implemented for the codimension one case
+ * (<tt>spacedim != dim</tt>).
+ *
  * <h3>Implementation</h3>
  *
  * The constructor creates a TensorProductPolynomials object
index 1b89c12470fc0269fbab4f5ebfd49d7f263ce136..6895cfc79045b14ebd502e0fadeb5bffa7b0aaa7 100644 (file)
@@ -26,7 +26,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MappingQ;
+template <int dim, int spacedim> class MappingQ;
 
 
 /*!@addtogroup fe */
@@ -43,6 +43,9 @@ template <int dim> class MappingQ;
  * the function itself is <i>degree+1</i>, as with usual polynomial
  * spaces.
  *
+ * This class is not implemented for the codimension one case
+ * (<tt>spacedim != dim</tt>).
+ *
  * @todo Even if this element is implemented for two and three space
  * dimensions, the definition of the node values relies on
  * consistently oriented faces in 3D. Therefore, care should be taken
index 78549296bb3cba7f7d1dea3f4560a309ab0b9e50..28a1f90548b7c4d33ab499f149c6ced15341c7a8 100644 (file)
@@ -73,12 +73,15 @@ DEAL_II_NAMESPACE_OPEN
  * multiplicity. The number of blocks of the system is simply the sum
  * of all multiplicities.
  *
+ * For more information on the template parameter <tt>spacedim</tt>
+ * see the documentation of Triangulation.
+ *
  * @ingroup febase fe vector_valued
  * 
  * @author Wolfgang Bangerth, Guido Kanschat, 1999, 2002, 2003, 2006, Ralf Hartmann 2001.
  */
-template <int dim>
-class FESystem : public FiniteElement<dim>
+template <int dim, int spacedim=dim>
+class FESystem : public FiniteElement<dim,spacedim>
 {
   public:
 
@@ -102,7 +105,7 @@ class FESystem : public FiniteElement<dim>
                                      * class needs to be of the same dimension
                                      * as is this object.
                                      */
-    FESystem (const FiniteElement<dim> &fe,
+    FESystem (const FiniteElement<dim,spacedim> &fe,
              const unsigned int n_elements);
 
                                     /** 
@@ -112,8 +115,8 @@ class FESystem : public FiniteElement<dim>
                                      *
                                      * See the other constructor.
                                      */
-    FESystem (const FiniteElement<dim> &fe1, const unsigned int n1,
-             const FiniteElement<dim> &fe2, const unsigned int n2);
+    FESystem (const FiniteElement<dim,spacedim> &fe1, const unsigned int n1,
+             const FiniteElement<dim,spacedim> &fe2, const unsigned int n2);
 
                                     /** 
                                      * Constructor for mixed
@@ -122,9 +125,9 @@ class FESystem : public FiniteElement<dim>
                                      *
                                      * See the other constructor.
                                      */
-    FESystem (const FiniteElement<dim> &fe1, const unsigned int n1,
-             const FiniteElement<dim> &fe2, const unsigned int n2,
-             const FiniteElement<dim> &fe3, const unsigned int n3);
+    FESystem (const FiniteElement<dim,spacedim> &fe1, const unsigned int n1,
+             const FiniteElement<dim,spacedim> &fe2, const unsigned int n2,
+             const FiniteElement<dim,spacedim> &fe3, const unsigned int n3);
 
                                     /**
                                      * Destructor.
@@ -324,11 +327,11 @@ class FESystem : public FiniteElement<dim>
                                      * @p get_interpolation_matrix
                                      * functions. Otherwise, an
                                      * exception of type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented
                                      * is thrown.
                                      */
     virtual void
-    get_interpolation_matrix (const FiniteElement<dim> &source,
+    get_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                              FullMatrix<double>           &matrix) const;
 
                                      /** 
@@ -362,7 +365,7 @@ class FESystem : public FiniteElement<dim>
                                      * multiplicities are greater
                                      * than one.
                                      */
-    virtual const FiniteElement<dim> &
+    virtual const FiniteElement<dim,spacedim> &
     base_element (const unsigned int index) const;
     
                                     /**
@@ -436,12 +439,12 @@ class FESystem : public FiniteElement<dim>
                                      * interpolation from a given element,
                                      * then they must throw an exception of
                                      * type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented,
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented,
                                      * which will get propagated out from
                                      * this element.
                                      */
     virtual void
-    get_face_interpolation_matrix (const FiniteElement<dim> &source,
+    get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                   FullMatrix<double>       &matrix) const;
     
 
@@ -463,12 +466,12 @@ class FESystem : public FiniteElement<dim>
                                      * interpolation from a given element,
                                      * then they must throw an exception of
                                      * type
-                                     * FiniteElement<dim>::ExcInterpolationNotImplemented,
+                                     * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented,
                                      * which will get propagated out from
                                      * this element.
                                      */
     virtual void
-    get_subface_interpolation_matrix (const FiniteElement<dim> &source,
+    get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
                                      const unsigned int        subface,
                                      FullMatrix<double>       &matrix) const;
 
@@ -508,7 +511,7 @@ class FESystem : public FiniteElement<dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -519,7 +522,7 @@ class FESystem : public FiniteElement<dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_line_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
 
                                     /**
                                      * Same as
@@ -530,7 +533,7 @@ class FESystem : public FiniteElement<dim>
                                      */
     virtual
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_quad_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_quad_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
     
                                     /**
                                      * Return whether this element dominates
@@ -546,7 +549,7 @@ class FESystem : public FiniteElement<dim>
                                      */
     virtual
     FiniteElementDomination::Domination
-    compare_for_face_domination (const FiniteElement<dim> &fe_other) const;
+    compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const;
                                     //@}
     
                                     /**
@@ -582,16 +585,16 @@ class FESystem : public FiniteElement<dim>
                                      * This function is needed by the
                                      * constructors of @p FESystem.
                                      */
-    virtual FiniteElement<dim> * clone() const;
+    virtual FiniteElement<dim,spacedim> * clone() const;
   
                                     /**
                                      * Prepare internal data
                                      * structures and fill in values
                                      * independent of the cell.
                                      */
-    virtual typename Mapping<dim>::InternalDataBase*
+    virtual typename Mapping<dim,spacedim>::InternalDataBase*
     get_data (const UpdateFlags      update_flags,
-             const Mapping<dim>    &mapping,
+             const Mapping<dim,spacedim>    &mapping,
              const Quadrature<dim> &quadrature) const ;
 
                                     /**
@@ -606,12 +609,12 @@ class FESystem : public FiniteElement<dim>
                                      * functions.
                                      */
     virtual void
-    fill_fe_values (const Mapping<dim>                      &mapping,
-                   const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_values (const Mapping<dim,spacedim>                      &mapping,
+                   const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                    const Quadrature<dim>                   &quadrature,
-                   typename Mapping<dim>::InternalDataBase &mapping_data,
-                   typename Mapping<dim>::InternalDataBase &fe_data,
-                   FEValuesData<dim>                       &data) const;
+                   typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+                   typename Mapping<dim,spacedim>::InternalDataBase &fe_data,
+                   FEValuesData<dim,spacedim>                       &data) const;
 
                                     /**
                                      * Implementation of the same
@@ -624,13 +627,13 @@ class FESystem : public FiniteElement<dim>
                                      * <tt>fill_fe*_values</tt> functions.
                                      */    
     virtual void
-    fill_fe_face_values (const Mapping<dim>                   &mapping,
-                        const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_face_values (const Mapping<dim,spacedim>                   &mapping,
+                        const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                         const unsigned int                    face_no,
                         const Quadrature<dim-1>              &quadrature,
-                        typename Mapping<dim>::InternalDataBase      &mapping_data,
-                        typename Mapping<dim>::InternalDataBase      &fe_data,
-                        FEValuesData<dim>                    &data) const ;
+                        typename Mapping<dim,spacedim>::InternalDataBase      &mapping_data,
+                        typename Mapping<dim,spacedim>::InternalDataBase      &fe_data,
+                        FEValuesData<dim,spacedim>                    &data) const ;
 
                                     /**
                                      * Implementation of the same
@@ -643,14 +646,14 @@ class FESystem : public FiniteElement<dim>
                                      * <tt>fill_fe*_values</tt> functions.
                                      */
     virtual void
-    fill_fe_subface_values (const Mapping<dim>                   &mapping,
-                           const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const Mapping<dim,spacedim>                   &mapping,
+                           const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int                    face_no,
                            const unsigned int                    sub_no,
                            const Quadrature<dim-1>              &quadrature,
-                           typename Mapping<dim>::InternalDataBase      &mapping_data,
-                           typename Mapping<dim>::InternalDataBase      &fe_data,
-                           FEValuesData<dim>                    &data) const ;
+                           typename Mapping<dim,spacedim>::InternalDataBase      &mapping_data,
+                           typename Mapping<dim,spacedim>::InternalDataBase      &fe_data,
+                           FEValuesData<dim,spacedim>                    &data) const ;
     
 
                                     /**
@@ -676,14 +679,14 @@ class FESystem : public FiniteElement<dim>
                                      * <tt>sub_no!=invalid_face_no</tt>.
                                      */
     template <int dim_1>
-    void compute_fill (const Mapping<dim>                   &mapping,
-                      const typename Triangulation<dim>::cell_iterator &cell,
+    void compute_fill (const Mapping<dim,spacedim>                   &mapping,
+                      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                       const unsigned int                    face_no,
                       const unsigned int                    sub_no,
                       const Quadrature<dim_1>              &quadrature,
-                      typename Mapping<dim>::InternalDataBase &mapping_data,
-                      typename Mapping<dim>::InternalDataBase &fe_data,
-                      FEValuesData<dim>                    &data) const ;
+                      typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+                      typename Mapping<dim,spacedim>::InternalDataBase &fe_data,
+                      FEValuesData<dim,spacedim>                    &data) const ;
 
   private:
 
@@ -698,7 +701,7 @@ class FESystem : public FiniteElement<dim>
                                      * Pairs of multiplicity and
                                      * element type.
                                      */
-    typedef std::pair<const FiniteElement<dim> *, unsigned int> ElementPair;
+    typedef std::pair<const FiniteElement<dim,spacedim> *, unsigned int> ElementPair;
     
                                     /**
                                      * Pointer to underlying finite
@@ -791,7 +794,7 @@ class FESystem : public FiniteElement<dim>
                                      * of the sub-element @p fe.
                                      */
     static std::vector<bool>
-    compute_restriction_is_additive_flags (const FiniteElement<dim> &fe,
+    compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe,
                                           const unsigned int        N);
     
                                     /**
@@ -799,9 +802,9 @@ class FESystem : public FiniteElement<dim>
                                      * with two different sub-elements.
                                      */
     static std::vector<bool>
-    compute_restriction_is_additive_flags (const FiniteElement<dim> &fe1,
+    compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe1,
                                           const unsigned int        N1,
-                                          const FiniteElement<dim> &fe2,
+                                          const FiniteElement<dim,spacedim> &fe2,
                                           const unsigned int        N2);
 
                                     /**
@@ -809,11 +812,11 @@ class FESystem : public FiniteElement<dim>
                                      * with three different sub-elements.
                                      */
     static std::vector<bool>
-    compute_restriction_is_additive_flags (const FiniteElement<dim> &fe1,
+    compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe1,
                                           const unsigned int        N1,
-                                          const FiniteElement<dim> &fe2,
+                                          const FiniteElement<dim,spacedim> &fe2,
                                           const unsigned int        N2,
-                                          const FiniteElement<dim> &fe3,
+                                          const FiniteElement<dim,spacedim> &fe3,
                                           const unsigned int        N3);
 
                                     /**
@@ -825,7 +828,7 @@ class FESystem : public FiniteElement<dim>
                                      * functions.
                                     */
     static std::vector<bool>
-    compute_restriction_is_additive_flags (const std::vector<const FiniteElement<dim>*> &fes,
+    compute_restriction_is_additive_flags (const std::vector<const FiniteElement<dim,spacedim>*> &fes,
                                            const std::vector<unsigned int>              &multiplicities);
     
     
@@ -835,7 +838,7 @@ class FESystem : public FiniteElement<dim>
                                      * finite element.
                                      */
     static std::vector<std::vector<bool> >
-    compute_nonzero_components (const FiniteElement<dim> &fe1,
+    compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
                                const unsigned int        N1);
 
                                     /**
@@ -844,9 +847,9 @@ class FESystem : public FiniteElement<dim>
                                      * finite element.
                                      */
     static std::vector<std::vector<bool> >
-    compute_nonzero_components (const FiniteElement<dim> &fe1,
+    compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
                                const unsigned int        N1,
-                               const FiniteElement<dim> &fe2,
+                               const FiniteElement<dim,spacedim> &fe2,
                                const unsigned int        N2);
 
                                     /**
@@ -855,11 +858,11 @@ class FESystem : public FiniteElement<dim>
                                      * finite element.
                                      */
     static std::vector<std::vector<bool> >
-    compute_nonzero_components (const FiniteElement<dim> &fe1,
+    compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
                                const unsigned int        N1,
-                               const FiniteElement<dim> &fe2,
+                               const FiniteElement<dim,spacedim> &fe2,
                                const unsigned int        N2,
-                               const FiniteElement<dim> &fe3,
+                               const FiniteElement<dim,spacedim> &fe3,
                                const unsigned int        N3);
 
                                     /**
@@ -871,7 +874,7 @@ class FESystem : public FiniteElement<dim>
                                      * the above functions.
                                     */
     static std::vector<std::vector<bool> >
-    compute_nonzero_components (const std::vector<const FiniteElement<dim>*> &fes,
+    compute_nonzero_components (const std::vector<const FiniteElement<dim,spacedim>*> &fes,
                                const std::vector<unsigned int>              &multiplicities);
     
                                     /**
@@ -910,7 +913,7 @@ class FESystem : public FiniteElement<dim>
                                      */
     template <int structdim>
     std::vector<std::pair<unsigned int, unsigned int> >
-    hp_object_dof_identities (const FiniteElement<dim> &fe_other) const;
+    hp_object_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const;
     
                                     /**
                                      * Usually: Fields of
@@ -922,7 +925,7 @@ class FESystem : public FiniteElement<dim>
                                      * @p InternalData objects for
                                      * each of the base elements.
                                      */
-    class InternalData : public FiniteElement<dim>::InternalDataBase
+    class InternalData : public FiniteElement<dim,spacedim>::InternalDataBase
     {
       public:
                                         /**
@@ -959,7 +962,7 @@ class FESystem : public FiniteElement<dim>
                                          * element.
                                          */
        void set_fe_data(const unsigned int                        base_no,
-                        typename FiniteElement<dim>::InternalDataBase *);
+                        typename FiniteElement<dim,spacedim>::InternalDataBase *);
 
                                         /**
                                          * Gives read-access to the
@@ -967,7 +970,7 @@ class FESystem : public FiniteElement<dim>
                                          * @p InternalData of the
                                          * @p base_noth base element.
                                          */    
-       typename FiniteElement<dim>::InternalDataBase &
+       typename FiniteElement<dim,spacedim>::InternalDataBase &
        get_fe_data (const unsigned int base_no) const;
 
 
@@ -979,7 +982,7 @@ class FESystem : public FiniteElement<dim>
                                          * element.
                                          */
        void set_fe_values_data (const unsigned int base_no,
-                                FEValuesData<dim> *);
+                                FEValuesData<dim,spacedim> *);
 
                                         /**
                                          * Gives read-access to the
@@ -987,7 +990,7 @@ class FESystem : public FiniteElement<dim>
                                          * @p FEValuesData for the
                                          * @p base_noth base element.
                                          */    
-       FEValuesData<dim> & get_fe_values_data (const unsigned int base_no) const;
+       FEValuesData<dim,spacedim> & get_fe_values_data (const unsigned int base_no) const;
 
                                         /**
                                          * Deletes the
@@ -1051,7 +1054,7 @@ class FESystem : public FiniteElement<dim>
                                          * elements, irrespective of
                                          * their multiplicity.
                                          */
-       typename std::vector<typename FiniteElement<dim>::InternalDataBase *> base_fe_datas;
+       typename std::vector<typename FiniteElement<dim,spacedim>::InternalDataBase *> base_fe_datas;
 
                                         /**
                                          * Pointers to the
@@ -1070,7 +1073,7 @@ class FESystem : public FiniteElement<dim>
                                          * by the InternalData
                                          * constructor.
                                          */
-       std::vector<FEValuesData<dim> *> base_fe_values_datas;
+       std::vector<FEValuesData<dim,spacedim> *> base_fe_values_datas;
     };
 };
 
index 05754070aea429b9ec11baed951544df0ead3346..4a4dc3bf3cc96545c1718a7644a696197de66de0 100644 (file)
@@ -26,11 +26,11 @@ DEAL_II_NAMESPACE_OPEN
 template <typename number> class FullMatrix;
 template <typename number> class Vector;
 template <int dim> class Quadrature;
-template <int dim> class FiniteElement;
-template <int dim> class DoFHandler;
+template <int dim, int spacedim> class FiniteElement;
+template <int dim, int spacedim> class DoFHandler;
 namespace hp
 {
-  template <int dim> class DoFHandler;
+  template <int dim, int spacedim> class DoFHandler;
 }
 template <int dim> class FiniteElementData;
 class ConstraintMatrix;
@@ -54,6 +54,10 @@ class ConstraintMatrix;
  * on each cell. Furthermore it provides the difference matrix
  * $id-I_h$ that is needed for evaluating $(id-I_h)z$ for e.g. the
  * dual solution $z$.
+ * 
+ * For more information about the <tt>spacedim</tt> template parameter
+ * check the documentation of FiniteElement or the one of
+ * Triangulation.
  *
  * @author Wolfgang Bangerth, Ralf Hartmann, Guido Kanschat;
  * 2000, 2003, 2004, 2005, 2006
@@ -78,7 +82,7 @@ class FETools
                                      *
                                      * @author Guido Kanschat, 2006
                                      */
-    template <int dim>
+    template <int dim, int spacedim=dim>
     class FEFactoryBase
     {
       public:
@@ -86,7 +90,7 @@ class FETools
                                          * Create a FiniteElement and
                                          * return a pointer to it.
                                          */
-       virtual FiniteElement<dim>*
+       virtual FiniteElement<dim,spacedim>*
        get (const unsigned int degree) const = 0;
 
                                          /**
@@ -114,14 +118,14 @@ class FETools
                                      * @author Guido Kanschat, 2006
                                      */
     template <class FE>
-    class FEFactory : public FEFactoryBase<FE::dimension>
+    class FEFactory : public FEFactoryBase<FE::dimension,FE::dimension>
     {
       public:
                                         /**
                                          * Create a FiniteElement and
                                          * return a pointer to it.
                                          */
-       virtual FiniteElement<FE::dimension>*
+       virtual FiniteElement<FE::dimension,FE::dimension>*
        get (const unsigned int degree) const;
     };
     
@@ -150,9 +154,9 @@ class FETools
                                      * size, the second one is
                                      * reinitialized for convenience.
                                      */
-    template<int dim>
+    template<int dim, int spacedim>
     static void compute_component_wise(
-      const FiniteElement<dim>&                fe,
+      const FiniteElement<dim,spacedim>&                fe,
       std::vector<unsigned int>&               renumbering,
       std::vector<std::vector<unsigned int> >& start_indices);
 
@@ -167,9 +171,9 @@ class FETools
                                      * @todo Which way does this
                                      * vector map the numbers?
                                      */
-    template<int dim>
+    template<int dim, int spacedim>
     static void compute_block_renumbering (
-      const FiniteElement<dim>&  fe,
+      const FiniteElement<dim,spacedim>&  fe,
       std::vector<unsigned int>& renumbering,
       std::vector<unsigned int>& start_indices);
     
@@ -191,11 +195,11 @@ class FETools
                                      * @p fe2 then the @p interpolation_matrix
                                      * is an embedding matrix.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static
     void
-    get_interpolation_matrix(const FiniteElement<dim> &fe1,
-                             const FiniteElement<dim> &fe2,
+    get_interpolation_matrix(const FiniteElement<dim,spacedim> &fe1,
+                             const FiniteElement<dim,spacedim> &fe2,
                              FullMatrix<number> &interpolation_matrix);
     
                                     /**
@@ -216,11 +220,11 @@ class FETools
                                      * the @p interpolation_matrix would be 
                                      * only the unit matrix.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static
     void
-    get_back_interpolation_matrix(const FiniteElement<dim> &fe1,
-                                  const FiniteElement<dim> &fe2,
+    get_back_interpolation_matrix(const FiniteElement<dim,spacedim> &fe1,
+                                  const FiniteElement<dim,spacedim> &fe2,
                                   FullMatrix<number> &interpolation_matrix);
 
                                     /**
@@ -240,11 +244,11 @@ class FETools
                                      * error-representations where $z$
                                      * denotes the dual solution.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static
     void
-    get_interpolation_difference_matrix(const FiniteElement<dim> &fe1,
-                                        const FiniteElement<dim> &fe2,
+    get_interpolation_difference_matrix(const FiniteElement<dim,spacedim> &fe1,
+                                        const FiniteElement<dim,spacedim> &fe2,
                                         FullMatrix<number> &difference_matrix);
 
                                     /**
@@ -252,9 +256,9 @@ class FETools
                                      * $L^2$-projection matrix from
                                      * fe1 to fe2.
                                      */
-    template <int dim, typename number>
-    static void get_projection_matrix(const FiniteElement<dim> &fe1,
-                                     const FiniteElement<dim> &fe2,
+    template <int dim, typename number, int spacedim>
+    static void get_projection_matrix(const FiniteElement<dim,spacedim> &fe1,
+                                     const FiniteElement<dim,spacedim> &fe2,
                                      FullMatrix<number> &matrix);
     
                                     /**
@@ -300,9 +304,9 @@ class FETools
                                      * points and and interpolation
                                      * functions.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void compute_node_matrix(FullMatrix<double>& M,
-                                   const FiniteElement<dim>& fe);
+                                   const FiniteElement<dim,spacedim>& fe);
     
                                     /**
                                      * For all possible (isotropic
@@ -370,8 +374,8 @@ class FETools
                                      * FiniteElement, where we want
                                      * to use this function mostly.
                                      */
-    template <int dim, typename number>
-    static void compute_embedding_matrices(const FiniteElement<dim> &fe,
+    template <int dim, typename number, int spacedim>
+    static void compute_embedding_matrices(const FiniteElement<dim,spacedim> &fe,
                                           std::vector<std::vector<FullMatrix<number> > >& matrices);
 
                                     /**
@@ -401,9 +405,9 @@ class FETools
                                      * matrices. It is not
                                      * sufficiently tested yet.
                                     */
-    template<int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static void
-    compute_face_embedding_matrices(const FiniteElement<dim>& fe,
+    compute_face_embedding_matrices(const FiniteElement<dim,spacedim>& fe,
                                    FullMatrix<number> (&matrices)[GeometryInfo<dim>::max_children_per_face],
                                    const unsigned int face_coarse,
                                    const unsigned int face_fine);
@@ -456,8 +460,8 @@ class FETools
                                      * FiniteElement, where we want
                                      * to use this function mostly.
                                      */
-    template <int dim, typename number>
-    static void compute_projection_matrices(const FiniteElement<dim> &fe,
+    template <int dim, typename number, int spacedim>
+    static void compute_projection_matrices(const FiniteElement<dim,spacedim> &fe,
                                            std::vector<std::vector<FullMatrix<number> > >& matrices);
 
 //TODO:[WB] Replace this documentation by something comprehensible
@@ -610,10 +614,10 @@ class FETools
                                      * the support points of the
                                      * finite element.
                                       */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     void
-    compute_projection_from_quadrature_points_matrix (const FiniteElement<dim> &fe,
+    compute_projection_from_quadrature_points_matrix (const FiniteElement<dim,spacedim> &fe,
                                                       const Quadrature<dim>    &lhs_quadrature,
                                                       const Quadrature<dim>    &rhs_quadrature,
                                                       FullMatrix<double>       &X);
@@ -629,10 +633,10 @@ class FETools
                                       * compute_projection_from_quadrature_points_matrix
                                       * function.
                                       */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     void
-    compute_interpolation_to_quadrature_points_matrix (const FiniteElement<dim> &fe,
+    compute_interpolation_to_quadrature_points_matrix (const FiniteElement<dim,spacedim> &fe,
                                                        const Quadrature<dim>    &quadrature,
                                                        FullMatrix<double>       &I_q);
     
@@ -699,16 +703,16 @@ class FETools
                                      * your hanging node constraints
                                      * object.
                                      */
-    template <int dim,
-              template <int> class DH1,
-              template <int> class DH2,
+    template <int dim, int spacedim,
+              template <int,int> class DH1,
+              template <int,int> class DH2,
               class InVector, class OutVector>
     static
     void
-    interpolate (const DH1<dim> &dof1,
-                 const InVector &u1,
-                 const DH2<dim> &dof2,
-                 OutVector      &u2);
+    interpolate (const DH1<dim,spacedim> &dof1,
+                 const InVector          &u1,
+                 const DH2<dim,spacedim> &dof2,
+                 OutVector               &u2);
     
                                     /**
                                      * Gives the interpolation of a
@@ -743,15 +747,15 @@ class FETools
                                      * at the DoF values on the
                                      * discontinuities.
                                      */
-    template <int dim,
-              template <int> class DH1,
-              template <int> class DH2,              
+    template <int dim, int spacedim, 
+              template <int, int> class DH1,
+              template <int, int> class DH2,              
               class InVector, class OutVector>
-    static void interpolate (const DH1<dim>         &dof1,
-                            const InVector         &u1,
-                            const DH2<dim>         &dof2,
-                            const ConstraintMatrix &constraints,
-                            OutVector&              u2);    
+    static void interpolate (const DH1<dim,spacedim>  &dof1,
+                            const InVector           &u1,
+                            const DH2<dim,spacedim>  &dof2,
+                            const ConstraintMatrix   &constraints,
+                            OutVector&                u2);    
 
                                     /**
                                      * Gives the interpolation of the
@@ -779,10 +783,10 @@ class FETools
                                      * function is simply an identity
                                      * mapping.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void back_interpolate (const DoFHandler<dim>    &dof1,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void back_interpolate (const DoFHandler<dim,spacedim>    &dof1,
                                  const InVector           &u1,
-                                 const FiniteElement<dim> &fe2,
+                                 const FiniteElement<dim,spacedim> &fe2,
                                  OutVector                &u1_interpolated);
 
                                      /**
@@ -793,10 +797,10 @@ class FETools
                                       */
     template <int dim,
               template <int> class DH,
-              class InVector, class OutVector>
+              class InVector, class OutVector, int spacedim>
     static void back_interpolate (const DH<dim>            &dof1,
                                  const InVector           &u1,
-                                 const FiniteElement<dim> &fe2,
+                                 const FiniteElement<dim,spacedim> &fe2,
                                  OutVector                &u1_interpolated);
 
                                      /**
@@ -826,11 +830,11 @@ class FETools
                                      * function is simply an identity
                                      * mapping.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void back_interpolate (const DoFHandler<dim>&  dof1,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void back_interpolate (const DoFHandler<dim,spacedim>&  dof1,
                                  const ConstraintMatrix& constraints1,
                                  const InVector&         u1,
-                                 const DoFHandler<dim>&  dof2,
+                                 const DoFHandler<dim,spacedim>&  dof2,
                                  const ConstraintMatrix& constraints2,
                                  OutVector&              u1_interpolated);
 
@@ -850,10 +854,10 @@ class FETools
                                      * additional
                                      * @p ConstraintMatrix object.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void interpolation_difference(const DoFHandler<dim> &dof1,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void interpolation_difference(const DoFHandler<dim,spacedim> &dof1,
                                         const InVector &z1,
-                                        const FiniteElement<dim> &fe2,
+                                        const FiniteElement<dim,spacedim> &fe2,
                                         OutVector &z1_difference);    
     
                                     /**
@@ -873,11 +877,11 @@ class FETools
                                      * nodes (locally refined grids)
                                      * are involved.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void interpolation_difference(const DoFHandler<dim>&  dof1,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void interpolation_difference(const DoFHandler<dim,spacedim>&  dof1,
                                         const ConstraintMatrix& constraints1,
                                         const InVector&         z1,
-                                        const DoFHandler<dim>&  dof2,
+                                        const DoFHandler<dim,spacedim>&  dof2,
                                         const ConstraintMatrix& constraints2,
                                         OutVector&              z1_difference);
     
@@ -895,10 +899,10 @@ class FETools
                                      * since a global mass matrix
                                      * must be inverted.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void project_dg (const DoFHandler<dim>& dof1,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void project_dg (const DoFHandler<dim,spacedim>& dof1,
                            const InVector&        u1,
-                           const DoFHandler<dim>& dof2,
+                           const DoFHandler<dim,spacedim>& dof2,
                            OutVector&             u2);
     
                                     /**
@@ -936,10 +940,10 @@ class FETools
                                      * this is not the case, an
                                      * exception will be raised.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void extrapolate (const DoFHandler<dim>& dof1,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void extrapolate (const DoFHandler<dim,spacedim>& dof1,
                             const InVector&        z1,
-                            const DoFHandler<dim>& dof2,
+                            const DoFHandler<dim,spacedim>& dof2,
                             OutVector&             z2);    
 
                                     /**
@@ -962,10 +966,10 @@ class FETools
                                      * for the other @p extrapolate
                                      * function.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void extrapolate (const DoFHandler<dim>&  dof1,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void extrapolate (const DoFHandler<dim,spacedim>&  dof1,
                             const InVector&         z1,
-                            const DoFHandler<dim>&  dof2,
+                            const DoFHandler<dim,spacedim>&  dof2,
                             const ConstraintMatrix& constraints,
                             OutVector&              z2);    
                                     //@}
@@ -1096,12 +1100,16 @@ class FETools
                                      * make your own elements known
                                      * to this function, use the
                                      * add_fe_name() function.
+                                     * This function does not work 
+                                     * if one wants to get a codimension
+                                     * 1 finite element.
                                      */
     template <int dim>
     static
-    FiniteElement<dim> *
+    FiniteElement<dim, dim> *
     get_fe_from_name (const std::string &name);
 
+
                                     /**
                                      * Extend the list of finite
                                      * elements that can be generated
@@ -1184,9 +1192,9 @@ class FETools
                                      * want your finite element added
                                      * to the map.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void add_fe_name (const std::string& name,
-                            const FEFactoryBase<dim>* factory);
+                            const FEFactoryBase<dim,spacedim>* factory);
     
                                     /**
                                      * The string used for
@@ -1303,16 +1311,16 @@ class FETools
                                      * the part of <tt>name</tt>
                                      * defining this element.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    FiniteElement<dim> *
+    FiniteElement<dim,spacedim> *
     get_fe_from_name_aux (std::string &name);
     
 };
 
 
 template<class FE>
-FiniteElement<FE::dimension>*
+FiniteElement<FE::dimension, FE::dimension>*
 FETools::FEFactory<FE>::get (const unsigned int degree) const
 {
   return new FE(degree);
index 027ee86bd1d3f42b532b3459360c7229610251ca..d854cf729994b0b135a5be5fde5ed8a9c509d7d0 100644 (file)
@@ -54,7 +54,7 @@ DEAL_II_NAMESPACE_OPEN
  * FiniteElement::update_each(flags) determine the values required by
  * the FiniteElement once or on each cell. The same functions exist in Mapping.
  *
- * Since the FiniteElement does not know if a value reuired from
+ * Since the FiniteElement does not know if a value required from
  * Mapping should be computed once or for each cell,
  * FEValuesBase::compute_update_flags() is used to compute the union
  * of all values to be computed ever. It does this by first adding to
@@ -143,13 +143,21 @@ enum UpdateFlags
                                        * reference to realcell.
                                        */
       update_JxW_values                   = 0x0020,
-                                      //! Normal vectors
+                                      //! Normal vectors to the faces
                                       /**
                                        * Compute the unit outer
                                        * normal vector on the face of
                                        * a cell.
                                        */
-      update_normal_vectors               = 0x0040,
+      update_face_normal_vectors          = 0x0040,
+                                      //! Normal vectors to the cells
+                                      /**
+                                       * Compute the unit outer
+                                       * normal vector on the cell
+                                       * itself. Only possible if
+                                       * dim=spacedim-1
+                                       */      
+      update_cell_normal_vectors          = 0x20000,
                                       //! Volume element
                                       /**
                                        * Compute the Jacobian of the
@@ -251,8 +259,14 @@ enum UpdateFlags
                                        * @deprecated Update second
                                        * derivatives.
                                        */
-      update_second_derivatives = update_hessians
-                               
+      update_second_derivatives = update_hessians,
+                                       //! Normal vectors
+                                      /**
+                                       * @deprecated Update normal
+                                       * vectors. Use
+                                       * update_face_normal_vectors
+                                       */
+      update_normal_vectors               = update_face_normal_vectors
 
 };
 
index 25b540778ea9d9d610e59f9d8ea463f03cf494d1..5798daaef20d46270f7c2902c567779d0ecd8ab2 100644 (file)
@@ -46,8 +46,8 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class Quadrature;
-template <int dim> class FEValuesBase;
+template <int dim>   class Quadrature;
+template <int dim, int spacedim=dim> class FEValuesBase;
 
 
 
@@ -151,7 +151,7 @@ namespace FEValuesViews
                                    *
                                    * @ingroup feaccess vector_valued
                                    */
-  template <int dim>
+  template <int dim, int spacedim=dim>  
   class Scalar
   {
     public:
@@ -172,7 +172,7 @@ namespace FEValuesViews
                                        * gradient is a
                                        * <code>Tensor@<1,dim@></code>.
                                        */
-      typedef Tensor<1,dim> gradient_type;
+      typedef Tensor<1,spacedim> gradient_type;
 
                                       /**
                                        * A typedef for the type of second
@@ -182,7 +182,7 @@ namespace FEValuesViews
                                        * Hessian is a
                                        * <code>Tensor@<2,dim@></code>.
                                        */
-      typedef Tensor<2,dim> hessian_type;
+      typedef Tensor<2,spacedim> hessian_type;
 
                                       /**
                                        * Constructor for an object that
@@ -191,7 +191,7 @@ namespace FEValuesViews
                                        * of the classes derived from
                                        * FEValuesBase).
                                        */
-      Scalar (const FEValuesBase<dim> &fe_values_base,
+      Scalar (const FEValuesBase<dim,spacedim> &fe_values_base,
              const unsigned int       component);
 
                                       /**
@@ -233,7 +233,7 @@ namespace FEValuesViews
                                        * A reference to the FEValuesBase object
                                        * we operator on.
                                        */
-      const FEValuesBase<dim> &fe_values;
+      const FEValuesBase<dim,spacedim> &fe_values;
 
                                       /**
                                        * The single scalar component this
@@ -254,7 +254,7 @@ namespace FEValuesViews
                                    *
                                    * @ingroup feaccess vector_valued
                                    */
-  template <int dim>
+  template <int dim, int spacedim=dim>  
   class Vector
   {
     public:
@@ -263,9 +263,9 @@ namespace FEValuesViews
                                        * values of the view this class
                                        * represents. Since we deal with a set
                                        * of <code>dim</code> components, the
-                                       * value type is a Tensor<1,dim>.
+                                       * value type is a Tensor<1,spacedim>.
                                        */
-      typedef Tensor<1,dim>          value_type;
+      typedef Tensor<1,spacedim>          value_type;
 
                                       /**
                                        * A typedef for the type of gradients
@@ -273,9 +273,9 @@ namespace FEValuesViews
                                        * represents. Here, for a set of
                                        * <code>dim</code> components of the
                                        * finite element, the gradient is a
-                                       * <code>Tensor@<2,dim@></code>.
+                                       * <code>Tensor@<2,spacedim@></code>.
                                        */
-      typedef Tensor<2,dim>          gradient_type;
+      typedef Tensor<2,spacedim>          gradient_type;
 
                                       /**
                                        * A typedef for the type of
@@ -284,9 +284,9 @@ namespace FEValuesViews
                                        * set of <code>dim</code> components
                                        * of the finite element, the
                                        * symmetrized gradient is a
-                                       * <code>SymmetricTensor@<2,dim@></code>.
+                                       * <code>SymmetricTensor@<2,spacedim@></code>.
                                        */
-      typedef SymmetricTensor<2,dim> symmetric_gradient_type;
+      typedef SymmetricTensor<2,spacedim> symmetric_gradient_type;
 
                                       /**
                                        * A typedef for the type of the
@@ -320,7 +320,7 @@ namespace FEValuesViews
                                        * index of the first component of the
                                        * selected vector.
                                        */
-      Vector (const FEValuesBase<dim> &fe_values_base,
+      Vector (const FEValuesBase<dim,spacedim> &fe_values_base,
              const unsigned int first_vector_component);
              
                                       /**
@@ -399,7 +399,7 @@ namespace FEValuesViews
                                        * A reference to the FEValuesBase object
                                        * we operator on.
                                        */
-      const FEValuesBase<dim> &fe_values;
+      const FEValuesBase<dim,spacedim> &fe_values;
 
                                       /**
                                        * The first component of the vector
@@ -435,7 +435,7 @@ namespace FEValuesViews
  * 
  * @author Guido Kanschat, 2000
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 class FEValuesData
 {
   public:
@@ -444,7 +444,7 @@ class FEValuesData
                                      * correct size.
                                      */
     void initialize (const unsigned int        n_quadrature_points,
-                    const FiniteElement<dim> &fe,
+                    const FiniteElement<dim,spacedim> &fe,
                     const UpdateFlags         flags);
 
                                     /**
@@ -493,13 +493,13 @@ class FEValuesData
                                      * is the same as for the
                                      * #ShapeVector data type.
                                      */
-    typedef std::vector<std::vector<Tensor<1,dim> > > GradientVector;
+    typedef std::vector<std::vector<Tensor<1,spacedim> > > GradientVector;
 
                                     /**
                                      * Likewise for second order
                                      * derivatives.
                                      */
-    typedef std::vector<std::vector<Tensor<2,dim> > > HessianVector;
+    typedef std::vector<std::vector<Tensor<2,spacedim> > > HessianVector;
 
                                     /**
                                      * Store the values of the shape
@@ -563,19 +563,19 @@ class FEValuesData
                                      * Array of the Jacobian matrices at the
                                      * quadrature points.
                                      */
-    std::vector<Tensor<2,dim> > jacobians;
+    std::vector<Tensor<2,spacedim> > jacobians;
 
                                     /**
                                      * Array of the derivatives of the Jacobian
                                      * matrices at the quadrature points.
                                      */
-    std::vector<Tensor<3,dim> > jacobian_grads;
+    std::vector<Tensor<3,spacedim> > jacobian_grads;
 
                                     /**
                                      * Array of the inverse Jacobian matrices 
                                      * at the quadrature points.
                                      */
-    std::vector<Tensor<2,dim> > inverse_jacobians;
+    std::vector<Tensor<2,spacedim> > inverse_jacobians;
 
                                     /**
                                      * Store an array of weights
@@ -609,27 +609,35 @@ class FEValuesData
                                      * real element, rather than on the
                                      * reference element.
                                      */
-    std::vector<Point<dim> >  quadrature_points;
+    std::vector<Point<spacedim> >  quadrature_points;
 
                                     /**
                                      * List of outward normal vectors at the
                                      * quadrature points. This field is filled
                                      * in by the finite element class.
                                      */
-    std::vector<Point<dim> >  normal_vectors;
+    std::vector<Point<spacedim> >  normal_vectors;
+
+                                      /** 
+                                      * List of outward vectors normal to the cell  
+                                       * surface (line) at the quadrature points
+                                      * for the codimension 1 case,
+                                      * when spacedim=3 (=2).
+                                      */
+    std::vector<Point<spacedim> >  cell_normal_vectors;
 
                                      /**
                                      * List of boundary forms at the
                                      * quadrature points. This field is filled
                                      * in by the finite element class.
                                      */
-    std::vector<Tensor<1,dim> >  boundary_forms;
+    std::vector<Tensor<1,spacedim> >  boundary_forms;
 
                                     /**
                                      * Array of the mapped support
                                      * points, filled by Mapping.
                                      */
-    std::vector<Point<dim> > support_points;
+    std::vector<Point<spacedim> > support_points;
 
                                     /**
                                      * Array of the Jacobian of the
@@ -797,8 +805,8 @@ class FEValuesData
  *
  * @author Wolfgang Bangerth, 1998, 2003, Guido Kanschat, 2001
  */
-template <int dim>
-class FEValuesBase : protected FEValuesData<dim>,
+template <int dim, int spacedim>
+  class FEValuesBase : protected FEValuesData<dim,spacedim>,
                      public Subscriptor
 {
   public:
@@ -835,9 +843,9 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      */
     FEValuesBase (const unsigned int n_q_points,
                  const unsigned int dofs_per_cell,
-                 const UpdateFlags         update_flags,
-                 const Mapping<dim>       &mapping,
-                 const FiniteElement<dim> &fe);
+                 const UpdateFlags update_flags,
+                 const Mapping<dim,spacedim> &mapping,
+                 const FiniteElement<dim,spacedim> &fe);
 
 
                                     /**
@@ -858,7 +866,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * FEValuesViews and in particular
                                      * in the @ref vector_valued module.
                                      */
-    FEValuesViews::Scalar<dim>
+    FEValuesViews::Scalar<dim,spacedim>
     operator[] (const FEValuesExtractors::Scalar &scalar) const;
 
                                     /**
@@ -871,7 +879,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * the namespace FEValuesViews and in particular
                                      * in the @ref vector_valued module.
                                      */
-    FEValuesViews::Vector<dim>
+    FEValuesViews::Vector<dim,spacedim>
     operator[] (const FEValuesExtractors::Vector &vector) const;
 
                                     //@}
@@ -976,7 +984,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * shape_grad_component()
                                      * function.
                                      */
-    const Tensor<1,dim> &
+    const Tensor<1,spacedim> &
     shape_grad (const unsigned int function,
                const unsigned int quadrature_point) const;
 
@@ -1004,7 +1012,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * is necessary since the other
                                      * function cannot be used.
                                      */
-    Tensor<1,dim>
+    Tensor<1,spacedim>
     shape_grad_component (const unsigned int function_no,
                          const unsigned int point_no,
                          const unsigned int component) const;
@@ -1038,14 +1046,14 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * shape_grad_grad_component()
                                      * function.
                                      */
-    const Tensor<2,dim> &
+    const Tensor<2,spacedim> &
     shape_hessian (const unsigned int function_no,
                   const unsigned int point_no) const;
 
                                     /**
                                      * @deprecated Wrapper for shape_hessian()
                                      */
-    const Tensor<2,dim> &
+    const Tensor<2,spacedim> &
     shape_2nd_derivative (const unsigned int function_no,
                          const unsigned int point_no) const;
 
@@ -1076,7 +1084,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * is necessary since the other
                                      * function cannot be used.
                                      */
-    Tensor<2,dim>
+    Tensor<2,spacedim>
     shape_hessian_component (const unsigned int function_no,
                                    const unsigned int point_no,
                                    const unsigned int component) const;
@@ -1084,7 +1092,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                     /**
                                      * @deprecated Wrapper for shape_hessian_component()
                                      */
-    Tensor<2,dim>
+    Tensor<2,spacedim>
     shape_2nd_derivative_component (const unsigned int function_no,
                                    const unsigned int point_no,
                                    const unsigned int component) const;
@@ -1357,7 +1365,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      */
     template <class InputVector>
     void get_function_gradients (const InputVector      &fe_function,
-                            std::vector<Tensor<1,dim> > &gradients) const;
+                            std::vector<Tensor<1,spacedim> > &gradients) const;
 
                                     /**
                                      * @deprecated Use
@@ -1365,7 +1373,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      */
     template <class InputVector>
     void get_function_grads (const InputVector      &fe_function,
-                            std::vector<Tensor<1,dim> > &gradients) const;
+                            std::vector<Tensor<1,spacedim> > &gradients) const;
 
                                     /**
                                      * Compute the gradients of the finite
@@ -1407,7 +1415,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      */
     template <class InputVector>
     void get_function_gradients (const InputVector               &fe_function,
-                            std::vector<std::vector<Tensor<1,dim> > > &gradients) const;
+                            std::vector<std::vector<Tensor<1,spacedim> > > &gradients) const;
 
     
                                     /**
@@ -1416,7 +1424,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      */
     template <class InputVector>
     void get_function_grads (const InputVector               &fe_function,
-                            std::vector<std::vector<Tensor<1,dim> > > &gradients) const;
+                            std::vector<std::vector<Tensor<1,spacedim> > > &gradients) const;
 
                                     /**
                                      * Function gradient access with
@@ -1427,7 +1435,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     template <class InputVector>
     void get_function_gradients (const InputVector& fe_function,
                                 const VectorSlice<const std::vector<unsigned int> >& indices,
-                                std::vector<Tensor<1,dim> >& gradients) const;
+                                std::vector<Tensor<1,spacedim> >& gradients) const;
 
                                     /**
                                      * @deprecated Use
@@ -1436,7 +1444,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     template <class InputVector>
     void get_function_grads (const InputVector& fe_function,
                             const VectorSlice<const std::vector<unsigned int> >& indices,
-                            std::vector<Tensor<1,dim> >& gradients) const;
+                            std::vector<Tensor<1,spacedim> >& gradients) const;
 
                                     /**
                                      * Function gradient access with
@@ -1447,7 +1455,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     template <class InputVector>
     void get_function_gradients (const InputVector& fe_function,
                                 const VectorSlice<const std::vector<unsigned int> >& indices,
-                                std::vector<std::vector<Tensor<1,dim> > >& gradients,
+                                std::vector<std::vector<Tensor<1,spacedim> > >& gradients,
                                 bool quadrature_points_fastest = false) const;
 
                                     /**
@@ -1457,7 +1465,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     template <class InputVector>
     void get_function_grads (const InputVector& fe_function,
                             const VectorSlice<const std::vector<unsigned int> >& indices,
-                            std::vector<std::vector<Tensor<1,dim> > >& gradients,
+                            std::vector<std::vector<Tensor<1,spacedim> > >& gradients,
                             bool quadrature_points_fastest = false) const;
 
                                     /**
@@ -1502,7 +1510,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     template <class InputVector>
     void
     get_function_hessians (const InputVector& fe_function,
-                          std::vector<Tensor<2,dim> >& hessians) const;
+                          std::vector<Tensor<2,spacedim> >& hessians) const;
 
     
                                     /**
@@ -1543,7 +1551,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     template <class InputVector>
     void
     get_function_hessians (const InputVector      &fe_function,
-                          std::vector<std::vector<Tensor<2,dim> > > &hessians,
+                          std::vector<std::vector<Tensor<2,spacedim> > > &hessians,
                           bool quadrature_points_fastest = false) const;
 
                                     /**
@@ -1557,7 +1565,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     void get_function_hessians (
       const InputVector& fe_function,
       const VectorSlice<const std::vector<unsigned int> >& indices,
-      std::vector<Tensor<2,dim> >& result) const;
+      std::vector<Tensor<2,spacedim> >& result) const;
 
                                     /**
                                      * Access to the second
@@ -1570,7 +1578,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     void get_function_hessians (
       const InputVector& fe_function,
       const VectorSlice<const std::vector<unsigned int> >& indices,
-      std::vector<std::vector<Tensor<2,dim> > >& result,
+      std::vector<std::vector<Tensor<2,spacedim> > >& result,
       bool quadrature_points_fastest = false) const;
 
                                     /**
@@ -1579,7 +1587,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     template <class InputVector>
     void
     get_function_2nd_derivatives (const InputVector&,
-                                 std::vector<Tensor<2,dim> >&) const;
+                                 std::vector<Tensor<2,spacedim> >&) const;
 
                                     /**
                                      * @deprecated Wrapper for get_function_hessians()
@@ -1587,7 +1595,7 @@ class FEValuesBase : protected FEValuesData<dim>,
     template <class InputVector>
     void
     get_function_2nd_derivatives (const InputVector&,
-                                 std::vector<std::vector<Tensor<2,dim> > >&,
+                                 std::vector<std::vector<Tensor<2,spacedim> > >&,
                                  bool = false) const;
     
 
@@ -1597,13 +1605,13 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * Position of the <tt>i</tt>th
                                      * quadrature point in real space.
                                      */
-    const Point<dim> & quadrature_point (const unsigned int i) const;
+    const Point<spacedim> & quadrature_point (const unsigned int i) const;
 
                                     /**
                                      * Return a pointer to the vector of
                                      * quadrature points.
                                      */
-    const std::vector<Point<dim> > & get_quadrature_points () const;
+    const std::vector<Point<spacedim> > & get_quadrature_points () const;
 
                                     /**
                                      * Mapped quadrature weight. If
@@ -1636,13 +1644,13 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * quadrature point, i.e.
                                      * $J_{ij}=dx_i/d\hat x_j$
                                      */
-    const Tensor<2,dim> & jacobian (const unsigned int quadrature_point) const;
+    const Tensor<2,spacedim> & jacobian (const unsigned int quadrature_point) const;
 
                                     /**
                                      * Pointer to the array holding
                                      * the values returned by jacobian().
                                      */
-    const std::vector<Tensor<2,dim> > & get_jacobians () const;
+    const std::vector<Tensor<2,spacedim> > & get_jacobians () const;
 
                                     /**
                                      * Return the second derivative of the
@@ -1651,14 +1659,14 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * Jacobian, at the specified quadrature
                                      * point, i.e. $G_{ijk}=dJ_{jk}/d\hat x_i$.
                                      */
-    const Tensor<3,dim> & jacobian_grad (const unsigned int quadrature_point) const;
+    const Tensor<3,spacedim> & jacobian_grad (const unsigned int quadrature_point) const;
 
                                     /**
                                      * Pointer to the array holding
                                      * the values returned by
                                      * jacobian_grads().
                                      */
-    const std::vector<Tensor<3,dim> > & get_jacobian_grads () const;
+    const std::vector<Tensor<3,spacedim> > & get_jacobian_grads () const;
 
                                     /**
                                      * Return the inverse Jacobian of the
@@ -1666,33 +1674,50 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      * quadrature point, i.e.
                                      * $J_{ij}=d\hat x_i/dx_j$
                                      */
-    const Tensor<2,dim> & inverse_jacobian (const unsigned int quadrature_point) const;
+    const Tensor<2,spacedim> & inverse_jacobian (const unsigned int quadrature_point) const;
 
                                     /**
                                      * Pointer to the array holding
                                      * the values returned by 
                                      * inverse_jacobian().
                                      */
-    const std::vector<Tensor<2,dim> > & get_inverse_jacobians () const;
+    const std::vector<Tensor<2,spacedim> > & get_inverse_jacobians () const;
 
                                     /**
                                      * Constant reference to the
                                      * selected mapping object.
                                      */
-    const Mapping<dim> & get_mapping () const;
+    const Mapping<dim,spacedim> & get_mapping () const;
 
                                     /**
                                      * Constant reference to the
                                      * selected finite element
                                      * object.
                                      */
-    const FiniteElement<dim> & get_fe () const;
+    const FiniteElement<dim,spacedim> & get_fe () const;
 
                                     /**
                                      * Return a triangulation
                                      * iterator to the current cell.
                                      */
-    const typename Triangulation<dim>::cell_iterator get_cell () const;
+    const typename Triangulation<dim,spacedim>::cell_iterator get_cell () const;
+
+                                    /**
+                                     * Returns the vectors normal to
+                                     * the cell in each of the
+                                     * quadrature points.
+                                     */
+
+    const std::vector<Point<spacedim> > & get_cell_normal_vectors () const;
+
+
+                                    /**
+                                     * Return the outward normal vector to
+                                     * the cell at the <tt>i</tt>th quadrature
+                                     * point. The length of the vector
+                                     * is normalized to one.
+                                     */
+    const Point<spacedim> & cell_normal_vector (const unsigned int i) const;
 
                                     /**
                                      * Determine an estimate for the
@@ -1835,7 +1860,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                           * conversion operator.
                                           */
         virtual
-        operator const typename Triangulation<dim>::cell_iterator () const = 0;
+        operator const typename Triangulation<dim,spacedim>::cell_iterator () const = 0;
 
                                          /**
                                           * Return the number of
@@ -2021,7 +2046,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                           * conversion operator.
                                           */
         virtual
-        operator const typename Triangulation<dim>::cell_iterator () const;
+        operator const typename Triangulation<dim,spacedim>::cell_iterator () const;
         
                                          /**
                                           * Return the number of
@@ -2230,7 +2255,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                           * iterator and store it in
                                           * this class.
                                           */
-        TriaCellIterator (const typename Triangulation<dim>::cell_iterator &cell);
+        TriaCellIterator (const typename Triangulation<dim,spacedim>::cell_iterator &cell);
         
                                          /**
                                           * Conversion operator to an
@@ -2248,7 +2273,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                           * from and to the same time.
                                           */
         virtual
-        operator const typename Triangulation<dim>::cell_iterator () const;
+        operator const typename Triangulation<dim,spacedim>::cell_iterator () const;
 
                                          /**
                                           * Implement the respective
@@ -2406,7 +2431,7 @@ class FEValuesBase : protected FEValuesData<dim>,
                                           * Copy of the iterator which
                                           * we use in this object.
                                           */
-        const typename Triangulation<dim>::cell_iterator cell;
+        const typename Triangulation<dim,spacedim>::cell_iterator cell;
 
                                          /**
                                           * String to be displayed
@@ -2432,23 +2457,23 @@ class FEValuesBase : protected FEValuesData<dim>,
                                     /**
                                      * Storage for the mapping object.
                                      */
-    const SmartPointer<const Mapping<dim> > mapping;
+    const SmartPointer<const Mapping<dim,spacedim> > mapping;
     
                                     /**
                                      * Store the finite element for later use.
                                      */
-    const SmartPointer<const FiniteElement<dim> > fe;
+    const SmartPointer<const FiniteElement<dim,spacedim> > fe;
 
     
                                     /**
                                      * Internal data of mapping.
                                      */
-    SmartPointer<typename Mapping<dim>::InternalDataBase> mapping_data;
+    SmartPointer<typename Mapping<dim,spacedim>::InternalDataBase> mapping_data;
 
                                     /**
                                      * Internal data of finite element.
                                      */
-    SmartPointer<typename Mapping<dim>::InternalDataBase> fe_data;
+    SmartPointer<typename Mapping<dim,spacedim>::InternalDataBase> fe_data;
 
                                     /**
                                      * Initialize some update
@@ -2506,8 +2531,8 @@ class FEValuesBase : protected FEValuesData<dim>,
  * 
  * @author Wolfgang Bangerth, 1998, Guido Kanschat, 2001
  */
-template <int dim>
-class FEValues : public FEValuesBase<dim>
+template <int dim, int spacedim=dim>
+  class FEValues : public FEValuesBase<dim,spacedim>
 {
   public:
                                      /**
@@ -2516,6 +2541,12 @@ class FEValues : public FEValuesBase<dim>
                                       */
     static const unsigned int dimension = dim;
 
+                                     /**
+                                      * Dimension of the space in
+                                      * which this object operates.
+                                      */
+    static const unsigned int space_dimension = spacedim;
+
                                      /**
                                       * Dimension of the object over
                                       * which we integrate. For the
@@ -2531,8 +2562,8 @@ class FEValues : public FEValuesBase<dim>
                                      * matching the quadrature rule
                                      * and update flags.
                                      */
-    FEValues (const Mapping<dim>       &mapping,
-             const FiniteElement<dim> &fe,
+    FEValues (const Mapping<dim,spacedim>       &mapping,
+             const FiniteElement<dim,spacedim> &fe,
              const Quadrature<dim>    &quadrature,
              const UpdateFlags         update_flags);
 
@@ -2540,7 +2571,7 @@ class FEValues : public FEValuesBase<dim>
                                      * Constructor. Uses MappingQ1
                                      * implicitly.
                                      */
-    FEValues (const FiniteElement<dim> &fe,
+    FEValues (const FiniteElement<dim,spacedim> &fe,
              const Quadrature<dim>    &quadrature,
              const UpdateFlags         update_flags);
     
@@ -2557,7 +2588,7 @@ class FEValues : public FEValuesBase<dim>
                                      * used by this FEValues
                                      * object.
                                      */
-    void reinit (const typename DoFHandler<dim>::cell_iterator &cell);
+    void reinit (const typename DoFHandler<dim,spacedim>::cell_iterator &cell);
 
                                     /**
                                      * Reinitialize the gradients,
@@ -2572,7 +2603,7 @@ class FEValues : public FEValuesBase<dim>
                                      * used by this @p FEValues
                                      * object.
                                      */
-    void reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell);
+    void reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell);
 
                                     /**
                                      * Reinitialize the gradients,
@@ -2587,7 +2618,7 @@ class FEValues : public FEValuesBase<dim>
                                      * used by this FEValues
                                      * object.
                                      */
-    void reinit (const typename MGDoFHandler<dim>::cell_iterator &cell);
+    void reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell);
 
                                     /**
                                      * Reinitialize the gradients,
@@ -2615,7 +2646,7 @@ class FEValues : public FEValuesBase<dim>
                                      * DoFHandler or other DoF
                                      * handler type objects.
                                      */
-    void reinit (const typename Triangulation<dim>::cell_iterator &cell);
+    void reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell);
 
                                     /**
                                      * Return a reference to the copy
@@ -2654,7 +2685,7 @@ class FEValues : public FEValuesBase<dim>
                                       * that one can templatize on
                                       * FEValues/hpFEValues).
                                       */
-    const FEValues<dim> & get_present_fe_values () const;
+    const FEValues<dim,spacedim> & get_present_fe_values () const;
     
   private:
                                     /**
@@ -2705,8 +2736,8 @@ class FEValues : public FEValuesBase<dim>
  *
  *  @author Wolfgang Bangerth, 1998, Guido Kanschat, 2000, 2001
  */
-template <int dim>
-class FEFaceValuesBase : public FEValuesBase<dim>
+template <int dim, int spacedim=dim>  
+class FEFaceValuesBase : public FEValuesBase<dim,spacedim>
 {
   public:
                                     /**
@@ -2730,8 +2761,8 @@ class FEFaceValuesBase : public FEValuesBase<dim>
     FEFaceValuesBase (const unsigned int n_q_points,
                      const unsigned int dofs_per_cell,
                      const UpdateFlags         update_flags,
-                     const Mapping<dim>       &mapping,
-                     const FiniteElement<dim> &fe,
+                     const Mapping<dim,spacedim>       &mapping,
+                     const FiniteElement<dim,spacedim> &fe,
                      const Quadrature<dim-1>& quadrature);
 
                                     /**
@@ -2759,7 +2790,7 @@ class FEFaceValuesBase : public FEValuesBase<dim>
                                      * this value to integrate
                                      * <tt>n.ds</tt>.
                                      */
-    const Tensor<1,dim> & boundary_form (const unsigned int i) const;
+    const Tensor<1,spacedim> & boundary_form (const unsigned int i) const;
     
                                     /**
                                      * Return the list of outward normal
@@ -2774,7 +2805,7 @@ class FEFaceValuesBase : public FEValuesBase<dim>
                                      * Jacobian of the surface
                                      * mapping.
                                      */
-    const std::vector<Tensor<1,dim> > & get_boundary_forms () const;
+    const std::vector<Tensor<1,spacedim> > & get_boundary_forms () const;
 
                                     /**
                                      * Return the index of the face
@@ -2828,16 +2859,19 @@ class FEFaceValuesBase : public FEValuesBase<dim>
  *
  * @author Wolfgang Bangerth, 1998, Guido Kanschat, 2000, 2001
  */
-template <int dim>
-class FEFaceValues : public FEFaceValuesBase<dim>
+template <int dim, int spacedim=dim>  
+class FEFaceValues : public FEFaceValuesBase<dim,spacedim>
 {
   public:
                                      /**
                                       * Dimension in which this object
                                       * operates.
                                       */
+
     static const unsigned int dimension = dim;
 
+    static const unsigned int space_dimension = spacedim;
+
                                      /**
                                       * Dimension of the object over
                                       * which we integrate. For the
@@ -2853,8 +2887,8 @@ class FEFaceValues : public FEFaceValuesBase<dim>
                                      * matching the quadrature rule
                                      * and update flags.
                                      */
-    FEFaceValues (const Mapping<dim>       &mapping,
-                 const FiniteElement<dim> &fe,
+    FEFaceValues (const Mapping<dim,spacedim>       &mapping,
+                 const FiniteElement<dim,spacedim> &fe,
                  const Quadrature<dim-1>  &quadrature,
                  const UpdateFlags         update_flags);
 
@@ -2862,7 +2896,7 @@ class FEFaceValues : public FEFaceValuesBase<dim>
                                      * Constructor. Uses MappingQ1
                                      * implicitly.
                                      */
-    FEFaceValues (const FiniteElement<dim> &fe,
+    FEFaceValues (const FiniteElement<dim,spacedim> &fe,
                  const Quadrature<dim-1>  &quadrature,
                  const UpdateFlags         update_flags);
 
@@ -2872,7 +2906,7 @@ class FEFaceValues : public FEFaceValuesBase<dim>
                                      * number @p face_no of @p cell
                                      * and the given finite element.
                                      */
-    void reinit (const typename DoFHandler<dim>::cell_iterator &cell,
+    void reinit (const typename DoFHandler<dim,spacedim>::cell_iterator &cell,
                 const unsigned int                            face_no);
 
                                     /**
@@ -2888,7 +2922,7 @@ class FEFaceValues : public FEFaceValuesBase<dim>
                                      * used by this FEValues
                                      * object.
                                      */
-    void reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell,
+    void reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
                 const unsigned int                              face_no);
 
                                     /**
@@ -2904,7 +2938,7 @@ class FEFaceValues : public FEFaceValuesBase<dim>
                                      * used by this FEValues
                                      * object.
                                      */
-    void reinit (const typename MGDoFHandler<dim>::cell_iterator &cell,
+    void reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
                 const unsigned int                              face_no);
 
                                     /**
@@ -2933,7 +2967,7 @@ class FEFaceValues : public FEFaceValuesBase<dim>
                                      * DoFHandler or other DoF
                                      * handler type objects.
                                      */
-    void reinit (const typename Triangulation<dim>::cell_iterator &cell,
+    void reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                 const unsigned int                    face_no);
     
                                      /**
@@ -2959,7 +2993,7 @@ class FEFaceValues : public FEFaceValuesBase<dim>
                                       * that one can templatize on
                                       * FEValues/hpFEValues).
                                       */
-    const FEFaceValues<dim> & get_present_fe_values () const;
+    const FEFaceValues<dim,spacedim> & get_present_fe_values () const;
   private:
 
                                     /**
@@ -3001,8 +3035,8 @@ class FEFaceValues : public FEFaceValuesBase<dim>
  *
  * @author Wolfgang Bangerth, 1998, Guido Kanschat, 2000, 2001
  */
-template <int dim>
-class FESubfaceValues : public FEFaceValuesBase<dim>
+template <int dim, int spacedim=dim>  
+class FESubfaceValues : public FEFaceValuesBase<dim,spacedim>
 {
   public:
                                      /**
@@ -3011,6 +3045,12 @@ class FESubfaceValues : public FEFaceValuesBase<dim>
                                       */
     static const unsigned int dimension = dim;
 
+                                     /**
+                                      * Dimension of the space in
+                                      * which this object operates.
+                                      */
+    static const unsigned int space_dimension = spacedim;
+
                                      /**
                                       * Dimension of the object over
                                       * which we integrate. For the
@@ -3026,8 +3066,8 @@ class FESubfaceValues : public FEFaceValuesBase<dim>
                                      * matching the quadrature rule
                                      * and update flags.
                                      */
-    FESubfaceValues (const Mapping<dim>       &mapping,
-                    const FiniteElement<dim> &fe,
+    FESubfaceValues (const Mapping<dim,spacedim>       &mapping,
+                    const FiniteElement<dim,spacedim> &fe,
                     const Quadrature<dim-1>  &face_quadrature,
                     const UpdateFlags         update_flags);
 
@@ -3035,7 +3075,7 @@ class FESubfaceValues : public FEFaceValuesBase<dim>
                                      * Constructor. Uses MappingQ1
                                      * implicitly.
                                      */
-    FESubfaceValues (const FiniteElement<dim> &fe,
+    FESubfaceValues (const FiniteElement<dim,spacedim> &fe,
                     const Quadrature<dim-1>  &face_quadrature,
                     const UpdateFlags         update_flags);
 
@@ -3052,7 +3092,7 @@ class FESubfaceValues : public FEFaceValuesBase<dim>
                                      * used by this
                                      * FESubfaceValues object.
                                      */
-    void reinit (const typename DoFHandler<dim>::cell_iterator &cell,
+    void reinit (const typename DoFHandler<dim,spacedim>::cell_iterator &cell,
                 const unsigned int                    face_no,
                 const unsigned int                    subface_no);
 
@@ -3069,7 +3109,7 @@ class FESubfaceValues : public FEFaceValuesBase<dim>
                                      * used by this FEValues
                                      * object.
                                      */
-    void reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell,
+    void reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
                 const unsigned int                    face_no,
                 const unsigned int                    subface_no);
     
@@ -3086,7 +3126,7 @@ class FESubfaceValues : public FEFaceValuesBase<dim>
                                      * used by this FEValues
                                      * object.
                                      */
-    void reinit (const typename MGDoFHandler<dim>::cell_iterator &cell,
+    void reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
                 const unsigned int                    face_no,
                 const unsigned int                    subface_no);
     
@@ -3116,7 +3156,7 @@ class FESubfaceValues : public FEFaceValuesBase<dim>
                                      * DoFHandler or other DoF
                                      * handler type objects.
                                      */
-    void reinit (const typename Triangulation<dim>::cell_iterator &cell,
+    void reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                 const unsigned int                    face_no,
                 const unsigned int                    subface_no);
 
@@ -3143,7 +3183,7 @@ class FESubfaceValues : public FEFaceValuesBase<dim>
                                       * that one can templatize on
                                       * FEValues/hpFEValues).
                                       */
-    const FESubfaceValues<dim> & get_present_fe_values () const;
+    const FESubfaceValues<dim,spacedim> & get_present_fe_values () const;
 
                                      /**
                                      * @todo Document this
@@ -3212,9 +3252,9 @@ namespace FEValuesExtractors
 
 namespace FEValuesViews
 {
-  template <int dim>
+  template <int dim, int spacedim>  
   inline
-  Scalar<dim>::Scalar (const FEValuesBase<dim> &fe_values,
+  Scalar<dim,spacedim>::Scalar (const FEValuesBase<dim,spacedim> &fe_values,
                       const unsigned int       component)
                  :
                  fe_values (fe_values),
@@ -3226,16 +3266,17 @@ namespace FEValuesViews
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>  
   inline
-  typename Scalar<dim>::value_type
-  Scalar<dim>::value (const unsigned int shape_function,
+  typename Scalar<dim,spacedim>::value_type
+  Scalar<dim,spacedim>::value (const unsigned int shape_function,
                      const unsigned int q_point) const
   {
+    typedef FEValuesBase<dim,spacedim> FVB;
     Assert (shape_function < fe_values.fe->dofs_per_cell,
            ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
     Assert (fe_values.update_flags & update_values,
-           typename FEValuesBase<dim>::ExcAccessToUninitializedField());    
+           typename FVB::ExcAccessToUninitializedField());    
 
                                     // an adaptation of the
                                     // FEValuesBase::shape_value_component
@@ -3274,16 +3315,17 @@ namespace FEValuesViews
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>  
   inline
-  typename Scalar<dim>::gradient_type
-  Scalar<dim>::gradient (const unsigned int shape_function,
+  typename Scalar<dim,spacedim>::gradient_type
+  Scalar<dim,spacedim>::gradient (const unsigned int shape_function,
                         const unsigned int q_point) const
   {
+    typedef FEValuesBase<dim,spacedim> FVB;
     Assert (shape_function < fe_values.fe->dofs_per_cell,
            ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
     Assert (fe_values.update_flags & update_gradients,
-           typename FEValuesBase<dim>::ExcAccessToUninitializedField());    
+           typename FVB::ExcAccessToUninitializedField());    
 
                                     // an adaptation of the
                                     // FEValuesBase::shape_grad_component
@@ -3322,16 +3364,17 @@ namespace FEValuesViews
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>  
   inline
-  typename Scalar<dim>::hessian_type
-  Scalar<dim>::hessian (const unsigned int shape_function,
+  typename Scalar<dim,spacedim>::hessian_type
+  Scalar<dim,spacedim>::hessian (const unsigned int shape_function,
                        const unsigned int q_point) const
   {
+    typedef FEValuesBase<dim,spacedim> FVB;
     Assert (shape_function < fe_values.fe->dofs_per_cell,
            ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
     Assert (fe_values.update_flags & update_hessians,
-           typename FEValuesBase<dim>::ExcAccessToUninitializedField());    
+           typename FVB::ExcAccessToUninitializedField());    
 
                                     // an adaptation of the
                                     // FEValuesBase::shape_grad_component
@@ -3370,9 +3413,9 @@ namespace FEValuesViews
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>  
   inline
-  Vector<dim>::Vector (const FEValuesBase<dim> &fe_values,
+  Vector<dim,spacedim>::Vector (const FEValuesBase<dim,spacedim> &fe_values,
                       const unsigned int       first_vector_component)
                  :
                  fe_values (fe_values),
@@ -3385,16 +3428,17 @@ namespace FEValuesViews
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>  
   inline
-  typename Vector<dim>::value_type
-  Vector<dim>::value (const unsigned int shape_function,
+  typename Vector<dim,spacedim>::value_type
+  Vector<dim,spacedim>::value (const unsigned int shape_function,
                      const unsigned int q_point) const
   {
+    typedef FEValuesBase<dim,spacedim> FVB;
     Assert (shape_function < fe_values.fe->dofs_per_cell,
            ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
     Assert (fe_values.update_flags & update_values,
-           typename FEValuesBase<dim>::ExcAccessToUninitializedField());    
+           typename FVB::ExcAccessToUninitializedField());    
 
                                     // compared to the scalar case above, we
                                     // can save some work here because we
@@ -3449,18 +3493,20 @@ namespace FEValuesViews
 
   
 
-  template <int dim>
+  template <int dim, int spacedim>  
   inline
-  typename Vector<dim>::gradient_type
-  Vector<dim>::gradient (const unsigned int shape_function,
+  typename Vector<dim,spacedim>::gradient_type
+  Vector<dim,spacedim>::gradient (const unsigned int shape_function,
                         const unsigned int q_point) const
   {
-                                    // this function works like in the case
-                                    // above    
+                                    // this function works like in
+                                    // the case above
+                               
+    typedef FEValuesBase<dim,spacedim> FVB;    
     Assert (shape_function < fe_values.fe->dofs_per_cell,
            ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
     Assert (fe_values.update_flags & update_gradients,
-           typename FEValuesBase<dim>::ExcAccessToUninitializedField());    
+           typename FVB::ExcAccessToUninitializedField());    
 
     gradient_type return_value;
     
@@ -3506,18 +3552,20 @@ namespace FEValuesViews
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>  
   inline
-  typename Vector<dim>::divergence_type
-  Vector<dim>::divergence (const unsigned int shape_function,
+  typename Vector<dim,spacedim>::divergence_type
+  Vector<dim,spacedim>::divergence (const unsigned int shape_function,
                           const unsigned int q_point) const
   {
-                                    // this function works like in the case
-                                    // above    
+                                    // this function works like in
+                                    // the case above
+                               
+    typedef FEValuesBase<dim,spacedim> FVB; 
     Assert (shape_function < fe_values.fe->dofs_per_cell,
            ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
     Assert (fe_values.update_flags & update_gradients,
-           typename FEValuesBase<dim>::ExcAccessToUninitializedField());    
+           typename FVB::ExcAccessToUninitializedField());    
 
     if (fe_values.fe->is_primitive() ||
        fe_values.fe->is_primitive(shape_function))
@@ -3565,18 +3613,19 @@ namespace FEValuesViews
   
 
 
-  template <int dim>
+  template <int dim, int spacedim>  
   inline
-  typename Vector<dim>::hessian_type
-  Vector<dim>::hessian (const unsigned int shape_function,
+  typename Vector<dim,spacedim>::hessian_type
+  Vector<dim,spacedim>::hessian (const unsigned int shape_function,
                        const unsigned int q_point) const
   {
-                                    // this function works like in the case
-                                    // above    
+                                    // this function works like in
+                                    // the case above                          
+    typedef FEValuesBase<dim,spacedim> FVB;    
     Assert (shape_function < fe_values.fe->dofs_per_cell,
            ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
     Assert (fe_values.update_flags & update_hessians,
-           typename FEValuesBase<dim>::ExcAccessToUninitializedField());    
+           typename FVB::ExcAccessToUninitializedField());    
 
     hessian_type return_value;
     
@@ -3871,33 +3920,33 @@ namespace FEValuesViews
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-FEValuesViews::Scalar<dim>
-FEValuesBase<dim>::
+FEValuesViews::Scalar<dim,spacedim>
+FEValuesBase<dim,spacedim>::
 operator[] (const FEValuesExtractors::Scalar &scalar) const
 {
-  return FEValuesViews::Scalar<dim> (*this, scalar.component);
+  return FEValuesViews::Scalar<dim,spacedim> (*this, scalar.component);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-FEValuesViews::Vector<dim>
-FEValuesBase<dim>::
+FEValuesViews::Vector<dim,spacedim>
+FEValuesBase<dim,spacedim>::
 operator[] (const FEValuesExtractors::Vector &vector) const
 {
   return
-    FEValuesViews::Vector<dim> (*this, vector.first_vector_component);
+    FEValuesViews::Vector<dim,spacedim> (*this, vector.first_vector_component);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 double
-FEValuesBase<dim>::shape_value (const unsigned int i,
+FEValuesBase<dim,spacedim>::shape_value (const unsigned int i,
                                const unsigned int j) const
 {
   Assert (i < fe->dofs_per_cell,
@@ -3926,10 +3975,10 @@ FEValuesBase<dim>::shape_value (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 double
-FEValuesBase<dim>::shape_value_component (const unsigned int i,
+FEValuesBase<dim,spacedim>::shape_value_component (const unsigned int i,
                                          const unsigned int j,
                                          const unsigned int component) const
 {
@@ -3990,10 +4039,10 @@ FEValuesBase<dim>::shape_value_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const Tensor<1,dim> &
-FEValuesBase<dim>::shape_grad (const unsigned int i,
+const Tensor<1,spacedim> &
+FEValuesBase<dim,spacedim>::shape_grad (const unsigned int i,
                               const unsigned int j) const
 {
   Assert (i < fe->dofs_per_cell,
@@ -4026,10 +4075,10 @@ FEValuesBase<dim>::shape_grad (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-Tensor<1,dim>
-FEValuesBase<dim>::shape_grad_component (const unsigned int i,
+Tensor<1,spacedim>
+FEValuesBase<dim,spacedim>::shape_grad_component (const unsigned int i,
                                         const unsigned int j,
                                         const unsigned int component) const
 {
@@ -4054,7 +4103,7 @@ FEValuesBase<dim>::shape_grad_component (const unsigned int i,
       if (component == fe->system_to_component_index(i).first)
        return this->shape_gradients[this->shape_function_to_row_table[i]][j];
       else
-       return Tensor<1,dim>();
+       return Tensor<1,spacedim>();
     }
   else
     {
@@ -4068,7 +4117,7 @@ FEValuesBase<dim>::shape_grad_component (const unsigned int i,
                                       // is non-zero at all within
                                       // this component:
       if (fe->get_nonzero_components(i)[component] == false)
-       return Tensor<1,dim>();
+       return Tensor<1,spacedim>();
 
                                       // count how many non-zero
                                       // component the shape function
@@ -4090,10 +4139,10 @@ FEValuesBase<dim>::shape_grad_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const Tensor<2,dim> &
-FEValuesBase<dim>::shape_hessian (const unsigned int i,
+const Tensor<2,spacedim> &
+FEValuesBase<dim,spacedim>::shape_hessian (const unsigned int i,
                                  const unsigned int j) const
 {
   Assert (i < fe->dofs_per_cell,
@@ -4126,10 +4175,10 @@ FEValuesBase<dim>::shape_hessian (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const Tensor<2,dim> &
-FEValuesBase<dim>::shape_2nd_derivative (const unsigned int i,
+const Tensor<2,spacedim> &
+FEValuesBase<dim,spacedim>::shape_2nd_derivative (const unsigned int i,
                                         const unsigned int j) const
 {
   return shape_hessian(i,j);
@@ -4137,10 +4186,10 @@ FEValuesBase<dim>::shape_2nd_derivative (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-Tensor<2,dim>
-FEValuesBase<dim>::shape_hessian_component (const unsigned int i,
+Tensor<2,spacedim>
+FEValuesBase<dim,spacedim>::shape_hessian_component (const unsigned int i,
                                            const unsigned int j,
                                            const unsigned int component) const
 {
@@ -4165,7 +4214,7 @@ FEValuesBase<dim>::shape_hessian_component (const unsigned int i,
       if (component == fe->system_to_component_index(i).first)
        return this->shape_hessians[this->shape_function_to_row_table[i]][j];
       else
-       return Tensor<2,dim>();
+       return Tensor<2,spacedim>();
     }
   else
     {
@@ -4179,7 +4228,7 @@ FEValuesBase<dim>::shape_hessian_component (const unsigned int i,
                                       // is non-zero at all within
                                       // this component:
       if (fe->get_nonzero_components(i)[component] == false)
-       return Tensor<2,dim>();
+       return Tensor<2,spacedim>();
 
                                       // count how many non-zero
                                       // component the shape function
@@ -4201,10 +4250,10 @@ FEValuesBase<dim>::shape_hessian_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-Tensor<2,dim>
-FEValuesBase<dim>::shape_2nd_derivative_component (const unsigned int i,
+Tensor<2,spacedim>
+FEValuesBase<dim,spacedim>::shape_2nd_derivative_component (const unsigned int i,
                                                   const unsigned int j,
                                                   const unsigned int component) const
 {
@@ -4213,38 +4262,38 @@ FEValuesBase<dim>::shape_2nd_derivative_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const FiniteElement<dim> & 
-FEValuesBase<dim>::get_fe () const
+const FiniteElement<dim,spacedim> & 
+FEValuesBase<dim,spacedim>::get_fe () const
 {
   return *fe;
 }
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const Mapping<dim> & 
-FEValuesBase<dim>::get_mapping () const
+const Mapping<dim,spacedim> & 
+FEValuesBase<dim,spacedim>::get_mapping () const
 {
   return *mapping;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const typename Triangulation<dim>::cell_iterator
-FEValuesBase<dim>::get_cell () const
+const typename Triangulation<dim,spacedim>::cell_iterator
+FEValuesBase<dim,spacedim>::get_cell () const
 {
   return *present_cell;
 }
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const std::vector<Point<dim> > &
-FEValuesBase<dim>::get_quadrature_points () const
+const std::vector<Point<spacedim> > &
+FEValuesBase<dim,spacedim>::get_quadrature_points () const
 {
   Assert (this->update_flags & update_quadrature_points, ExcAccessToUninitializedField());
   return this->quadrature_points;
@@ -4252,10 +4301,10 @@ FEValuesBase<dim>::get_quadrature_points () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 const std::vector<double> &
-FEValuesBase<dim>::get_JxW_values () const
+FEValuesBase<dim,spacedim>::get_JxW_values () const
 {
   Assert (this->update_flags & update_JxW_values, ExcAccessToUninitializedField());
   return this->JxW_values;
@@ -4263,10 +4312,10 @@ FEValuesBase<dim>::get_JxW_values () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const std::vector<Tensor<2,dim> >&
-FEValuesBase<dim>::get_jacobians () const
+const std::vector<Tensor<2,spacedim> >&
+FEValuesBase<dim,spacedim>::get_jacobians () const
 {
   Assert (this->update_flags & update_jacobians, ExcAccessToUninitializedField());
   return this->jacobians;
@@ -4274,10 +4323,10 @@ FEValuesBase<dim>::get_jacobians () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const std::vector<Tensor<3,dim> >&
-FEValuesBase<dim>::get_jacobian_grads () const
+const std::vector<Tensor<3,spacedim> >&
+FEValuesBase<dim,spacedim>::get_jacobian_grads () const
 {
   Assert (this->update_flags & update_jacobian_grads, ExcAccessToUninitializedField());
   return this->jacobian_grads;
@@ -4285,10 +4334,10 @@ FEValuesBase<dim>::get_jacobian_grads () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const std::vector<Tensor<2,dim> >&
-FEValuesBase<dim>::get_inverse_jacobians () const
+const std::vector<Tensor<2,spacedim> >&
+FEValuesBase<dim,spacedim>::get_inverse_jacobians () const
 {
   Assert (this->update_flags & update_inverse_jacobians, ExcAccessToUninitializedField());
   return this->inverse_jacobians;
@@ -4296,10 +4345,9 @@ FEValuesBase<dim>::get_inverse_jacobians () const
 
 
 
-template <int dim>
-inline
-const Point<dim> &
-FEValuesBase<dim>::quadrature_point (const unsigned int i) const
+template <int dim, int spacedim>
+const Point<spacedim> &
+FEValuesBase<dim,spacedim>::quadrature_point (const unsigned int i) const
 {
   Assert (this->update_flags & update_quadrature_points, ExcAccessToUninitializedField());
   Assert (i<this->quadrature_points.size(), ExcIndexRange(i, 0, this->quadrature_points.size()));
@@ -4310,10 +4358,10 @@ FEValuesBase<dim>::quadrature_point (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 double
-FEValuesBase<dim>::JxW (const unsigned int i) const
+FEValuesBase<dim,spacedim>::JxW (const unsigned int i) const
 {
   Assert (this->update_flags & update_JxW_values, ExcAccessToUninitializedField());
   Assert (i<this->JxW_values.size(), ExcIndexRange(i, 0, this->JxW_values.size()));
@@ -4323,10 +4371,10 @@ FEValuesBase<dim>::JxW (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const Tensor<2,dim> &
-FEValuesBase<dim>::jacobian (const unsigned int i) const
+const Tensor<2,spacedim> &
+FEValuesBase<dim,spacedim>::jacobian (const unsigned int i) const
 {
   Assert (this->update_flags & update_jacobians, ExcAccessToUninitializedField());
   Assert (i<this->jacobians.size(), ExcIndexRange(i, 0, this->jacobians.size()));
@@ -4336,10 +4384,10 @@ FEValuesBase<dim>::jacobian (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const Tensor<3,dim> &
-FEValuesBase<dim>::jacobian_grad (const unsigned int i) const
+const Tensor<3,spacedim> &
+FEValuesBase<dim,spacedim>::jacobian_grad (const unsigned int i) const
 {
   Assert (this->update_flags & update_jacobian_grads, ExcAccessToUninitializedField());
   Assert (i<this->jacobian_grads.size(), ExcIndexRange(i, 0, this->jacobian_grads.size()));
@@ -4349,10 +4397,10 @@ FEValuesBase<dim>::jacobian_grad (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const Tensor<2,dim> &
-FEValuesBase<dim>::inverse_jacobian (const unsigned int i) const
+const Tensor<2,spacedim> &
+FEValuesBase<dim,spacedim>::inverse_jacobian (const unsigned int i) const
 {
   Assert (this->update_flags & update_inverse_jacobians, ExcAccessToUninitializedField());
   Assert (i<this->inverse_jacobians.size(), ExcIndexRange(i, 0, this->inverse_jacobians.size()));
@@ -4362,53 +4410,53 @@ FEValuesBase<dim>::inverse_jacobian (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector>
 inline
 void
-FEValuesBase<dim>::get_function_grads (const InputVector           &fe_function,
-                                      std::vector<Tensor<1,dim> > &gradients) const
+FEValuesBase<dim,spacedim>::get_function_grads (const InputVector           &fe_function,
+                                      std::vector<Tensor<1,spacedim> > &gradients) const
 {
   get_function_gradients(fe_function, gradients);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 template <class InputVector>
 inline
 void
-FEValuesBase<dim>::get_function_grads (
+FEValuesBase<dim,spacedim>::get_function_grads (
   const InputVector& fe_function,
   const VectorSlice<const std::vector<unsigned int> >& indices,
-  std::vector<Tensor<1,dim> > &values) const
+  std::vector<Tensor<1,spacedim> > &values) const
 {
   get_function_gradients(fe_function, indices, values);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 template <class InputVector>
 inline
 void
-FEValuesBase<dim>::
+FEValuesBase<dim,spacedim>::
 get_function_grads (const InputVector                         &fe_function,
-                   std::vector<std::vector<Tensor<1,dim> > > &gradients) const
+                   std::vector<std::vector<Tensor<1,spacedim> > > &gradients) const
 {
   get_function_gradients(fe_function, gradients);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 template <class InputVector>
 inline
 void
-FEValuesBase<dim>::get_function_grads (
+FEValuesBase<dim,spacedim>::get_function_grads (
   const InputVector& fe_function,
   const VectorSlice<const std::vector<unsigned int> >& indices,
-  std::vector<std::vector<Tensor<1,dim> > >& values,
+  std::vector<std::vector<Tensor<1,spacedim> > >& values,
   bool q_points_fastest) const
 {
   get_function_gradients(fe_function, indices, values, q_points_fastest);
@@ -4416,26 +4464,26 @@ FEValuesBase<dim>::get_function_grads (
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 template <class InputVector>
 inline
 void
-FEValuesBase<dim>::
+FEValuesBase<dim,spacedim>::
 get_function_2nd_derivatives (const InputVector           &fe_function,
-                             std::vector<Tensor<2,dim> > &hessians) const
+                             std::vector<Tensor<2,spacedim> > &hessians) const
 {
   get_function_hessians(fe_function, hessians);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 template <class InputVector>
 inline
 void
-FEValuesBase<dim>::
+FEValuesBase<dim,spacedim>::
 get_function_2nd_derivatives (const InputVector                         &fe_function,
-                             std::vector<std::vector<Tensor<2,dim> > > &hessians,
+                             std::vector<std::vector<Tensor<2,spacedim> > > &hessians,
                              bool quadrature_points_fastest) const
 {
   get_function_hessians(fe_function, hessians, quadrature_points_fastest);
@@ -4443,23 +4491,40 @@ get_function_2nd_derivatives (const InputVector                         &fe_func
 
 
 
+template <int dim, int spacedim>  
+inline
+const Point<spacedim> &
+FEValuesBase<dim,spacedim>::cell_normal_vector (const unsigned int i) const
+{
+  typedef FEValuesBase<dim,spacedim> FVB;
+  Assert (i<this->cell_normal_vectors.size(),
+         ExcIndexRange(i, 0, this->cell_normal_vectors.size()));
+  Assert (this->update_flags & update_cell_normal_vectors,
+         typename FVB::ExcAccessToUninitializedField());
+  
+  return this->cell_normal_vectors[i];
+}
+
+
+
+
 /*------------------------ Inline functions: FEValues ----------------------------*/
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 const Quadrature<dim> &
-FEValues<dim>::get_quadrature () const 
+FEValues<dim,spacedim>::get_quadrature () const 
 {
   return quadrature;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const FEValues<dim> &
-FEValues<dim>::get_present_fe_values () const 
+const FEValues<dim,spacedim> &
+FEValues<dim,spacedim>::get_present_fe_values () const 
 {
   return *this;
 }
@@ -4468,24 +4533,25 @@ FEValues<dim>::get_present_fe_values () const
 /*------------------------ Inline functions: FEFaceValuesBase --------------------*/
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 const Point<dim> &
-FEFaceValuesBase<dim>::normal_vector (const unsigned int i) const
+FEFaceValuesBase<dim,spacedim>::normal_vector (const unsigned int i) const
 {
+  typedef FEValuesBase<dim,spacedim> FVB;
   Assert (i<this->normal_vectors.size(),
          ExcIndexRange(i, 0, this->normal_vectors.size()));
   Assert (this->update_flags & update_normal_vectors,
-         typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+         typename FVB::ExcAccessToUninitializedField());
   
   return this->normal_vectors[i];
 }
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 unsigned int
-FEFaceValuesBase<dim>::get_face_index () const
+FEFaceValuesBase<dim,spacedim>::get_face_index () const
 {
   return present_face_index;
 }
@@ -4493,45 +4559,46 @@ FEFaceValuesBase<dim>::get_face_index () const
 
 /*------------------------ Inline functions: FE*FaceValues --------------------*/
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
 const Quadrature<dim-1> &
-FEFaceValuesBase<dim>::get_quadrature () const 
+FEFaceValuesBase<dim,spacedim>::get_quadrature () const 
 {
   return quadrature;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const FEFaceValues<dim> &
-FEFaceValues<dim>::get_present_fe_values () const 
+const FEFaceValues<dim,spacedim> &
+FEFaceValues<dim,spacedim>::get_present_fe_values () const 
 {
   return *this;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const FESubfaceValues<dim> &
-FESubfaceValues<dim>::get_present_fe_values () const 
+const FESubfaceValues<dim,spacedim> &
+FESubfaceValues<dim,spacedim>::get_present_fe_values () const 
 {
   return *this;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 inline
-const Tensor<1,dim> &
-FEFaceValuesBase<dim>::boundary_form (const unsigned int i) const
+const Tensor<1,spacedim> &
+FEFaceValuesBase<dim,spacedim>::boundary_form (const unsigned int i) const
 {
+  typedef FEValuesBase<dim,spacedim> FVB;
   Assert (i<this->boundary_forms.size(),
          ExcIndexRange(i, 0, this->boundary_forms.size()));
   Assert (this->update_flags & update_boundary_forms,
-         typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+         typename FVB::ExcAccessToUninitializedField());
   
   return this->boundary_forms[i];
 }
index efc90904bfcab0fe8dc5d882296cb6c331cc3de9..6ce98fb94ab02ee6a6114f9f3307d159450619f8 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 template <int dim> class Quadrature;
-template <int dim> class FEValuesData;
-template <int dim> class FEValuesBase;
-template <int dim> class FEValues;
-template <int dim> class FEFaceValues;
-template <int dim> class FESubfaceValues;
+template <int dim, int spacedim> class FEValuesData;
+template <int dim, int spacedim> class FEValuesBase;
+template <int dim, int spacedim> class FEValues;
+template <int dim, int spacedim> class FEFaceValues;
+template <int dim, int spacedim> class FESubfaceValues;
 
 //TODO: Offset in transform functions should be replaced by initializing VectorSlice correctly
 
@@ -54,11 +54,15 @@ template <int dim> class FESubfaceValues;
  *
  * A hint to implementators: no function except the two functions
  * @p update_once and @p update_each may add any flags.
+ * 
+ * For more information about the <tt>spacedim</tt> template parameter
+ * check the documentation of FiniteElement or the one of
+ * Triangulation.
  *
  * @ingroup mapping
  * @author Guido Kanschat, Ralf Hartmann 2000, 2001
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 class Mapping : public Subscriptor
 {
   public:
@@ -74,9 +78,9 @@ class Mapping : public Subscriptor
                                      * @p p_real on the real cell
                                      * @p cell and returns @p p_real.
                                      */
-    virtual Point<dim>
+    virtual Point<spacedim>
     transform_unit_to_real_cell (
-      const typename Triangulation<dim>::cell_iterator &cell,
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
       const Point<dim>                                 &p) const = 0;
     
                                     /**
@@ -87,8 +91,8 @@ class Mapping : public Subscriptor
                                      */
     virtual Point<dim>
     transform_real_to_unit_cell (
-      const typename Triangulation<dim>::cell_iterator &cell,
-      const Point<dim>                                 &p) const = 0;
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+      const Point<spacedim>                            &p) const = 0;
     
                                     /**
                                      * Base class for internal data
@@ -224,7 +228,7 @@ class Mapping : public Subscriptor
                                          * mapped (generalized)
                                          * support points.
                                          */
-       std::vector<Point<dim> > support_point_values;
+       std::vector<Point<spacedim> > support_point_values;
        
                                         /*
                                          * The Jacobian of the
@@ -232,7 +236,7 @@ class Mapping : public Subscriptor
                                          * (generalized) support
                                          * points.
                                          */
-       std::vector<Tensor<2,dim> > support_point_gradients;
+       std::vector<Tensor<2,spacedim> > support_point_gradients;
        
                                         /*
                                          * The inverse of the
@@ -241,7 +245,7 @@ class Mapping : public Subscriptor
                                          * (generalized) support
                                          * points.
                                          */
-       std::vector<Tensor<2,dim> > support_point_inverse_gradients;
+       std::vector<Tensor<2,spacedim> > support_point_inverse_gradients;
        
        
       private:
@@ -263,7 +267,7 @@ class Mapping : public Subscriptor
                                      * cell. Alternatively, this is
                                      * equivalent to a multiplication
                                      * from the left with the
-                                     * transpose if the inverse
+                                     * transpose of the inverse
                                      * matrix.
                                      *
                                      * The list of arguments is as follows:
@@ -282,7 +286,7 @@ class Mapping : public Subscriptor
     void
     transform_covariant (const VectorSlice<const std::vector<Tensor<1,dim> > > input,
                          const unsigned int                                    offset,
-                         VectorSlice<std::vector<Tensor<1,dim> > >             output,
+                         VectorSlice<std::vector<Tensor<1,spacedim> > >        output,
                         const InternalDataBase &internal) const = 0;
 
                                      /**
@@ -301,7 +305,7 @@ class Mapping : public Subscriptor
     void
     transform_covariant (const VectorSlice<const std::vector<Tensor<2,dim> > > input,
                          const unsigned int                 offset,
-                        VectorSlice<std::vector<Tensor<2,dim> > >      output,
+                        VectorSlice<std::vector<Tensor<2,spacedim> > >      output,
                         const InternalDataBase &internal) const = 0;
     
                                     /**
@@ -327,10 +331,10 @@ class Mapping : public Subscriptor
                                      */
     virtual
     void
-    transform_contravariant (const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+    transform_contravariant (const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
                              const unsigned int                 offset,
-                            VectorSlice<std::vector<Tensor<1,dim> > >      output,
-                            const typename Mapping<dim>::InternalDataBase &internal) const = 0;
+                            VectorSlice<std::vector<Tensor<1,spacedim> > >      output,
+                            const typename Mapping<dim,spacedim>::InternalDataBase &internal) const = 0;
 
                                      /**
                                       * Transform a set of matrices
@@ -353,18 +357,18 @@ class Mapping : public Subscriptor
                                       */
     
     virtual void
-    transform_contravariant (const VectorSlice<const std::vector<Tensor<2,dim> > > intput,
+    transform_contravariant (const VectorSlice<const std::vector<Tensor<2,spacedim> > > intput,
                              const unsigned int                 offset,
-                            const VectorSlice<std::vector<Tensor<2,dim> > > output,
-                            const typename Mapping<dim>::InternalDataBase &internal) const = 0;
+                            const VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+                            const typename Mapping<dim,spacedim>::InternalDataBase &internal) const = 0;
 
                                     /**
                                      * The transformed (generalized)
                                      * support point.
                                      */
-    const Point<dim>& support_point_value(
+    const Point<spacedim>& support_point_value(
       const unsigned int index,
-      const typename Mapping<dim>::InternalDataBase &internal) const;
+      const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;
     
                                     /**
                                      * The Jacobian
@@ -372,9 +376,9 @@ class Mapping : public Subscriptor
                                      * in the (generalized) support
                                      * point.
                                      */
-    const Tensor<2,dim>& support_point_gradient(
+    const Tensor<2,spacedim>& support_point_gradient(
       const unsigned int index,
-      const typename Mapping<dim>::InternalDataBase &internal) const;
+      const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;
     
                                     /**
                                      * The inverse Jacobian
@@ -382,9 +386,9 @@ class Mapping : public Subscriptor
                                      * in the (generalized) support
                                      * point.
                                      */
-    const Tensor<2,dim>& support_point_inverse_gradient(
+    const Tensor<2,spacedim>& support_point_inverse_gradient(
       const unsigned int index,
-      const typename Mapping<dim>::InternalDataBase &internal) const;
+      const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;
     
                                      /**
                                       * Return a pointer to a copy of the
@@ -400,7 +404,7 @@ class Mapping : public Subscriptor
                                       * hp::MappingCollection class.
                                       */
     virtual
-    Mapping<dim> * clone () const = 0;
+    Mapping<dim,spacedim> * clone () const = 0;
     
                                     /**
                                      * Exception
@@ -490,15 +494,31 @@ class Mapping : public Subscriptor
                                      * and the inverse operations in
                                      * @p inverse_jacobians.
                                      */
+/*     virtual void */
+/*     fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell, */
+/*                 const Quadrature<dim>                         &quadrature, */
+/*                 InternalDataBase                              &internal, */
+/*                 std::vector<Point<spacedim> >                 &quadrature_points, */
+/*                 std::vector<double>                           &JxW_values) const = 0; */
+
+                                      /** The function above adjusted
+                                      * with the variable
+                                      * cell_normal_vectors for the
+                                      * case of codimension 1
+                                      */
     virtual void
-    fill_fe_values (const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                    const Quadrature<dim>                         &quadrature,
                    InternalDataBase                              &internal,
-                   std::vector<Point<dim> >                      &quadrature_points,
+                   std::vector<Point<spacedim> >                 &quadrature_points,
                    std::vector<double>                           &JxW_values,
-                   std::vector<Tensor<2,dim> >                   &jacobians,
-                   std::vector<Tensor<3,dim> >                   &jacobian_grads,
-                   std::vector<Tensor<2,dim> >                   &inverse_jacobians) const = 0;
+                   std::vector<Tensor<2,spacedim> >              &jacobians,
+                   std::vector<Tensor<3,spacedim> >              &jacobian_grads,
+                   std::vector<Tensor<2,spacedim> >              &inverse_jacobians,
+                   std::vector<Point<spacedim> >                 &cell_normal_vectors
+                  ) const=0;
+
+
 
                                     /**
                                      * Performs the same as @p fill_fe_values
@@ -522,21 +542,21 @@ class Mapping : public Subscriptor
                                      * transformed quadrature weight.
                                      */
     virtual void
-    fill_fe_face_values (const typename Triangulation<dim>::cell_iterator &cell,
-                        const unsigned int                        face_no,
-                        const Quadrature<dim-1>                  &quadrature,
-                        InternalDataBase                         &internal,
-                        std::vector<Point<dim> >        &quadrature_points,
-                        std::vector<double>                      &JxW_values,
-                        std::vector<Tensor<1,dim> >     &boundary_form,
-                        std::vector<Point<dim> >        &normal_vectors,
-                        std::vector<double>             &cell_JxW_values) const = 0;
+    fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                        const unsigned int                                        face_no,
+                        const Quadrature<dim-1>                                   &quadrature,
+                        InternalDataBase                                          &internal,
+                        std::vector<Point<dim> >                                  &quadrature_points,
+                        std::vector<double>                                       &JxW_values,
+                        std::vector<Tensor<1,dim> >                               &boundary_form,
+                        std::vector<Point<spacedim> >                             &normal_vectors,
+                        std::vector<double>                                       &cell_JxW_values) const = 0;
 
                                     /**
                                      * See above.
                                      */
     virtual void
-    fill_fe_subface_values (const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int                        face_no,
                            const unsigned int                        sub_no,
                            const Quadrature<dim-1>                  &quadrature,
@@ -544,7 +564,7 @@ class Mapping : public Subscriptor
                            std::vector<Point<dim> >        &quadrature_points,
                            std::vector<double>                      &JxW_values,
                            std::vector<Tensor<1,dim> >     &boundary_form,
-                           std::vector<Point<dim> >        &normal_vectors,
+                           std::vector<Point<spacedim> >        &normal_vectors,
                            std::vector<double>             &cell_JxW_values) const = 0;
 
                                     /**
@@ -553,20 +573,20 @@ class Mapping : public Subscriptor
                                      * and <tt>fill_fe_...values</tt>
                                      * functions.
                                      */
-  friend class FEValuesBase<dim>;
-  friend class FEValues<dim>;
-  friend class FEFaceValues<dim>;
-  friend class FESubfaceValues<dim>;
+  friend class FEValuesBase<dim,spacedim>;
+  friend class FEValues<dim,spacedim>;
+  friend class FEFaceValues<dim,spacedim>;
+  friend class FESubfaceValues<dim,spacedim>;
 };
 
 
 /* ------------------------- inline functions ------------------------- */
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 UpdateFlags
-Mapping<dim>::InternalDataBase::current_update_flags () const
+Mapping<dim,spacedim>::InternalDataBase::current_update_flags () const
 {
   if (first_cell)
     {
@@ -580,56 +600,56 @@ Mapping<dim>::InternalDataBase::current_update_flags () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 bool
-Mapping<dim>::InternalDataBase::is_first_cell () const
+Mapping<dim,spacedim>::InternalDataBase::is_first_cell () const
 {
   return first_cell;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 void
-Mapping<dim>::InternalDataBase::clear_first_cell ()
+Mapping<dim,spacedim>::InternalDataBase::clear_first_cell ()
 {
   first_cell = false;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const Point<dim>&
-Mapping<dim>::support_point_value(
+const Point<spacedim>&
+Mapping<dim,spacedim>::support_point_value(
   const unsigned int index,
-  const typename Mapping<dim>::InternalDataBase& internal) const
+  const typename Mapping<dim,spacedim>::InternalDataBase& internal) const
 {
   AssertIndexRange(index, internal.support_point_values.size());
   return internal.support_point_values[index];  
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const Tensor<2,dim>&
-Mapping<dim>::support_point_gradient(
+const Tensor<2,spacedim>&
+Mapping<dim,spacedim>::support_point_gradient(
   const unsigned int index,
-  const typename Mapping<dim>::InternalDataBase& internal) const
+  const typename Mapping<dim,spacedim>::InternalDataBase& internal) const
 {
   AssertIndexRange(index, internal.support_point_gradients.size());
   return internal.support_point_gradients[index];
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const Tensor<2,dim>&
-Mapping<dim>::support_point_inverse_gradient(
+const Tensor<2,spacedim>&
+Mapping<dim,spacedim>::support_point_inverse_gradient(
   const unsigned int index,
-  const typename Mapping<dim>::InternalDataBase& internal) const
+  const typename Mapping<dim,spacedim>::InternalDataBase& internal) const
 {
   AssertIndexRange(index, internal.support_point_inverse_gradients.size());
   return internal.support_point_inverse_gradients[index];
index e0cb99d4c65dddf7d074d5e4473a3080e76eca02..fe1eb1bf7a2ada63f2b8f9ed8d2b0b689996e97d 100644 (file)
@@ -34,11 +34,15 @@ DEAL_II_NAMESPACE_OPEN
  * To use this class, make sure that the
  * Boundary::@p get_normals_at_vertices function is implemented
  * for the users boundary object.
+ * 
+ * For more information about the <tt>spacedim</tt> template parameter
+ * check the documentation of FiniteElement or the one of
+ * Triangulation.
  *
  * @author Wolfgang Bangerth, 2001
  */
-template <int dim>
-class MappingC1 : public MappingQ<dim>
+template<int dim, int spacedim=dim>
+class MappingC1 : public MappingQ<dim,spacedim>
 {
   public:
                                     /**
@@ -57,7 +61,7 @@ class MappingC1 : public MappingQ<dim>
                                       * copy then assumes ownership of it.
                                       */
     virtual
-    Mapping<dim> * clone () const;
+    Mapping<dim,spacedim> * clone () const;
 
   protected:
                                     /**
index 2ef9a7d79ff68437644d57760637d8589988e4f8..6656512626e2b4e420f91f3ff44ad843ba55912c 100644 (file)
@@ -32,87 +32,94 @@ DEAL_II_NAMESPACE_OPEN
  * along the coordinate directions. It is specifically developed for
  * cartesian meshes. Apply this mapping to a general mesh to get
  * strange results.
+ * 
+ * For more information about the <tt>spacedim</tt> template parameter
+ * check the documentation of FiniteElement or the one of
+ * Triangulation.
  *
  * @author Guido Kanschat, 2001; Ralf Hartmann, 2005
  */
-template <int dim>
-class MappingCartesian : public Mapping<dim>
+template <int dim, int spacedim=dim>
+class MappingCartesian : public Mapping<dim,spacedim>
 {
   public:
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim, spacedim>::InternalDataBase *
     get_data (const UpdateFlags,
              const Quadrature<dim>& quadrature) const;
 
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim, spacedim>::InternalDataBase *
     get_face_data (const UpdateFlags flags,
                   const Quadrature<dim-1>& quadrature) const;
 
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim, spacedim>::InternalDataBase *
     get_subface_data (const UpdateFlags flags,
                      const Quadrature<dim-1>& quadrature) const;
 
     virtual void
-    fill_fe_values (const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                    const Quadrature<dim>& quadrature,
-                   typename Mapping<dim>::InternalDataBase &mapping_data,
-                   std::vector<Point<dim> >        &quadrature_points,
-                   std::vector<double>             &JxW_values,
-                   std::vector<Tensor<2,dim> >     &jacobians,
-                   std::vector<Tensor<3,dim> >     &jacobian_grads,
-                   std::vector<Tensor<2,dim> >     &inverse_jacobians) const ;
+                   typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
+                   std::vector<Point<spacedim> >                     &quadrature_points,
+                   std::vector<double>                               &JxW_values,
+                   std::vector<Tensor<2,spacedim> >                  &jacobians,
+                   std::vector<Tensor<3,spacedim> >                  &jacobian_grads,
+                   std::vector<Tensor<2,spacedim> >                  &inverse_jacobians,
+                   std::vector<Point<spacedim> >   &) const ;
+
 
     virtual void
-    fill_fe_face_values (const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                         const unsigned int face_no,
                         const Quadrature<dim-1>& quadrature,
-                        typename Mapping<dim>::InternalDataBase &mapping_data,
+                        typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
                         std::vector<Point<dim> >        &quadrature_points,
                         std::vector<double>             &JxW_values,
                         std::vector<Tensor<1,dim> >        &boundary_form,
                         std::vector<Point<dim> >        &normal_vectors,
                         std::vector<double>             &cell_JxW_values) const ;
     virtual void
-    fill_fe_subface_values (const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int face_no,
                            const unsigned int sub_no,
                            const Quadrature<dim-1>& quadrature,
-                           typename Mapping<dim>::InternalDataBase &mapping_data,
+                           typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
                            std::vector<Point<dim> >        &quadrature_points,
                            std::vector<double>             &JxW_values,
                            std::vector<Tensor<1,dim> >        &boundary_form,
                            std::vector<Point<dim> >        &normal_vectors,
                            std::vector<double>             &cell_JxW_values) const ;
 
+
     virtual void
-    transform_covariant (const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+    transform_covariant (const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
                          const unsigned int                 offset,
-                        VectorSlice<std::vector<Tensor<1,dim> > > output,
-                        const typename Mapping<dim>::InternalDataBase &internal) const;
+                        VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+                        const typename Mapping<dim, spacedim>::InternalDataBase &internal) const;
     
     virtual void
-    transform_covariant (const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+    transform_covariant (const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
                          const unsigned int                 offset,
-                        VectorSlice<std::vector<Tensor<2,dim> > > output,
-                        const typename Mapping<dim>::InternalDataBase &internal) const;
+                        VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+                        const typename Mapping<dim, spacedim>::InternalDataBase &internal) const;
     
     virtual void
-    transform_contravariant (const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+    transform_contravariant (const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
                              const unsigned int                 offset,
-                            VectorSlice<std::vector<Tensor<1,dim> > > output,
-                            const typename Mapping<dim>::InternalDataBase &internal) const;
+                            VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+                            const typename Mapping<dim, spacedim>::InternalDataBase &internal) const;
     
     virtual void
-    transform_contravariant (const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+    transform_contravariant (const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
                              const unsigned int                 offset,
-                            VectorSlice<std::vector<Tensor<2,dim> > > output,
-                            const typename Mapping<dim>::InternalDataBase &internal) const;
+                            VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+                            const typename Mapping<dim, spacedim>::InternalDataBase &internal) const;
 
-    virtual Point<dim>
+    virtual Point<spacedim>
     transform_unit_to_real_cell (
-      const typename Triangulation<dim>::cell_iterator &cell,
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
       const Point<dim>                                 &p) const;
 
                                     /**
@@ -127,8 +134,8 @@ class MappingCartesian : public Mapping<dim>
                                      */
     virtual Point<dim>
     transform_real_to_unit_cell (
-      const typename Triangulation<dim>::cell_iterator &cell,
-      const Point<dim>                                 &p) const;
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+      const Point<spacedim>                            &p) const;
     
 
                                      /**
@@ -137,14 +144,14 @@ class MappingCartesian : public Mapping<dim>
                                       * copy then assumes ownership of it.
                                       */
     virtual
-    Mapping<dim> * clone () const;
+    Mapping<dim, spacedim> * clone () const;
     
   protected:
                                     /** 
                                      * Storage for internal data of
                                      * the scaling.
                                      */
-    class InternalData : public Mapping<dim>::InternalDataBase
+    class InternalData : public Mapping<dim, spacedim>::InternalDataBase
     {
       public:
                                         /**
@@ -180,7 +187,7 @@ class MappingCartesian : public Mapping<dim>
                                      * Do the computation for the
                                      * <tt>fill_*</tt> functions.
                                      */
-    void compute_fill (const typename Triangulation<dim>::cell_iterator &cell,
+    void compute_fill (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                       const unsigned int face_no,
                       const unsigned int sub_no,
                       InternalData& data,
index 53b3290ba643c00a1e210a92496d1a3420b5ac5b..c9caead15715da7eec64ff792f4fb41d5e739f91 100644 (file)
@@ -35,11 +35,15 @@ template <int dim> class TensorProductPolynomials;
  * For more details about Qp-mappings, see the `mapping' report at
  * <tt>deal.II/doc/reports/mapping_q/index.html</tt> in the `Reports'
  * section of `Documentation'.
+ * 
+ * For more information about the <tt>spacedim</tt> template parameter
+ * check the documentation of FiniteElement or the one of
+ * Triangulation.
  *
  * @author Ralf Hartmann, 2000, 2001, 2005; Guido Kanschat 2000, 2001
  */
-template <int dim>
-class MappingQ : public MappingQ1<dim>
+template <int dim, int spacedim=dim>
+class MappingQ : public MappingQ1<dim,spacedim>
 {
   public:
                                     /**
@@ -79,7 +83,7 @@ class MappingQ : public MappingQ1<dim>
                                      * #tensor_pols pointer as done
                                      * by a default copy constructor.
                                      */
-    MappingQ (const MappingQ<dim> &mapping);
+    MappingQ (const MappingQ<dim,spacedim> &mapping);
 
                                     /**
                                      * Destructor.
@@ -92,9 +96,9 @@ class MappingQ : public MappingQ1<dim>
                                      * @p p_real on the real cell
                                      * @p cell and returns @p p_real.
                                      */
-    virtual Point<dim>
+    virtual Point<spacedim>
     transform_unit_to_real_cell (
-      const typename Triangulation<dim>::cell_iterator &cell,
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
       const Point<dim>                                 &p) const;
     
                                     /**
@@ -109,48 +113,48 @@ class MappingQ : public MappingQ1<dim>
                                      */
     virtual Point<dim>
     transform_real_to_unit_cell (
-      const typename Triangulation<dim>::cell_iterator &cell,
-      const Point<dim>                                 &p) const;
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+      const Point<spacedim>                            &p) const;
 
                                     /**
                                      * Implementation of the
                                      * interface in Mapping.
                                      */
     virtual void
-    transform_covariant (const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+    transform_covariant (const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
                          const unsigned int                 offset,
-                        VectorSlice<std::vector<Tensor<1,dim> > > output,
-                        const typename Mapping<dim>::InternalDataBase &internal) const;
+                        VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+                        const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;
     
                                     /**
                                      * Implementation of the
                                      * interface in Mapping.
                                      */
     virtual void
-    transform_covariant (const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+    transform_covariant (const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
                          const unsigned int                 offset,
-                        VectorSlice<std::vector<Tensor<2,dim> > > output,
-                        const typename Mapping<dim>::InternalDataBase &internal) const;
+                        VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+                        const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;
     
                                     /**
                                      * Implementation of the
                                      * interface in Mapping.
                                      */
     virtual void
-    transform_contravariant (const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+    transform_contravariant (const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
                              const unsigned int                 offset,
-                            VectorSlice<std::vector<Tensor<1,dim> > > output,
-                            const typename Mapping<dim>::InternalDataBase &internal) const;    
+                            VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+                            const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;    
 
                                     /**
                                      * Implementation of the
                                      * interface in Mapping.
                                      */
     virtual void
-    transform_contravariant (const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+    transform_contravariant (const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
                              const unsigned int                 offset,
-                            VectorSlice<std::vector<Tensor<2,dim> > > output,
-                            const typename Mapping<dim>::InternalDataBase &internal) const;    
+                            VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+                            const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;    
     
                                     /**
                                      * Return the degree of the
@@ -165,13 +169,13 @@ class MappingQ : public MappingQ1<dim>
                                       * copy then assumes ownership of it.
                                       */
     virtual
-    Mapping<dim> * clone () const;
+    Mapping<dim,spacedim> * clone () const;
     
                                     /** 
                                      * Storage for internal data of
                                      * Q_degree transformation.
                                      */
-    class InternalData : public MappingQ1<dim>::InternalData
+    class InternalData : public MappingQ1<dim,spacedim>::InternalData
     {
       public:
                                         /**
@@ -218,7 +222,7 @@ class MappingQ : public MappingQ1<dim>
                                          * On interior cells
                                          * @p MappingQ1 is used.
                                          */
-       typename MappingQ1<dim>::InternalData mapping_q1_data;
+       typename MappingQ1<dim,spacedim>::InternalData mapping_q1_data;
     };
 
   protected:
@@ -227,24 +231,25 @@ class MappingQ : public MappingQ1<dim>
                                      * Mapping.
                                      */
     virtual void
-    fill_fe_values (const typename Triangulation<dim>::cell_iterator &cell,
-                   const Quadrature<dim>                &quadrature,
-                   typename Mapping<dim>::InternalDataBase &mapping_data,
-                   typename std::vector<Point<dim> >             &quadrature_points,
-                   std::vector<double>                  &JxW_values,
-                   std::vector<Tensor<2,dim> >          &jacobians,
-                   std::vector<Tensor<3,dim> >          &jacobian_grads,
-                   std::vector<Tensor<2,dim> >          &inverse_jacobians) const ;
+    fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                   const Quadrature<dim>                                     &quadrature,
+                   typename Mapping<dim,spacedim>::InternalDataBase          &mapping_data,
+                   typename std::vector<Point<spacedim> >                    &quadrature_points,
+                   std::vector<double>                                       &JxW_values,
+                   std::vector<Tensor<2,spacedim> >                          &jacobians,
+                   std::vector<Tensor<3,spacedim> >                          &jacobian_grads,
+                   std::vector<Tensor<2,spacedim> >                          &inverse_jacobians,
+                    std::vector<Point<spacedim> >                             &cell_normal_vectors) const ;
 
                                     /**
                                      * Implementation of the interface in
                                      * Mapping.
                                      */
     virtual void
-    fill_fe_face_values (const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                         const unsigned int face_no,
                         const Quadrature<dim-1>& quadrature,
-                        typename Mapping<dim>::InternalDataBase &mapping_data,
+                        typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
                         typename std::vector<Point<dim> >        &quadrature_points,
                         std::vector<double>             &JxW_values,
                         typename std::vector<Tensor<1,dim> >        &exterior_form,
@@ -256,11 +261,11 @@ class MappingQ : public MappingQ1<dim>
                                      * Mapping.
                                      */
     virtual void
-    fill_fe_subface_values (const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int face_no,
                            const unsigned int sub_no,
                            const Quadrature<dim-1>& quadrature,
-                           typename Mapping<dim>::InternalDataBase &mapping_data,
+                           typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
                            typename std::vector<Point<dim> >        &quadrature_points,
                            std::vector<double>             &JxW_values,
                            typename std::vector<Tensor<1,dim> >        &exterior_form,
@@ -291,7 +296,7 @@ class MappingQ : public MappingQ1<dim>
                                      * on the boundary.
                                      */
     virtual void
-    add_line_support_points (const typename Triangulation<dim>::cell_iterator &cell,
+    add_line_support_points (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                             std::vector<Point<dim> > &a) const;
 
                                     /**
@@ -319,23 +324,23 @@ class MappingQ : public MappingQ1<dim>
                                      * on the boundary.
                                      */
     virtual void
-    add_quad_support_points(const typename Triangulation<dim>::cell_iterator &cell,
+    add_quad_support_points(const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            std::vector<Point<dim> > &a) const;
     
   private:
     
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_data (const UpdateFlags,
              const Quadrature<dim>& quadrature) const;
 
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_face_data (const UpdateFlags flags,
                   const Quadrature<dim-1>& quadrature) const;
 
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_subface_data (const UpdateFlags flags,
                      const Quadrature<dim-1>& quadrature) const;
     
@@ -345,11 +350,11 @@ class MappingQ : public MappingQ1<dim>
                                      */
     virtual void
     compute_shapes_virtual (const std::vector<Point<dim> > &unit_points,
-                           typename MappingQ1<dim>::InternalData &data) const;
+                           typename MappingQ1<dim,spacedim>::InternalData &data) const;
 
                                     /**
                                      * This function is needed by the
-                                     * constructor of <tt>MappingQ<dim></tt>
+                                     * constructor of <tt>MappingQ<dim,spacedim></tt>
                                      * for <tt>dim=</tt> 2 and 3.
                                      *
                                      * For <tt>degree<4</tt> this function
@@ -427,7 +432,7 @@ class MappingQ : public MappingQ1<dim>
                                      * the mapping.
                                      */
     virtual void compute_mapping_support_points(
-      const typename Triangulation<dim>::cell_iterator &cell,
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
       std::vector<Point<dim> > &a) const;
 
                                     /**
@@ -445,7 +450,7 @@ class MappingQ : public MappingQ1<dim>
                                      * possible.
                                      */
     void compute_support_points_laplace(
-      const typename Triangulation<dim>::cell_iterator &cell,
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
       std::vector<Point<dim> > &a) const;
     
                                     /**
index 293609b83c354d178bba9f15ef285ff4a7e2b921..7935b2854cf6dc983dde44ca153b655037d96f33 100644 (file)
@@ -41,11 +41,15 @@ DEAL_II_NAMESPACE_OPEN
  * Shape function for this mapping are the same as for the finite
  * element FE_Q of order 1. Therefore, coupling these two yields
  * an isoparametric element.
+ * 
+ * For more information about the <tt>spacedim</tt> template parameter
+ * check the documentation of FiniteElement or the one of
+ * Triangulation.
  *
  * @author Guido Kanschat, 2000, 2001; Ralf Hartmann, 2000, 2001, 2005
  */
-template <int dim>
-class MappingQ1 : public Mapping<dim>
+template <int dim, int spacedim=dim>
+class MappingQ1 : public Mapping<dim,spacedim>
 {
   public:
                                     /**
@@ -53,9 +57,9 @@ class MappingQ1 : public Mapping<dim>
                                      */
     MappingQ1 ();
     
-    virtual Point<dim>
+    virtual Point<spacedim>
     transform_unit_to_real_cell (
-      const typename Triangulation<dim>::cell_iterator &cell,
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
       const Point<dim>                                 &p) const;
     
                                     /**
@@ -70,32 +74,32 @@ class MappingQ1 : public Mapping<dim>
                                      */
     virtual Point<dim>
     transform_real_to_unit_cell (
-      const typename Triangulation<dim>::cell_iterator &cell,
-      const Point<dim>                                 &p) const;
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+      const Point<spacedim>                            &p) const;
     
     virtual void
     transform_covariant (const VectorSlice<const std::vector<Tensor<1,dim> > > input,
                          const unsigned int                 offset,
-                        VectorSlice<std::vector<Tensor<1,dim> > > output,
-                        const typename Mapping<dim>::InternalDataBase &internal) const;
+                        VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+                        const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;
     
     virtual void
     transform_covariant (const VectorSlice<const std::vector<Tensor<2,dim> > > input,
                          const unsigned int                 offset,
-                        VectorSlice<std::vector<Tensor<2,dim> > > output,
-                        const typename Mapping<dim>::InternalDataBase &internal) const;
+                        VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+                        const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;
     
     virtual void
-    transform_contravariant (const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+    transform_contravariant (const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
                              const unsigned int                 offset,
-                            VectorSlice<std::vector<Tensor<1,dim> > > output,
-                            const typename Mapping<dim>::InternalDataBase &internal) const;
+                            VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+                            const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;
     
     virtual void
-    transform_contravariant (const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+    transform_contravariant (const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
                              const unsigned int                 offset,
-                            VectorSlice<std::vector<Tensor<2,dim> > > output,
-                            const typename Mapping<dim>::InternalDataBase &internal) const;
+                            VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+                            const typename Mapping<dim,spacedim>::InternalDataBase &internal) const;
     
                                      /**
                                       * Return a pointer to a copy of the
@@ -103,13 +107,13 @@ class MappingQ1 : public Mapping<dim>
                                       * copy then assumes ownership of it.
                                       */
     virtual
-    Mapping<dim> * clone () const;
+    Mapping<dim,spacedim> * clone () const;
 
                                     /** 
                                      * Storage for internal data of
                                      * d-linear transformation.
                                      */
-    class InternalData : public Mapping<dim>::InternalDataBase
+    class InternalData : public Mapping<dim,spacedim>::InternalDataBase
     {
       public:
                                         /**
@@ -216,7 +220,7 @@ class MappingQ1 : public Mapping<dim>
                                          *
                                          * Computed on each cell.
                                          */
-       std::vector<Tensor<2,dim> > covariant;
+       std::vector<Tensor<2,spacedim> > covariant;
        
                                         /**
                                          * Tensors of contravariant
@@ -229,7 +233,7 @@ class MappingQ1 : public Mapping<dim>
                                          *
                                          * Computed on each cell.
                                          */
-       std::vector<Tensor<2,dim> > contravariant;
+       std::vector<Tensor<2,spacedim> > contravariant;
        
                                         /**
                                          * Unit tangential vectors. Used
@@ -239,26 +243,26 @@ class MappingQ1 : public Mapping<dim>
                                          *
                                          * Filled once.
                                          */
-        std::vector<std::vector<Tensor<1,dim> > > unit_tangentials;
+        std::vector<std::vector<Tensor<1,spacedim> > > unit_tangentials;
        
                                         /**
                                          * Auxiliary vectors for internal use.
                                          */
-        std::vector<std::vector<Tensor<1,dim> > > aux;
+        std::vector<std::vector<Tensor<1,spacedim> > > aux;
 
                                         /**
                                          * Stores the support points of
                                          * the mapping shape functions on
                                          * the @p cell_of_current_support_points.
                                          */
-       std::vector<Point<dim> > mapping_support_points;
+       std::vector<Point<spacedim> > mapping_support_points;
        
                                         /**
                                          * Stores the cell of which the
                                          * @p mapping_support_points are
                                          * stored.
                                          */
-       typename Triangulation<dim>::cell_iterator cell_of_current_support_points;
+       typename Triangulation<dim,spacedim>::cell_iterator cell_of_current_support_points;
        
                                         /**
                                          * Default value of this flag
@@ -303,44 +307,45 @@ class MappingQ1 : public Mapping<dim>
                                      * Mapping.
                                      */
     virtual void
-    fill_fe_values (const typename Triangulation<dim>::cell_iterator &cell,
-                   const Quadrature<dim>& quadrature,
-                   typename Mapping<dim>::InternalDataBase &mapping_data,
-                   typename std::vector<Point<dim> >       &quadrature_points,
-                   std::vector<double>             &JxW_values,
-                   std::vector<Tensor<2,dim> >     &jacobians,
-                   std::vector<Tensor<3,dim> >     &jacobian_grads,
-                   std::vector<Tensor<2,dim> >     &inverse_jacobians) const ;
+    fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                   const Quadrature<dim>                                     & quadrature,
+                   typename Mapping<dim,spacedim>::InternalDataBase          &mapping_data,
+                   typename std::vector<Point<spacedim> >                    &quadrature_points,
+                   std::vector<double>                                       &JxW_values,
+                   std::vector<Tensor<2,spacedim> >                          &jacobians,
+                   std::vector<Tensor<3,spacedim> >                          &jacobian_grads,
+                   std::vector<Tensor<2,spacedim> >                          &inverse_jacobians,
+                   std::vector<Point<spacedim> >                             &cell_normal_vectors) const;
 
                                     /**
                                      * Implementation of the interface in
                                      * Mapping.
                                      */
     virtual void
-    fill_fe_face_values (const typename Triangulation<dim>::cell_iterator &cell,
-                        const unsigned int face_no,
-                        const Quadrature<dim-1>quadrature,
-                        typename Mapping<dim>::InternalDataBase &mapping_data,
-                        typename std::vector<Point<dim> >        &quadrature_points,
-                        std::vector<double>             &JxW_values,
-                        typename std::vector<Tensor<1,dim> >        &boundary_form,
-                        typename std::vector<Point<dim> >        &normal_vectors,
-                        std::vector<double>             &cell_JxW_values) const ;
+    fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                        const unsigned int                               face_no,
+                        const Quadrature<dim-1>                          &quadrature,
+                        typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+                        typename std::vector<Point<dim> >                &quadrature_points,
+                        std::vector<double>                              &JxW_values,
+                        typename std::vector<Tensor<1,dim> >             &boundary_form,
+                        typename std::vector<Point<spacedim> >           &normal_vectors,
+                        std::vector<double>                              &cell_JxW_values) const ;
 
                                     /**
                                      * Implementation of the interface in
                                      * Mapping.
                                      */
     virtual void
-    fill_fe_subface_values (const typename Triangulation<dim>::cell_iterator &cell,
+    fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int face_no,
                            const unsigned int sub_no,
                            const Quadrature<dim-1>& quadrature,
-                           typename Mapping<dim>::InternalDataBase &mapping_data,
+                           typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
                            typename std::vector<Point<dim> >        &quadrature_points,
                            std::vector<double>             &JxW_values,
                            typename std::vector<Tensor<1,dim> >        &boundary_form,
-                           typename std::vector<Point<dim> >        &normal_vectors,
+                           typename std::vector<Point<spacedim> >        &normal_vectors,
                            std::vector<double>             &cell_JxW_values) const ;
     
                                     /**
@@ -392,17 +397,17 @@ class MappingQ1 : public Mapping<dim>
                                      * Do the computation for the
                                      * <tt>fill_*</tt> functions.
                                      */
-    void compute_fill (const typename Triangulation<dim>::cell_iterator &cell,
+    void compute_fill (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                       const unsigned int      npts,
                       const DataSetDescriptor data_set,
                       InternalData           &data,
-                      std::vector<Point<dim> > &quadrature_points) const;
+                      std::vector<Point<spacedim> > &quadrature_points) const;
     
                                     /**
                                      * Do the computation for the
                                      * <tt>fill_*</tt> functions.
                                      */
-    void compute_fill_face (const typename Triangulation<dim>::cell_iterator &cell,
+    void compute_fill_face (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            const unsigned int      face_no,
                            const unsigned int      subface_no,
                            const unsigned int      npts,
@@ -412,7 +417,7 @@ class MappingQ1 : public Mapping<dim>
                            std::vector<Point<dim> >    &quadrature_points,
                            std::vector<double>         &JxW_values,
                            std::vector<Tensor<1,dim> > &boundary_form,
-                           std::vector<Point<dim> > &normal_vectors,
+                           std::vector<Point<spacedim> > &normal_vectors,
                            std::vector<double>         &cell_JxW_values) const;
     
                                     /**
@@ -448,7 +453,7 @@ class MappingQ1 : public Mapping<dim>
                                      * computations of the mapping
                                      * support points.
                                      */
-    Point<dim> transform_unit_to_real_cell_internal (const InternalData &mdata) const;
+    Point<spacedim> transform_unit_to_real_cell_internal (const InternalData &mdata) const;
     
                                     /**
                                      * Transforms the point @p p on
@@ -484,8 +489,8 @@ class MappingQ1 : public Mapping<dim>
                                      * @p mdata will be changed by
                                      * this function.
                                      */
-    void transform_real_to_unit_cell_internal (const typename Triangulation<dim>::cell_iterator &cell,
-                                              const Point<dim> &p,
+    void transform_real_to_unit_cell_internal (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                                              const Point<spacedim> &p,
                                               InternalData &mdata,
                                               Point<dim> &p_unit) const;
 
@@ -567,17 +572,17 @@ class MappingQ1 : public Mapping<dim>
     virtual UpdateFlags update_each (const UpdateFlags flags) const;
 
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_data (const UpdateFlags,
              const Quadrature<dim>& quadrature) const;
 
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_face_data (const UpdateFlags flags,
                   const Quadrature<dim-1>& quadrature) const;
 
     virtual
-    typename Mapping<dim>::InternalDataBase *
+    typename Mapping<dim,spacedim>::InternalDataBase *
     get_subface_data (const UpdateFlags flags,
                      const Quadrature<dim-1>& quadrature) const;
 
@@ -598,8 +603,8 @@ class MappingQ1 : public Mapping<dim>
                                      * geometry of the cell.
                                      */
     virtual void compute_mapping_support_points(
-      const typename Triangulation<dim>::cell_iterator &cell,
-      std::vector<Point<dim> > &a) const;
+      const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+      std::vector<Point<spacedim> > &a) const;
 
                                     /**
                                      * Number of shape functions. Is
@@ -616,10 +621,10 @@ class MappingQ1 : public Mapping<dim>
  * functions), we define a static MappingQ1 objects once and for all
  * places where it is needed.
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 struct StaticMappingQ1
 {
-    static MappingQ1<dim> mapping;
+    static MappingQ1<dim, spacedim> mapping;
 };
 
 
@@ -627,10 +632,10 @@ struct StaticMappingQ1
 
 /*----------------------------------------------------------------------*/
 
-template<int dim>
+template<int dim, int spacedim>
 inline
 double
-MappingQ1<dim>::InternalData::shape (const unsigned int qpoint,
+MappingQ1<dim,spacedim>::InternalData::shape (const unsigned int qpoint,
                                     const unsigned int shape_nr) const
 {
   Assert(qpoint*n_shape_functions + shape_nr < shape_values.size(),
@@ -641,10 +646,10 @@ MappingQ1<dim>::InternalData::shape (const unsigned int qpoint,
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 inline
 double &
-MappingQ1<dim>::InternalData::shape (const unsigned int qpoint,
+MappingQ1<dim,spacedim>::InternalData::shape (const unsigned int qpoint,
                                     const unsigned int shape_nr)
 {
   Assert(qpoint*n_shape_functions + shape_nr < shape_values.size(),
@@ -654,10 +659,10 @@ MappingQ1<dim>::InternalData::shape (const unsigned int qpoint,
 }
 
 
-template <int dim>
+template<int dim, int spacedim>
 inline
 Tensor<1,dim>
-MappingQ1<dim>::InternalData::derivative (const unsigned int qpoint,
+MappingQ1<dim,spacedim>::InternalData::derivative (const unsigned int qpoint,
                                          const unsigned int shape_nr) const
 {
   Assert(qpoint*n_shape_functions + shape_nr < shape_derivatives.size(),
@@ -668,10 +673,10 @@ MappingQ1<dim>::InternalData::derivative (const unsigned int qpoint,
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 inline
 Tensor<1,dim> &
-MappingQ1<dim>::InternalData::derivative (const unsigned int qpoint,
+MappingQ1<dim,spacedim>::InternalData::derivative (const unsigned int qpoint,
                                          const unsigned int shape_nr)
 {
   Assert(qpoint*n_shape_functions + shape_nr < shape_derivatives.size(),
@@ -681,11 +686,11 @@ MappingQ1<dim>::InternalData::derivative (const unsigned int qpoint,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 Tensor<2,dim>
-MappingQ1<dim>::InternalData::second_derivative (const unsigned int qpoint,
-                                                const unsigned int shape_nr) const
+MappingQ1<dim,spacedim>::InternalData::second_derivative (const unsigned int qpoint,
+                                                         const unsigned int shape_nr) const
 {
   Assert(qpoint*n_shape_functions + shape_nr < shape_second_derivatives.size(),
         ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
@@ -695,10 +700,10 @@ MappingQ1<dim>::InternalData::second_derivative (const unsigned int qpoint,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 Tensor<2,dim> &
-MappingQ1<dim>::InternalData::second_derivative (const unsigned int qpoint,
+MappingQ1<dim,spacedim>::InternalData::second_derivative (const unsigned int qpoint,
                                                 const unsigned int shape_nr)
 {
   Assert(qpoint*n_shape_functions + shape_nr < shape_second_derivatives.size(),
@@ -714,23 +719,6 @@ MappingQ1<dim>::InternalData::second_derivative (const unsigned int qpoint,
 
 #ifndef DOXYGEN
 
-template<> void MappingQ1<1>::compute_shapes_virtual (
-  const std::vector<Point<1> > &unit_points,
-  InternalData& data) const;
-template<> void MappingQ1<2>::compute_shapes_virtual (
-  const std::vector<Point<2> > &unit_points,
-  InternalData &data) const;
-template<> void MappingQ1<3>::compute_shapes_virtual (
-  const std::vector<Point<3> > &unit_points,
-  InternalData &data) const;
-
-template <>
-void
-MappingQ1<1>::compute_face_data (const UpdateFlags,
-                                 const Quadrature<1> &,
-                                 const unsigned int,
-                                 InternalData &) const;
-
 template <> void MappingQ1<1>::compute_fill_face (
   const Triangulation<1>::cell_iterator &,
   const unsigned int,
index ab701da551c3cf6f24a7519635115dce7f82c0cd..949f37c599a272449bb2ef656bd2d3801029937f 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 by the deal.II authors
+//    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -77,11 +77,15 @@ DEAL_II_NAMESPACE_OPEN
  * Not specifying this template argument in applications using the PETSc
  * vector classes leads to the construction of a copy of the vector
  * which is not acccessible afterwards!
+ * 
+ * For more information about the <tt>spacedim</tt> template parameter
+ * check the documentation of FiniteElement or the one of
+ * Triangulation.
  *
  * @author Michael Stadler, 2001
  */
-template <int dim, class EulerVectorType = Vector<double> >
-class MappingQ1Eulerian : public MappingQ1<dim>
+template <int dim, class EulerVectorType = Vector<double>, int spacedim=dim >
+class MappingQ1Eulerian : public MappingQ1<dim,spacedim>
 {
   public:
 
@@ -104,7 +108,7 @@ class MappingQ1Eulerian : public MappingQ1<dim>
                                      * of a nonlinear problem.
                                      * Alternatively, the @p Vector
                                      * can be initialized by
-                                     * <tt>DoFObjectAccessor::set_dof_values()</tt>.
+                                     * <tt>DoFAccessor::set_dof_values()</tt>.
                                      */
     MappingQ1Eulerian (const EulerVectorType  &euler_transform_vectors,
                        const DoFHandler<dim> &shiftmap_dof_handler);
@@ -115,7 +119,7 @@ class MappingQ1Eulerian : public MappingQ1<dim>
                                       * copy then assumes ownership of it.
                                       */
     virtual
-    Mapping<dim> * clone () const;
+    Mapping<dim,spacedim> * clone () const;
 
     
                                     /**
index c1786d4e59860f63daccd772396f2aaab4645d33..83a05632629dc00384ad58ad68f2a763f9e3adb4 100644 (file)
@@ -85,8 +85,8 @@ DEAL_II_NAMESPACE_OPEN
  *
  * @author Joshua White, 2008
  */
-template <int dim, class EulerVectorType = Vector<double> >
-class MappingQEulerian : public MappingQ<dim>
+template <int dim, class EulerVectorType = Vector<double>, int spacedim=dim >
+class MappingQEulerian : public MappingQ<dim, spacedim>
 {
   public:
                                      /**
@@ -109,7 +109,7 @@ class MappingQEulerian : public MappingQ<dim>
                                       * of a nonlinear problem.
                                       * Alternatively, the @p Vector
                                       * can be initialized by
-                                      * <tt>DoFObjectAccessor::set_dof_values()</tt>.
+                                      * <tt>DoFAccessor::set_dof_values()</tt>.
                                       */
 
     MappingQEulerian (const unsigned int     degree,
@@ -122,7 +122,7 @@ class MappingQEulerian : public MappingQ<dim>
                                       * copy then assumes ownership of it.
                                       */
     virtual
-    Mapping<dim> * clone () const;
+    Mapping<dim,spacedim> * clone () const;
 
                                      /**
                                       * Exception
index 27a78155bc2dfe75df2eaf700af61a353f3f2d35..33b297fe7569809ad7684509892b1b3ca4786df3 100644 (file)
 #include <base/exceptions.h>
 #include <base/point.h>
 #include <base/table.h>
+#include <grid/tria.h>
 #include <map>
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class Triangulation;
+template <int dim, int spacedim> class Triangulation;
 template <typename number> class Vector;
 template <typename number> class SparseMatrix;
 
@@ -43,6 +44,9 @@ template <typename number> class SparseMatrix;
  * transform (simple-shaped) grids to a more complicated ones, like a
  * shell onto a grid of an airfoil, for example.
  *
+ * No meshes for the codimension one case are provided at the moment.
+ *
+ *
  * @ingroup grid
  * @author Wolfgang Bangerth, Ralf Hartmann, Guido Kanschat, Stefan
  * Nauber, Joerg Weimar, Yaqi Wang, Luca Heltai, 1998, 1999, 2000, 2001, 2002,
@@ -81,8 +85,8 @@ class GridGenerator
                                      * void upon calling this
                                      * function.
                                      */
-    template <int dim>
-    static void hyper_cube (Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    static void hyper_cube (Triangulation<dim,spacedim>  &tria,
                            const double        left = 0.,
                            const double        right= 1.);
 
@@ -97,12 +101,23 @@ class GridGenerator
                                      * the given volume is
                                      * <tt>repetitions<sup>dim</sup></tt>.
                                      *
-                                     * @note The triangulation needs to be
-                                     * void upon calling this
+                                     * If spacedim=dim+1 the same
+                                     * mesh as in the case
+                                     * spacedim=dim is created, but
+                                     * the vertices have an
+                                     * additional coordinate =0. So,
+                                     * if dim=1 one obtains line
+                                     * along the x axis in the xy
+                                     * plane, and if dim=3 one
+                                     * obtains a square in lying in
+                                     * the xy plane in 3d space.
+                                     *
+                                     * @note The triangulation needs
+                                     * to be void upon calling this
                                      * function.
                                      */
     template <int dim>
-    static void subdivided_hyper_cube (Triangulation<dim> &tria,
+    static void subdivided_hyper_cube (Triangulation<dim>  &tria,
                                        const unsigned int  repetitions,
                                        const double        left = 0.,
                                        const double        right= 1.);
@@ -137,11 +152,11 @@ class GridGenerator
                                      * void upon calling this
                                      * function.
                                      */
-    template <int dim>
-    static void hyper_rectangle (Triangulation<dim> &tria,
-                                const Point<dim>   &p1,
-                                const Point<dim>   &p2,
-                                const bool          colorize = false);
+    template <int dim, int spacedim>
+    static void hyper_rectangle (Triangulation<dim,spacedim> &tria,
+                                const Point<spacedim>       &p1,
+                                const Point<spacedim>       &p2,
+                                const bool                  colorize = false);
 
                                     /**
                                      * Create a coordinate-parallel
@@ -201,7 +216,7 @@ class GridGenerator
                                const std::vector<unsigned int> &repetitions,
                                const Point<dim>                &p1,
                                const Point<dim>                &p2,
-                               const bool                       colorize=false);
+                               const bool                      colorize=false);
 
                                     /**
                                      * Like the previous
@@ -236,11 +251,11 @@ class GridGenerator
     template <int dim>
     static
     void
-    subdivided_hyper_rectangle(Triangulation<dim>              &tria,
+    subdivided_hyper_rectangle(Triangulation<dim>                      &tria,
                               const std::vector<std::vector<double> > &step_sizes,
-                              const Point<dim>                &p_1,
-                              const Point<dim>                &p_2,
-                              const bool                       colorize);
+                              const Point<dim>                        &p_1,
+                              const Point<dim>                        &p_2,
+                              const bool                              colorize);
 
                                     /**
                                      * Like the previous function, but with
@@ -263,7 +278,7 @@ class GridGenerator
                                const std::vector< std::vector<double> > &spacing,
                                const Point<dim>                         &p,
                                const Table<dim,unsigned char>           &material_id,
-                               const bool                                colorize=false);
+                               const bool                               colorize=false);
     
                                     /**
                                      * A parallelogram. The first
@@ -660,7 +675,7 @@ class GridGenerator
                                      * @param R           The radius of the circle, which forms the middle line of the torus containing the loop of cells. Must be greater than @p r.
                                      * @param r           The radius of the cylinder bend together as loop.
                                      */
-    static void moebius (Triangulation<3>&  tria,
+    static void moebius (Triangulation<3,3>&  tria,
                         const unsigned int   n_cells,
                         const unsigned int   n_rotations,
                         const double         R,
@@ -718,8 +733,8 @@ class GridGenerator
                                      * the hyper_rectangle()
                                      * function of this class.
                                      */
-    template <int dim>
-    static void colorize_hyper_rectangle (Triangulation<dim> &tria);
+    template <int dim, int spacedim>
+    static void colorize_hyper_rectangle (Triangulation<dim,spacedim> &tria);
 
                                     /**
                                      * Perform the action specified
@@ -770,6 +785,7 @@ class GridGenerator
 
 
 
+
 DEAL_II_NAMESPACE_CLOSE
 
 #endif
index 11b9659bff71b3677e7decf02f9ae1e398ea01bd..ce142469ee3eaaa1907a4d8cec548c4419476339 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 template <int dim> class Point;
-template <int dim> class Triangulation;
+template <int dim, int space_dim> class Triangulation;
 template <int dim> class CellData;
 class SubCellData;
 
 
 /**
- * This class implements an input mechanism for grid data. It allows
- * to read a grid structure into a triangulation object. At present,
- * UCD (unstructured cell data), DB Mesh and Gmsh are supported as input
- * format for grid data. Any numerical data after the block of
- * topological information is ignored.
+ * This class implements an input mechanism for grid data. It allows to
+ * read a grid structure into a triangulation object. At present, UCD
+ * (unstructured cell data), DB Mesh, XDA, Gmsh, Tecplot, NetCDF and Cubit
+ * are supported as input format for grid data. Any numerical data after
+ * the block of topological information is ignored. Notice also that at
+ * the moment in the codimension 1 case only UCD and Gmsh format are
+ * accepted.
  *
  * Since the coarse mesh fed into a @p Triangulation object cannot
  * have hanging nodes, strange things will happen if the input file
@@ -202,7 +204,7 @@ class SubCellData;
  * @ingroup input
  * @author Wolfgang Bangerth, 1998, 2000, Luca Heltai, 2004, 2007
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 class GridIn
 {
   public:
@@ -241,7 +243,7 @@ class GridIn
                                      * Attach this triangulation
                                      * to be fed with the grid data.
                                      */
-    void attach_triangulation (Triangulation<dim> &tria);
+    void attach_triangulation (Triangulation<dim,spacedim> &tria);
 
                                     /**
                                      * Read from the given stream. If
@@ -401,7 +403,7 @@ class GridIn
                                      * Store address of the triangulation to
                                      * be fed with the data read in.
                                      */
-    SmartPointer<Triangulation<dim> > tria;
+    SmartPointer<Triangulation<dim,spacedim> > tria;
     
                                     /**
                                      * This function can write the
@@ -449,7 +451,7 @@ class GridIn
                                      * user.
                                      */
     static void debug_output_grid (const std::vector<CellData<dim> > &cells,
-                                  const std::vector<Point<dim> >    &vertices,
+                                  const std::vector<Point<spacedim> > &vertices,
                                   std::ostream &out);
 
   private:
@@ -516,6 +518,13 @@ void
 GridIn<2>::debug_output_grid (const std::vector<CellData<2> > &cells,
                              const std::vector<Point<2> >    &vertices,
                              std::ostream                    &out);
+
+
+template <>
+void
+GridIn<2,3>::debug_output_grid (const std::vector<CellData<2> > &cells,
+                             const std::vector<Point<3> >    &vertices,
+                             std::ostream                    &out);
 template <>
 void
 GridIn<3>::debug_output_grid (const std::vector<CellData<3> > &cells,
index 56e2cff960e9dbbd7a9f1bc50183387f08207885..6184ca278b879587f2f59c072180deff6e9e1f3e 100644 (file)
 #include <base/config.h>
 #include <base/exceptions.h>
 #include <base/point.h>
+#include <grid/tria.h>
+#include <fe/mapping.h>
+
 #include <string>
 
 DEAL_II_NAMESPACE_OPEN
 
 class ParameterHandler;
-template <int dim> class Triangulation;
-template <int dim> class Mapping;
+template <int dim, int spacedim> class Triangulation;
+template <int dim, int spacedim> class Mapping;
 
 
 /**
@@ -823,6 +826,9 @@ class GridOut
                                      * together with their level and
                                      * their material id or boundary
                                      * indicator, resp.
+                                     * 
+                                     * Not implemented for the
+                                     * codimension one case.
                                      */
     template <int dim>
     void write_dx (const Triangulation<dim> &tria,
@@ -886,6 +892,9 @@ class GridOut
                                      * can be found in the
                                      * documentation of the
                                      * GridOutFlags::Gnuplot() class.
+                                     *
+                                     * Not implemented for the
+                                     * codimension one case.
                                      */
     template <int dim>
     void write_gnuplot (const Triangulation<dim> &tria,
@@ -925,9 +934,12 @@ class GridOut
                                      * can be found in the
                                      * documentation of the
                                      * GridOut::Msh() class.
+                                     *
+                                     * Works also in the
+                                     * codimension one case.
                                      */
-    template <int dim>
-    void write_msh (const Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    void write_msh (const Triangulation<dim,spacedim> &tria,
                    std::ostream             &out) const;
 
                                     /**
@@ -964,9 +976,12 @@ class GridOut
                                      * can be found in the
                                      * documentation of the
                                      * GridOut::Ucd() class.
+                                     *
+                                     * Works also for the
+                                     * codimension one case.
                                      */
-    template <int dim>
-    void write_ucd (const Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    void write_ucd (const Triangulation<dim,spacedim> &tria,
                    std::ostream             &out) const;
 
                                     /**
@@ -1024,6 +1039,9 @@ class GridOut
                                      * viewpoint for three
                                      * dimensional grids is of
                                      * importance here.
+                                     *
+                                     * Not implemented for the
+                                     * codimension one case.
                                      */
     template <int dim>
     void write_eps (const Triangulation<dim> &tria,
@@ -1053,11 +1071,14 @@ class GridOut
                                      * or at 800+@p boundary_id. Therefore,
                                      * boundary edges are alway in front of
                                      * cells.
+                                     *
+                                     * Not implemented for the
+                                     * codimension one case.
                                      */
     template <int dim>
     void write_xfig (const Triangulation<dim> &tria,
-                   std::ostream             &out,
-                   const Mapping<dim>       *mapping=0) const;
+                   std::ostream              &out,
+                   const Mapping<dim>        *mapping=0) const;
     
                                     /**
                                      * Write grid to @p out according
@@ -1066,20 +1087,20 @@ class GridOut
                                      * appropriate <tt>write_*</tt>
                                      * function.
                                      */
-    template <int dim>
-    void write (const Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    void write (const Triangulation<dim,spacedim> &tria,
                std::ostream             &out,
                const OutputFormat        output_format,
-               const Mapping<dim>       *mapping=0) const;
+               const Mapping<dim,spacedim>       *mapping=0) const;
     
                                     /**
                                      * Write mesh in default format
                                      * set by ParameterHandler.
                                      */
-    template <int dim>
-    void write (const Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    void write (const Triangulation<dim,spacedim> &tria,
                std::ostream             &out,
-               const Mapping<dim>       *mapping=0) const;
+               const Mapping<dim,spacedim>       *mapping=0) const;
     
                                     /**
                                      * Set flags for DX output
@@ -1292,8 +1313,8 @@ class GridOut
                                      * would complain anyway when compiling
                                      * the function for <tt>dim==1</tt>. Bad luck.
                                      */
-    template <int dim>
-    void write_msh_faces (const Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    void write_msh_faces (const Triangulation<dim,spacedim> &tria,
                          const unsigned int        starting_index,
                          std::ostream             &out) const;
 
@@ -1302,7 +1323,15 @@ class GridOut
                                      * of above function for 1d. Does
                                      * nothing.
                                      */
-    void write_msh_faces (const Triangulation<1> &tria,
+    void write_msh_faces (const Triangulation<1,1> &tria,
+                         const unsigned int      starting_index,
+                         std::ostream           &out) const;
+                                    /**
+                                     * Declaration of the specialization
+                                     * of above function for 1d, 2sd. Does
+                                     * nothing.
+                                     */
+    void write_msh_faces (const Triangulation<1,2> &tria,
                          const unsigned int      starting_index,
                          std::ostream           &out) const;
    
@@ -1335,8 +1364,8 @@ class GridOut
                                      * when compiling the function
                                      * for <tt>dim==1/2</tt>. Bad luck.
                                      */
-    template <int dim>
-    void write_msh_lines (const Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    void write_msh_lines (const Triangulation<dim,spacedim> &tria,
                          const unsigned int        starting_index,
                          std::ostream             &out) const;
 
@@ -1345,16 +1374,32 @@ class GridOut
                                      * of above function for 1d. Does
                                      * nothing.
                                      */
-    void write_msh_lines (const Triangulation<1> &tria,
+    void write_msh_lines (const Triangulation<1,1> &tria,
                          const unsigned int      starting_index,
                          std::ostream           &out) const;
    
+                                    /**
+                                     * Declaration of the specialization
+                                     * of above function for 1d, 2sd. Does
+                                     * nothing.
+                                     */
+    void write_msh_lines (const Triangulation<1,2> &tria,
+                         const unsigned int      starting_index,
+                         std::ostream           &out) const;
                                     /**
                                      * Declaration of the specialization
                                      * of above function for 2d. Does
                                      * nothing.
                                      */
-    void write_msh_lines (const Triangulation<2> &tria,
+    void write_msh_lines (const Triangulation<2,2> &tria,
+                         const unsigned int      starting_index,
+                         std::ostream           &out) const;
+                                    /**
+                                     * Declaration of the specialization
+                                     * of above function for 2d, 3sd. Does
+                                     * nothing.
+                                     */
+    void write_msh_lines (const Triangulation<2,3> &tria,
                          const unsigned int      starting_index,
                          std::ostream           &out) const;
 
@@ -1384,8 +1429,8 @@ class GridOut
                                      */
 
    
-    template <int dim>
-    void write_ucd_faces (const Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    void write_ucd_faces (const Triangulation<dim,spacedim> &tria,
                          const unsigned int        starting_index,
                          std::ostream             &out) const;
 
@@ -1394,7 +1439,16 @@ class GridOut
                                      * of above function for 1d. Does
                                      * nothing.
                                      */
-    void write_ucd_faces (const Triangulation<1> &tria,
+    void write_ucd_faces (const Triangulation<1,1> &tria,
+                         const unsigned int      starting_index,
+                         std::ostream           &out) const;
+
+                                    /**
+                                     * Declaration of the specialization
+                                     * of above function for 1d, 2sd. Does
+                                     * nothing.
+                                     */
+    void write_ucd_faces (const Triangulation<1,2> &tria,
                          const unsigned int      starting_index,
                          std::ostream           &out) const;
 
@@ -1426,8 +1480,8 @@ class GridOut
                                      */
 
    
-    template <int dim>
-    void write_ucd_lines (const Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    void write_ucd_lines (const Triangulation<dim,spacedim> &tria,
                          const unsigned int        starting_index,
                          std::ostream             &out) const;
 
@@ -1436,16 +1490,33 @@ class GridOut
                                      * of above function for 1d. Does
                                      * nothing.
                                      */
-    void write_ucd_lines (const Triangulation<1> &tria,
+    void write_ucd_lines (const Triangulation<1,1> &tria,
                          const unsigned int      starting_index,
                          std::ostream           &out) const;
+                                    /**
+                                     * Declaration of the specialization
+                                     * of above function for 1d, 2sd. Does
+                                     * nothing.
+                                     */
+    void write_ucd_lines (const Triangulation<1,2> &tria,
+                         const unsigned int      starting_index,
+                         std::ostream           &out) const;
+
 
                                     /**
                                      * Declaration of the specialization
                                      * of above function for 2d. Does
                                      * nothing.
                                      */
-    void write_ucd_lines (const Triangulation<2> &tria,
+    void write_ucd_lines (const Triangulation<2,2> &tria,
+                         const unsigned int      starting_index,
+                         std::ostream           &out) const;
+                                    /**
+                                     * Declaration of the specialization
+                                     * of above function for 2d, 3sd. Does
+                                     * nothing.
+                                     */
+    void write_ucd_lines (const Triangulation<2,3> &tria,
                          const unsigned int      starting_index,
                          std::ostream           &out) const;
     
@@ -1467,15 +1538,21 @@ class GridOut
                                      * same as for @p write_ucd_faces. See
                                      * there for more information.
                                      */
-    template <int dim>
-    unsigned int n_boundary_faces (const Triangulation<dim> &tria) const;
+    template <int dim, int spacedim>
+    unsigned int n_boundary_faces (const Triangulation<dim,spacedim> &tria) const;
 
                                     /**
                                      * Declaration of the specialization
                                      * of above function for
                                      * 1d. Simply returns zero.
                                      */
-    unsigned int n_boundary_faces (const Triangulation<1> &tria) const;
+    unsigned int n_boundary_faces (const Triangulation<1,1> &tria) const;
+                                    /**
+                                     * Declaration of the specialization
+                                     * of above function for
+                                     * 1d, 2sd. Simply returns zero.
+                                     */
+    unsigned int n_boundary_faces (const Triangulation<1,2> &tria) const;
 
                                     /**
                                      * Return the number of lines in the
@@ -1495,22 +1572,35 @@ class GridOut
                                      * same as for @p write_ucd_faces. See
                                      * there for more information.
                                      */
-    template <int dim>
-    unsigned int n_boundary_lines (const Triangulation<dim> &tria) const;
+    template <int dim, int spacedim>
+    unsigned int n_boundary_lines (const Triangulation<dim,spacedim> &tria) const;
 
                                     /**
                                      * Declaration of the specialization
                                      * of above function for
                                      * 1d. Simply returns zero.
                                      */
-    unsigned int n_boundary_lines (const Triangulation<1> &tria) const;
+    unsigned int n_boundary_lines (const Triangulation<1,1> &tria) const;
+
+                                    /**
+                                     * Declaration of the specialization
+                                     * of above function for
+                                     * 1d, 2sd. Simply returns zero.
+                                     */
+    unsigned int n_boundary_lines (const Triangulation<1,2> &tria) const;
 
                                     /**
                                      * Declaration of the specialization
                                      * of above function for
                                      * 2d. Simply returns zero.
                                      */
-    unsigned int n_boundary_lines (const Triangulation<2> &tria) const;
+    unsigned int n_boundary_lines (const Triangulation<2,2> &tria) const;
+                                    /**
+                                     * Declaration of the specialization
+                                     * of above function for
+                                     * 2d, 3sd. Simply returns zero.
+                                     */
+    unsigned int n_boundary_lines (const Triangulation<2,3> &tria) const;
 };
 
 
index b6cf4956aaa9627147885ae1f7c64aaf26243c5e..f84a97e98515f6fccec0fcfffa3c92778d71c46f 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -16,6 +16,7 @@
 
 #include <base/config.h>
 #include <base/exceptions.h>
+#include <grid/tria.h>
 
 #include <vector>
 #include <limits>
@@ -23,7 +24,7 @@
 DEAL_II_NAMESPACE_OPEN
 
 // forward declarations
-template <int dim> class Triangulation;
+template <int dim, int spacedim> class Triangulation;
 template <class T> class Vector;
 
 
@@ -173,10 +174,10 @@ class GridRefinement
                                      * general doc for this class for
                                      * more information.
                                      */
-    template <int dim, class Vector>
-    static void refine (Triangulation<dim> &tria,
-                       const Vector       &criteria,
-                       const double        threshold);
+    template <int dim, class Vector, int spacedim>
+    static void refine (Triangulation<dim,spacedim> &tria,
+                       const Vector                &criteria,
+                       const double                threshold);
 
                                     /**
                                      * Analogue to the @p refine
@@ -186,10 +187,10 @@ class GridRefinement
                                      * criterion is less than the
                                      * given threshold.
                                      */
-    template <int dim, class Vector>
-    static void coarsen (Triangulation<dim> &tria,
-                        const Vector       &criteria,
-                        const double        threshold);
+    template <int dim, class Vector, int spacedim>
+    static void coarsen (Triangulation<dim,spacedim> &tria,
+                        const Vector                &criteria,
+                        const double                threshold);
     
                                     /**
                                      * Refine the triangulation by
@@ -223,14 +224,14 @@ class GridRefinement
                                      * this class for more
                                      * information.
                                      */
-    template <int dim, class Vector>
+    template <int dim, class Vector, int spacedim>
     static
     void
-    refine_and_coarsen_fixed_number (Triangulation<dim> &tria,
-                                     const Vector       &criteria,
-                                     const double        top_fraction_of_cells,
-                                     const double        bottom_fraction_of_cells,
-                                    const unsigned int  max_n_cells = std::numeric_limits<unsigned int>::max());
+    refine_and_coarsen_fixed_number (Triangulation<dim,spacedim> &tria,
+                                     const Vector                &criteria,
+                                     const double                top_fraction_of_cells,
+                                     const double                bottom_fraction_of_cells,
+                                    const unsigned int          max_n_cells = std::numeric_limits<unsigned int>::max());
     
                                     /**
                                      * Refine the triangulation by
@@ -264,14 +265,14 @@ class GridRefinement
                                      * this class for more
                                      * information.
                                      */
-    template <int dim, class Vector>
+    template <int dim, class Vector, int spacedim>
     static
     void
-    refine_and_coarsen_fixed_fraction (Triangulation<dim> &tria,
-                                       const Vector       &criteria,
-                                       const double        top_fraction,
-                                       const double        bottom_fraction,
-                                      const unsigned int  max_n_cells = std::numeric_limits<unsigned int>::max());
+    refine_and_coarsen_fixed_fraction (Triangulation<dim,spacedim> &tria,
+                                       const Vector                &criteria,
+                                       const double                top_fraction,
+                                       const double                bottom_fraction,
+                                      const unsigned int          max_n_cells = std::numeric_limits<unsigned int>::max());
 
 
 
@@ -296,34 +297,16 @@ class GridRefinement
                                      * information.
                                      */
     
-    template <int dim, class Vector>
+    template <int dim, class Vector, int spacedim>
     static
     void
-    refine_and_coarsen_optimize (Triangulation<dim> &tria,
-                                 const Vector       &criteria);
+    refine_and_coarsen_optimize (Triangulation<dim,spacedim> &tria,
+                                 const Vector                &criteria);
 
                                     /**
                                      * Exception
                                      */
     DeclException0 (ExcInvalidParameterValue);
-
-
-  private:
-    
-                                    /**
-                                     * Sorts the vector @p ind as an
-                                     * index vector of @p a in
-                                     * increasing order.  This
-                                     * implementation of quicksort
-                                     * seems to be faster than the
-                                     * STL version and is needed in
-                                     * @p refine_and_coarsen_optimize
-                                     */
-    template <class Vector>
-    static void qsort_index (const Vector               &a,
-                             std::vector<unsigned int>  &ind,
-                             int                         l,
-                             int                         r);
 };
 
 
index 68a022c4cec9fb50e50fafff8ea74a6ce1a836a9..7e947f0ccee8206e37823aca403565affcf3da46 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -643,7 +643,7 @@ DEAL_II_NAMESPACE_OPEN
  * @ingroup grid
  * @author Wolfgang Bangerth, 2000, Michael Anderson 2003, Ralf Hartmann 2005
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 class GridReordering
 {
   public:
@@ -670,7 +670,7 @@ class GridReordering
                                      *
                                      * In 2d and 3d this function checks
                                      * whether all cells have
-                                     * negative or positiv
+                                     * negative or positive
                                      * measure/volume. In the former
                                      * case, all cells are inverted.
                                      * It does nothing in 1d.
@@ -692,7 +692,7 @@ class GridReordering
                                      * reorder_cells().
                                      */
     static void invert_all_cells_of_negative_grid(
-      const std::vector<Point<dim> > &all_vertices,
+      const std::vector<Point<spacedim> > &all_vertices,
       std::vector<CellData<dim> > &original_cells);    
 };
 
@@ -702,17 +702,19 @@ template<>
 void
 GridReordering<2>::reorder_cells (std::vector<CellData<2> > &original_cells);
 
+template<>
+void
+GridReordering<2,3>::reorder_cells (std::vector<CellData<2> > &original_cells);
+
 template<>
 void
 GridReordering<2>::invert_all_cells_of_negative_grid(const std::vector<Point<2> > &all_vertices,
                                                     std::vector<CellData<2> >    &cells);
 
-template <>
+template<>
 void
-Triangulation<2>::create_triangulation_compatibility (const std::vector<Point<2> >    &v,
-                                                     const std::vector<CellData<2> > &c,
-                                                     const SubCellData               &subcelldata);
-
+GridReordering<2,3>::invert_all_cells_of_negative_grid(const std::vector<Point<3> > &all_vertices,
+                                                    std::vector<CellData<2> >    &cells);
 
 
 DEAL_II_NAMESPACE_CLOSE
index 9c3f178e8e21b2288b9e3177452b287c017a92f2..fd53c06208090befbf9706eff06b5d82dde59bfc 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int> class DoFHandler;
-template <int> class Mapping;
+template <int, int> class DoFHandler;
+template <int, int> class Mapping;
 namespace hp
 {
-  template <int> class DoFHandler;
-  template <int> class MappingCollection;
+  template <int, int> class DoFHandler;
+  template <int, int> class MappingCollection;
 }
 
 class SparsityPattern;
@@ -60,15 +60,20 @@ class GridTools
                                      * this function will not catch
                                      * this.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    double diameter (const Triangulation<dim> &tria);
+    double diameter (const Triangulation<dim, spacedim> &tria);
 
                                     /**
                                      * Same function, but for 1d.
                                      */
     static
-    double diameter (const Triangulation<1> &tria);
+    double diameter (const Triangulation<1> &tria); 
+                                    /**
+                                     * Same function, but for 1d, 2sd.
+                                     */
+    static
+    double diameter (const Triangulation<1,2> &tria);
 
                                     /**
                                      * Given a list of vertices (typically
@@ -90,7 +95,7 @@ class GridTools
     static
     double cell_measure (const std::vector<Point<dim> > &all_vertices,
                         const unsigned int (&vertex_indices)[GeometryInfo<dim>::vertices_per_cell]);
-
                                     /**
                                      * Remove vertices that are not
                                      * referenced by any of the
@@ -119,10 +124,13 @@ class GridTools
                                      * by that class, so we have to
                                      * eliminate unused vertices
                                      * beforehand.
+                                     * 
+                                     * Not implemented for the
+                                     * codimension one case.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void delete_unused_vertices (std::vector<Point<dim> >    &vertices,
+    void delete_unused_vertices (std::vector<Point<spacedim> >    &vertices,
                                 std::vector<CellData<dim> > &cells,
                                 SubCellData                 &subcelldata);
     
@@ -149,9 +157,9 @@ class GridTools
                                      * their difference in each coordinate
                                      * direction is less than @p tol.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void delete_duplicated_vertices (std::vector<Point<dim> >    &all_vertices,
+    void delete_duplicated_vertices (std::vector<Point<spacedim> >    &all_vertices,
                                     std::vector<CellData<dim> > &cells,
                                     SubCellData                 &subcelldata,
                                     std::vector<unsigned int>   &considered_vertices,
@@ -186,10 +194,10 @@ class GridTools
                                      * return value have to be of
                                      * type <tt>Point<dim></tt>.
                                      */
-    template <int dim, typename Predicate>
+    template <int dim, typename Predicate, int spacedim>
     static
     void transform (const Predicate    &predicate,
-                   Triangulation<dim> &triangulation);
+                   Triangulation<dim,spacedim> &triangulation);
 
                                     /**
                                      * Shift each vertex of the
@@ -202,10 +210,10 @@ class GridTools
                                      * hold for this function as
                                      * well.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void shift (const Point<dim>   &shift_vector,
-               Triangulation<dim> &triangulation);
+    void shift (const Point<spacedim>   &shift_vector,
+               Triangulation<dim,spacedim> &triangulation);
 
 
                                     /**
@@ -241,10 +249,10 @@ class GridTools
                                      * hold for this function as
                                      * well.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     void scale (const double        scaling_factor,
-               Triangulation<dim> &triangulation);
+               Triangulation<dim, spacedim> &triangulation);
 
                                      /**
                                       * Find and return the number of
@@ -258,11 +266,11 @@ class GridTools
                                       *
                                       * @author Ralf B. Schulz, 2006
                                       */
-    template <int dim, template <int> class Container>
+    template <int dim, template <int, int> class Container, int spacedim>
     static
     unsigned int
-    find_closest_vertex (const Container<dim> &container,
-                         const Point<dim>     &p);
+    find_closest_vertex (const Container<dim, spacedim> &container,
+                         const Point<spacedim>     &p);
 
                                      /**
                                       * Find and return a vector of
@@ -282,10 +290,10 @@ class GridTools
                                       * @author Ralf B. Schulz,
                                       * Wolfgang Bangerth, 2006
                                       */
-   template<int dim, template <int> class Container>
+   template<int dim, template <int, int> class Container, int spacedim>
    static
-   std::vector<typename Container<dim>::active_cell_iterator>
-   find_cells_adjacent_to_vertex (const Container<dim> &container,
+   std::vector<typename Container<dim,spacedim>::active_cell_iterator>
+   find_cells_adjacent_to_vertex (const Container<dim,spacedim> &container,
                                  const unsigned int    vertex);
 
 
@@ -317,11 +325,11 @@ class GridTools
                                       * local coordinate of the given point
                                       * without additional computational cost.
                                       */
-    template <int dim, typename Container>
+    template <int dim, template <int,int> class Container, int spacedim>
     static
-    typename Container::active_cell_iterator
-    find_active_cell_around_point (const Container  &container,
-                                   const Point<dim> &p);
+    typename Container<dim,spacedim>::active_cell_iterator
+    find_active_cell_around_point (const Container<dim,spacedim>  &container,
+                                   const Point<spacedim> &p);
 
                                      /**
                                       * Find and return an iterator to
@@ -377,12 +385,12 @@ class GridTools
                                       * This is not automatically performed
                                       * by the algorithm.
                                       */
-    template <int dim, template<int> class Container>
+    template <int dim, template<int, int> class Container, int spacedim>
     static
-    std::pair<typename Container<dim>::active_cell_iterator, Point<dim> >
-    find_active_cell_around_point (const Mapping<dim>   &mapping,
-                                   const Container<dim> &container,
-                                   const Point<dim>     &p);
+    std::pair<typename Container<dim,spacedim>::active_cell_iterator, Point<spacedim> >
+    find_active_cell_around_point (const Mapping<dim,spacedim>   &mapping,
+                                   const Container<dim,spacedim> &container,
+                                   const Point<spacedim>     &p);
 
                                     /**
                                      * A version of the previous function
@@ -394,12 +402,12 @@ class GridTools
                                      * finite element index for all other DoF
                                      * handlers is always zero.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    std::pair<typename hp::DoFHandler<dim>::active_cell_iterator, Point<dim> >
-    find_active_cell_around_point (const hp::MappingCollection<dim>   &mapping,
-                                   const hp::DoFHandler<dim> &container,
-                                   const Point<dim>     &p);
+    std::pair<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator, Point<spacedim> >
+    find_active_cell_around_point (const hp::MappingCollection<dim,spacedim>   &mapping,
+                                   const hp::DoFHandler<dim,spacedim> &container,
+                                   const Point<spacedim>     &p);
 
                                     /**
                                      * Return a list of all descendents of
@@ -450,10 +458,10 @@ class GridTools
                                      * cells as they are traversed in their
                                      * natural order using cell iterators.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    get_face_connectivity_of_cells (const Triangulation<dim> &triangulation,
-                                   SparsityPattern          &connectivity);
+    get_face_connectivity_of_cells (const Triangulation<dim, spacedim> &triangulation,
+                                   SparsityPattern                    &connectivity);
     
                                      /**
                                       * Use the METIS partitioner to generate
@@ -475,10 +483,10 @@ class GridTools
                                       * requires METIS when multiple
                                       * partitions are required.
                                       */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     void partition_triangulation (const unsigned int  n_partitions,
-                                  Triangulation<dim> &triangulation);
+                                  Triangulation<dim, spacedim> &triangulation);
 
                                     /**
                                      * This function does the same as the
@@ -556,11 +564,11 @@ class GridTools
                                      * you may want to build your own
                                      * connectivity graph.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     void partition_triangulation (const unsigned int     n_partitions,
                                  const SparsityPattern &cell_connection_graph,
-                                  Triangulation<dim>    &triangulation);
+                                  Triangulation<dim,spacedim>    &triangulation);
     
                                      /**
                                       * For each active cell, return in the
@@ -577,9 +585,9 @@ class GridTools
                                      * <tt>DoFTools::get_subdomain_association</tt>
                                      * function.
                                       */
-    template <int dim>
+    template <int dim, int spacedim>
     static void
-    get_subdomain_association (const Triangulation<dim>  &triangulation,
+    get_subdomain_association (const Triangulation<dim, spacedim>  &triangulation,
                                std::vector<unsigned int> &subdomain);
 
                                      /**
@@ -599,9 +607,9 @@ class GridTools
                                      * <tt>DoFTools::count_dofs_with_subdomain_association</tt>
                                      * function.
                                       */
-    template <int dim>
+    template <int dim, int spacedim>
     static unsigned int
-    count_cells_with_subdomain_association (const Triangulation<dim> &triangulation,
+    count_cells_with_subdomain_association (const Triangulation<dim, spacedim> &triangulation,
                                             const unsigned int        subdomain);
 
                                      /**
@@ -681,11 +689,11 @@ class GridTools
                                       * different refinement histories
                                       * beyond the coarse mesh.
                                       */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     bool
-    have_same_coarse_mesh (const Triangulation<dim> &mesh_1,
-                           const Triangulation<dim> &mesh_2);
+    have_same_coarse_mesh (const Triangulation<dim, spacedim> &mesh_1,
+                           const Triangulation<dim, spacedim> &mesh_2);
 
                                      /**
                                       * The same function as above,
@@ -712,19 +720,19 @@ class GridTools
                                      * @ref step_24 "step-24" for an example
                                      * of use of this function.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     double
-    minimal_cell_diameter (const Triangulation<dim> &triangulation);
+    minimal_cell_diameter (const Triangulation<dim, spacedim> &triangulation);
 
                                     /**
                                      * Return the diamater of the largest
                                      * active cell of a triangulation.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     double
-    maximal_cell_diameter (const Triangulation<dim> &triangulation);
+    maximal_cell_diameter (const Triangulation<dim, spacedim> &triangulation);
 
                                     /**
                                      * Given the two triangulations
@@ -742,12 +750,12 @@ class GridTools
                                      * derived from the same coarse
                                      * grid.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     void
-    create_union_triangulation (const Triangulation<dim> &triangulation_1,
-                               const Triangulation<dim> &triangulation_2,
-                               Triangulation<dim>       &result);
+    create_union_triangulation (const Triangulation<dim, spacedim> &triangulation_1,
+                               const Triangulation<dim, spacedim> &triangulation_2,
+                               Triangulation<dim, spacedim>       &result);
     
                                      /**
                                       * Exception
@@ -802,9 +810,9 @@ class GridTools
 
 /* ----------------- Template function --------------- */
 
-template <int dim, typename Predicate>
+template <int dim, typename Predicate, int spacedim>
 void GridTools::transform (const Predicate    &predicate,
-                          Triangulation<dim> &triangulation)
+                          Triangulation<dim, spacedim> &triangulation)
 {
   Assert (triangulation.n_levels() == 1,
          ExcTriangulationHasBeenRefined());
@@ -818,7 +826,7 @@ void GridTools::transform (const Predicate    &predicate,
                                   // that we get to all vertices in
                                   // the triangulation by only
                                   // visiting the active cells.
-  typename Triangulation<dim>::active_cell_iterator
+  typename Triangulation<dim, spacedim>::active_cell_iterator
     cell = triangulation.begin_active (),
     endc = triangulation.end ();
   for (; cell!=endc; ++cell)
@@ -924,13 +932,20 @@ GridTools::get_active_neighbors(const typename Container::active_cell_iterator
 
 
 // declaration of explicit specializations
+
 template <>
 double
-GridTools::cell_measure(const std::vector<Point<2> > &all_vertices,
-                       const unsigned int (&vertex_indices) [GeometryInfo<2>::vertices_per_cell]);
-
+GridTools::cell_measure<3>(const std::vector<Point<3> > &all_vertices,
+                       const unsigned int (&vertex_indices) [GeometryInfo<3>::vertices_per_cell]);
 
+template <>
+double
+GridTools::cell_measure<2>(const std::vector<Point<2> > &all_vertices,
+                       const unsigned int (&vertex_indices) [GeometryInfo<2>::vertices_per_cell]);
 
+// double
+// GridTools::cell_measure<2,3>(const std::vector<Point<3> > &all_vertices,
+//                     const unsigned int (&vertex_indices) [GeometryInfo<2>::vertices_per_cell]);
 
 
 DEAL_II_NAMESPACE_CLOSE
index 90c9960edd0890266fe9b7ce6fc67c486b6a28ad..4f9ae16e59ae3e5642c9cf0ba26ebba5a9c294bb 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class Boundary;
-template <int dim> class StraightBoundary;
+template <int dim, int spacedim> class Boundary;
+template <int dim, int spacedim> class StraightBoundary;
 
-template <int, int> class TriaObjectAccessor;
+template <int, int, int> class TriaAccessor;
+template <int, int, int> class TriaAccessor;
 
 namespace internal
 {
@@ -39,18 +40,18 @@ namespace internal
     template <int dim> class TriaFaces;
   }
 }
-template <int dim> class DoFHandler;
+template <int dim, int spacedim> class DoFHandler;
 namespace hp
 {
-  template <int dim> class DoFHandler;
+  template <int dim, int spacedim> class DoFHandler;
 }
-template <int dim> class MGDoFHandler;
+template <int dim, int spacedim> class MGDoFHandler;
 
 /*------------------------------------------------------------------------*/
 
 /**
  *  Structure which is passed to the
- *  <tt>Triangulation<dim>::create_triangulation</tt> function. It
+ *  <tt>Triangulation<dim,spacedim>::create_triangulation</tt> function. It
  *  contains all data needed to construct a cell, namely the indices
  *  of the vertices and the material indicator.
  *
@@ -76,14 +77,14 @@ struct CellData
 
 
 /**
- *  Structure to be passed to the Triangulation<dim>::create_triangulation
+ *  Structure to be passed to the Triangulation<dim,spacedim>::create_triangulation
  *  function to describe boundary information.
  *
  *  This structure is the same for all dimensions, since we use an input
  *  function which is the same for all dimensions. The content of objects
  *  of this structure varies with the dimensions, however.
  *
- *  Since in one space dimension, there is no boundary information apart
+ *  Since in one dimension, there is no boundary information apart
  *  from the two end points of the interval, this structure does not contain
  *  anything and exists only for consistency, to allow a common interface
  *  for all space dimensions. All fields should always be empty.
@@ -289,7 +290,7 @@ namespace internal
  *
  * In the old days, whenever one wanted to access one of these
  * numbers, one had to perform a loop over all lines, e.g., and count
- * the elements until we hit the end iterator. This is time consuming
+ * the elements until we hit the end . This is time consuming
  * and since access to the number of lines etc is a rather frequent
  * operation, this was not an optimal solution.
  *
@@ -345,7 +346,16 @@ namespace internal
 
 /**
  *  Triangulations denote a hierarchy of levels of elements which together
- *  form a region in @p dim spatial dimensions.
+ *  form a @p dim -dimensional manifold in @p spacedim spatial dimensions 
+ *  (if spacedim is not specified it takes the default value @ spacedim=dim).
+ *  
+ *  Thus, for example, an object of type @p Triangulation<1,1> (or simply 
+ *  @p Triangulation<1> since @p spacedim==dim by default) is used to represent 
+ *  and handle the usual one-dimensional triangulation used in the finite 
+ *  element method (so, segments on a straight line). On the other hand, 
+ *  objects such as @p Triangulation<1,2> or @p Triangulation<2,3> (that 
+ *  are associated with curves in 2D or surfaces in 3D) 
+ *  are the ones one wants to use in the boundary element method.
  *
  *  This class is written to be as independent of the dimension as possible
  *  (thus the complex construction of the internal::Triangulation::TriaLevel
@@ -410,7 +420,7 @@ namespace internal
  *  By using the cell iterators, you can write code nearly independent of
  *  the spatial dimension. The same applies for substructure iterators,
  *  where a substructure is defined as a face of a cell. The face of a
- *  cell is be a vertex in 1D and a line in 2D; however, vertices are
+ *  cell is a vertex in 1D and a line in 2D; however, vertices are
  *  handled in a different way and therefore lines have no faces.
  *
  *  The Triangulation class offers functions like @p begin_active which gives
@@ -418,12 +428,14 @@ namespace internal
  *  returning iterators. Take a look at the class doc to get an overview.
  *
  *  Usage of these iterators works mostly like with the STL iterators. Some
- *  examples taken from the Triangulation source code follow.
+ *  examples taken from the Triangulation source code follow (notice that in the last
+ *  two examples the template parameter @p spacedim has been omitted, so it takes
+ *  the default value @ dim).
  *  <ul>
  *  <li> <em>Counting the number of cells on a specific level</em>
  *    @verbatim
- *     template <int dim>
- *     int Triangulation<dim>::n_cells (const int level) const {
+ *     template <int dim, int spacedim>
+ *     int Triangulation<dim, spacedim>::n_cells (const int level) const {
  *        cell_iterator cell = begin (level),
  *                      endc = end(level);
  *        int n=0;
@@ -530,7 +542,7 @@ namespace internal
  *
  *        Creating the hierarchical information needed for this
  *        library from cells storing only vertex information can be
- *        quite a complex task.  For example in 2d, we have to create
+ *        quite a complex task.  For example in 2D, we have to create
  *        lines between vertices (but only once, though there are two
  *        cells which link these two vertices) and we have to create
  *        neighborship information. Grids being read in should
@@ -547,7 +559,7 @@ namespace internal
  *        To guarantee this, in the input vector keeping the cell list, the
  *        vertex indices for each cell have to be in a defined order, see the
  *        documentation of GeometryInfo<dim>. In one dimension, the first vertex
- *        index must refer to that vertex with the lower coordinate value. In 2d
+ *        index must refer to that vertex with the lower coordinate value. In 2D
  *        and 3D, the correspondoing conditions are not easy to verify and no
  *        full attempt to do so is made.
  *        If you violate this condition, you may end up with matrix entries
@@ -560,7 +572,7 @@ namespace internal
  *        the vertex numbering within cells. They do not only hold for
  *        the data read from an UCD or any other input file, but also
  *        for the data passed to the
- *        <tt>Triangulation<dim>::create_triangulation ()</tt>
+ *        <tt>Triangulation<dim,spacedim>::create_triangulation ()</tt>
  *        function. See the documentation for the GridIn class
  *        for more details on this, and above all to the
  *        GridReordering class that explains many of the
@@ -568,13 +580,13 @@ namespace internal
  *        satisfy the conditions outlined above.
  *
  *     <li> Copying a triangulation: when computing on time dependent meshes
- *        of when using adaptive refinement, you will often want to create a
+ *        or when using adaptive refinement, you will often want to create a
  *        new triangulation to be the same as another one. This is facilitated
  *        by the @p copy_triangulation function.
  *
  *        It is guaranteed that vertex, line or cell numbers in the two
  *        triangulations are the same and that two iterators walking on the
- *        two triangulations visit matching cells if the are incremented in
+ *        two triangulations visit matching cells if they are incremented in
  *        parallel. It may be conceivable to implement a clean-up in the copy
  *        operation, which eliminates holes of unused memory, re-joins
  *        scattered data and so on. In principle this would be a useful
@@ -584,7 +596,7 @@ namespace internal
  *   </ul>
  *
  *   Finally, there is a special function for folks who like bad grids:
- *   <tt>Triangulation<dim>::distort_random</tt>. It moves all the vertices in the
+ *   <tt>Triangulation<dim,spacedim>::distort_random</tt>. It moves all the vertices in the
  *   grid a bit around by a random value, leaving behind a distorted mesh.
  *   Note that you should apply this function to the final mesh, since
  *   refinement smoothes the mesh a bit.
@@ -1180,7 +1192,7 @@ namespace internal
  * @ingroup grid aniso
  * @author Wolfgang Bangerth, 1998; Ralf Hartmann, 2005
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 class Triangulation : public Subscriptor
 {
   private:
@@ -1190,7 +1202,7 @@ class Triangulation : public Subscriptor
                                      * the definition of the iterator
                                      * classes simpler.
                                      */
-    typedef internal::Triangulation::Iterators<dim> IteratorSelector;
+    typedef internal::Triangulation::Iterators<dim, spacedim> IteratorSelector;
                      
   public:
                                     /**
@@ -1199,8 +1211,18 @@ class Triangulation : public Subscriptor
                                      * boundary object has been explicitly
                                      * set using set_boundary().
                                      */
-    static const StraightBoundary<dim> straight_boundary;
-    
+    static const StraightBoundary<dim,spacedim> straight_boundary;
+
+                                    /** 
+                                     * Default boundary object to be
+                                     * used in the codimension 1
+                                     * case.  This is used for those
+                                     * boundaries for which no
+                                     * boundary object has been
+                                     * explicitly set using
+                                     * set_boundary().
+                                     */
+    static const StraightBoundary<spacedim,spacedim> straight_manifold_description;
                                     /**
                                      * Declare some symbolic names
                                      * for mesh smoothing
@@ -1291,7 +1313,7 @@ class Triangulation : public Subscriptor
                                           */
         virtual
         void
-        pre_refinement_notification (const Triangulation<dim> &tria);
+        pre_refinement_notification (const Triangulation<dim, spacedim> &tria);
         
                                          /**
                                           * After refinement is actually
@@ -1302,7 +1324,7 @@ class Triangulation : public Subscriptor
                                           */
         virtual
         void
-        post_refinement_notification (const Triangulation<dim> &tria);
+        post_refinement_notification (const Triangulation<dim, spacedim> &tria);
 
                                          /**
                                           * At the end of a call to
@@ -1320,8 +1342,8 @@ class Triangulation : public Subscriptor
                                           */
         virtual
         void
-        copy_notification (const Triangulation<dim> &old_tria,
-                          const Triangulation<dim> &new_tria);
+        copy_notification (const Triangulation<dim, spacedim> &old_tria,
+                          const Triangulation<dim, spacedim> &new_tria);
     };
     
                                     /**
@@ -1330,6 +1352,12 @@ class Triangulation : public Subscriptor
                                      */
     static const unsigned int dimension = dim;
 
+                                    /**
+                                     * Make the space-dimension available
+                                     * in function templates.
+                                     */
+    static const unsigned int space_dimension = spacedim;
+
                                     /**
                                      *  Create an empty
                                      *  triangulation. Do not create
@@ -1369,7 +1397,7 @@ class Triangulation : public Subscriptor
                                      *  code has to be changed to
                                      *  avoid copies.
                                      */
-    Triangulation (const Triangulation<dim> &t);
+    Triangulation (const Triangulation<dim, spacedim> &t);
     
                                     /**
                                      *  Delete the object and all levels of
@@ -1389,16 +1417,25 @@ class Triangulation : public Subscriptor
     void clear ();
     
                                     /**                                        
-                                     * Assign a boundary object to a certain
-                                     * part of the boundary of a the
-                                     * triangulation. If a face with boundary
-                                     * number @p number is refined, this
-                                     * object is used to find the location of
-                                     * new vertices on the boundary. It is
-                                     * also used for for non-linear (i.e.:
-                                     * non-Q1) transformations of cells to
-                                     * the unit cell in shape function
-                                     * calculations.
+                                     * If @p dim==spacedim, assign a boundary
+                                     * object to a certain part of the
+                                     * boundary of a the triangulation. If a
+                                     * face with boundary number @p number is
+                                     * refined, this object is used to find
+                                     * the location of new vertices on the
+                                     * boundary. It is also used for for
+                                     * non-linear (i.e.: non-Q1)
+                                     * transformations of cells to the unit
+                                     * cell in shape function calculations.
+                                     * 
+                                     * If @p dim!=spacedim the boundary object
+                                     * is in fact the exact manifold that the
+                                     * triangulation is approximating (for
+                                     * example a circle approximated by a
+                                     * polygon triangulation). As above, the
+                                     * refinement is made in such a way that
+                                     * the new points are located on the exact
+                                     * manifold.
                                      *
                                      * Numbers of boundary objects correspond
                                      * to material numbers of faces at the
@@ -1432,7 +1469,7 @@ class Triangulation : public Subscriptor
                                      * approximation.
                                      */
     void set_boundary (const unsigned int   number,
-                      const Boundary<dim> &boundary_object);
+                      const Boundary<dim,spacedim> &boundary_object);
 
                                      /**
                                       * Reset those parts of the boundary with
@@ -1452,7 +1489,7 @@ class Triangulation : public Subscriptor
                                      * the same as in
                                      * @p set_boundary
                                      */
-    const Boundary<dim> & get_boundary (const unsigned int number) const;
+    const Boundary<dim,spacedim> & get_boundary (const unsigned int number) const;
 
                                     /**
                                      * Returns a vector containing
@@ -1512,7 +1549,7 @@ class Triangulation : public Subscriptor
                                      *  new Triangulation as well, if that is
                                      *  desired.
                                      */
-    virtual void copy_triangulation (const Triangulation<dim> &old_tria);
+    virtual void copy_triangulation (const Triangulation<dim, spacedim> &old_tria);
 
                                     /**
                                      * Create a triangulation from a
@@ -1549,7 +1586,7 @@ class Triangulation : public Subscriptor
                                      * and the GridIn and
                                      * GridReordering class.
                                      */
-    virtual void create_triangulation (const std::vector<Point<dim> >    &vertices,
+    virtual void create_triangulation (const std::vector<Point<spacedim> >    &vertices,
                                       const std::vector<CellData<dim> > &cells,
                                       const SubCellData                 &subcelldata);
 
@@ -1564,7 +1601,7 @@ class Triangulation : public Subscriptor
                                      * create_triangulation().
                                      */
     virtual void create_triangulation_compatibility (
-      const std::vector<Point<dim> >    &vertices,
+      const std::vector<Point<spacedim> >    &vertices,
       const std::vector<CellData<dim> > &cells,
       const SubCellData                 &subcelldata);
 
@@ -1674,13 +1711,6 @@ class Triangulation : public Subscriptor
                                      * class for more information on
                                      * smoothing upon refinement.
                                      *
-                                     * This part of the function is
-                                     * mostly dimension
-                                     * independent. However, for some
-                                     * dimension dependent things, it
-                                     * calls
-                                     * @p prepare_refinement_dim_dependent.
-                                     *
                                      * Regarding the coarsening part,
                                      * flagging and deflagging cells
                                      * in preparation of the actual
@@ -2582,9 +2612,9 @@ class Triangulation : public Subscriptor
                                      * 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
+                                     * 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
+                                     * <tt>n_lines()</tt>, as lines are faces in 2D and
                                      * therefore have no level.
                                      */
     
@@ -2734,8 +2764,8 @@ class Triangulation : public Subscriptor
 
                                     /**
                                      *  Return total number of used faces,
-                                     *  active or not.  In 2d, the result
-                                     *  equals n_lines(), while in 3d it
+                                     *  active or not.  In 2D, the result
+                                     *  equals n_lines(), while in 3D it
                                      *  equals n_quads(). Since there are no
                                      *  face objects in 1d, the function
                                      *  returns zero in 1d.
@@ -2744,8 +2774,8 @@ class Triangulation : public Subscriptor
 
                                     /**
                                      *  Return total number of active faces,
-                                     *  active or not.  In 2d, the result
-                                     *  equals n_active_lines(), while in 3d
+                                     *  active or not.  In 2D, the result
+                                     *  equals n_active_lines(), while in 3D
                                      *  it equals n_active_quads(). Since
                                      *  there are no face objects in 1d, the
                                      *  function returns zero in 1d.
@@ -2797,7 +2827,7 @@ class Triangulation : public Subscriptor
                                      * used by the function
                                      * get_used_vertices().
                                      */
-    const std::vector<Point<dim> > &
+    const std::vector<Point<spacedim> > &
     get_vertices () const;
 
                                     /**
@@ -3018,23 +3048,28 @@ class Triangulation : public Subscriptor
 
                                     /**
                                      *  Write a bool vector to the given stream,
-                                     *  writing a pre- and a postfix magica
+                                     *  writing a pre- and a postfix magic
                                      *  number. The vector is written in an
                                      *  almost binary format, i.e. the bool
                                      *  flags are packed but the data is written
                                      *  as ASCII text.
                                      *
-                                     *  The flags are stored in a binary
-                                     *  format: for each @p true, a @p 1
-                                     *  bit is stored, a @p 0 bit otherwise.
-                                     *  The bits are stored as <tt>unsigned char</tt>,
-                                     *  thus avoiding endianess. They are
-                                     *  written to @p out in plain text, thus
-                                     *  amounting to 3.6 bits per active cell
-                                     *  on the average. Other information
-                                     *  (magic numbers ans number of elements)
-                                     *  is stored as plain text
-                                     *  as well. The format should therefore be
+                                     *  The flags are stored in a
+                                     *  binary format: for each @p
+                                     *  true, a @p 1 bit is stored, a
+                                     *  @p 0 bit otherwise.  The bits
+                                     *  are stored as <tt>unsigned
+                                     *  char</tt>, thus avoiding
+                                     *  endianess. They are written
+                                     *  to @p out in plain text, thus
+                                     *  amounting to 3.6 bits in the
+                                     *  output per bits in the input
+                                     *  on the average. Other
+                                     *  information (magic numbers
+                                     *  and number of elements of the
+                                     *  input vector) is stored as
+                                     *  plain text as well. The
+                                     *  format should therefore be
                                      *  interplatform compatible.
                                      */
     static void write_bool_vector (const unsigned int       magic_number1,
@@ -3103,164 +3138,12 @@ class Triangulation : public Subscriptor
                                      */
     void execute_coarsening ();
 
-                                    /**
-                                     * Actually refine a cell, i.e. create its
-                                     * children. The faces of the cell have to
-                                     * be refined already, whereas the inner
-                                     * lines in 2D or lines and quads in 3D
-                                     * will be created in this
-                                     * function. Therefore iterator pointers
-                                     * into the vectors of lines, quads and
-                                     * cells have to be passed, which point at
-                                     * (or "before") the reserved space.
-                                     */
-    void create_children (unsigned int &next_unused_vertex,
-                         raw_line_iterator &next_unused_line,
-                         raw_quad_iterator &next_unused_quad,
-                         raw_cell_iterator &next_unused_cell,
-                         cell_iterator &cell);
-
-                                    /**
-                                     * Actually delete a cell, or rather all
-                                     * its children, which is the main step for
-                                     * the coarsening process.  This is the
-                                     * dimension dependent part of @p
-                                     * execute_coarsening. The second argument
-                                     * is a vector which gives for each line
-                                     * index the number of cells containing
-                                     * this line. This information is needed to
-                                     * decide whether a refined line may be
-                                     * coarsened or not in 3D. In 1D and 2D
-                                     * this argument is not needed and thus
-                                     * ignored. The same applies for the last
-                                     * argument and quads instead of lines.
-                                     */
-    void delete_children (cell_iterator &cell,
-                         std::vector<unsigned int> &line_cell_count,
-                         std::vector<unsigned int> &quad_cell_count);
-
-                                    /**
-                                     * Set the neighbor information of all
-                                     * outer neighbor of all children of the
-                                     * given cell <tt>cell</tt>, if
-                                     * <tt>refining=true</tt>. In this
-                                     * constellation the function is called
-                                     * after the creation of children in @p
-                                     * execute_refinement. If
-                                     * <tt>refining=false</tt>, it is assumed,
-                                     * that the given cell is just coarsened,
-                                     * i.e. that its children are about to be
-                                     * deleted, thus they do not need new
-                                     * neighbor information.
-                                     *
-                                     * In both cases, the neighbor information
-                                     * of the cell's neighbors are updated, if
-                                     * necessary.
-                                     */
-    void update_neighbors (cell_iterator &cell,
-                          bool refining);
-    
-                                    /**
-                                     * Fill the vector @p line_cell_count
-                                     * needed by @p delete_children with the
-                                     * number of cells containing a given
-                                     * line. As this is only needed in 3D, it
-                                     * is only implemented there and throws an
-                                     * exception otherwise.
-                                     */
-    void count_cells_at_line (std::vector<unsigned int> &line_cell_count);
-
-                                    /**
-                                     * Fill the vector @p quad_cell_count
-                                     * needed by @p delete_children with the
-                                     * number of cells containing a given
-                                     * quad. As this is only needed in 3D, it
-                                     * is only implemented there and throws an
-                                     * exception otherwise.
-                                     */
-    void count_cells_at_quad (std::vector<unsigned int> &quad_cell_count);
-
-                                    /**
-                                     * Some dimension dependent stuff for
-                                     * mesh smoothing.
-                                     *
-                                     * At present, this function does nothing
-                                     * in 1d and 2d, but makes sure no two
-                                     * cells with a level difference greater
-                                     * than one share one line in 3d. This
-                                     * is a requirement needed for the
-                                     * interpolation of hanging nodes, since
-                                     * otherwise to steps of interpolation
-                                     * would be necessary. This would make
-                                     * the processes implemented in the
-                                     * @p ConstraintMatrix class much more
-                                     * complex, since these two steps of
-                                     * interpolation do not commute.
-                                     */
-    void prepare_refinement_dim_dependent ();
-
-                                    /**
-                                     * At the boundary of the domain, the new
-                                     * point on the face may be far inside the
-                                     * current cell, if the boundary has a
-                                     * strong curvature. If we allow anisotropic
-                                     * refinement here, the resulting cell may
-                                     * be strongly distorted. To prevent this,
-                                     * this function flags such cells for
-                                     * isotropic refinement. It is called
-                                     * automatically from
-                                     * prepare_coarsening_and_refinement().
-                                     */
-    void prevent_distorted_boundary_cells ();
-
                                     /**
                                      * Make sure that either all or none of
                                      * the children of a cell are tagged for
                                      * coarsening.
                                      */
     void fix_coarsen_flags ();
-    
-                                    /**
-                                     * Helper function for
-                                     * @p fix_coarsen_flags. Return wether 
-                                     * coarsening of this cell is allowed.
-                                     * Coarsening can be forbidden if the
-                                     * neighboring cells are or will be
-                                     * refined twice along the common face. 
-                                     */
-    bool coarsening_allowed (cell_iterator& cell);
-
-                                    /**
-                                     * Re-compute the number of
-                                     * lines, quads, etc. This
-                                     * function is called by
-                                     * @p execute_coarsening_and_refinement
-                                     * and by
-                                     * @p create_triangulation after
-                                     * the grid was changed.
-                                     *
-                                     * This function simply delegates
-                                     * to the functions below, which
-                                     * count only a certain class of
-                                     * objects.
-                                     */
-    void update_number_cache ();
-
-                                    /**
-                                     * Recompute the number of lines.
-                                     */
-    void update_number_cache_lines ();
-
-                                    /**
-                                     * Recompute the number of quads.
-                                     */
-    void update_number_cache_quads ();
-
-                                    /**
-                                     * Recompute the number of hexes.
-                                     */
-    void update_number_cache_hexes ();
-
 
                                     /**
                                      *  Array of pointers pointing to the
@@ -3271,8 +3154,8 @@ class Triangulation : public Subscriptor
 
                                     /**
                                      *  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
+                                     *  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.
                                      */
@@ -3283,7 +3166,7 @@ class Triangulation : public Subscriptor
                                      *  Array of the vertices of this
                                      *  triangulation.
                                      */
-    std::vector<Point<dim> >              vertices;
+    std::vector<Point<spacedim> >              vertices;
 
                                     /**
                                      *  Array storing a bit-pattern which
@@ -3300,7 +3183,18 @@ class Triangulation : public Subscriptor
                                      *  and can thus never be
                                      *  associated with a boundary.
                                      */
-    SmartPointer<const Boundary<dim> > boundary[255];
+    SmartPointer<const Boundary<dim,spacedim> > boundary[255];
+
+                                    /**
+                                     *  Collection of ly
+                                     *  objects. We only need 255
+                                     *  objects rather than 256,
+                                     *  since the indicator 255 is
+                                     *  reserved for interior faces
+                                     *  and can thus never be
+                                     *  associated with a boundary.
+                                     */
+    SmartPointer<const Boundary<spacedim,spacedim> > manifold_description[255];
 
                                     /**
                                      * Flag indicating whether
@@ -3342,38 +3236,50 @@ class Triangulation : public Subscriptor
                                      */    
     mutable std::list<RefinementListener *> refinement_listeners;
 
+                                    /**
+                                     * Forward declaration of a class
+                                     * into which we put significant
+                                     * parts of the implementation.
+                                     *
+                                     * See the .cc file for more
+                                     * information.
+                                     */
+    struct Implementation;
+    
                                     // make a couple of classes
                                     // friends
-    template <int,int> friend class TriaAccessor;
+    template <int,int,int> friend class TriaAccessorBase;
+    template <int,int,int> friend class TriaAccessor;
 
-    template <int dim1, int dim2>
-    friend class TriaObjectAccessor;
+    template <int dim1, int dim2, int dim3>
+    friend class TriaAccessor;
     
-    friend class CellAccessor<dim>;
+    friend class CellAccessor<dim, spacedim>;
     
-    friend class TriaRawIterator<1,TriaObjectAccessor<1, 1> >;
-    friend class TriaRawIterator<1,CellAccessor<1> >;
+    friend class TriaRawIterator<TriaAccessor<1, 1, 1> >;
+    friend class TriaRawIterator<CellAccessor<1, 1> >;
 
-    friend class TriaRawIterator<2,TriaObjectAccessor<1, 2> >;
-    friend class TriaRawIterator<2,TriaObjectAccessor<2, 2> >;
-    friend class TriaRawIterator<2,CellAccessor<2> >;
+    friend class TriaRawIterator<TriaAccessor<1, 2, 2> >;
+    friend class TriaRawIterator<TriaAccessor<2, 2, 2> >;
+    friend class TriaRawIterator<CellAccessor<2, 2> >;
 
-    friend class TriaRawIterator<3,TriaObjectAccessor<1, 3> >;
-    friend class TriaRawIterator<3,TriaObjectAccessor<2, 3> >;
-    friend class TriaRawIterator<3,TriaObjectAccessor<3, 3> >;
-    friend class TriaRawIterator<3,CellAccessor<3> >;
-    
-    friend class hp::DoFHandler<dim>;
+    friend class TriaRawIterator<TriaAccessor<1, 3, 3> >;
+    friend class TriaRawIterator<TriaAccessor<2, 3, 3> >;
+    friend class TriaRawIterator<TriaAccessor<3, 3, 3> >;
+    friend class TriaRawIterator<CellAccessor<3, 3> >;
     
+    friend class hp::DoFHandler<dim,spacedim>;
+
+    friend class Triangulation<dim,spacedim>::Implementation;
 };
 
 
 #ifndef DOXYGEN
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 bool
-Triangulation<dim>::vertex_used(const unsigned int index) const
+Triangulation<dim,spacedim>::vertex_used(const unsigned int index) const
 {
   Assert (index < vertices_used.size(),
          ExcIndexRange(index, 0, vertices_used.size()));
@@ -3383,166 +3289,38 @@ Triangulation<dim>::vertex_used(const unsigned int index) const
 
 /* -------------- declaration of explicit specializations ------------- */
 
+template <> unsigned int Triangulation<1,1>::n_raw_lines (const unsigned int level) const;
+template <> unsigned int Triangulation<1,1>::n_quads () const;
+template <> unsigned int Triangulation<1,1>::n_quads (const unsigned int level) const;
+template <> unsigned int Triangulation<1,1>::n_raw_quads (const unsigned int level) const;
+template <> unsigned int Triangulation<2,2>::n_raw_quads (const unsigned int level) const;
+template <> unsigned int Triangulation<1,1>::n_raw_quads () const;
+template <> unsigned int Triangulation<1,1>::n_raw_hexs (const unsigned int level) const;
+template <> unsigned int Triangulation<1,1>::n_active_quads (const unsigned int level) const;
+template <> unsigned int Triangulation<1,1>::n_active_quads () const;
+template <> unsigned int Triangulation<1,1>::max_adjacent_cells () const;
+
+
+// -------------------------------------------------------------------
+// -- Explicit specializations for codimension one grids
+
+
+template <> unsigned int Triangulation<1,2>::n_raw_lines (const unsigned int level) const;
+template <> unsigned int Triangulation<1,2>::n_quads () const;
+template <> unsigned int Triangulation<1,2>::n_quads (const unsigned int level) const;
+template <> unsigned int Triangulation<1,2>::n_raw_quads (const unsigned int level) const;
+template <> unsigned int Triangulation<2,3>::n_raw_quads (const unsigned int level) const;
+template <> unsigned int Triangulation<1,2>::n_raw_quads () const;
+template <> unsigned int Triangulation<1,2>::n_raw_hexs (const unsigned int level) const;
+template <> unsigned int Triangulation<1,2>::n_active_quads (const unsigned int level) const;
+template <> unsigned int Triangulation<1,2>::n_active_quads () const;
+template <> unsigned int Triangulation<1,2>::max_adjacent_cells () const;
+
+
+// -------------------------------------------------------------------
+
 
 
-template <> Triangulation<1>::cell_iterator Triangulation<1>::begin (const unsigned int level) const;
-template <> Triangulation<1>::raw_cell_iterator Triangulation<1>::end () const;
-template <> Triangulation<2>::cell_iterator Triangulation<2>::begin (const unsigned int level) const;
-template <> Triangulation<2>::raw_cell_iterator Triangulation<2>::end () const;
-template <> Triangulation<3>::cell_iterator Triangulation<3>::begin (const unsigned int level) const;
-template <> Triangulation<3>::raw_cell_iterator Triangulation<3>::end () const;
-template <> void Triangulation<1>::create_triangulation (const std::vector<Point<1> >    &v,
-                                                        const std::vector<CellData<1> > &cells,
-                                                        const SubCellData                          &subcelldata);
-template <> void Triangulation<2>::create_triangulation (const std::vector<Point<2> >    &v,
-                                                        const std::vector<CellData<2> > &cells,
-                                                        const SubCellData                          &subcelldata);
-template <> void Triangulation<3>::create_triangulation (const std::vector<Point<3> >    &v,
-                                                        const std::vector<CellData<3> > &cells,
-                                                        const SubCellData                          &subcelldata);
-template <> void Triangulation<1>::distort_random (const double factor,
-                                                  const bool   keep_boundary);
-template <> void Triangulation<1>::clear_user_pointers ();
-template <> void Triangulation<1>::clear_user_flags ();
-template <> void Triangulation<2>::clear_user_pointers ();
-template <> void Triangulation<2>::clear_user_flags ();
-template <> void Triangulation<3>::clear_user_pointers ();
-template <> void Triangulation<3>::clear_user_flags ();
-template <> void Triangulation<1>::clear_user_flags_line ();
-template <> void Triangulation<1>::clear_user_flags_quad ();
-template <> void Triangulation<1>::save_user_flags_quad (std::ostream &) const;
-template <> void Triangulation<1>::save_user_flags_quad (std::vector<bool> &) const;
-template <> void Triangulation<1>::load_user_flags_quad (std::istream &);
-template <> void Triangulation<1>::load_user_flags_quad (const std::vector<bool> &);
-template <> void Triangulation<1>::clear_user_flags_hex ();
-template <> void Triangulation<1>::save_user_flags_hex (std::ostream &) const;
-template <> void Triangulation<1>::save_user_flags_hex (std::vector<bool> &) const;
-template <> void Triangulation<1>::load_user_flags_hex (std::istream &);
-template <> void Triangulation<1>::load_user_flags_hex (const std::vector<bool> &);
-template <> void Triangulation<2>::clear_user_flags_quad ();
-template <> void Triangulation<2>::clear_user_flags_hex ();
-template <> void Triangulation<2>::save_user_flags_hex (std::ostream &) const;
-template <> void Triangulation<2>::save_user_flags_hex (std::vector<bool> &) const;
-template <> void Triangulation<2>::load_user_flags_hex (std::istream &);
-template <> void Triangulation<2>::load_user_flags_hex (const std::vector<bool> &);
-template <> void Triangulation<3>::clear_user_flags_quad ();
-template <> void Triangulation<3>::clear_user_flags_hex ();
-template <> Triangulation<1>::raw_cell_iterator Triangulation<1>::begin_raw (const unsigned int level) const;
-template <> Triangulation<1>::active_cell_iterator Triangulation<1>::begin_active (const unsigned int level) const;
-template <> Triangulation<1>::raw_cell_iterator Triangulation<1>::last_raw () const;
-template <> Triangulation<1>::raw_cell_iterator Triangulation<1>::last_raw (const unsigned int level) const;
-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;
-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>::face_iterator Triangulation<1>::last_face () const;
-template <> Triangulation<1>::active_face_iterator Triangulation<1>::last_active_face () const;
-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 <> Triangulation<1>::raw_quad_iterator Triangulation<1>::begin_raw_quad (const unsigned int level) const;
-template <> Triangulation<1>::quad_iterator Triangulation<1>::begin_quad (const unsigned int level) const;
-template <> Triangulation<1>::active_quad_iterator Triangulation<1>::begin_active_quad (const unsigned int level) const;
-template <> Triangulation<1>::raw_quad_iterator Triangulation<1>::end_quad () const;
-template <> Triangulation<1>::raw_quad_iterator Triangulation<1>::last_raw_quad (const unsigned int level) const;
-template <> Triangulation<1>::raw_quad_iterator Triangulation<1>::last_raw_quad () const;
-template <> Triangulation<1>::quad_iterator Triangulation<1>::last_quad (const unsigned int level) const;
-template <> Triangulation<1>::quad_iterator Triangulation<1>::last_quad () const;
-template <> Triangulation<1>::active_quad_iterator Triangulation<1>::last_active_quad (const unsigned int level) const;
-template <> Triangulation<1>::active_quad_iterator Triangulation<1>::last_active_quad () const;
-template <> Triangulation<1>::raw_hex_iterator Triangulation<1>::begin_raw_hex (const unsigned int level) const;
-template <> Triangulation<1>::hex_iterator Triangulation<1>::begin_hex (const unsigned int) const;
-template <> Triangulation<1>::active_hex_iterator Triangulation<1>::begin_active_hex (const unsigned int level) const;
-template <> Triangulation<1>::raw_hex_iterator Triangulation<1>::end_hex () const;
-template <> Triangulation<1>::raw_hex_iterator Triangulation<1>::last_raw_hex (const unsigned int level) const;
-template <> Triangulation<1>::raw_hex_iterator Triangulation<1>::last_raw_hex () const;
-template <> Triangulation<1>::hex_iterator Triangulation<1>::last_hex (const unsigned int level) const;
-template <> Triangulation<1>::hex_iterator Triangulation<1>::last_hex () const;
-template <> Triangulation<1>::active_hex_iterator Triangulation<1>::last_active_hex (const unsigned int level) const;
-template <> Triangulation<1>::active_hex_iterator Triangulation<1>::last_active_hex () const;
-template <> Triangulation<2>::raw_cell_iterator Triangulation<2>::begin_raw (const unsigned int level) const;
-template <> Triangulation<2>::active_cell_iterator Triangulation<2>::begin_active (const unsigned int level) const;
-template <> Triangulation<2>::raw_cell_iterator Triangulation<2>::last_raw () const;
-template <> Triangulation<2>::raw_cell_iterator Triangulation<2>::last_raw (const unsigned int level) const;
-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;
-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>::face_iterator Triangulation<2>::last_face () const;
-template <> Triangulation<2>::active_face_iterator Triangulation<2>::last_active_face () const;
-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 <> Triangulation<2>::raw_hex_iterator Triangulation<2>::begin_raw_hex (const unsigned int level) const;
-template <> Triangulation<2>::hex_iterator Triangulation<2>::begin_hex (const unsigned int level) const;
-template <> Triangulation<2>::active_hex_iterator Triangulation<2>::begin_active_hex (const unsigned int level) const;
-template <> Triangulation<2>::raw_hex_iterator Triangulation<2>::end_hex () const;
-template <> Triangulation<2>::raw_hex_iterator Triangulation<2>::last_raw_hex (const unsigned int level) const;
-template <> Triangulation<2>::raw_hex_iterator Triangulation<2>::last_raw_hex () const;
-template <> Triangulation<2>::hex_iterator Triangulation<2>::last_hex (const unsigned int level) const;
-template <> Triangulation<2>::hex_iterator Triangulation<2>::last_hex () const;
-template <> Triangulation<2>::active_hex_iterator Triangulation<2>::last_active_hex (const unsigned int level) const;
-template <> Triangulation<2>::active_hex_iterator Triangulation<2>::last_active_hex () const;
-template <> Triangulation<3>::raw_cell_iterator Triangulation<3>::begin_raw (const unsigned int level) const;
-template <> Triangulation<3>::active_cell_iterator Triangulation<3>::begin_active (const unsigned int level) const;
-template <> Triangulation<3>::raw_cell_iterator Triangulation<3>::last_raw () const;
-template <> Triangulation<3>::raw_cell_iterator Triangulation<3>::last_raw (const unsigned int level) const;
-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;
-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>::face_iterator Triangulation<3>::last_face () const;
-template <> Triangulation<3>::active_face_iterator Triangulation<3>::last_active_face () const;
-template <> Triangulation<3>::raw_quad_iterator Triangulation<3>::begin_raw_quad (const unsigned int level) const;
-template <> unsigned int Triangulation<1>::n_raw_lines (const unsigned int level) const;
-template <> unsigned int Triangulation<1>::n_quads () const;
-template <> unsigned int Triangulation<1>::n_quads (const unsigned int level) const;
-template <> unsigned int Triangulation<1>::n_raw_quads (const unsigned int level) const;
-template <> unsigned int Triangulation<2>::n_raw_quads (const unsigned int level) const;
-template <> unsigned int Triangulation<1>::n_raw_quads () const;
-template <> unsigned int Triangulation<1>::n_raw_hexs (const unsigned int level) const;
-template <> unsigned int Triangulation<1>::n_active_quads (const unsigned int level) const;
-template <> unsigned int Triangulation<1>::n_active_quads () const;
-template <> unsigned int Triangulation<1>::max_adjacent_cells () const;
-template <> void Triangulation<1>::execute_refinement ();
-template <> void Triangulation<2>::execute_refinement ();
-template <> void Triangulation<3>::execute_refinement ();
-template <> void Triangulation<3>::prepare_refinement_dim_dependent ();
-template <> void Triangulation<1>::delete_children (cell_iterator &cell,
-                                                   std::vector<unsigned int> &,
-                                                   std::vector<unsigned int> &);
-template <> void Triangulation<2>::delete_children (cell_iterator &cell,
-                                                   std::vector<unsigned int> &,
-                                                   std::vector<unsigned int> &);
-template <> void Triangulation<3>::delete_children (cell_iterator &cell,
-                                                   std::vector<unsigned int> &line_cell_count,
-                                                   std::vector<unsigned int> &quad_cell_count);
-template <> void Triangulation<2>::create_children (unsigned int &next_unused_vertex,
-                                                   raw_line_iterator &next_unused_line,
-                                                   raw_quad_iterator &next_unused_quad,
-                                                   raw_cell_iterator &next_unused_cell,
-                                                   cell_iterator &cell);
-template <> void Triangulation<3>::update_neighbors (cell_iterator &cell,
-                                                    bool refining);
-template <> void Triangulation<3>::count_cells_at_line (std::vector<unsigned int> &line_cell_count);
-template <> void Triangulation<3>::count_cells_at_quad (std::vector<unsigned int> &quad_cell_count);
-template <> void Triangulation<1>::prevent_distorted_boundary_cells ();
-template <> void Triangulation<1>::update_number_cache_quads ();
-template <> void Triangulation<1>::update_number_cache_hexes ();
-template <> void Triangulation<2>::update_number_cache_hexes ();
 
 #endif // DOXYGEN
 
index 1c43fe7facfb6892ff4156247c1db39c5807f05a..f9ec8c6eeb001e6d592deb006d37ef168d821df2 100644 (file)
@@ -18,6 +18,7 @@
 #include <base/exceptions.h>
 #include <base/geometry_info.h>
 #include <grid/tria_iterator_base.h>
+#include <grid/tria_iterator_selector.h>
 
 
 namespace std
@@ -30,10 +31,10 @@ DEAL_II_NAMESPACE_OPEN
 
 template <int dim> class Point;
 
-template <int dim> class Triangulation;
-template <int dim, typename Accessor> class TriaRawIterator;
-template <int dim, typename Accessor> class TriaIterator;
-template <int dim, typename Accessor> class TriaActiveIterator;
+template <int dim, int spacedim> class Triangulation;
+template <typename Accessor> class TriaRawIterator;
+template <typename Accessor> class TriaIterator;
+template <typename Accessor> class TriaActiveIterator;
 
 
 namespace internal
@@ -44,12 +45,8 @@ namespace internal
     template <typename G> class TriaObjects;
   }
 }
-template <int celldim, int dim> class TriaObjectAccessor;
-template <int dim>              class TriaObjectAccessor<0, dim>;
-template <int dim>              class TriaObjectAccessor<1, dim>;
-template <int dim>              class TriaObjectAccessor<2, dim>;
-template <int dim>              class TriaObjectAccessor<3, dim>;
-
+template <int celldim, int dim, int spacedim>  class TriaAccessor;
+template <int dim, int spacedim>               class TriaAccessor<0, dim, spacedim>;
 
 // note: the file tria_accessor.templates.h is included at the end of
 // this file.  this includes a lot of templates. originally, this was
@@ -154,8 +151,8 @@ namespace TriaAccessorExceptions
  * @ingroup Accessors
  * @author Wolfgang Bangerth, 1998
  */
-template <int structdim, int dim>
-class TriaAccessor
+template <int structdim, int dim, int spacedim=dim>
+class TriaAccessorBase
 {
   protected:
                                     /**
@@ -174,10 +171,10 @@ class TriaAccessor
                                      *  only callable from friend
                                      *  classes.
                                      */
-    TriaAccessor (const Triangulation<dim> *parent =  0,
-                 const int                 level  = -1,
-                 const int                 index  = -1,
-                 const AccessorData       *       =  0);
+    TriaAccessorBase (const Triangulation<dim,spacedim> *parent =  0,
+                     const int                 level  = -1,
+                     const int                 index  = -1,
+                     const AccessorData       *       =  0);
 
                                     /**
                                      *  Copy operator. Since this is
@@ -190,7 +187,7 @@ class TriaAccessor
                                      *  since it is only to be called
                                      *  from the iterator class.
                                      */
-    void copy_from (const TriaAccessor &);
+    void copy_from (const TriaAccessorBase &);
 
                                     /**
                                      *  Copy operator. This is normally
@@ -209,24 +206,68 @@ class TriaAccessor
                                      *  and will give a linker error if
                                      *  used anyway.
                                      */
-    void operator = (const TriaAccessor *);
+    void operator = (const TriaAccessorBase *);
     
                                     /**
                                      *  Same as above.
                                      */
-    TriaAccessor & operator = (const TriaAccessor &);
+    TriaAccessorBase & operator = (const TriaAccessorBase &);
 
-  protected:
-    
                                     /**
                                      *  Compare for equality.            
                                      */
-    bool operator == (const TriaAccessor &) const;
+    bool operator == (const TriaAccessorBase &) const;
        
                                     /**
                                      * Compare for inequality.
                                      */
-    bool operator != (const TriaAccessor &) const;
+    bool operator != (const TriaAccessorBase &) const;
+
+                                    /**
+                                     * @name Advancement of iterators
+                                     */
+                                    /**
+                                     * @{
+                                     */
+                                    /**
+                                     *  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
+                                     *  is the last on this level,
+                                     *  the first on the next level
+                                     *  is accessed.
+                                     */
+    void operator ++ ();
+
+                                    /**
+                                     *  This operator moves the
+                                     *  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
+                                     *  element is the first on this
+                                     *  level, the last on the
+                                     *  previous level is accessed.
+                                     */
+    void operator -- ();
+                                    /**
+                                     * @}
+                                     */
+    
+                                    /**
+                                     * Access to the other objects of
+                                     * a Triangulation with same
+                                     * dimension.
+                                     */
+    internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<structdim> > &
+    objects () const;
     
   public:
                                     /**
@@ -238,9 +279,13 @@ class TriaAccessor
                                      */
     typedef void * LocalData;
     
-                                    /**@ name Iterator address and state
+                                    /**
+                                     * @name Iterator address and state
                                      */
-                                    /*@{*/
+                                    /**
+                                     * @{
+                                     */
+
                                     /**
                                      *  Return the level the element
                                      *  pointed to belongs to.
@@ -271,10 +316,13 @@ class TriaAccessor
                                      * pointed to by this class
                                      * belongs to.
                                      */
-    const Triangulation<dim> & get_triangulation () const;
+    const Triangulation<dim,spacedim> & get_triangulation () const;
     
-                                    /*@}*/
+                                    /**
+                                     * @}
+                                     */
   protected:
+
                                     /**
                                      *  Used to store the index of
                                      *  the element presently pointed
@@ -287,19 +335,22 @@ class TriaAccessor
                                      *  Pointer to the triangulation
                                      *  which we act on.
                                      */
-    const Triangulation<dim> *tria;
-
+    const Triangulation<dim,spacedim> *tria;
+    
   private:
     
                                     /**
-                                     * Dimension of the TriaObject
-                                     * this accessor gives access to.
-                                     */
-    static const unsigned int objectdim = dim;
+                                     *  Space dimension of the Accessor
+                                     */  
+    static const unsigned int space_dimension = spacedim; 
+
+    static const unsigned int dimension = dim;
 
-    template <int anydim, typename Accessor> friend class TriaRawIterator;
-    template <int anydim, typename Accessor> friend class TriaIterator;
-    template <int anydim, typename Accessor> friend class TriaActiveIterator;
+    static const unsigned int structure_dimension = structdim;
+
+    template <typename Accessor> friend class TriaRawIterator;
+    template <typename Accessor> friend class TriaIterator;
+    template <typename Accessor> friend class TriaActiveIterator;
 };
 
 
@@ -316,9 +367,13 @@ class TriaAccessor
  * This template is a partial specialization of the general template
  * used for cells only, i.e. for the case where <tt>structdim</tt>
  * (the dimensionality of the object represented, for example 1 for a
- * line) equals <tt>dim</tt> (the dimensionality of the space the
- * object lives in, for example 3 if we solve three-dimensional
- * problems). The difference is that cells have a level in the
+ * line) equals <tt>dim</tt> (the dimensionality of the triangulation
+ * the object lives in, for example 2 if we solve problems on a
+ * two-dimensional manifold -- whether this manifold is itself the
+ * space $R^2$ or embedded in a higher-dimensional space whose
+ * dimensionality is determined by the <code>spacedim</code> template
+ * argument). The reason for using a partial specialization rather
+ * than the general template is that cells have a level in the
  * triangulation hierarchy associated with them, whereas faces and
  * edges do not.
  *
@@ -328,8 +383,8 @@ class TriaAccessor
  * @ingroup Accessors
  * @author Wolfgang Bangerth, 1998
  */
-template <int dim>
-class TriaAccessor<dim,dim>
+template <int dim, int spacedim>
+class TriaAccessorBase<dim,dim,spacedim>
 {
   protected:
                                     /**
@@ -348,10 +403,10 @@ class TriaAccessor<dim,dim>
                                      *  only callable from friend
                                      *  classes.
                                      */
-    TriaAccessor (const Triangulation<dim> *parent =  0,
-                 const int                 level  = -1,
-                 const int                 index  = -1,
-                 const AccessorData       *       =  0);
+    TriaAccessorBase (const Triangulation<dim,spacedim> *parent =  0,
+                     const int                 level  = -1,
+                     const int                 index  = -1,
+                     const AccessorData       *       =  0);
 
                                     /**
                                      *  Copy operator. Since this is
@@ -364,7 +419,7 @@ class TriaAccessor<dim,dim>
                                      *  since it is only to be called
                                      *  from the iterator class.
                                      */
-    void copy_from (const TriaAccessor &);
+    void copy_from (const TriaAccessorBase &);
 
                                     /**
                                      *  Copy operator. This is normally
@@ -383,25 +438,69 @@ class TriaAccessor<dim,dim>
                                      *  and will give a linker error if
                                      *  used anyway.
                                      */
-    void operator = (const TriaAccessor *);
-    
+    void operator = (const TriaAccessorBase *);
+        
                                     /**
                                      *  Same as above.
                                      */
-    TriaAccessor & operator = (const TriaAccessor &);
+    TriaAccessorBase & operator = (const TriaAccessorBase &);
+
+                                    /**
+                                     * @name Advancement of iterators
+                                     */
+                                    /**
+                                     * @{
+                                     */
+    
+                                    /**
+                                     *  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
+                                     *  is the last on this level,
+                                     *  the first on the next level
+                                     *  is accessed.
+                                     */
+    void operator ++ ();
+
+                                    /**
+                                     *  This operator moves the
+                                     *  iterator to the previous
+                                     *  element.
+                                     *
+                                     *  For cells only:
+                                     *  The previous element is
+                                     *  previous on 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.
+                                     */
+    void operator -- ();
+
+                                    /**
+                                     * Access to the other objects of
+                                     * a Triangulation with same
+                                     * dimension.
+                                     */
+    internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<dim> > &
+    objects () const;
 
   protected:
     
                                     /**
                                      *  Compare for equality.            
                                      */
-    bool operator == (const TriaAccessor &) const;
+    bool operator == (const TriaAccessorBase &) const;
        
                                     /**
                                      * Compare for inequality.
                                      */
-    bool operator != (const TriaAccessor &) const;
-    
+    bool operator != (const TriaAccessorBase &) const;
+
   public:
                                     /**
                                      * Data type to be used for passing
@@ -412,9 +511,11 @@ class TriaAccessor<dim,dim>
                                      */
     typedef void * LocalData;
     
-                                    /**@ name Iterator address and state
+                                    /** @name Iterator address and state
+                                     */
+                                    /**
+                                     * @{
                                      */
-                                    /*@{*/
                                     /**
                                      *  Return the level the element
                                      *  pointed to belongs to.
@@ -445,9 +546,11 @@ class TriaAccessor<dim,dim>
                                      * pointed to by this class
                                      * belongs to.
                                      */
-    const Triangulation<dim> & get_triangulation () const;
+    const Triangulation<dim,spacedim> & get_triangulation () const;
     
-                                    /*@}*/
+                                    /**
+                                     * @}
+                                     */
   protected:
                                     /**
                                      *  Used to store the level
@@ -469,137 +572,204 @@ class TriaAccessor<dim,dim>
                                      *  Pointer to the triangulation
                                      *  which we act on.
                                      */
-    const Triangulation<dim> *tria;
+    const Triangulation<dim,spacedim> *tria;
 
-  private:
-    
                                     /**
-                                     * Dimension of the TriaObject
-                                     * this accessor gives access to.
-                                     */
-    static const unsigned int objectdim = dim;
+                                     *  Space dimension of the Accessor
+                                     */  
+    static const unsigned int space_dimension = spacedim; 
 
-    template <int anydim, typename Accessor> friend class TriaRawIterator;
-    template <int anydim, typename Accessor> friend class TriaIterator;
-    template <int anydim, typename Accessor> friend class TriaActiveIterator;
-};
+    static const unsigned int dimension = dim;
+
+    static const unsigned int structure_dimension = dim;
 
+  private:
+    
+    template <typename Accessor> friend class TriaRawIterator;
+    template <typename Accessor> friend class TriaIterator;
+    template <typename Accessor> friend class TriaActiveIterator;
 
+    template <int, int, int> friend class TriaAccessor;
+};
 
 
 /**
- * Common template for line, quad, hex accessors.  According to
- * @p celldim, objects of this class represent lines, quadrilaterals,
- * or hexahedra in @p dim space dimensions. Concrete implementations
- * are done for specialized @p celldim template parameter. For easier
- * access, we nevertheless document all functions of the specialized
- * classes here as well. However, they are not implemented.
+ * A class that represents accessor objects to iterators that don't
+ * make sense such as quad iterators in on 1d meshes.  This class can
+ * not be used to create objects (it will in fact throw an exception
+ * if this should ever be attempted but it sometimes allows code to be
+ * written in a simpler way in a dimension independent way. For
+ * example, it allows to write code that works on quad iterators that
+ * is dimension independent because quad iterators (with the current
+ * class) exist and are syntactically correct. You can not expect,
+ * however, to ever generate one of these iterators, meaning you need
+ * to expect to wrap the code block in which you use quad iterators
+ * into something like <code>if (dim@>1)</code> -- which makes eminent
+ * sense anyway.
  *
- * @ingroup grid
- * @ingroup Accessors
- * @author Wolfgang Bangerth, Guido Kanschat, 1999
+ * This class provides the minimal interface necessary for Accessor
+ * classes to interact with Iterator classes. However, this is only
+ * for syntactic correctness, none of the functions do anything but
+ * generate errors.
+ *
+ * @author Wolfgang Bangerth, 2008
  */
-template <int celldim, int dim>
-class TriaObjectAccessor :  public TriaAccessor<celldim,dim>
+template <int structdim, int dim, int spacedim=dim>
+class InvalidAccessor :  public TriaAccessorBase<structdim,dim,spacedim>
 {
   public:
                                     /**
                                      * Propagate typedef from
                                      * base class to this class.
                                      */
-    typedef typename TriaAccessor<celldim,dim>::AccessorData AccessorData;
-
+    typedef typename TriaAccessorBase<structdim,dim,spacedim>::AccessorData AccessorData;
+
+                                    /**
+                                     * Constructor.  This class is
+                                     * used for iterators that make
+                                     * sense in a given dimension,
+                                     * for example quads for 1d
+                                     * meshes. Consequently, while
+                                     * the creation of such objects
+                                     * is syntactically valid, they
+                                     * make no semantic sense, and we
+                                     * generate an exception when
+                                     * such an object is actually
+                                     * generated.
+                                     */
+    InvalidAccessor (const Triangulation<dim,spacedim> *parent     =  0,
+                    const int                 level      = -1,
+                    const int                 index      = -1,
+                    const AccessorData       *local_data =  0);
+    
+                                    /**
+                                     * Copy constructor.  This class
+                                     * is used for iterators that
+                                     * make sense in a given
+                                     * dimension, for example quads
+                                     * for 1d meshes. Consequently,
+                                     * while the creation of such
+                                     * objects is syntactically
+                                     * valid, they make no semantic
+                                     * sense, and we generate an
+                                     * exception when such an object
+                                     * is actually generated.
+                                     */
+    InvalidAccessor (const InvalidAccessor &);
+
+                                    /**
+                                     * Conversion from other
+                                     * accessors to the current
+                                     * invalid one. This of course
+                                     * also leads to a run-time
+                                     * error.
+                                     */
+    template <typename OtherAccessor>
+    InvalidAccessor (const OtherAccessor &);
+    
                                     /**
-                                     * Constructor.
-                                     * By default, an illegal
-                                     * accessor is constructed.
+                                     * Dummy copy operation.
                                      */
-    TriaObjectAccessor (const Triangulation<dim> *parent     =  0,
-                       const int                 level      = -1,
-                       const int                 index      = -1,
-                       const AccessorData       *local_data =  0);
+    void copy_from (const InvalidAccessor &);
 
                                     /**
-                                     * Copy the data of a line. Only
-                                     * implemented for
-                                     * <tt>celldim==1</tt>.
+                                     * Dummy comparison operators.
                                      */
+    bool operator == (const InvalidAccessor &) const;
+    bool operator != (const InvalidAccessor &) const;
 
-    void set (const internal::Triangulation::TriaObject<1>&) const;
-    
                                     /**
-                                     * Copy the data of the given
-                                     * quad. Only implemented for
-                                     * <tt>celldim==2</tt>.
+                                     * Dummy operators to make things
+                                     * compile. Does nothing.
                                      */
-    void set (const internal::Triangulation::TriaObject<2>&) const;
+    void operator ++ () const;
+    void operator -- () const;
     
                                     /**
-                                     * Copy the data of the given
-                                     * hex. Only implemented for
-                                     * <tt>celldim==3</tt>.
+                                     * Dummy function representing
+                                     * whether the accessor points to
+                                     * a used or an unused object.
                                      */
-    void set (const internal::Triangulation::TriaObject<3>&) const;
+    bool used () const;
 
                                     /**
-                                     *  Index of vertex. The convention
-                                     *  regarding the numbering of vertices
-                                     *  is laid down in the documentation of
-                                     *  the GeometryInfo class.
-                                     *
-                                     *  Note that the returned value is only
-                                     *  the index of the geometrical
-                                     *  vertex. It has nothing to do with
-                                     *  possible degrees of freedom
-                                     *  associated with it. For this, see the
-                                     *  @p DoFAccessor::vertex_dof_index
-                                     *  functions.
-                                     */ 
-    unsigned int vertex_index (const unsigned int i) const;
-
-                                    /**
-                                     *  Return a reference to the
-                                     *  @p ith vertex.
+                                     * Dummy function representing
+                                     * whether the accessor points to
+                                     * an object that has children.
                                      */
-    Point<dim> & vertex (const unsigned int i) const;
+    bool has_children () const;
+};
+
+
 
+/**
+ * A class that provides access to objects in a triangulation such as
+ * its vertices, sub-objects, children, geometric information, etc.
+ * This class represents objects of dimension <code>structdim</code>
+ * (i.e. 1 for lines, 2 for quads, 3 for hexes) in a triangulation of
+ * dimensionality <code>dim</code> (i.e. 1 for a triangulation of
+ * lines, 2 for a triangulation of quads, and 3 for a triangulation of
+ * hexes) that is embedded in a space of dimensionality
+ * <code>spacedim</code> (for <code>spacedim==dim</code> the
+ * triangulation represents a domain in $R^{dim}$, for
+ * <code>spacedim@>dim</code> the triangulation is of a manifold
+ * embedded in a higher dimensional space).
+ *
+ * @author Wolfgang Bangerth and others, 1998, 2000, 2008
+ */
+template <int structdim, int dim, int spacedim>
+class TriaAccessor : public TriaAccessorBase<structdim, dim, spacedim>
+{
+  public:
                                     /**
-                                     *  Pointer to the @p ith line
-                                     *  bounding this object.
-                                     *
-                                     * Implemented only for <tt>celldim>1</tt>.
+                                     * Propagate typedef from
+                                     * base class to this class.
                                      */
-    TriaIterator<dim,TriaObjectAccessor<1, dim> >
-    line (const unsigned int i) const;
+    typedef
+    typename TriaAccessorBase<structdim,dim,spacedim>::AccessorData
+    AccessorData;
 
                                     /**
-                                     * Line index of the @p ith
-                                     * line. The level is naturally
-                                     * the same as that of the
-                                     * object.
-                                     *
-                                     * Implemented only for <tt>celldim>1</tt>.
-                                     */
-    unsigned int line_index (const unsigned int i) const;
-    
-                                    /**
-                                     *  Pointer to the @p ith quad
-                                     *  bounding this object.
-                                     *
-                                     * Implemented only for <tt>celldim>2</tt>.
+                                     *  Constructor.
                                      */
-    TriaIterator<dim,TriaObjectAccessor<2, dim> >
-    quad (const unsigned int i) const;
+    TriaAccessor (const Triangulation<dim,spacedim> *parent     =  0,
+                 const int                 level      = -1,
+                 const int                 index      = -1,
+                 const AccessorData       *local_data =  0);
 
                                     /**
-                                     * Quad index of the @p ith
-                                     * quad. The level is naturally
-                                     * the same as that of the object.
-                                     *
-                                     * Implemented only for <tt>celldim>2</tt>.
+                                     * Conversion constructor. This
+                                     * constructor exists to make certain
+                                     * constructs simpler to write in
+                                     * dimension independent code. For
+                                     * example, it allows assigning a face
+                                     * iterator to a line iterator, an
+                                     * operation that is useful in 2d but
+                                     * doesn't make any sense in 3d. The
+                                     * constructor here exists for the
+                                     * purpose of making the code conform to
+                                     * C++ but it will unconditionally abort;
+                                     * in other words, assigning a face
+                                     * iterator to a line iterator is better
+                                     * put into an if-statement that checks
+                                     * that the dimension is two, and assign
+                                     * to a quad iterator in 3d (an operator
+                                     * that, without this constructor would
+                                     * be illegal if we happen to compile for
+                                     * 2d).
                                      */
-    unsigned int quad_index (const unsigned int i) const;
+    template <int structdim2, int dim2, int spacedim2>
+    TriaAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &);
 
+                                    /**
+                                     * Another conversion operator
+                                     * between objects that don't
+                                     * make sense, just like the
+                                     * previous one.
+                                     */
+    template <int structdim2, int dim2, int spacedim2>
+    TriaAccessor (const TriaAccessor<structdim2,dim2,spacedim2> &);
+    
                                     /**
                                      *  Test for the element being
                                      *  used or not.  The return
@@ -615,245 +785,265 @@ class TriaObjectAccessor :  public TriaAccessor<celldim,dim>
                                      */
     bool used () const;
 
+
                                     /**
-                                     * @name User data
+                                     *  @name Accessing sub-objects
                                      */
-                                    /*@{*/
                                     /**
-                                     *  Set the @p used flag. You
-                                     *  should know quite exactly
-                                     *  what you are doing of you
-                                     *  touch this function. It is
-                                     *  exclusively for internal use
-                                     *  in the library.
+                                     * @{
                                      */
-    void set_used_flag () const;
-
+    
                                     /**
-                                     *  Clear the @p used flag. You
-                                     *  should know quite exactly
-                                     *  what you are doing of you
-                                     *  touch this function. It is
-                                     *  exclusively for internal use
-                                     *  in the library.
-                                     */
-    void clear_used_flag () const;
-
-                                    /**
-                                     *  Read the user flag.
-                                     */
-    bool user_flag_set () const;
+                                     *  Return the global index of i-th
+                                     *  vertex of the current object. The
+                                     *  convention regarding the numbering of
+                                     *  vertices is laid down in the
+                                     *  documentation of the GeometryInfo
+                                     *  class.
+                                     *
+                                     *  Note that the returned value is only
+                                     *  the index of the geometrical
+                                     *  vertex. It has nothing to do with
+                                     *  possible degrees of freedom
+                                     *  associated with it. For this, see the
+                                     *  @p DoFAccessor::vertex_dof_index
+                                     *  functions.
+                                     */ 
+    unsigned int vertex_index (const unsigned int i) const;
 
                                     /**
-                                     *  Set the user flag.
+                                     *  Return a reference to the
+                                     *  @p ith vertex.
                                      */
-    void set_user_flag () const;
+    Point<spacedim> & vertex (const unsigned int i) const;
 
                                     /**
-                                     *  Clear the user flag.
+                                     * Pointer to the @p ith line
+                                     * bounding this object.
                                      */
-    void clear_user_flag () const;
+    typename internal::Triangulation::Iterators<dim,spacedim>::line_iterator
+    line (const unsigned int i) const;
 
                                     /**
-                                     *  Set the user flag for this
-                                     * and all descendants.
+                                     * Line index of the @p ith
+                                     * line bounding this object.
+                                     *
+                                     * Implemented only for
+                                     * <tt>structdim>1</tt>,
+                                     * otherwise an exception
+                                     * generated.
                                      */
-    void recursively_set_user_flag () const;
-
+    unsigned int line_index (const unsigned int i) const;
+    
                                     /**
-                                     *  Clear the user flag for this
-                                     * and all descendants. 
+                                     * Pointer to the @p ith quad
+                                     * bounding this object.
                                      */
-    void recursively_clear_user_flag () const;
+    typename internal::Triangulation::Iterators<dim,spacedim>::quad_iterator
+    quad (const unsigned int i) const;
 
                                     /**
-                                     * Reset the user data to zero,
-                                     * independent if pointer or index.
+                                     * Quad index of the @p ith
+                                     * quad bounding this object.
+                                     *
+                                     * Implemented only for
+                                     * <tt>structdim>2</tt>,
+                                     * otherwise an exception
+                                     * generated.
                                      */
-    void clear_user_data () const;
-    
+    unsigned int quad_index (const unsigned int i) const;
                                     /**
-                                     * Set the user pointer
-                                     * to @p p.
+                                     * @}
                                      */
-    void set_user_pointer (void *p) const;
 
                                     /**
-                                     * Reset the user pointer
-                                     * to a @p NULL pointer.
+                                     *  @name Orientation of sub-objects
                                      */
-    void clear_user_pointer () const;
-    
                                     /**
-                                     * Access the value of the user
-                                     * pointer. It is in the
-                                     * responsibility of the user to
-                                     * make sure that the pointer
-                                     * points to something
-                                     * useful. You should use the new
-                                     * style cast operator to
-                                     * maintain a minimum of
-                                     * typesafety, e.g.
-                                     * <tt>A *a=static_cast<A*>(cell->user_pointer());</tt>.
+                                     * @{
                                      */
-    void * user_pointer () const;
 
+                                     /**
+                                      * Return whether the face with
+                                      * index @p face has its normal
+                                      * pointing in the standard
+                                      * direction (@p true) or
+                                      * whether it is the opposite
+                                      * (@p false). Which is the
+                                      * standard direction is
+                                      * documented with the
+                                      * GeometryInfo class. In
+                                      * 1d and 2d, this is always
+                                      * @p true, but in 3d it may be
+                                      * different, see the respective
+                                      * discussion in the
+                                      * documentation of the
+                                      * GeometryInfo class.
+                                      *
+                                      * This function is really only
+                                      * for internal use in the
+                                      * library unless you absolutely
+                                      * know what this is all about.
+                                      */
+    bool face_orientation (const unsigned int face) const;
+
+                                     /**
+                                      * Return whether the face with index @p
+                                      * face is rotated by 180 degrees (@p true)
+                                      * or or not (@p false). In 1d and 2d, this
+                                      * is always @p false, but in 3d it may be
+                                      * different, see the respective discussion
+                                      * in the documentation of the
+                                      * GeometryInfo class.
+                                      *
+                                      * This function is really only
+                                      * for internal use in the
+                                      * library unless you absolutely
+                                      * know what this is all about.
+                                      */
+    bool face_flip (const unsigned int face) const;
+
+                                     /**
+                                      * Return whether the face with index @p
+                                      * face is rotated by 90 degrees (@p true)
+                                      * or or not (@p false). In 1d and 2d, this
+                                      * is always @p false, but in 3d it may be
+                                      * different, see the respective discussion
+                                      * in the documentation of the
+                                      * GeometryInfo class.
+                                      *
+                                      * This function is really only
+                                      * for internal use in the
+                                      * library unless you absolutely
+                                      * know what this is all about.
+                                      */
+    bool face_rotation (const unsigned int face) const;
+
+                                     /**
+                                      * Return whether the line with index @p
+                                      * line is oriented in standard
+                                      * direction. @p true indicates, that the
+                                      * line is oriented from vertex 0 to vertex
+                                      * 1, whereas it is the other way around
+                                      * otherwise. In 1d and 2d, this is always
+                                      * @p true, but in 3d it may be different,
+                                      * see the respective discussion in the
+                                      * documentation of the 
+                                      * GeometryInfo classe.
+                                      *
+                                      * This function is really only
+                                      * for internal use in the
+                                      * library unless you absolutely
+                                      * know what this is all about.
+                                      */
+    bool line_orientation (const unsigned int line) const;
                                     /**
-                                     * Set the user pointer of this
-                                     * object and all its children to
-                                     * the given value. This is
-                                     * useful for example if all
-                                     * cells of a certain subdomain,
-                                     * or all faces of a certain part
-                                     * of the boundary should have
-                                     * user pointers pointing to
-                                     * objects describing this part
-                                     * of the domain or boundary.
-                                     *
-                                     * Note that the user pointer is
-                                     * not inherited under mesh
-                                     * refinement, so after mesh
-                                     * refinement there might be
-                                     * cells or faces that don't have
-                                     * user pointers pointing to the
-                                     * describing object. In this
-                                     * case, simply loop over all the
-                                     * elements of the coarsest level
-                                     * that has this information, and
-                                     * use this function to
-                                     * recursively set the user
-                                     * pointer of all finer levels of
-                                     * the triangulation.
-                                     */
-    void recursively_set_user_pointer (void *p) const;
-    
-                                    /**
-                                     * Clear the user pointer of this
-                                     * object and all of its
-                                     * descendants. The same holds as
-                                     * said for the
-                                     * recursively_set_user_pointer()
-                                     * function.
-                                     */
-    void recursively_clear_user_pointer () const;
-    
-                                    /**
-                                     * Set the user index
-                                     * to @p p.
-                                     */
-    void set_user_index (const unsigned int p) const;
-    
-                                    /**
-                                     * Reset the user index to 0.
+                                     * @}
                                      */
-    void clear_user_index () const;
     
                                     /**
-                                     * Access the value of the user
-                                     * index.
+                                     *  @name Accessing children
                                      */
-    unsigned int user_index () const;
-
                                     /**
-                                     * Set the user index of this
-                                     * object and all its children.
-                                     *
-                                     * Note that the user index is
-                                     * not inherited under mesh
-                                     * refinement, so after mesh
-                                     * refinement there might be
-                                     * cells or faces that don't have
-                                     * the expected user indices. In
-                                     * this case, simply loop over
-                                     * all the elements of the
-                                     * coarsest level that has this
-                                     * information, and use this
-                                     * function to recursively set
-                                     * the user index of all finer
-                                     * levels of the triangulation.
+                                     * @{
                                      */
-    void recursively_set_user_index (const unsigned int p) const;
 
                                     /**
-                                     * Clear the user index of this
-                                     * object and all of its
-                                     * descendants. The same holds as
-                                     * said for the
-                                     * recursively_set_user_index()
-                                     * function.
+                                     *  Test whether the object has
+                                     *  children.
                                      */
-    void recursively_clear_user_index () const;
+    bool has_children () const;
 
                                     /**
-                                     * Return the @p RefinementCase<dim>
-                                     * of this cell.
+                                     * Return the number of immediate
+                                     * children of this object. The
+                                     * number of children of an
+                                     * unrefined cell is zero.
                                      */
-    RefinementCase<celldim> refinement_case() const;
+    unsigned int n_children() const;
 
                                     /**
-                                     * Set the @p RefinementCase<dim> this
-                                     * TriaObject is refined with.
-                                     * Not defined for
-                                     * <tt>celldim=1</tt> as lines
-                                     * are always refined resulting
-                                     * in 2 children lines (isotropic
-                                     * refinement).
+                                     * Compute and return the number
+                                     * of active descendants of this
+                                     * objects. For example, if all
+                                     * of the eight children of a hex
+                                     * are further refined
+                                     * isotropically exactly once,
+                                     * the returned number will be
+                                     * 64, not 80.
                                      *
-                                     * You should know quite exactly
-                                     * what you are doing if you
-                                     * touch this function. It is
-                                     * exclusively for internal use
-                                     * in the library.
+                                     * If the present cell is not
+                                     * refined, one is returned.
+                                     *
+                                     * If one considers a triangulation as a
+                                     * forest where the root of each tree are
+                                     * the coarse mesh cells and nodes have
+                                     * descendents (the children of a cell),
+                                     * then this function returns the number
+                                     * of terminal nodes in the sub-tree
+                                     * originating from the current object;
+                                     * consequently, if the current object is
+                                     * not further refined, the answer is
+                                     * one.
                                      */
-    void set_refinement_case (const RefinementCase<celldim> &ref_case) const;
+    unsigned int number_of_children () const;
 
                                     /**
-                                     * Clear the RefinementCase<dim> of
-                                     * this TriaObject, i.e. reset it
-                                     * to RefinementCase<dim>::no_refinement.
+                                     * Return the number of times
+                                     * that this object is
+                                     * refined. Note that not all its
+                                     * children are refined that
+                                     * often (which is why we prepend
+                                     * @p max_), the returned number
+                                     * is rather the maximum number
+                                     * of refinement in any branch of
+                                     * children of this object.
                                      *
-                                     * You should know quite exactly
-                                     * what you are doing if you
-                                     * touch this function. It is
-                                     * exclusively for internal use
-                                     * in the library.
+                                     * For example, if this object is
+                                     * refined, and one of its children is
+                                     * refined exactly one more time, then
+                                     * <tt>max_refinement_depth</tt> should
+                                     * return 2.
+                                     *
+                                     * If this object is not refined (i.e. it
+                                     * is active), then the return value is
+                                     * zero.
                                      */
-    void clear_refinement_case () const;
-                                    /*@}*/
+    unsigned int max_refinement_depth () const;
     
                                     /**
-                                     *  Pointer to the @p ith
+                                     *  Return an iterator to the @p ith
                                      *  child.
                                      */
-    TriaIterator<dim,TriaObjectAccessor<celldim,dim> >
+    TriaIterator<TriaAccessor<structdim,dim,spacedim> >
     child (const unsigned int i) const;
 
                                     /**
-                                     *  Pointer to the @p object, which is
-                                     *  identical to the ith child for
-                                     *  isotropic refinement. If the object is
-                                     *  refined anisotropically, the returned
-                                     *  child will in fact be a grandchild of
-                                     *  the object.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<celldim,dim> >
+                                     *  Return an iterator to that object
+                                     *  that is identical to the ith child
+                                     *  for isotropic refinement. If the
+                                     *  current object is refined
+                                     *  isotropically, then the returned
+                                     *  object is the ith child. If the
+                                     *  current object is refined
+                                     *  anisotropically, the returned child
+                                     *  may in fact be a grandchild of the
+                                     *  object, or may not exist at all (in
+                                     *  which case an exception is
+                                     *  generated).
+                                     */
+    TriaIterator<TriaAccessor<structdim,dim,spacedim> >
     isotropic_child (const unsigned int i) const;
 
                                     /**
-                                     *  Index of the @p ith child.
-                                     *  The level of the child is one
-                                     *  higher than that of the
-                                     *  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.
+                                     * Return the RefinementCase
+                                     * of this cell.
                                      */
-    int child_index (const unsigned int i) const;
+    RefinementCase<structdim> refinement_case() const;
 
                                     /**
-                                     *  Index of the @p ith isotropic_child.
-                                     *  The level of the (grand-)child is 
+                                     *  Index of the @p ith child.
+                                     *  The level of the child is one
                                      *  higher than that of the
                                      *  present cell, if the children
                                      *  of a cell are accessed. The
@@ -861,89 +1051,34 @@ class TriaObjectAccessor :  public TriaAccessor<celldim,dim>
                                      *  If the child does not exist, -1
                                      *  is returned.
                                      */
-    int isotropic_child_index (const unsigned int i) const;
+    int child_index (const unsigned int i) const;
 
                                     /**
-                                     *  Set the index of the ith
-                                     *  child. Since the children
-                                     *  come at least in pairs, we
-                                     *  need to store the index of
-                                     *  only every second child,
-                                     *  i.e. of the even numbered
-                                     *  children. Make sure, that the
-                                     *  index of child i=0 is set
-                                     *  first. Calling this function
-                                     *  for odd numbered children is
-                                     *  not allowed.
-                                     */
-    void set_children (const unsigned int i, const int index) const;
-       
-                                    /**
-                                     *  Clear the child field,
-                                     *  i.e. set it to a value which
-                                     *  indicates that this cell has
-                                     *  no children.
+                                     *  Index of the @p ith isotropic child.
+                                     *  See the isotropic_child() function
+                                     *  for a definition of this concept.  If
+                                     *  the child does not exist, -1 is
+                                     *  returned.
                                      */
-    void clear_children () const;
-    
+    int isotropic_child_index (const unsigned int i) const;    
                                     /**
-                                     *  Test whether the object has
-                                     *  children.
+                                     * @}
                                      */
-    bool has_children () const;
 
                                     /**
-                                     * Return the number of immediate
-                                     * children of this object. The
-                                     * number of children of an
-                                     * unrefined cell is zero.
+                                     *  @name Dealing with boundary indicators
                                      */
-    unsigned int n_children() const;
-    
                                     /**
-                                     * Return the index of the vertex
-                                     * in the middle of this object,
-                                     * if it exists. In order to
-                                     * exist, the object needs to be
-                                     * refined - for 2D and 3D it
-                                     * needs to be refined
-                                     * isotropically or else the
-                                     * anisotropic children have to
-                                     * be refined again. If the
-                                     * middle vertex does not exist,
-                                     * return
-                                     * <tt>numbers::invalid_unsigned_int</tt>.
-                                     */
-    unsigned int middle_vertex_index() const;
-
-                                    /**
-                                     * Number of times that this
-                                     * object is refined. Note that
-                                     * not all its children are
-                                     * refined that often (which is
-                                     * why we prepend @p max_), the
-                                     * returned number is rather the
-                                     * maximum number of refinement
-                                     * in any branch of children of
-                                     * this object.
-                                     *
-                                     * For example, if this object is
-                                     * refined, and one of its children is
-                                     * refined exactly one more time, then
-                                     * <tt>max_refinement_depth</tt> should
-                                     * return 2.
-                                     *
-                                     * If this object is not refined (i.e. it
-                                     * is active), then the return value is
-                                     * zero.
+                                     * @{
                                      */
-    unsigned int max_refinement_depth () const;    
     
                                     /**
                                      * Boundary indicator of this
-                                     * object.  If the return value
-                                     * is 255, then this line is in
-                                     * the interior of the domain.
+                                     * object.
+                                     *
+                                     * If the return value is the special
+                                     * value 255, then this object is in the
+                                     * interior of the domain.
                                      */
     unsigned char boundary_indicator () const;
 
@@ -1001,1920 +1136,53 @@ class TriaObjectAccessor :  public TriaAccessor<celldim,dim>
     void set_all_boundary_indicators (const unsigned char) const;
     
                                     /**
-                                     * Return whether this object is
-                                     * at the boundary. This is
-                                     * checked via the boundary
-                                     * indicator field, which is
-                                     * always 255 if the object is in
-                                     * the interior of the
-                                     * domain. Obviously, the use of
-                                     * this function is only possible
-                                     * for <tt>dim>celldim</tt>; however,
-                                     * for <tt>dim==celldim</tt>, an
-                                     * object is a cell and the
-                                     * CellAccessor class
-                                     * offers another possibility to
-                                     * determine whether a cell is at
-                                     * the boundary or not.
+                                     * Return whether this object is at the
+                                     * boundary. Obviously, the use of this
+                                     * function is only possible for
+                                     * <tt>dim@>structdim</tt>; however, for
+                                     * <tt>dim==celldim</tt>, an object is a
+                                     * cell and the CellAccessor class offers
+                                     * another possibility to determine
+                                     * whether a cell is at the boundary or
+                                     * not.
                                      */
     bool at_boundary () const;
 
                                     /**
-                                     * Diameter of the object.
-                                     *
-                                     * The diameter of an object is
-                                     * computed to be the largest
-                                     * diagonal. This is not
-                                     * necessarily the true diameter,
-                                     * but completely sufficient for
-                                     * computations.
+                                     * @}
                                      */
-    double diameter () const;
+    
 
+                                    /**
+                                     * @name User data
+                                     */
+                                    /**
+                                     * @{
+                                     */
                                     /**
-                                     * Center of the object. The
-                                     * center of an object is defined
-                                     * to be the average of the
-                                     * vertices, which is also where
-                                     * the (dim-)linear mapping
-                                     * places the midpoint of the
-                                     * unit cell in real space.
-                                     * However, this may not be the
-                                     * barycenter of the object.
+                                     *  Read the user flag.
                                      */
-    Point<dim> center () const;
+    bool user_flag_set () const;
 
                                     /**
-                                     * Barycenter of the object.
+                                     *  Set the user flag.
                                      */
-    Point<dim> barycenter () const;
+    void set_user_flag () const;
 
                                     /**
-                                     * Volume of the object.  Here,
-                                     * the volume is defined to be
-                                     * confined by the (dim-)linear
-                                     * mapping of the unit cell.  No
-                                     * information about the boundary
-                                     * is used. If a more
-                                     * sophisticated computation is
-                                     * needed, try the volume of an
-                                     * appropriate finite element
-                                     * class.
+                                     *  Clear the user flag.
                                      */
-    double measure () const;
+    void clear_user_flag () const;
 
                                     /**
-                                     * Number of active descendants.
-                                     * This function only counts the
-                                     * number of active descendants,
-                                     * i.e. the number of descendants
-                                     * which are not further
-                                     * refined. Thus, if all of the
-                                     * eight children of a hex are
-                                     * further refined isotropically
-                                     * exactly once, the returned
-                                     * number will be 64, not 80.
-                                     *
-                                     * If the present cell is not refined,
-                                     * one is returned.
-                                     */
-    unsigned int number_of_children () const;
-
-                                     /**
-                                      * Return whether the face with
-                                      * index @p face has its normal
-                                      * pointing in the standard
-                                      * direction (@p true) or
-                                      * whether it is the opposite
-                                      * (@p false). Which is the
-                                      * standard direction is
-                                      * documented with the
-                                      * GeometryInfo class. In
-                                      * 1d and 2d, this is always
-                                      * @p true, but in 3d it may be
-                                      * different, see the respective
-                                      * discussion in the
-                                      * documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_orientation (const unsigned int face) const;
-
-                                     /**
-                                      * Return whether the face with index @p
-                                      * face is rotated by 180 degrees (@p true)
-                                      * or or not (@p false). In 1d and 2d, this
-                                      * is always @p false, but in 3d it may be
-                                      * different, see the respective discussion
-                                      * in the documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_flip (const unsigned int face) const;
-
-                                     /**
-                                      * Return whether the face with index @p
-                                      * face is rotated by 90 degrees (@p true)
-                                      * or or not (@p false). In 1d and 2d, this
-                                      * is always @p false, but in 3d it may be
-                                      * different, see the respective discussion
-                                      * in the documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_rotation (const unsigned int face) const;
-    
-                                     /**
-                                      * Return whether the line with index @p
-                                      * line is oriented in standard
-                                      * direction. @p true indicates, that the
-                                      * line is oriented from vertex 0 to vertex
-                                      * 1, whereas it is the other way around
-                                      * otherwise. In 1d and 2d, this is always
-                                      * @p true, but in 3d it may be different,
-                                      * see the respective discussion in the
-                                      * documentation of the 
-                                      * GeometryInfo classe.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool line_orientation (const unsigned int line) const;
-    
-                                     /**
-                                      * Set whether the quad with
-                                      * index @p face has its normal
-                                      * pointing in the standard
-                                      * direction (@p true) or
-                                      * whether it is the opposite
-                                      * (@p false). Which is the
-                                      * standard direction is
-                                      * documented with the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is only for
-                                      * internal use in the
-                                      * library. Setting this flag to
-                                      * any other value than the one
-                                      * that the triangulation has
-                                      * already set is bound to bring
-                                      * you desaster.
-                                     *
-                                     * It is only possible to set the
-                                     * face_orientation of cells in 3d
-                                     * (i.e. <code>celldim==3 &&
-                                     * dim==3</code>).
-                                      */
-    void set_face_orientation (const unsigned int face,
-                               const bool         orientation) const;
-
-                                    /**
-                                      * Set the flag indicating, what
-                                      * <code>face_flip()</code> will
-                                      * return.
-                                     *
-                                     * It is only possible to set the
-                                     * face_flip of cells in 3d
-                                     * (i.e. <code>celldim==3 &&
-                                     * dim==3</code>).
-                                      */
-    void set_face_flip (const unsigned int face,
-                       const bool         flip) const;
-
-                                    /**
-                                      * Set the flag indicating, what
-                                      * <code>face_rotation()</code> will
-                                      * return.
-                                     *
-                                     * It is only possible to set the
-                                     * face_rotation of cells in 3d
-                                     * (i.e. <code>celldim==3 &&
-                                     * dim==3</code>).
-                                      */
-    void set_face_rotation (const unsigned int face,
-                           const bool         rotation) const;
-
-                                     /**
-                                      * Set the flag indicating, what
-                                      * <code>line_orientation()</code> will
-                                      * return.
-                                     *
-                                     * It is only possible to set the
-                                     * line_orientation of faces in 3d
-                                     * (i.e. <code>celldim==2 &&
-                                     * dim==3</code>).
-                                      */
-    void set_line_orientation (const unsigned int line,
-                               const bool         orientation) const;
-
-  private:
-                                    /**
-                                     *  Copy operator. This is normally
-                                     *  used in a context like
-                                     *  <tt>iterator a,b;  *a=*b;</tt>. Since
-                                     *  the meaning is to copy the object
-                                     *  pointed to by @p b to the object
-                                     *  pointed to by @p a and since
-                                     *  accessors are not real but
-                                     *  virtual objects, this operation
-                                     *  is not useful for iterators on
-                                     *  triangulations. We declare this
-                                     *  function here private, thus it may
-                                     *  not be used from outside.
-                                     *  Furthermore it is not implemented
-                                     *  and will give a linker error if
-                                     *  used anyway.
-                                     */
-    void operator = (const TriaObjectAccessor<celldim, dim> &);
-
-  protected:
-                                    /**@name Advancement of iterators*/
-                                    /*@{*/
-                                    /**
-                                     *  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
-                                     *  is the last on this level,
-                                     *  the first on the next level
-                                     *  is accessed.
-                                     */
-    void operator ++ ();
-
-                                    /**
-                                     *  This operator moves the
-                                     *  iterator to the previous
-                                     *  element.
-                                     *
-                                     *  For cells only:
-                                     *  The previous element is
-                                     *  previous on 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.
-                                     */
-    void operator -- ();
-
-  private:
-    
-                                    /**
-                                     * Dimension of the TriaObject
-                                     * this accessor gives access to.
-                                     */
-    static const unsigned int objectdim = celldim;
-                                    /*@}*/
-
-                                    /**
-                                     * Declare some friends.
-                                     */
-    template <int anydim, typename AnyAccessor> friend class TriaRawIterator;
-};
-
-
-
-/**
- * Closure class to stop induction of classes. Should never be called
- * and thus produces an error when created.
- *
- * @ingroup grid
- */
-template<int dim>
-class TriaObjectAccessor<0, dim> : public TriaAccessor<0,dim>
-{
-  public:
-                                    /**
-                                     * Propagate typedef from
-                                     * base class to this class.
-                                     */
-    typedef typename TriaAccessor<0,dim>::AccessorData AccessorData;
-
-                                    /**
-                                     * Constructor. Should never be
-                                     * called and thus produces an
-                                     * error.
-                                     */
-    TriaObjectAccessor (const Triangulation<dim> *parent     =  0,
-                       const int                 level      = -1,
-                       const int                 index      = -1,
-                       const AccessorData       *local_data =  0)
-                    :
-                   TriaAccessor<0,dim> (parent, level, index, local_data)
-      {
-       Assert (false, ExcInternalError());
-      }
-};
-
-
-
-/**
- *   Accessor to dereference the data of lines. This accessor is used
- *   to point to lines in @p dim space dimensions. There is a derived
- *   class for lines in one space dimension, in which case a line is
- *   also a cell and thus has much more functionality than in other
- *   dimensions.
- *
- * @ingroup grid
- *   @author Wolfgang Bangerth, 1998
- */
-template <int dim>
-class TriaObjectAccessor<1, dim> :  public TriaAccessor<1,dim>
-{
-  public:
-                                    /**
-                                     * Propagate typedef from
-                                     * base class to this class.
-                                     */
-    typedef typename TriaAccessor<1,dim>::AccessorData AccessorData;
-
-                                    /**
-                                     *  Constructor.
-                                     */
-    TriaObjectAccessor (const Triangulation<dim> *parent     =  0,
-                       const int                 level      = -1,
-                       const int                 index      = -1,
-                       const AccessorData       *local_data =  0);
-
-                                    /**
-                                     *  Copy the data of the given
-                                     *  line.
-                                     */
-    void set (const internal::Triangulation::TriaObject<1> &l) const;
-
-                                    /**
-                                     *  Return the index of vertex
-                                     *  <tt>i=0,1</tt> of a line.
-                                     *
-                                     *  Note that the returned value is only
-                                     *  the index of the geometrical
-                                     *  vertex. It has nothing to do with
-                                     *  possible degrees of freedom
-                                     *  associated with it. For this, see the
-                                     *  @p DoFAccessor::vertex_dof_index
-                                     *  functions.
-                                     */ 
-    unsigned int vertex_index (const unsigned int i) const;
-
-                                    /**
-                                     *  Return a reference to the
-                                     *  @p ith vertex.
-                                     */
-    Point<dim> & vertex (const unsigned int i) const;
-
-                                    /**
-                                     *  Test for the element being
-                                     *  used or not.  The return
-                                     *  value is @p true for all
-                                     *  iterators that are either
-                                     *  normal iterators or active
-                                     *  iterators, only raw iterators
-                                     *  can return @p false. Since
-                                     *  raw iterators are only used
-                                     *  in the interiors of the
-                                     *  library, you will not usually
-                                     *  need this function.
-                                     */
-    bool used () const;
-
-                                    /**
-                                     *  Set the @p used flag. Only
-                                     *  for internal use in the
-                                     *  library.
-                                     */
-    void set_used_flag () const;
-
-                                    /**
-                                     *  Clear the @p used flag. Only
-                                     *  for internal use in the
-                                     *  library.
-                                     */
-    void clear_used_flag () const;
-
-                                    /**
-                                     *  Return whether the user flag
-                                     *  is set or not.
-                                     */
-    bool user_flag_set () const;
-
-                                    /**
-                                     *  Flag the user flag for this cell.
-                                     */
-    void set_user_flag () const;
-
-                                    /**
-                                     *  Clear the user flag.
-                                     */
-    void clear_user_flag () const;
-
-                                    /**
-                                     *  Set the user flag of this
-                                     *  object and of all its
-                                     *  children and their children,
-                                     *  etc.
-                                     */
-    void recursively_set_user_flag () const;
-
-                                    /**
-                                     *  Clear the user flag of this
-                                     *  object and of all its
-                                     *  children and their children,
-                                     *  etc.
-                                     */
-    void recursively_clear_user_flag () const;
-
-                                    /**
-                                     * Reset the user data to zero,
-                                     * independent if pointer or index.
-                                     */
-    void clear_user_data () const;
-    
-                                    /**
-                                     * Set the user pointer of this
-                                     * line to @p p.
-                                     */
-    void set_user_pointer (void *p) const;
-
-                                    /**
-                                     * Set the user pointer of this
-                                     * object and all its children to
-                                     * the given value. This is
-                                     * useful for example if all
-                                     * cells of a certain subdomain,
-                                     * or all faces of a certain part
-                                     * of the boundary should have
-                                     * user pointers pointing to
-                                     * objects describing this part
-                                     * of the domain or boundary.
-                                     *
-                                     * Note that the user pointer is
-                                     * not inherited under mesh
-                                     * refinement, so after mesh
-                                     * refinement there might be
-                                     * cells or faces that don't have
-                                     * user pointers pointing to the
-                                     * describing object. In this
-                                     * case, simply loop over all the
-                                     * elements of the coarsest level
-                                     * that has this information, and
-                                     * use this function to
-                                     * recursively set the user
-                                     * pointer of all finer levels of
-                                     * the triangulation.
-                                     */
-    void recursively_set_user_pointer (void *p) const;
-
-                                    /**
-                                     * Clear the user pointer of this
-                                     * object and all of its
-                                     * descendants. The same holds as
-                                     * said for the
-                                     * recursively_set_user_pointer()
-                                     * function.
-                                     */
-    void recursively_clear_user_pointer () const;
-
-                                    /**
-                                     * Reset the user pointer of this
-                                     * line to a @p NULL pointer.
-                                     */
-    void clear_user_pointer () const;
-
-                                    /**
-                                     * Access the value of the user
-                                     * pointer of this line. It is in
-                                     * the responsibility of the user
-                                     * to make sure that the pointer
-                                     * points to something
-                                     * useful. You should use the new
-                                     * style cast operator to
-                                     * maintain a minimum of
-                                     * typesafety, e.g.
-                                     * <tt>A *a=static_cast<A*>(cell->user_pointer());</tt>.
-                                     */
-    void * user_pointer () const;
-
-                                    /**
-                                     * Return the @p RefinementCase<dim>
-                                     * of this cell.
-                                     */
-    RefinementCase<1> refinement_case() const;
-    
-                                    /**
-                                     * Set the user index
-                                     * to @p p.
-                                     */
-    void set_user_index (const unsigned int p) const;
-    
-                                    /**
-                                     * Reset the user index to 0.
-                                     */
-    void clear_user_index () const;
-    
-                                    /**
-                                     * Access the value of the user
-                                     * index.
-                                     */
-    unsigned int user_index () const;
-
-                                    /**
-                                     * Set the user index of this
-                                     * object and all its children.
-                                     *
-                                     * Note that the user index is
-                                     * not inherited under mesh
-                                     * refinement, so after mesh
-                                     * refinement there might be
-                                     * cells or faces that don't have
-                                     * the expected user indices. In
-                                     * this case, simply loop over
-                                     * all the elements of the
-                                     * coarsest level that has this
-                                     * information, and use this
-                                     * function to recursively set
-                                     * the user index of all finer
-                                     * levels of the triangulation.
-                                     */
-    void recursively_set_user_index (const unsigned int p) const;
-
-                                    /**
-                                     * Clear the user index of this
-                                     * object and all of its
-                                     * descendants. The same holds as
-                                     * said for the
-                                     * recursively_set_user_index()
-                                     * function.
-                                     */
-    void recursively_clear_user_index () const;
-
-                                    /**
-                                     *  Return a pointer to the
-                                     *  @p ith child.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<1, dim> >
-    child (const unsigned int i) const;
-
-                                    /**
-                                     *  Pointer to the @p object, which is
-                                     *  identical to the ith child for
-                                     *  isotropic refinement. For lines this
-                                     *  does exactly the same as
-                                     *  <tt>child(i)</tt>.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<1,dim> >
-    isotropic_child (const unsigned int i) const;
-
-                                    /**
-                                     *  Return the index of the
-                                     *  @p ith child.  The level of
-                                     *  the child is one higher than
-                                     *  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;
-
-                                    /**
-                                     *  Index of the @p ith isotropic_child.
-                                     *  The level of the (grand-)child is 
-                                     *  higher than that of the
-                                     *  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 isotropic_child_index (const unsigned int i) const;
-
-                                    /**
-                                     *  Set the index of the ith
-                                     *  child. Since the children
-                                     *  come at least in pairs, we
-                                     *  need to store the index of
-                                     *  only every second child,
-                                     *  i.e. of the even numbered
-                                     *  children. Make sure, that the
-                                     *  index of child i=0 is set
-                                     *  first. Calling this function
-                                     *  for odd numbered children is
-                                     *  not allowed.
-                                     *  The level of the child
-                                     *  is one level up of the level
-                                     *  of the cell to which this
-                                     *  iterator points if
-                                     *  @p dim=1 and lines are cells.
-                                     *  Otherwise the line and its children
-                                     *  have no level.
-                                     */
-    void set_children (const unsigned int i, const int index) const;
-       
-                                    /**
-                                     *  Clear the child field,
-                                     *  i.e. set it to a value which
-                                     *  indicates that this cell has
-                                     *  no children.
-                                     */
-    void clear_children () const;
-
-                                    /**
-                                     *  Test whether the line has
-                                     *  children.
-                                     */
-    bool has_children () const;
-
-                                    /**
-                                     * Return the number of immediate
-                                     * children of this object.
-                                     */
-    unsigned int n_children() const;
-
-                                    /**
-                                     * Return the index of the vertex
-                                     * in the middle of this object,
-                                     * if it exists. In order to
-                                     * exist, the object needs to be
-                                     * refined - for 2D and 3D it
-                                     * needs to be refined
-                                     * isotropically or else the
-                                     * anisotropic children have to
-                                     * be refined again. If the
-                                     * middle vertex does not exist,
-                                     * return
-                                     * <tt>numbers::invalid_unsigned_int</tt>.
-                                     */
-    unsigned int middle_vertex_index() const;
-
-                                    /**
-                                     * Return the number of times
-                                     * that this cell is
-                                     * refined. Note that not all its
-                                     * children are refined that
-                                     * often (which is why we prepend
-                                     * @p max_), the returned number
-                                     * is rather the maximum number
-                                     * of refinement in any branch of
-                                     * children of this object.
-                                     *
-                                     * For example, if this object is
-                                     * refined, and one of its children is
-                                     * refined exactly one more time, then
-                                     * <tt>max_refinement_depth</tt> should
-                                     * return 2.
-                                     *
-                                     * If this object is not refined (i.e. it
-                                     * is active), then the return value is
-                                     * zero.
-                                     */
-    unsigned int max_refinement_depth () const;
-    
-                                    /**
-                                     * Return the boundary indicator
-                                     * of this line. Since boundary
-                                     * data is only useful for
-                                     * structures with a dimension
-                                     * less than the dimension of a
-                                     * cell, this function issues an
-                                     * error if <tt>dim<2</tt>.
-                                     *
-                                     * If the return value is 255,
-                                     * then this line is in the
-                                     * interior of the domain.
-                                     */
-    unsigned char boundary_indicator () const;
-
-                                    /**
-                                     * Set the boundary indicator of
-                                     * this line.  The same applies
-                                     * as for the
-                                     * <tt>boundary_indicator()</tt>
-                                     * function.
-                                     *
-                                     * You should be careful with
-                                     * this function and especially
-                                     * never try to set the boundary
-                                     * indicator to 255, unless you
-                                     * exactly know what you are
-                                     * doing, since this value is
-                                     * reserved for another purpose
-                                     * and algorithms may not work if
-                                     * boundary cells have this
-                                     * boundary indicator or if
-                                     * interior cells have boundary
-                                     * indicators other than 255.
-                                     */
-    void set_boundary_indicator (const unsigned char) const;
-
-                                    /**
-                                     * Do as set_boundary_indicator()
-                                     * but also set the boundary
-                                     * indicators of the objects that
-                                     * bound the current object. For
-                                     * example, in 3d, if
-                                     * set_boundary_indicator() is
-                                     * called on a face, then the
-                                     * boundary indicator of the 4
-                                     * edges that bound the face
-                                     * remain unchanged. On the other
-                                     * hand, the boundary indicators
-                                     * of face and edges are all set
-                                     * at the same time using the
-                                     * current function.
-                                     */
-    void set_all_boundary_indicators (const unsigned char) const;
-
-                                    /**
-                                     * Return whether this line is at
-                                     * the boundary. This is checked
-                                     * via the the boundary indicator
-                                     * field, which is always 255 if
-                                     * the line is in the interior of
-                                     * the domain. Obviously, this is
-                                     * only possible for <tt>dim>1</tt>;
-                                     * however, for <tt>dim==1</tt>, a
-                                     * line is a cell and the
-                                     * CellAccessor class
-                                     * offers another possibility to
-                                     * determine whether a cell is at
-                                     * the boundary or not.
-                                     */
-    bool at_boundary () const;
-
-                                    /**
-                                     * Return the length of the
-                                     * line. If the line describes
-                                     * part of the boundary (e.g. if
-                                     * it is face to a cell in 2D)
-                                     * and is not a straight one, ask
-                                     * the finite element class for
-                                     * the correct length!
-                                     */
-    double diameter () const;
-
-                                    /**
-                                     * Return the center of the
-                                     * line. This is the average of
-                                     * the two vertices, which is the
-                                     * obvious definition for
-                                     * straight lines. However, if
-                                     * you use higher order mappings
-                                     * from the unit cell to the real
-                                     * cell (in more than one space
-                                     * dimension), the bounding lines
-                                     * may not necessarily be
-                                     * straight.  In that case ask
-                                     * the finite element class for
-                                     * the correct place of the
-                                     * midpoint of the line in real
-                                     * space.
-                                     */
-    Point<dim> center () const;
-
-                                    /**
-                                     * Return the barycenter of the
-                                     * line, which is the
-                                     * midpoint. The same applies as
-                                     * for the @p center function
-                                     * with regard to lines at the
-                                     * boundary.
-                                     */
-    Point<dim> barycenter () const;
-    
-                                    /**
-                                     * Return the length of the line.
-                                     * The same applies as for the
-                                     * @p center function with
-                                     * regard to lines at the
-                                     * boundary.
-                                     */
-    double measure () const;
-
-                                    /**
-                                     * Compute and return the number
-                                     * of children of this
-                                     * line. Actually, this function
-                                     * only counts the number of
-                                     * active children, i.e. the
-                                     * number if lines which are not
-                                     * further refined. Thus, if both
-                                     * of the two children of a line
-                                     * are further refined exactly
-                                     * once, the returned number will
-                                     * be four, not six.
-                                     *
-                                     * If the present cell is not
-                                     * refined, one is returned.
-                                     */
-    unsigned int number_of_children () const;
-    
-                                     /**
-                                      * Return whether the face with
-                                      * index @p face has its normal
-                                      * pointing in the standard
-                                      * direction (@p true) or
-                                      * whether it is the opposite
-                                      * (@p false). Which is the
-                                      * standard direction is
-                                      * documented with the
-                                      * GeometryInfo class. In
-                                      * 1d and 2d, this is always
-                                      * @p true, but in 3d it may be
-                                      * different, see the respective
-                                      * discussion in the
-                                      * documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_orientation (const unsigned int face) const;
-
-                                     /**
-                                      * Return whether the face with index @p
-                                      * face is rotated by 180 degrees (@p true)
-                                      * or or not (@p false). In 1d and 2d, this
-                                      * is always @p false, but in 3d it may be
-                                      * different, see the respective discussion
-                                      * in the documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_flip (const unsigned int face) const;
-
-                                     /**
-                                      * Return whether the face with index @p
-                                      * face is rotated by 90 degrees (@p true)
-                                      * or or not (@p false). In 1d and 2d, this
-                                      * is always @p false, but in 3d it may be
-                                      * different, see the respective discussion
-                                      * in the documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_rotation (const unsigned int face) const;
-    
-                                     /**
-                                      * Return whether the line with index @p
-                                      * line is oriented in standard
-                                      * direction. @p true indicates, that the
-                                      * line is oriented from vertex 0 to vertex
-                                      * 1, whereas it is the other way around
-                                      * otherwise. In 1d and 2d, this is always
-                                      * @p true, but in 3d it may be different,
-                                      * see the respective discussion in the
-                                      * documentation of the 
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool line_orientation (const unsigned int line) const;
-    
-                                     /**
-                                      * Set the flag indicating, what
-                                      * <code>line_orientation()</code> will
-                                      * return.
-                                     *
-                                     * It is only possible to set the
-                                     * line_orientation of faces in 3d
-                                     * (i.e. <code>celldim==2 &&
-                                     * dim==3</code>).
-                                      */
-    void set_line_orientation (const unsigned int line,
-                               const bool         orientation) const;
-    
-  private:
-                                    /**
-                                     *  Copy operator. This is normally
-                                     *  used in a context like
-                                     *  <tt>iterator a,b;  *a=*b;</tt>. Since
-                                     *  the meaning is to copy the object
-                                     *  pointed to by @p b to the object
-                                     *  pointed to by @p a and since
-                                     *  accessors are not real but
-                                     *  virtual objects, this operation
-                                     *  is not useful for iterators on
-                                     *  triangulations. We declare this
-                                     *  function here private, thus it may
-                                     *  not be used from outside.
-                                     *  Furthermore it is not implemented
-                                     *  and will give a linker error if
-                                     *  used anyway.
-                                     */
-    void operator = (const TriaObjectAccessor<1, dim> &);
-
-  protected:
-    
-                                    /**@name Advancement of iterators*/
-                                    /*@{*/
-                                    /**
-                                     *  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
-                                     *  is the last on this level,
-                                     *  the first on the next level
-                                     *  is accessed.
-                                     */
-    void operator ++ ();
-
-                                    /**
-                                     *  This operator moves the
-                                     *  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
-                                     *  element is the first on this
-                                     *  level, the last on the
-                                     *  previous level is accessed.
-                                     */
-    void operator -- ();
-
-                                    /**
-                                     * Access to the other objects of
-                                     * a Triangulation with same
-                                     * dimension. This function is
-                                     * specialized for dim==1 because
-                                     * lines are stored in
-                                     * TriaLevel<1> for dim==1 but in
-                                     * TriaFace<dim> for dim!=1. All
-                                     * accessor functions using this
-                                     * function can be implemented
-                                     * for all dim without
-                                     * specialization.
-                                     */
-    internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<1> > & objects() const;
-
-  private:
-    
-                                    /**
-                                     * Dimension of the TriaObject
-                                     * this accessor gives access to.
-                                     */
-    static const unsigned int objectdim = 1;
-
-                                    /*@}*/
-
-                                    /**
-                                     * Declare some friends.
-                                     */
-    template <int anydim, typename AnyAccessor> friend class TriaRawIterator;
-};
-
-
-
-/**
- *   Accessor to dereference the data of quads. This accessor is used
- *   to point to quads in @p dim space dimensions (only <tt>dim>=2</tt>
- *   seems reasonable to me). There is a derived class for quads in
- *   two space dimension, in which case a quad is also a cell and thus
- *   has much more functionality than in other dimensions.
- *
- * @ingroup grid
- *   @author Wolfgang Bangerth, 1998
- */
-template <int dim>
-class TriaObjectAccessor<2, dim> :  public TriaAccessor<2,dim>
-{
-  public:
-                                    /**
-                                     * Propagate typedef from base
-                                     * class to this class.
-                                     */
-    typedef typename TriaAccessor<2,dim>::AccessorData AccessorData;
-
-                                    /**
-                                     *  Constructor.
-                                     */
-    TriaObjectAccessor (const Triangulation<dim> *parent     =  0,
-                       const int                 level      = -1,
-                       const int                 index      = -1,
-                       const AccessorData       *local_data =  0);
-
-                                    /**
-                                     *  Copy the data of the given quad.
-                                     */
-    void set (const internal::Triangulation::TriaObject<2> &q) const;
-
-                                    /**
-                                     * Return index of a vertex of a
-                                     * quad in the internal data
-                                     * structure of a Triangulation.
-                                     *
-                                     * For local numbering of the
-                                     * vertices, see the page on
-                                     * Geometry.
-                                     *
-                                     * @attention The value returned
-                                     * is only the index of the
-                                     * geometrical vertex. It has
-                                     * nothing to do with possible
-                                     * degrees of freedom associated
-                                     * with it. For this, see the
-                                     * DoFAccessor::vertex_dof_index
-                                     * functions.
-                                     */ 
-    unsigned int vertex_index (const unsigned int i) const;
-
-                                    /**
-                                     *  Return a reference to the
-                                     *  @p ith vertex.
-                                     */
-    Point<dim> & vertex (const unsigned int i) const;
-
-                                    /**
-                                     *  Return a pointer to the
-                                     *  @p ith line bounding this
-                                     *  Quad.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<1, dim> >
-    line (const unsigned int i) const;
-
-                                    /**
-                                     * Return the line index of the
-                                     * @p ith side (a line). The
-                                     * line has no level.
-                                     */
-    unsigned int line_index (const unsigned int i) const;
-    
-                                    /**
-                                     *  Test for the element being
-                                     *  used or not.  The return
-                                     *  value is @p true for all
-                                     *  iterators that are either
-                                     *  normal iterators or active
-                                     *  iterators, only raw iterators
-                                     *  can return @p false. Since
-                                     *  raw iterators are only used
-                                     *  in the interiors of the
-                                     *  library, you will not usually
-                                     *  need this function.
-                                     */
-    bool used () const;
-
-                                    /**
-                                     *  Set the @p used flag. You
-                                     *  should know quite exactly
-                                     *  what you are doing of you
-                                     *  touch this function. It is
-                                     *  exclusively for internal use
-                                     *  in the library.
-                                     */
-    void set_used_flag () const;
-
-                                    /**
-                                     *  Clear the @p used flag. You
-                                     *  should know quite exactly
-                                     *  what you are doing of you
-                                     *  touch this function. It is
-                                     *  exclusively for internal use
-                                     *  in the library.
-                                     */
-    void clear_used_flag () const;
-
-                                    /**
-                                     *  Return whether the user flag
-                                     *  is set or not.
-                                     */
-    bool user_flag_set () const;
-
-                                    /**
-                                     *  Flag the user flag for this
-                                     *  cell.
-                                     */
-    void set_user_flag () const;
-
-                                    /**
-                                     *  Clear the user flag.
-                                     */
-    void clear_user_flag () const;
-
-                                    /**
-                                     *  Set the user flag of this
-                                     *  object and of all its
-                                     *  children and their children,
-                                     *  etc.
-                                     */
-    void recursively_set_user_flag () const;
-
-                                    /**
-                                     *  Clear the user flag of this
-                                     *  object and of all its
-                                     *  children and their children,
-                                     *  etc.
-                                     */
-    void recursively_clear_user_flag () const;
-
-                                    /**
-                                     * Reset the user data to zero,
-                                     * independent if pointer or index.
-                                     */
-    void clear_user_data () const;
-    
-                                    /**
-                                     * Set the user pointer of this
-                                     * quad to @p p.
-                                     */
-    void set_user_pointer (void *p) const;
-
-                                    /**
-                                     * Reset the user pointer of this
-                                     * quad to a @p NULL pointer.
-                                     */
-    void clear_user_pointer () const;
-
-                                    /**
-                                     * Access the value of the user
-                                     * pointer of this quad. It is in
-                                     * the responsibility of the user
-                                     * to make sure that the pointer
-                                     * points to something
-                                     * useful. You should use the new
-                                     * style cast operator to
-                                     * maintain a minimum of
-                                     * typesafety, e.g.
-                                     * <tt>A *a=static_cast<A*>(cell->user_pointer());</tt>.
-                                     */
-    void * user_pointer () const;
-
-                                    /**
-                                     * Set the user pointer of this
-                                     * object and all its children to
-                                     * the given value. This is
-                                     * useful for example if all
-                                     * cells of a certain subdomain,
-                                     * or all faces of a certain part
-                                     * of the boundary should have
-                                     * user pointers pointing to
-                                     * objects describing this part
-                                     * of the domain or boundary.
-                                     *
-                                     * Note that the user pointer is
-                                     * not inherited under mesh
-                                     * refinement, so after mesh
-                                     * refinement there might be
-                                     * cells or faces that don't have
-                                     * user pointers pointing to the
-                                     * describing object. In this
-                                     * case, simply loop over all the
-                                     * elements of the coarsest level
-                                     * that has this information, and
-                                     * use this function to
-                                     * recursively set the user
-                                     * pointer of all finer levels of
-                                     * the triangulation.
-                                     */
-    void recursively_set_user_pointer (void *p) const;
-
-                                    /**
-                                     * Clear the user pointer of this
-                                     * object and all of its
-                                     * descendants. The same holds as
-                                     * said for the
-                                     * recursively_set_user_pointer()
-                                     * function.
-                                     */
-    void recursively_clear_user_pointer () const;
-
-                                    /**
-                                     * Set the user index
-                                     * to @p p.
-                                     */
-    void set_user_index (const unsigned int p) const;
-    
-                                    /**
-                                     * Reset the user index to 0.
-                                     */
-    void clear_user_index () const;
-    
-                                    /**
-                                     * Access the value of the user
-                                     * index.
-                                     */
-    unsigned int user_index () const;
-
-                                    /**
-                                     * Set the user index of this
-                                     * object and all its children.
-                                     *
-                                     * Note that the user index is
-                                     * not inherited under mesh
-                                     * refinement, so after mesh
-                                     * refinement there might be
-                                     * cells or faces that don't have
-                                     * the expected user indices. In
-                                     * this case, simply loop over
-                                     * all the elements of the
-                                     * coarsest level that has this
-                                     * information, and use this
-                                     * function to recursively set
-                                     * the user index of all finer
-                                     * levels of the triangulation.
-                                     */
-    void recursively_set_user_index (const unsigned int p) const;
-
-                                    /**
-                                     * Clear the user index of this
-                                     * object and all of its
-                                     * descendants. The same holds as
-                                     * said for the
-                                     * recursively_set_user_index()
-                                     * function.
-                                     */
-    void recursively_clear_user_index () const;
-                                    /**
-
-                                     * Return the @p RefinementCase<dim>
-                                     * of this cell.
-                                     */
-    RefinementCase<2> refinement_case() const;
-
-                                    /**
-                                     * Set the @p RefinementCase<dim> this
-                                     * TriaObject is refined with.
-                                     *
-                                     * You should know quite exactly
-                                     * what you are doing if you
-                                     * touch this function. It is
-                                     * exclusively for internal use
-                                     * in the library.
-                                     */
-    void set_refinement_case (const RefinementCase<2> &refinement_case) const;
-
-                                    /**
-                                     * Clear the RefinementCase<dim> of
-                                     * this TriaObject, i.e. reset it
-                                     * to RefinementCase<dim>::no_refinement.
-                                     *
-                                     * You should know quite exactly
-                                     * what you are doing if you
-                                     * touch this function. It is
-                                     * exclusively for internal use
-                                     * in the library.
-                                     */
-    void clear_refinement_case () const;
-
-                                    /**
-                                     *  Return a pointer to the @p ith
-                                     *  child.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<2, dim> > child (const unsigned int i) const;
-
-                                    /**
-                                     *  Pointer to the @p object, which is
-                                     *  identical to the ith child for
-                                     *  isotropic refinement. If the object is
-                                     *  refined anisotropically, the returned
-                                     *  child will in fact be a grandchild of
-                                     *  the object.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<2,dim> >
-    isotropic_child (const unsigned int i) const;
-
-                                    /**
-                                     *  Return the index of the
-                                     *  @p ith child.  The level of
-                                     *  the child is one higher than
-                                     *  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;
-
-                                    /**
-                                     *  Index of the @p ith isotropic_child.
-                                     *  The level of the (grand-)child is 
-                                     *  higher than that of the
-                                     *  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 isotropic_child_index (const unsigned int i) const;
-
-                                    /**
-                                     *  Set the index of the ith
-                                     *  child. Since the children
-                                     *  come at least in pairs, we
-                                     *  need to store the index of
-                                     *  only every second child,
-                                     *  i.e. of the even numbered
-                                     *  children. Make sure, that the
-                                     *  index of child i=0 is set
-                                     *  first. Calling this function
-                                     *  for odd numbered children is
-                                     *  not allowed.
-                                     */
-    void set_children (const unsigned int i, const int index) const;
-       
-                                    /**
-                                     *  Clear the child field,
-                                     *  i.e. set it to a value which
-                                     *  indicates that this cell has
-                                     *  no children.
-                                     */
-    void clear_children () const;
-    
-                                    /**
-                                     *  Test whether the quad has
-                                     *  children.
-                                     */
-    bool has_children () const;
-
-                                    /**
-                                     * Return the number of immediate
-                                     * children of this object.
-                                     */
-    unsigned int n_children() const;
-
-                                    /**
-                                     * Return the index of the vertex
-                                     * in the middle of this object,
-                                     * if it exists. In order to
-                                     * exist, the object needs to be
-                                     * refined - for 2D and 3D it
-                                     * needs to be refined
-                                     * isotropically or else the
-                                     * anisotropic children have to
-                                     * be refined again. If the
-                                     * middle vertex does not exist,
-                                     * return
-                                     * <tt>numbers::invalid_unsigned_int</tt>.
-                                     */
-    unsigned int middle_vertex_index() const;
-
-                                    /**
-                                     * Return the number of times
-                                     * that this cell is
-                                     * refined. Note that not all its
-                                     * children are refined that
-                                     * often (which is why we prepend
-                                     * @p max_), the returned number
-                                     * is rather the maximum number
-                                     * of refinement in any branch of
-                                     * children of this object.
-                                     *
-                                     * For example, if this object is
-                                     * refined, and one of its children is
-                                     * refined exactly one more time, then
-                                     * <tt>max_refinement_depth</tt> should
-                                     * return 2.
-                                     *
-                                     * If this object is not refined (i.e. it
-                                     * is active), then the return value is
-                                     * zero.
-                                     */
-    unsigned int max_refinement_depth () const;
-    
-                                    /**
-                                     * Return the boundary indicator
-                                     * of this quad. Since boundary
-                                     * data is only useful for
-                                     * structures with a dimension
-                                     * less than the dimension of a
-                                     * cell, this function issues an
-                                     * error if <tt>dim<3</tt>.
-                                     *
-                                     * If the return value is 255,
-                                     * then this quad is in the
-                                     * interior of the domain.
-                                     */
-    unsigned char boundary_indicator () const;
-
-                                    /**
-                                     * Set the boundary indicator of
-                                     * this quad.  The same applies
-                                     * as for the
-                                     * <tt>boundary_indicator()</tt>
-                                     * function.
-                                     *
-                                     * Note that it only sets the
-                                     * boundary object of the current
-                                     * object itself, not the
-                                     * indicators of the ones that
-                                     * bound it. For example, in 3d,
-                                     * if this function is called on
-                                     * a face, then the boundary
-                                     * indicator of the 4 edges that
-                                     * bound the face remain
-                                     * unchanged. If you want to set
-                                     * the boundary indicators of
-                                     * face and edges at the same
-                                     * time, use the
-                                     * set_all_boundary_indicators()
-                                     * function.
-                                     *
-                                     * You should be careful with
-                                     * this function and especially
-                                     * never try to set the boundary
-                                     * indicator to 255, unless you
-                                     * exactly know what you are
-                                     * doing, since this value is
-                                     * reserved for another purpose
-                                     * and algorithms may not work if
-                                     * boundary cells have this
-                                     * boundary indicator or if
-                                     * interior cells have boundary
-                                     * indicators other than 255.
-                                     */
-    void set_boundary_indicator (const unsigned char) const;
-
-                                    /**
-                                     * Do as set_boundary_indicator()
-                                     * but also set the boundary
-                                     * indicators of the objects that
-                                     * bound the current object. For
-                                     * example, in 3d, if
-                                     * set_boundary_indicator() is
-                                     * called on a face, then the
-                                     * boundary indicator of the 4
-                                     * edges that bound the face
-                                     * remain unchanged. On the other
-                                     * hand, the boundary indicators
-                                     * of face and edges are all set
-                                     * at the same time using the
-                                     * current function.
-                                     */
-    void set_all_boundary_indicators (const unsigned char) const;
-
-                                    /**
-                                     * Return whether this quad is at
-                                     * the boundary. This is checked
-                                     * via the the boundary indicator
-                                     * field, which is always 255 if
-                                     * the quad is in the interior of
-                                     * the domain. Obviously, this
-                                     * function is only useful for
-                                     * <tt>dim>2</tt>; however, for
-                                     * <tt>dim==2</tt>, a quad is a cell
-                                     * and the CellAccessor
-                                     * class offers another
-                                     * possibility to determine
-                                     * whether a cell is at the
-                                     * boundary or not.
-                                     */
-    bool at_boundary () const;
-    
-                                    /**
-                                     * Return the diameter of the
-                                     * quad. If the quad describes
-                                     * part of the boundary (e.g. if
-                                     * it is face to a cell in 3D)
-                                     * and is not a plane one, ask
-                                     * the finite element class for
-                                     * the correct length!
-                                     *
-                                     * The diameter of a quad is
-                                     * computed to be the larger of
-                                     * the two diagonals. You should
-                                     * absolutely be clear about the
-                                     * fact that this definitely is
-                                     * not the diameter of all
-                                     * quadrilaterals; however it may
-                                     * serve as an approximation and
-                                     * is exact in many cases,
-                                     * especially if the
-                                     * quadrilateral is not too much
-                                     * distorted.
-                                     */
-    double diameter () const;
-
-                                    /**
-                                     * Return the center of the
-                                     * quad. The center of a quad is
-                                     * defined to be the average of
-                                     * the four vertices, which is
-                                     * also the point where the
-                                     * bilinear mapping places the
-                                     * midpoint of the unit quad in
-                                     * real space.  However, this may
-                                     * not be the point of the
-                                     * barycenter of the quad.
-                                     *
-                                     * Also note that if you use
-                                     * higher order mappings from the
-                                     * unit cell to the real cell (in
-                                     * more than two space
-                                     * dimension), the bounding quads
-                                     * may not necessarily be
-                                     * straight.  In that case ask
-                                     * the finite element class for
-                                     * the correct place of the
-                                     * midpoint of the quad in real
-                                     * space.
-                                     */
-    Point<dim> center () const;
-
-                                    /**
-                                     * Return the barycenter of the
-                                     * qaud. The same applies as for
-                                     * the @p center function with
-                                     * regard to quads at the
-                                     * boundary.
-                                     */
-    Point<dim> barycenter () const;
-
-                                    /**
-                                     * Return the area of the
-                                     * quad. With area, we mean the
-                                     * area included by the straight
-                                     * lines connecting the four
-                                     * vertices, i.e. no information
-                                     * about the boundary is used; if
-                                     * you want other than bilinearly
-                                     * mapped unit quadrilaterals,
-                                     * ask the appropriate finite
-                                     * element class for the area of
-                                     * this quad.
-                                     */
-    double measure () const;
-
-                                    /**
-                                     * Compute and return the number
-                                     * of children of this
-                                     * quad. Actually, this function
-                                     * only counts the number of
-                                     * active children, i.e. the
-                                     * number if quads which are not
-                                     * further refined. Thus, if all
-                                     * of the four children of a quad
-                                     * are further refined
-                                     * isotropically exactly once,
-                                     * the returned number will be
-                                     * 16, not 20.
-                                     *
-                                     * If the present cell is not
-                                     * refined, one is returned.
-                                     */
-    unsigned int number_of_children () const;
-
-                                     /**
-                                      * Return whether the face with
-                                      * index @p face has its normal
-                                      * pointing in the standard
-                                      * direction (@p true) or
-                                      * whether it is the opposite
-                                      * (@p false). Which is the
-                                      * standard direction is
-                                      * documented with the
-                                      * GeometryInfo class. In
-                                      * 1d and 2d, this is always
-                                      * @p true, but in 3d it may be
-                                      * different, see the respective
-                                      * discussion in the
-                                      * documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_orientation (const unsigned int face) const;
-
-                                     /**
-                                      * Return whether the face with index @p
-                                      * face is rotated by 180 degrees (@p true)
-                                      * or or not (@p false). In 1d and 2d, this
-                                      * is always @p false, but in 3d it may be
-                                      * different, see the respective discussion
-                                      * in the documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_flip (const unsigned int face) const;
-
-                                     /**
-                                      * Return whether the face with index @p
-                                      * face is rotated by 90 degrees (@p true)
-                                      * or or not (@p false). In 1d and 2d, this
-                                      * is always @p false, but in 3d it may be
-                                      * different, see the respective discussion
-                                      * in the documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_rotation (const unsigned int face) const;
-    
-                                     /**
-                                      * Return whether the line with index @p
-                                      * line is oriented in standard
-                                      * direction. @p true indicates, that the
-                                      * line is oriented from vertex 0 to vertex
-                                      * 1, whereas it is the other way around
-                                      * otherwise. In 1d and 2d, this is always
-                                      * @p true, but in 3d it may be different,
-                                      * see the respective discussion in the
-                                      * documentation of the 
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool line_orientation (const unsigned int line) const;
-    
-                                     /**
-                                      * Set the flag indicating, what
-                                      * <code>line_orientation()</code> will
-                                      * return.
-                                     *
-                                     * It is only possible to set the
-                                     * line_orientation of faces in 3d
-                                     * (i.e. <code>celldim==2 &&
-                                     * dim==3</code>).
-                                      */
-    void set_line_orientation (const unsigned int line,
-                               const bool         orientation) const;
-
-  private:
-                                    /**
-                                     * Copy operator. This is
-                                     * normally used in a context
-                                     * like <tt>iterator a,b;
-                                     * *a=*b;</tt>. Since the meaning
-                                     * is to copy the object pointed
-                                     * to by @p b to the object
-                                     * pointed to by @p a and since
-                                     * accessors are not real but
-                                     * virtual objects, this
-                                     * operation is not useful for
-                                     * iterators on
-                                     * triangulations. We declare
-                                     * this function here private,
-                                     * thus it may not be used from
-                                     * outside.  Furthermore it is
-                                     * not implemented and will give
-                                     * a linker error if used anyway.
-                                     */
-    void operator = (const TriaObjectAccessor<2, dim> &);
-
-  protected:
-                                    /**@name Advancement of iterators*/
-                                    /*@{*/
-                                    /**
-                                     *  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
-                                     *  is the last on this level,
-                                     *  the first on the next level
-                                     *  is accessed.
-                                     */
-    void operator ++ ();
-
-                                    /**
-                                     *  This operator moves the
-                                     *  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
-                                     *  element is the first on this
-                                     *  level, the last on the
-                                     *  previous level is accessed.
-                                     */
-    void operator -- ();
-
-                                    /**
-                                     * Access to the other objects of
-                                     * a Triangulation of same
-                                     * dimension. This function is
-                                     * specialized for dim==2 and
-                                     * dim==3 because quads are
-                                     * stored in TriaLevel<2> for
-                                     * dim==2 but in TriaFace<3> for
-                                     * dim==3. All accessor functions
-                                     * using this function can be
-                                     * implemented for all dimensions
-                                     * without specialization.
-                                     */
-    internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<2> > & objects() const;
-
-  private:
-    
-                                    /**
-                                     * Dimension of the TriaObject
-                                     * this accessor gives access to.
-                                     */
-    static const unsigned int objectdim = 2;
-                                    /*@}*/
-
-                                    /**
-                                     * Declare some friends.
-                                     */
-    template <int anydim, typename AnyAccessor> friend class TriaRawIterator;
-};
-
-
-
-/**
- *   Accessor to dereference the data of hexahedra. This accessor is
- *   used to point to hexs in @p dim space dimensions (only
- *   <tt>dim>=3</tt> seems reasonable to me). There is a derived class for
- *   hexs in three space dimension, in which case a hex is also a cell
- *   and thus has much more functionality than in other dimensions.
- *
- * @ingroup grid
- *   @author Wolfgang Bangerth, 1998
- */
-template <int dim>
-class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
-{
-  public:
-                                    /**
-                                     * Propagate typedef from base
-                                     * class to this class.
-                                     */
-    typedef typename TriaAccessor<3,dim>::AccessorData AccessorData;
-
-                                    /**
-                                     *  Constructor.
-                                     */
-    TriaObjectAccessor (const Triangulation<dim> *parent     =  0,
-                       const int                 level      = -1,
-                       const int                 index      = -1,
-                       const AccessorData       *local_data =  0);
-
-                                    /**
-                                     *  Copy the data of the given
-                                     *  hex.
-                                     */
-    void set (const internal::Triangulation::TriaObject<3> &h) const;
-    
-                                    /**
-                                     *  Return index of a vertex of a hex in the internal structures of Triangulation.
-                                     *
-                                     * For local numbering of the
-                                     * vertices, see the page on
-                                     * Geometry.
-                                     *
-                                     *
-                                     *  Note that the returned value is only
-                                     *  the index of the geometrical
-                                     *  vertex. It has nothing to do with
-                                     *  possible degrees of freedom
-                                     *  associated with it. For this, see the
-                                     *  @p DoFAccessor::vertex_dof_index
-                                     *  functions.
-                                     */ 
-    unsigned int vertex_index (const unsigned int i) const;
-
-                                    /**
-                                     *  Return a reference to the
-                                     *  @p ith vertex.
-                                     */
-    Point<dim> & vertex (const unsigned int i) const;
-
-                                    /**
-                                     *  Return a pointer to the
-                                     *  @p ith line bounding this
-                                     *  @p Hex.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<1, dim> >
-    line (const unsigned int i) const;
-
-                                    /**
-                                     * Return the line index of the
-                                     * @p ith line. The line has no
-                                     * level.
-                                     */
-    unsigned int line_index (const unsigned int i) const;
-    
-                                    /**
-                                     *  Return a pointer to the
-                                     *  @p ith quad bounding this
-                                     *  @p Hex.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<2, dim> >
-    quad (const unsigned int i) const;
-
-                                    /**
-                                     * Return the quad index of the
-                                     * @p ith side (a quad). The quad
-                                     * has no level.
-                                     */
-    unsigned int quad_index (const unsigned int i) const;
-
-                                    /**
-                                     *  Test for the element being
-                                     *  used or not.  The return
-                                     *  value is @p true for all
-                                     *  iterators that are either
-                                     *  normal iterators or active
-                                     *  iterators, only raw iterators
-                                     *  can return @p false. Since
-                                     *  raw iterators are only used
-                                     *  in the interiors of the
-                                     *  library, you will not usually
-                                     *  need this function.
-                                     */
-    bool used () const;
-
-                                    /**
-                                     *  Set the @p used flag. You
-                                     *  should know quite exactly
-                                     *  what you are doing of you
-                                     *  touch this function. It is
-                                     *  exclusively for internal use
-                                     *  in the library.
-                                     */
-    void set_used_flag () const;
-
-                                    /**
-                                     *  Clear the @p used flag. You
-                                     *  should know quite exactly
-                                     *  what you are doing of you
-                                     *  touch this function. It is
-                                     *  exclusively for internal use
-                                     *  in the library.
-                                     */
-    void clear_used_flag () const;
-
-                                    /**
-                                     *  Return whether the user flag
-                                     *  is set or not.
-                                     */
-    bool user_flag_set () const;
-
-                                    /**
-                                     *  Flag the user flag for this
-                                     *  cell.
-                                     */
-    void set_user_flag () const;
-
-                                    /**
-                                     *  Clear the user flag.
-                                     */
-    void clear_user_flag () const;
-
-                                    /**
-                                     *  Set the user flag of this
-                                     *  object and of all its
-                                     *  children and their children,
-                                     *  etc.
+                                     *  Set the user flag for this
+                                     * and all descendants.
                                      */
     void recursively_set_user_flag () const;
 
                                     /**
-                                     *  Clear the user flag of this
-                                     *  object and of all its
-                                     *  children and their children,
-                                     *  etc.
+                                     *  Clear the user flag for this
+                                     * and all descendants. 
                                      */
     void recursively_clear_user_flag () const;
 
@@ -2925,22 +1193,22 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
     void clear_user_data () const;
     
                                     /**
-                                     * Set the user pointer of this
-                                     * hex to @p p.
+                                     * Set the user pointer
+                                     * to @p p.
                                      */
     void set_user_pointer (void *p) const;
 
                                     /**
-                                     * Reset the user pointer of this
-                                     * hex to a @p NULL pointer.
+                                     * Reset the user pointer
+                                     * to a @p NULL pointer.
                                      */
     void clear_user_pointer () const;
-
+    
                                     /**
                                      * Access the value of the user
-                                     * pointer of this hex. It is in
-                                     * the responsibility of the user
-                                     * to make sure that the pointer
+                                     * pointer. It is in the
+                                     * responsibility of the user to
+                                     * make sure that the pointer
                                      * points to something
                                      * useful. You should use the new
                                      * style cast operator to
@@ -2978,7 +1246,7 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
                                      * the triangulation.
                                      */
     void recursively_set_user_pointer (void *p) const;
-
+    
                                     /**
                                      * Clear the user pointer of this
                                      * object and all of its
@@ -2988,7 +1256,7 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
                                      * function.
                                      */
     void recursively_clear_user_pointer () const;
-
+    
                                     /**
                                      * Set the user index
                                      * to @p p.
@@ -3035,389 +1303,83 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
                                      * function.
                                      */
     void recursively_clear_user_index () const;
-    
-                                    /**
-                                     * Return the @p RefinementCase<dim>
-                                     * of this cell.
-                                     */
-    RefinementCase<3> refinement_case() const;
-
-                                    /**
-                                     * Set the @p RefinementCase<dim> this
-                                     * TriaObject is refined with.
-                                     *
-                                     * You should know quite exactly
-                                     * what you are doing if you
-                                     * touch this function. It is
-                                     * exclusively for internal use
-                                     * in the library.
-                                     */
-    void set_refinement_case (const RefinementCase<3> &ref_case) const;
-
-                                    /**
-                                     * Clear the RefinementCase<dim> of
-                                     * this TriaObject, i.e. reset it
-                                     * to RefinementCase<dim>::no_refinement.
-                                     *
-                                     * You should know quite exactly
-                                     * what you are doing if you
-                                     * touch this function. It is
-                                     * exclusively for internal use
-                                     * in the library.
-                                     */
-    void clear_refinement_case () const;
-
-                                    /**
-                                     *  Return a pointer to the
-                                     *  @p ith child.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<3, dim> >
-    child (const unsigned int i) const;
-
-                                    /**
-                                     *  Pointer to the @p object, which is
-                                     *  identical to the ith child for
-                                     *  isotropic refinement. If the object is
-                                     *  refined anisotropically, the returned
-                                     *  child will in fact be a grandchild of
-                                     *  the object.
-                                     */
-    TriaIterator<dim,TriaObjectAccessor<3,dim> >
-    isotropic_child (const unsigned int i) const;
-
-                                    /**
-                                     *  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
-                                     *  is returned.
-                                     */
-    int child_index (const unsigned int i) const;
-
-                                    /**
-                                     *  Index of the @p ith isotropic_child.
-                                     *  The level of the (grand-)child is 
-                                     *  higher than that of the
-                                     *  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 isotropic_child_index (const unsigned int i) const;
-
-                                    /**
-                                     *  Set the index of the ith
-                                     *  child. Since the children
-                                     *  come at least in pairs, we
-                                     *  need to store the index of
-                                     *  only every second child,
-                                     *  i.e. of the even numbered
-                                     *  children. Make sure, that the
-                                     *  index of child i=0 is set
-                                     *  first. Calling this function
-                                     *  for odd numbered children is
-                                     *  not allowed.
-                                     */
-    void set_children (const unsigned int i, const int index) const;
-       
                                     /**
-                                     *  Clear the child field,
-                                     *  i.e. set it to a value which
-                                     *  indicates that this cell has
-                                     *  no children.
+                                     * @}
                                      */
-    void clear_children () const;
     
                                     /**
-                                     *  Test whether the hex has
-                                     *  children.
-                                     */
-    bool has_children () const;
-
-                                    /**
-                                     * Return the number of immediate
-                                     * children of this object.
-                                     */
-    unsigned int n_children() const;
-
-                                    /**
-                                     * Return the index of the vertex
-                                     * in the middle of this object,
-                                     * if it exists. In order to
-                                     * exist, the object needs to be
-                                     * refined - for 2D and 3D it
-                                     * needs to be refined
-                                     * isotropically or else the
-                                     * anisotropic children have to
-                                     * be refined again. If the
-                                     * middle vertex does not exist,
-                                     * return
-                                     * <tt>numbers::invalid_unsigned_int</tt>.
-                                     */
-    unsigned int middle_vertex_index() const;
-
-                                    /**
-                                     * Return the number of times
-                                     * that this cell is
-                                     * refined. Note that not all its
-                                     * children are refined that
-                                     * often (which is why we prepend
-                                     * @p max_), the returned number
-                                     * is rather the maximum number
-                                     * of refinement in any branch of
-                                     * children of this object.
-                                     *
-                                     * For example, if this object is
-                                     * refined, and one of its children is
-                                     * refined exactly one more time, then
-                                     * <tt>max_refinement_depth</tt> should
-                                     * return 2.
-                                     *
-                                     * If this object is not refined (i.e. it
-                                     * is active), then the return value is
-                                     * zero.
+                                     * @name Geometric information about an object
                                      */
-    unsigned int max_refinement_depth () const;    
-    
                                     /**
-                                     * Return the boundary indicator
-                                     * of this hex. Since boundary
-                                     * data is only useful for
-                                     * structures with a dimension
-                                     * less than the dimension of a
-                                     * cell, this function issues an
-                                     * error if <tt>dim<4</tt>.
-                                     *
-                                     * If the return value is 255,
-                                     * then this line is in the
-                                     * interior of the domain.
+                                     * @{
                                      */
-    unsigned char boundary_indicator () const;
 
                                     /**
-                                     * Set the boundary indicator of
-                                     * this hex.  The same applies as
-                                     * for the
-                                     * <tt>boundary_indicator()</tt>
-                                     * function.
-                                     *
-                                     * Note that it only sets the
-                                     * boundary object of the current
-                                     * object itself, not the
-                                     * indicators of the ones that
-                                     * bound it. For example, in 3d,
-                                     * if this function is called on
-                                     * a face, then the boundary
-                                     * indicator of the 4 edges that
-                                     * bound the face remain
-                                     * unchanged. If you want to set
-                                     * the boundary indicators of
-                                     * face and edges at the same
-                                     * time, use the
-                                     * set_all_boundary_indicators()
-                                     * function.
+                                     * Diameter of the object.
                                      *
-                                     * You should be careful with
-                                     * this function and especially
-                                     * never try to set the boundary
-                                     * indicator to 255, unless you
-                                     * exactly know what you are
-                                     * doing, since this value is
-                                     * reserved for another purpose
-                                     * and algorithms may not work if
-                                     * boundary cells have this
-                                     * boundary indicator or if
-                                     * interior cells have boundary
-                                     * indicators other than 255.
+                                     * The diameter of an object is computed
+                                     * to be the largest diagonal. This is
+                                     * not necessarily the true diameter for
+                                     * objects that may use higher order
+                                     * mappings, but completely sufficient
+                                     * for most computations.
                                      */
-    void set_boundary_indicator (const unsigned char) const;
+    double diameter () const;
 
-                                    /**
-                                     * Do as set_boundary_indicator()
-                                     * but also set the boundary
-                                     * indicators of the objects that
-                                     * bound the current object. For
-                                     * example, in 3d, if
-                                     * set_boundary_indicator() is
-                                     * called on a face, then the
-                                     * boundary indicator of the 4
-                                     * edges that bound the face
-                                     * remain unchanged. On the other
-                                     * hand, the boundary indicators
-                                     * of face and edges are all set
-                                     * at the same time using the
-                                     * current function.
+                                    /**
+                                     * Center of the object. The center of an
+                                     * object is defined to be the average of
+                                     * the locations of the vertices, which
+                                     * is also where the (dim-)linear mapping
+                                     * places the midpoint of the unit cell
+                                     * in real space.  However, this may not
+                                     * be the barycenter of the object and it
+                                     * may also not be the true center of an
+                                     * object if higher order mappings are
+                                     * used.
                                      */
-    void set_all_boundary_indicators (const unsigned char) const;
+    Point<spacedim> center () const;
 
                                     /**
-                                     * Return whether this hex is at
-                                     * the boundary. This is checked
-                                     * via the boundary indicator
-                                     * field, which is always 255 if
-                                     * the hex is in the interior of
-                                     * the domain. Obviously, the use
-                                     * of this function is only
-                                     * possible for <tt>dim>3</tt>;
-                                     * however, for <tt>dim==3</tt>, a hex
-                                     * is a cell and the
-                                     * CellAccessor class
-                                     * offers another possibility to
-                                     * determine whether a cell is at
-                                     * the boundary or not.
+                                     * Barycenter of the object.
                                      */
-    bool at_boundary () const;
+    Point<spacedim> barycenter () const;
 
                                     /**
-                                     * Return the diameter of the hex.
-                                     *
-                                     * The diameter of a hex is
-                                     * computed to be the largest
-                                     * diagonal. You should
-                                     * absolutely be clear about the
-                                     * fact that this definitely is
-                                     * not the diameter of all
-                                     * hexahedra; however it may
-                                     * serve as an approximation and
-                                     * is exact in many cases,
-                                     * especially if the hexahedron
-                                     * is not too much distorted.
-                                     */
-    double diameter () const;
-
-                                    /**
-                                     * Return the center of the
-                                     * hex. The center of a hex is
-                                     * defined to be the average of
-                                     * the vertices, which is also
-                                     * the point where the trilinear
-                                     * mapping places the midpoint of
-                                     * the unit hex in real space.
-                                     * However, this may not be the
-                                     * point of the barycenter of the
-                                     * hex.
-                                     */
-    Point<dim> center () const;
-
-                                    /**
-                                     * Return the barycenter of the
-                                     * hex.
-                                     */
-    Point<dim> barycenter () const;
-
-                                    /**
-                                     * Return the volume of the
-                                     * hex. With volume, we mean the
-                                     * area included by the
-                                     * hexahedron if its faces are
-                                     * supposed to be derived by a
-                                     * trilinear mapping from the
-                                     * unit cell, only using the
-                                     * location of the vertices.
-                                     * Therefore, no information
-                                     * about the boundary is used; if
-                                     * you want other than
-                                     * trilinearly mapped unit
-                                     * hexahedra, ask the appropriate
-                                     * finite element class for the
-                                     * volume.
+                                     * Volume of the object.  Here, the
+                                     * volume is defined to be confined by
+                                     * the (dim-)linear mapping of the unit
+                                     * cell.  No information about the actual
+                                     * geometric boundary of the domain is
+                                     * used.
                                      */
     double measure () const;
-
                                     /**
-                                     * Compute and return the number
-                                     * of children of this
-                                     * hex. Actually, this function
-                                     * only counts the number of
-                                     * active children, i.e. the
-                                     * number if hexs which are not
-                                     * further refined. Thus, if all
-                                     * of the eight children of a hex
-                                     * are further refined
-                                     * isotropically exactly once,
-                                     * the returned number will be
-                                     * 64, not 80.
-                                     *
-                                     * If the present cell is not
-                                     * refined, one is returned.
+                                     * @}
                                      */
-    unsigned int number_of_children () const;
-
-                                     /**
-                                      * Return whether the face with
-                                      * index @p face has its normal
-                                      * pointing in the standard
-                                      * direction (@p true) or
-                                      * whether it is the opposite
-                                      * (@p false). Which is the
-                                      * standard direction is
-                                      * documented with the
-                                      * GeometryInfo class.  In
-                                      * 1d and 2d, this is always
-                                      * @p true, but in 3d it may be
-                                      * different, see the respective
-                                      * discussion in the
-                                      * documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_orientation (const unsigned int face) const;
-                                     /**
-                                      * Return whether the face with index @p
-                                      * face is rotated by 180 degrees (@p true)
-                                      * or or not (@p false). In 1d and 2d, this
-                                      * is always @p false, but in 3d it may be
-                                      * different, see the respective discussion
-                                      * in the documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_flip (const unsigned int face) const;
-
-                                     /**
-                                      * Return whether the face with index @p
-                                      * face is rotated by 90 degrees (@p true)
-                                      * or or not (@p false). In 1d and 2d, this
-                                      * is always @p false, but in 3d it may be
-                                      * different, see the respective discussion
-                                      * in the documentation of the
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
-                                      */
-    bool face_rotation (const unsigned int face) const;
     
-                                     /**
-                                      * Return whether the line with index @p
-                                      * line is oriented in standard
-                                      * direction. @p true indicates, that the
-                                      * line is oriented from vertex 0 to vertex
-                                      * 1, whereas it is the other way around
-                                      * otherwise. In 1d and 2d, this is always
-                                      * @p true, but in 3d it may be different,
-                                      * see the respective discussion in the
-                                      * documentation of the 
-                                      * GeometryInfo class.
-                                      *
-                                      * This function is really only
-                                      * for internal use in the
-                                      * library unless you absolutely
-                                      * know what this is all about.
+    
+  private:
+                                    /**
+                                     *  Copy the data of the given
+                                     *  object into the internal data
+                                     *  structures of a
+                                     *  triangulation.
+                                     */
+    void set (const internal::Triangulation::TriaObject<structdim> &o) const;
+    
+                                     /**
+                                      * Set the flag indicating, what
+                                      * <code>line_orientation()</code> will
+                                      * return.
+                                     *
+                                     * It is only possible to set the
+                                     * line_orientation of faces in 3d
+                                     * (i.e. <code>celldim==2 &&
+                                     * dim==3</code>).
                                       */
-    bool line_orientation (const unsigned int line) const;
+    void set_line_orientation (const unsigned int line,
+                               const bool         orientation) const;
     
                                      /**
                                       * Set whether the quad with
@@ -3467,80 +1429,183 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
     void set_face_rotation (const unsigned int face,
                            const bool         rotation) const;
     
-  private:
-                                    /**
-                                     *  Copy operator. This is normally
-                                     *  used in a context like
-                                     *  <tt>iterator a,b;  *a=*b;</tt>. Since
-                                     *  the meaning is to copy the
-                                     *  object pointed to by @p b to
-                                     *  the object pointed to by
-                                     *  @p a and since accessors are
-                                     *  not real but virtual objects,
-                                     *  this operation is not useful
-                                     *  for iterators on
-                                     *  triangulations. We declare
-                                     *  this function here private,
-                                     *  thus it may not be used from
-                                     *  outside.  Furthermore it is
-                                     *  not implemented and will give
-                                     *  a linker error if used
-                                     *  anyway.
+                                    /**
+                                     *  Set the @p used flag. Only
+                                     *  for internal use in the
+                                     *  library.
                                      */
-    void operator = (const TriaObjectAccessor<3, dim> &);
+    void set_used_flag () const;
 
-  protected:
-                                    /**@name Advancement of iterators*/
-                                    /*@{*/
                                     /**
-                                     *  This operator advances the
-                                     *  iterator to the next element.
+                                     *  Clear the @p used flag. Only
+                                     *  for internal use in the
+                                     *  library.
+                                     */
+    void clear_used_flag () const;
+
+                                    /**
+                                     * Set the @p RefinementCase<dim> this
+                                     * TriaObject is refined with.
+                                     * Not defined for
+                                     * <tt>celldim=1</tt> as lines
+                                     * are always refined resulting
+                                     * in 2 children lines (isotropic
+                                     * refinement).
                                      *
-                                     *  The next element is next on
-                                     *  this level if there are
-                                     *  more. If the present element
-                                     *  is the last on this level,
-                                     *  the first on the next level
-                                     *  is accessed.
+                                     * You should know quite exactly
+                                     * what you are doing if you
+                                     * touch this function. It is
+                                     * exclusively for internal use
+                                     * in the library.
                                      */
-    void operator ++ ();
+    void set_refinement_case (const RefinementCase<structdim> &ref_case) const;
 
-                                    /**
-                                     *  This operator moves the
-                                     *  iterator to the previous
-                                     *  element.
+                                    /**
+                                     * Clear the RefinementCase<dim> of
+                                     * this TriaObject, i.e. reset it
+                                     * to RefinementCase<dim>::no_refinement.
                                      *
-                                     *  The previous element is
-                                     *  previous on 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.
+                                     * You should know quite exactly
+                                     * what you are doing if you
+                                     * touch this function. It is
+                                     * exclusively for internal use
+                                     * in the library.
                                      */
-    void operator -- ();
+    void clear_refinement_case () const;
+
+                                    /**
+                                     *  Set the index of the ith
+                                     *  child. Since the children
+                                     *  come at least in pairs, we
+                                     *  need to store the index of
+                                     *  only every second child,
+                                     *  i.e. of the even numbered
+                                     *  children. Make sure, that the
+                                     *  index of child i=0 is set
+                                     *  first. Calling this function
+                                     *  for odd numbered children is
+                                     *  not allowed.
+                                     */
+    void set_children (const unsigned int i, const int index) const;
+       
+                                    /**
+                                     *  Clear the child field,
+                                     *  i.e. set it to a value which
+                                     *  indicates that this cell has
+                                     *  no children.
+                                     */
+    void clear_children () const;    
 
   private:
+                                    /**
+                                     *  Copy operator. This is normally used
+                                     *  in a context like <tt>iterator a,b;
+                                     *  *a=*b;</tt>. Presumably, the intent
+                                     *  here is to copy the object pointed to
+                                     *  by @p b to the object pointed to by
+                                     *  @p a. However, the result of
+                                     *  dereferencing an iterator is not an
+                                     *  object but an accessor; consequently,
+                                     *  this operation is not useful for
+                                     *  iterators on triangulations. We
+                                     *  declare this function here private,
+                                     *  thus it may not be used from outside.
+                                     *  Furthermore it is not implemented and
+                                     *  will give a linker error if used
+                                     *  anyway.
+                                     */
+    void operator = (const TriaAccessor &);
+    
+                                    /**
+                                     * Forward declaration of a class
+                                     * into which we put significant
+                                     * parts of the implementation.
+                                     *
+                                     * See the .templates.h file for
+                                     * more information.
+                                     */
+    struct Implementation;
+    
+    
+    template <int, int> friend class Triangulation;
     
+    friend class Implementation;
+};
+
+
+
+
+
+
+/**
+ * Closure class to stop induction of classes. Should never be called
+ * and thus produces an error when created.
+ *
+ * @ingroup grid
+ */
+template<int dim, int spacedim>
+class TriaAccessor<0, dim, spacedim> : public TriaAccessorBase<0,dim, spacedim>
+{
+  public:
+                                    /**
+                                     * Propagate typedef from
+                                     * base class to this class.
+                                     */
+    typedef typename TriaAccessorBase<0,dim,spacedim>::AccessorData AccessorData;
+
+                                    /**
+                                     * Constructor. Should never be
+                                     * called and thus produces an
+                                     * error.
+                                     */
+    TriaAccessor (const Triangulation<dim,spacedim> *parent     =  0,
+                 const int                 level      = -1,
+                 const int                 index      = -1,
+                 const AccessorData       *local_data =  0)
+                    :
+                   TriaAccessorBase<0,dim, spacedim> (parent, level, index, local_data)
+      {
+       Assert (false, ExcInternalError());
+      }
+
+                                    /**
+                                     * Boundary indicator of this
+                                     * object.
+                                     */
+    unsigned char boundary_indicator () const
+      {
+       Assert (false, ExcInternalError());
+       return 0;
+      }
+
                                     /**
-                                     * Dimension of the TriaObject
-                                     * this accessor gives access to.
+                                     * Whether this object is used.
                                      */
-    static const unsigned int objectdim = 3;
-                                    /*@}*/
+    bool used () const
+      {
+       Assert (false, ExcInternalError());
+       return false;
+      }
 
                                     /**
-                                     * Declare some friends.
+                                     * Produce a dummy child object.
                                      */
-    template <int anydim, typename AnyAccessor> friend class TriaRawIterator;
+    TriaIterator<InvalidAccessor<0,dim,spacedim> >
+    child (const unsigned int) const
+      {
+       Assert (false, ExcInternalError());
+       return TriaIterator<InvalidAccessor<0,dim,spacedim> >();
+      }
 };
 
 
 
+
 /**
  * This class allows access to a cell: a line in one dimension, a quad
  * in two dimension, etc.
  *
- * The following refers to any space dimension:
+ * The following refers to any dimension:
  * 
  * This class allows access to a <tt>cell</tt>, which is a line in 1D
  * and a quad in 2D. Cells have more functionality than lines or quads
@@ -3552,24 +1617,207 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
  * @ingroup Accessors
  * @author Wolfgang Bangerth, 1998, 1999, 2000
  */
-template <int dim>
-class CellAccessor :  public TriaObjectAccessor<dim,dim>
+template <int dim, int spacedim=dim>
+class CellAccessor :  public TriaAccessor<dim,dim,spacedim>
 {
   public:
                                     /**
                                      * Propagate the AccessorData type
                                      * into the present class.
                                      */
-    typedef typename TriaObjectAccessor<dim,dim>::AccessorData AccessorData;
+    typedef typename TriaAccessor<dim,dim,spacedim>::AccessorData AccessorData;
+    
+                                    /**
+                                     *  @name Constructors
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
+                                    /**
+                                     *  Constructor.
+                                     */
+    CellAccessor (const Triangulation<dim,spacedim> *parent     =  0,
+                 const int                 level      = -1,
+                 const int                 index      = -1,
+                 const AccessorData       *local_data =  0);
+
+                                    /**
+                                     * Copy constructor.
+                                     */
+    CellAccessor (const CellAccessor &cell_accessor);
+
+                                    /**
+                                     * Conversion constructor. This
+                                     * constructor exists to make certain
+                                     * constructs simpler to write in
+                                     * dimension independent code. For
+                                     * example, it allows assigning a face
+                                     * iterator to a line iterator, an
+                                     * operation that is useful in 2d but
+                                     * doesn't make any sense in 3d. The
+                                     * constructor here exists for the
+                                     * purpose of making the code conform to
+                                     * C++ but it will unconditionally abort;
+                                     * in other words, assigning a face
+                                     * iterator to a line iterator is better
+                                     * put into an if-statement that checks
+                                     * that the dimension is two, and assign
+                                     * to a quad iterator in 3d (an operator
+                                     * that, without this constructor would
+                                     * be illegal if we happen to compile for
+                                     * 2d).
+                                     */
+    template <int structdim2, int dim2, int spacedim2>
+    CellAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &);
+
+                                    /**
+                                     * Another conversion operator
+                                     * between objects that don't
+                                     * make sense, just like the
+                                     * previous one.
+                                     */
+    template <int structdim2, int dim2, int spacedim2>
+    CellAccessor (const TriaAccessor<structdim2,dim2,spacedim2> &);
+
+                                    /**
+                                     * @}
+                                     */
+    
+                                    /**
+                                     *  @name Accessing sub-objects and neighbors
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
+                                    /**
+                                     *  Return a pointer to the
+                                     *  @p ith child. Overloaded
+                                     *  version which returns a more
+                                     *  reasonable iterator class.
+                                     */
+    TriaIterator<CellAccessor<dim, spacedim> >
+    child (const unsigned int i) const;
+
+                                    /**
+                                     * Return an iterator to the
+                                     * @p ith face of this cell.
+                                     *
+                                     * This function is not
+                                     * implemented in 1D, and maps to
+                                     * QuadAccessor::line in 2D.
+                                     */
+    TriaIterator<TriaAccessor<dim-1,dim,spacedim> >
+    face (const unsigned int i) const;
+
+                                    /**
+                                     * Return the (global) index of the
+                                     * @p ith face of this cell.
+                                     *
+                                     * This function is not
+                                     * implemented in 1D, and maps to
+                                     * line_index in 2D and quad_index
+                                     * in 3D.
+                                     */
+    unsigned int
+    face_index (const unsigned int i) const;
+
+                                     /**
+                                      * Return an iterator to that
+                                      * cell that neighbors the
+                                      * present cell on the given face
+                                      * and subface number.
+                                      *
+                                      * To succeed, the present cell
+                                      * must not be further refined,
+                                      * and the neighbor on the given
+                                      * face must be further refined
+                                      * exactly once; the returned
+                                      * cell is then a child of that
+                                      * neighbor.
+                                      *
+                                      * The function may not be called
+                                      * in 1d, since there we have no
+                                      * subfaces.  The implementation
+                                      * of this function is rather
+                                      * straightforward in 2d, by
+                                      * first determining which face
+                                      * of the neighbor cell the
+                                      * present cell is bordering on
+                                      * (this is what the
+                                      * @p neighbor_of_neighbor
+                                      * function does), and then
+                                      * asking
+                                      * @p GeometryInfo::child_cell_on_subface
+                                      * for the index of the
+                                      * child.
+                                      *
+                                      * However, the situation is more
+                                      * complicated in 3d, since there faces may
+                                      * have more than one orientation, and we
+                                      * have to use @p face_orientation, @p
+                                      * face_flip and @p face_rotation for both
+                                      * this and the neighbor cell to figure out
+                                      * which cell we want to have.
+                                      *
+                                      * This can lead to surprising
+                                      * results: if we are sitting on
+                                      * a cell and are asking for a
+                                      * cell behind subface
+                                      * <tt>sf</tt>, then this means
+                                      * that we are considering the
+                                      * subface for the face in the
+                                      * natural direction for the
+                                      * present cell. However, if the
+                                      * face as seen from this cell
+                                      * has
+                                      * <tt>face_orientation()==false</tt>,
+                                      * then the child of the face
+                                      * that separates the present
+                                      * cell from the neighboring
+                                      * cell's child is not
+                                      * necessarily the @p sf-th child
+                                      * of the face of this cell. This
+                                      * is so because the @p
+                                      * subface_no on a cell corresponds to the
+                                      * subface with respect to the
+                                      * intrinsic ordering of the
+                                      * present cell, whereas children
+                                      * of face iterators are computed
+                                      * with respect to the intrinsic
+                                      * ordering of faces; these two
+                                      * orderings are only identical
+                                      * if the face orientation is @p
+                                      * true, and reversed otherwise.
+                                     *
+                                     * Similarly, effects of
+                                     * <tt>face_flip()==true</tt> and
+                                     * <tt>face_rotation()==true()</tt>, both
+                                     * of which indicate a non-standard face
+                                     * have to be considered.
+                                      *
+                                      * Fortunately, this is only very rarely of
+                                      * concern, since usually one simply wishes
+                                      * to loop over all finer neighbors at a
+                                      * given face of an active cell. Only in
+                                      * the process of refinement of a
+                                      * Triangulation we want to set neighbor
+                                      * information for both our child cells and
+                                      * the neighbor's children. Since we can
+                                      * respect orientation of faces from our
+                                      * current cell in that case, we do NOT
+                                      * respect face_orientation, face_flip and
+                                      * face_rotation of the present cell within
+                                      * this function, i.e. the returned
+                                      * neighbor's child is behind subface @p
+                                      * subface concerning the intrinsic
+                                      * ordering of the given face.
+                                      */
+    TriaIterator<CellAccessor<dim, spacedim> >
+    neighbor_child_on_subface (const unsigned int face_no,
+                               const unsigned int subface_no) const;
     
-                                    /**
-                                     *  Constructor.
-                                     */
-    CellAccessor (const Triangulation<dim> *parent     =  0,
-                 const int                 level      = -1,
-                 const int                 index      = -1,
-                 const AccessorData       *local_data =  0);
-
                                     /**
                                      *  Return a pointer to the
                                      *  @p ith neighbor.  If the
@@ -3581,7 +1829,7 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      *  same level as this cell, i.e. it may
                                      *  or may not be refined.
                                      */
-    TriaIterator<dim,CellAccessor<dim> >
+    TriaIterator<CellAccessor<dim, spacedim>  >
     neighbor (const unsigned int i) const;
 
                                     /**
@@ -3600,15 +1848,6 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      */
     int neighbor_level (const unsigned int i) const;
 
-                                    /**
-                                     *  Set the neighbor @p i of
-                                     *  this cell to the cell pointed
-                                     *  to by @p pointer.  This line
-                                     *  must be used.
-                                     */
-    void set_neighbor (const unsigned int i,
-                      const TriaIterator<dim,CellAccessor<dim> > &pointer) const;
-
                                     /**
                                      * Return the how-many'th
                                      * neighbor this cell is of
@@ -3687,6 +1926,17 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      */
     unsigned int neighbor_face_no (const unsigned int neighbor) const;
     
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Dealing with boundary indicators
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
                                     /**
                                      *  Return whether the @p ith
                                      *  vertex or face (depending on
@@ -3720,9 +1970,9 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                     /**
                                      * This is a slight variation to
                                      * the @p at_boundary function:
-                                     * for 1 and 2 space dimensions,
+                                     * for 1 and 2 dimensions,
                                      * it is equivalent, for three
-                                     * space dimensions it returns
+                                     * dimensions it returns
                                      * whether at least one of the 12
                                      * lines of the hexahedron is at
                                      * a boundary. This, of course,
@@ -3731,6 +1981,16 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      * but also some other cases.
                                      */
     bool has_boundary_lines () const;
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Dealing with refinement indicators
+                                     */
+                                    /**
+                                     * @{
+                                     */
 
                                     /**
                                      *  Return the @p
@@ -3811,133 +2071,16 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      *  Clear the coarsen flag.
                                      */
     void clear_coarsen_flag () const;
-
                                     /**
-                                     *  Return a pointer to the
-                                     *  @p ith child. Overloaded
-                                     *  version which returns a more
-                                     *  reasonable iterator class.
+                                     * @}
                                      */
-    TriaIterator<dim,CellAccessor<dim> >
-    child (const unsigned int i) const;
 
                                     /**
-                                     * Return an iterator to the
-                                     * @p ith face of this cell.
-                                     *
-                                     * This function is not
-                                     * implemented in 1D, and maps to
-                                     * QuadAccessor::line in 2D.
+                                     *  @name Dealing with material indicators
                                      */
-    TriaIterator<dim,TriaObjectAccessor<dim-1, dim> >
-    face (const unsigned int i) const;
-
                                     /**
-                                     * Return the (global) index of the
-                                     * @p ith face of this cell.
-                                     *
-                                     * This function is not
-                                     * implemented in 1D, and maps to
-                                     * line_index in 2D and quad_index
-                                     * in 3D.
+                                     * @{
                                      */
-    unsigned int
-    face_index (const unsigned int i) const;
-
-                                     /**
-                                      * Return an iterator to that
-                                      * cell that neighbors the
-                                      * present cell on the given face
-                                      * and subface number.
-                                      *
-                                      * To succeed, the present cell
-                                      * must not be further refined,
-                                      * and the neighbor on the given
-                                      * face must be further refined
-                                      * exactly once; the returned
-                                      * cell is then a child of that
-                                      * neighbor.
-                                      *
-                                      * The function may not be called
-                                      * in 1d, since there we have no
-                                      * subfaces.  The implementation
-                                      * of this function is rather
-                                      * straightforward in 2d, by
-                                      * first determining which face
-                                      * of the neighbor cell the
-                                      * present cell is bordering on
-                                      * (this is what the
-                                      * @p neighbor_of_neighbor
-                                      * function does), and then
-                                      * asking
-                                      * @p GeometryInfo::child_cell_on_subface
-                                      * for the index of the
-                                      * child.
-                                      *
-                                      * However, the situation is more
-                                      * complicated in 3d, since there faces may
-                                      * have more than one orientation, and we
-                                      * have to use @p face_orientation, @p
-                                      * face_flip and @p face_rotation for both
-                                      * this and the neighbor cell to figure out
-                                      * which cell we want to have.
-                                      *
-                                      * This can lead to surprising
-                                      * results: if we are sitting on
-                                      * a cell and are asking for a
-                                      * cell behind subface
-                                      * <tt>sf</tt>, then this means
-                                      * that we are considering the
-                                      * subface for the face in the
-                                      * natural direction for the
-                                      * present cell. However, if the
-                                      * face as seen from this cell
-                                      * has
-                                      * <tt>face_orientation()==false</tt>,
-                                      * then the child of the face
-                                      * that separates the present
-                                      * cell from the neighboring
-                                      * cell's child is not
-                                      * necessarily the @p sf-th child
-                                      * of the face of this cell. This
-                                      * is so because the @p
-                                      * subface_no on a cell corresponds to the
-                                      * subface with respect to the
-                                      * intrinsic ordering of the
-                                      * present cell, whereas children
-                                      * of face iterators are computed
-                                      * with respect to the intrinsic
-                                      * ordering of faces; these two
-                                      * orderings are only identical
-                                      * if the face orientation is @p
-                                      * true, and reversed otherwise.
-                                     *
-                                     * Similarly, effects of
-                                     * <tt>face_flip()==true</tt> and
-                                     * <tt>face_rotation()==true()</tt>, both
-                                     * of which indicate a non-standard face
-                                     * have to be considered.
-                                      *
-                                      * Fortunately, this is only very rarely of
-                                      * concern, since usually one simply wishes
-                                      * to loop over all finer neighbors at a
-                                      * given face of an active cell. Only in
-                                      * the process of refinement of a
-                                      * Triangulation we want to set neighbor
-                                      * information for both our child cells and
-                                      * the neighbor's children. Since we can
-                                      * respect orientation of faces from our
-                                      * current cell in that case, we do NOT
-                                      * respect face_orientation, face_flip and
-                                      * face_rotation of the present cell within
-                                      * this function, i.e. the returned
-                                      * neighbor's child is behind subface @p
-                                      * subface concerning the intrinsic
-                                      * ordering of the given face.
-                                      */
-    TriaIterator<dim,CellAccessor<dim> >
-    neighbor_child_on_subface (const unsigned int face_no,
-                               const unsigned int subface_no) const;
     
                                     /**
                                      * Return the material id of this
@@ -3966,6 +2109,16 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      * the given value.
                                      */
     void recursively_set_material_id (const unsigned char new_material_id) const;
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Dealing with subdomain indicators
+                                     */
+                                    /**
+                                     * @{
+                                     */
 
                                     /**
                                      * Return the subdomain id of
@@ -3979,6 +2132,17 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      */
     void set_subdomain_id (const unsigned int new_subdomain_id) const;
 
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Other functions
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
                                     /**
                                      * Test whether the cell has children
                                      * (this is the criterion for activity
@@ -4004,7 +2168,28 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      * a point is in- or outside the
                                      * cell in real space.
                                      */
-    bool point_inside (const Point<dim> &p) const;
+    bool point_inside (const Point<spacedim> &p) const;
+
+
+                                    /**
+                                     *  Set the neighbor @p i of
+                                     *  this cell to the cell pointed
+                                     *  to by @p pointer.
+                                     *
+                                     * This function shouldn't really be
+                                     * public (but needs to for various
+                                     * reasons in order not to make a long
+                                     * list of functions friends): it
+                                     * modifies internal data structures and
+                                     * may leave things. Do not use it from
+                                     * application codes.
+                                     */
+    void set_neighbor (const unsigned int i,
+                      const TriaIterator<CellAccessor<dim, spacedim> > &pointer) const;
+    
+                                    /**
+                                     * @}
+                                     */
     
     
                                     /**
@@ -4078,48 +2263,97 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      *  a linker error if used
                                      *  anyway.
                                      */
-    void operator = (const CellAccessor<dim> &);
+    void operator = (const CellAccessor<dim, spacedim> &);
 };
 
 
 
-/* -------------- declaration of explicit specializations ------------- */
+/* -------------- declaration of explicit
+   specializations and general templates ------------- */
+
+
+template <int structdim, int dim, int spacedim>
+template <typename OtherAccessor>
+InvalidAccessor<structdim, dim, spacedim>::
+InvalidAccessor (const OtherAccessor &)
+{
+  Assert (false,
+         ExcMessage ("You are attempting an illegal conversion between "
+                     "iterator/accessor types. The constructor you call "
+                     "only exists to make certain template constructs "
+                     "easier to write as dimension independent code but "
+                     "the conversion is not valid in the current context."));
+}
+
+
+
+template <int structdim, int dim, int spacedim>
+template <int structdim2, int dim2, int spacedim2>
+TriaAccessor<structdim,dim,spacedim>::
+TriaAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+{
+  Assert (false,
+         ExcMessage ("You are attempting an illegal conversion between "
+                     "iterator/accessor types. The constructor you call "
+                     "only exists to make certain template constructs "
+                     "easier to write as dimension independent code but "
+                     "the conversion is not valid in the current context."));
+}
 
-#ifndef DOXYGEN
 
-template <> Point<2> TriaObjectAccessor<2, 2>::barycenter () const;
-template <> Point<3> TriaObjectAccessor<2, 3>::barycenter () const;
-template <> Point<3> TriaObjectAccessor<3, 3>::barycenter () const;
-template <> internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<1> >&
-TriaObjectAccessor<1, 1>::objects() const;
-template <> internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<2> >&
-TriaObjectAccessor<2, 2>::objects() const;
-template <> bool CellAccessor<1>::at_boundary () const;
-template <> bool CellAccessor<1>::point_inside (const Point<1> &p) const;
-template <> bool CellAccessor<2>::at_boundary () const;
-template <> bool CellAccessor<2>::point_inside (const Point<2> &p) const;
-template <> bool CellAccessor<3>::at_boundary () const;
-template <> bool CellAccessor<3>::point_inside (const Point<3> &) const;
-
-template <> bool CellAccessor<1>::has_boundary_lines () const;
-
-template <>
-TriaIterator<1,CellAccessor<1> >
-CellAccessor<1>::neighbor_child_on_subface (const unsigned int,
-                                            const unsigned int) const;
-template <>
-TriaIterator<2,CellAccessor<2> >
-CellAccessor<2>::neighbor_child_on_subface (const unsigned int,
-                                            const unsigned int) const;
-template <>
-TriaIterator<3,CellAccessor<3> >
-CellAccessor<3>::neighbor_child_on_subface (const unsigned int,
-                                            const unsigned int) const;
-
-template <> double TriaObjectAccessor<2, 2>::measure () const;
-template <> double TriaObjectAccessor<2, 3>::measure () const;
-template <> double TriaObjectAccessor<3, 3>::measure () const;
 
+template <int dim, int spacedim>
+template <int structdim2, int dim2, int spacedim2>
+CellAccessor<dim,spacedim>::
+CellAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+{
+  Assert (false,
+         ExcMessage ("You are attempting an illegal conversion between "
+                     "iterator/accessor types. The constructor you call "
+                     "only exists to make certain template constructs "
+                     "easier to write as dimension independent code but "
+                     "the conversion is not valid in the current context."));
+}
+
+
+
+template <int structdim, int dim, int spacedim>
+template <int structdim2, int dim2, int spacedim2>
+TriaAccessor<structdim,dim,spacedim>::
+TriaAccessor (const TriaAccessor<structdim2,dim2,spacedim2> &)
+{
+  Assert (false,
+         ExcMessage ("You are attempting an illegal conversion between "
+                     "iterator/accessor types. The constructor you call "
+                     "only exists to make certain template constructs "
+                     "easier to write as dimension independent code but "
+                     "the conversion is not valid in the current context."));
+}
+
+
+
+template <int dim, int spacedim>
+template <int structdim2, int dim2, int spacedim2>
+CellAccessor<dim,spacedim>::
+CellAccessor (const TriaAccessor<structdim2,dim2,spacedim2> &)
+{
+  Assert (false,
+         ExcMessage ("You are attempting an illegal conversion between "
+                     "iterator/accessor types. The constructor you call "
+                     "only exists to make certain template constructs "
+                     "easier to write as dimension independent code but "
+                     "the conversion is not valid in the current context."));
+}
+
+
+#ifndef DOXYGEN
+
+template <> bool CellAccessor<1,1>::point_inside (const Point<1> &p) const;
+template <> bool CellAccessor<2,2>::point_inside (const Point<2> &p) const;
+template <> bool CellAccessor<3,3>::point_inside (const Point<3> &) const;
+template <> bool CellAccessor<1,2>::point_inside (const Point<2> &p) const;
+template <> bool CellAccessor<2,3>::point_inside (const Point<3> &p) const;
+// -------------------------------------------------------------------
 
 #endif // DOXYGEN
 
index e49745f7f5c90f3808e90fdecf0853b6cb7e4ecc..fadf48bb510e0f7751390b2316abf792a6da8c51 100644 (file)
@@ -15,6 +15,7 @@
 
 
 #include <base/config.h>
+#include <base/template_constraints.h>
 #include <grid/tria.h>
 #include <grid/tria_levels.h>
 #include <grid/tria_faces.h>
 
 DEAL_II_NAMESPACE_OPEN
 
-/*------------------------ Functions: TriaAccessor ---------------------------*/
+/*------------------------ Functions: TriaAccessorBase ---------------------------*/
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 inline
-TriaAccessor<structdim,dim>::TriaAccessor (const Triangulation<dim> *parent,
+TriaAccessorBase<structdim,dim,spacedim>::TriaAccessorBase (const Triangulation<dim,spacedim> *parent,
                                           const int                 level,
                                           const int                 index,
                                           const AccessorData       *)
@@ -51,10 +52,10 @@ TriaAccessor<structdim,dim>::TriaAccessor (const Triangulation<dim> *parent,
 
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 inline
 void
-TriaAccessor<structdim,dim>::copy_from (const TriaAccessor<structdim,dim> &a)
+TriaAccessorBase<structdim,dim,spacedim>::copy_from (const TriaAccessorBase<structdim,dim,spacedim> &a)
 {
   present_index = a.present_index;
   tria = a.tria;
@@ -62,10 +63,10 @@ TriaAccessor<structdim,dim>::copy_from (const TriaAccessor<structdim,dim> &a)
 
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 inline
 bool
-TriaAccessor<structdim,dim>::operator == (const TriaAccessor<structdim,dim> &a) const
+TriaAccessorBase<structdim,dim,spacedim>::operator == (const TriaAccessorBase<structdim,dim,spacedim> &a) const
 {
   Assert (tria == a.tria, TriaAccessorExceptions::ExcCantCompareIterators());
   return (present_index == a.present_index);
@@ -73,10 +74,10 @@ TriaAccessor<structdim,dim>::operator == (const TriaAccessor<structdim,dim> &a)
 
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 inline
 bool
-TriaAccessor<structdim,dim>::operator != (const TriaAccessor<structdim,dim> &a) const
+TriaAccessorBase<structdim,dim,spacedim>::operator != (const TriaAccessorBase<structdim,dim,spacedim> &a) const
 {
   Assert (tria == a.tria, TriaAccessorExceptions::ExcCantCompareIterators());
   return (present_index != a.present_index);
@@ -84,30 +85,30 @@ TriaAccessor<structdim,dim>::operator != (const TriaAccessor<structdim,dim> &a)
 
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 inline
 int
-TriaAccessor<structdim,dim>::level ()
+TriaAccessorBase<structdim,dim,spacedim>::level ()
 {
   return 0;
 }
 
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 inline
 int
-TriaAccessor<structdim,dim>::index () const
+TriaAccessorBase<structdim,dim,spacedim>::index () const
 {
   return present_index;
 }
 
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 inline
 IteratorState::IteratorStates
-TriaAccessor<structdim,dim>::state () const
+TriaAccessorBase<structdim,dim,spacedim>::state () const
 {
   if (present_index>=0)
     return IteratorState::valid;
@@ -120,21 +121,102 @@ TriaAccessor<structdim,dim>::state () const
 
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 inline
-const Triangulation<dim> &
-TriaAccessor<structdim,dim>::get_triangulation () const
+const Triangulation<dim,spacedim> &
+TriaAccessorBase<structdim,dim,spacedim>::get_triangulation () const
 {
   return *tria;
 }
 
 
 
-/*------------------------ Functions: TriaAccessor<dim,dim> ---------------------------*/
+template <int structdim, int dim, int spacedim>
+inline
+void
+TriaAccessorBase<structdim,dim,spacedim>::operator ++ ()
+{
+                                  // this iterator is used for
+                                  // objects without level
+  ++this->present_index;
+                                  // is index still in the range of
+                                  // the vector? (note that we don't
+                                  // have to set the level, since
+                                  // dim!=1 and the object therefore
+                                  // has no level)
+  if (this->present_index
+      >=
+      static_cast<int>(objects().cells.size()))
+    this->present_index = -1;
+}
+
+
+template <int structdim, int dim, int spacedim>
+inline
+void
+TriaAccessorBase<structdim,dim,spacedim>::operator -- ()
+{
+                                  // same as operator++
+  --this->present_index;
+
+  if (this->present_index < 0) 
+    this->present_index = -1;
+}
+
+
+namespace internal
+{
+  namespace TriaAccessorBase
+  {
+                                    /**
+                                     * Out of a face object, get the
+                                     * sub-objects of dimensionality
+                                     * given by the last argument.
+                                     */
+    template <int dim>
+    inline
+    internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<1> > &
+    get_objects (internal::Triangulation::TriaFaces<dim> *faces,
+                const internal::int2type<1>)
+    {
+      return faces->lines;
+    }
+
+
+    template <int dim>
+    inline
+    internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<2> > &
+    get_objects (internal::Triangulation::TriaFaces<dim> *faces,
+                const internal::int2type<2>)
+    {
+      return faces->quads;
+    }
+  }
+}
+
+  
+
+
+template <int structdim, int dim, int spacedim>
+inline
+internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<structdim> > &
+TriaAccessorBase<structdim,dim,spacedim>::objects() const
+{
+                                  // get sub-objects. note that the
+                                  // current class is only used for
+                                  // objects that are *not* cells
+  return internal::TriaAccessorBase::get_objects (this->tria->faces,
+                                             internal::int2type<structdim> ());
+}
+
+
+
+
+/*------------------------ Functions: TriaAccessorBase<dim,dim> ---------------------------*/
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-TriaAccessor<dim,dim>::TriaAccessor (const Triangulation<dim> *parent,
+TriaAccessorBase<dim,dim,spacedim>::TriaAccessorBase (const Triangulation<dim,spacedim> *parent,
                                     const int                 level,
                                     const int                 index,
                                     const AccessorData       *)
@@ -146,10 +228,10 @@ TriaAccessor<dim,dim>::TriaAccessor (const Triangulation<dim> *parent,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 void
-TriaAccessor<dim,dim>::copy_from (const TriaAccessor<dim,dim> &a)
+TriaAccessorBase<dim,dim,spacedim>::copy_from (const TriaAccessorBase<dim,dim,spacedim> &a)
 {
   present_level = a.present_level;
   present_index = a.present_index;
@@ -158,10 +240,10 @@ TriaAccessor<dim,dim>::copy_from (const TriaAccessor<dim,dim> &a)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 bool
-TriaAccessor<dim,dim>::operator == (const TriaAccessor<dim,dim> &a) const
+TriaAccessorBase<dim,dim,spacedim>::operator == (const TriaAccessorBase<dim,dim,spacedim> &a) const
 {
   Assert (tria == a.tria, TriaAccessorExceptions::ExcCantCompareIterators());
   return ((present_index == a.present_index) &&
@@ -170,10 +252,10 @@ TriaAccessor<dim,dim>::operator == (const TriaAccessor<dim,dim> &a) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 bool
-TriaAccessor<dim,dim>::operator != (const TriaAccessor<dim,dim> &a) const
+TriaAccessorBase<dim,dim,spacedim>::operator != (const TriaAccessorBase<dim,dim,spacedim> &a) const
 {
   Assert (tria == a.tria, TriaAccessorExceptions::ExcCantCompareIterators());
   return ((present_index != a.present_index) ||
@@ -182,30 +264,30 @@ TriaAccessor<dim,dim>::operator != (const TriaAccessor<dim,dim> &a) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 int
-TriaAccessor<dim,dim>::level () const
+TriaAccessorBase<dim,dim,spacedim>::level () const
 {
   return present_level;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 int
-TriaAccessor<dim,dim>::index () const
+TriaAccessorBase<dim,dim,spacedim>::index () const
 {
   return present_index;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 IteratorState::IteratorStates
-TriaAccessor<dim,dim>::state () const
+TriaAccessorBase<dim,dim,spacedim>::state () const
 {
   if ((present_level>=0) && (present_index>=0))
     return IteratorState::valid;
@@ -218,1379 +300,1637 @@ TriaAccessor<dim,dim>::state () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-const Triangulation<dim> &
-TriaAccessor<dim,dim>::get_triangulation () const
+const Triangulation<dim,spacedim> &
+TriaAccessorBase<dim,dim,spacedim>::get_triangulation () const
 {
   return *tria;
 }
 
 
-/*------------------------ Functions: LineAccessor ---------------------------*/
 
-
-template <int dim>
+template <int dim, int spacedim>
 inline
-TriaObjectAccessor<1,dim>::TriaObjectAccessor (
-  const Triangulation<dim> *parent,
-  const int                 level,
-  const int                 index,
-  const AccessorData       *local_data)
-                :
-                TriaAccessor<1,dim> (parent, level, index, local_data)
+void
+TriaAccessorBase<dim,dim,spacedim>::operator ++ ()
 {
-  if (dim!=1)
-    Assert(level <= 0, ExcInternalError());
+                                  // in structdim == dim, so we have
+                                  // cells here. these have levels
+  ++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]->cells.cells.size()))
+    {
+                                      // no -> go one level up until we find
+                                      // one with more than zero cells
+      ++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;
+       }
+    }
 }
 
 
-// first implement the lines functions as they are used by many
-// subsequent accessor functions
-template <>
+template <int dim, int spacedim>
 inline
-internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<1> > &
-TriaObjectAccessor<1,1>::objects() const
+void
+TriaAccessorBase<dim,dim,spacedim>::operator -- ()
 {
-  return this->tria->levels[this->present_level]->cells;
+                                  // same as 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]->cells.cells.size()-1;
+    }
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<1> > &
-TriaObjectAccessor<1,dim>::objects() const
+internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<dim> > &
+TriaAccessorBase<dim,dim,spacedim>::objects() const
 {
-  return this->tria->faces->lines;
+  return this->tria->levels[this->present_level]->cells;
 }
 
 
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<1,dim>::used () const
-{
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  return objects().used[this->present_index];
-}
 
 
+/*------------------------ Functions: InvalidAccessor ---------------------------*/
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<1,dim>::user_flag_set () const
+template <int structdim, int dim, int spacedim>
+InvalidAccessor<structdim, dim, spacedim>::
+InvalidAccessor (const Triangulation<dim,spacedim> *,
+                const int                 ,
+                const int                 ,
+                const AccessorData       *)
 {
-  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return objects().user_flags[this->present_index];
+  Assert (false,
+         ExcMessage ("You are attempting an illegal conversion between "
+                     "iterator/accessor types. The constructor you call "
+                     "only exists to make certain template constructs "
+                     "easier to write as dimension independent code but "
+                     "the conversion is not valid in the current context."));
 }
 
 
 
-template <int dim>
-inline
-void
-TriaObjectAccessor<1,dim>::set_user_flag () const 
+template <int structdim, int dim, int spacedim>
+InvalidAccessor<structdim, dim, spacedim>::
+InvalidAccessor (const InvalidAccessor &i)
+               :
+               TriaAccessorBase<structdim,dim,spacedim> (static_cast<const TriaAccessorBase<structdim,dim,spacedim>&>(i))
 {
-  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_flags[this->present_index] = true;
+  Assert (false,
+         ExcMessage ("You are attempting an illegal conversion between "
+                     "iterator/accessor types. The constructor you call "
+                     "only exists to make certain template constructs "
+                     "easier to write as dimension independent code but "
+                     "the conversion is not valid in the current context."));
 }
 
 
 
-template <int dim>
-inline
+template <int structdim, int dim, int spacedim>
 void
-TriaObjectAccessor<1,dim>::clear_user_flag () const
+InvalidAccessor<structdim, dim, spacedim>::
+copy_from (const InvalidAccessor &)
 {
-  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_flags[this->present_index] = false;
+                                  // nothing to do here. we could
+                                  // throw an exception but we can't
+                                  // get here without first creating
+                                  // an object which would have
+                                  // already thrown
 }
 
 
-template <int dim>
-inline
-RefinementCase<1>
-TriaObjectAccessor<1, dim>::refinement_case() const
-{
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
 
-  return objects().children[this->present_index] != -1 ?
-    RefinementCase<1>::cut_x : RefinementCase<1>::no_refinement;
+template <int structdim, int dim, int spacedim>
+bool
+InvalidAccessor<structdim, dim, spacedim>::
+operator == (const InvalidAccessor &) const
+{
+                                  // nothing to do here. we could
+                                  // throw an exception but we can't
+                                  // get here without first creating
+                                  // an object which would have
+                                  // already thrown
+  return false;
 }
 
 
 
-template <int dim>
-inline
+template <int structdim, int dim, int spacedim>
 bool
-TriaObjectAccessor<1,dim>::has_children () const
-{
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  return (objects().children[this->present_index] != -1);
+InvalidAccessor<structdim, dim, spacedim>::
+operator != (const InvalidAccessor &) const
+{
+                                  // nothing to do here. we could
+                                  // throw an exception but we can't
+                                  // get here without first creating
+                                  // an object which would have
+                                  // already thrown
+  return true;
 }
 
 
 
-template <int dim>
-inline
-int
-TriaObjectAccessor<1,dim>::child_index (const unsigned int i) const
+template <int structdim, int dim, int spacedim>
+bool
+InvalidAccessor<structdim, dim, spacedim>::used () const
 {
-  Assert (i<2, ExcIndexRange(i,0,2));
-  Assert (has_children(), TriaAccessorExceptions::ExcCellHasNoChildren());
-  return objects().children[this->present_index]+i;
+                                  // nothing to do here. we could
+                                  // throw an exception but we can't
+                                  // get here without first creating
+                                  // an object which would have
+                                  // already thrown
+  return false;
 }
 
 
 
-template <int dim>
-inline
-int
-TriaObjectAccessor<1,dim>::isotropic_child_index (const unsigned int i) const
+template <int structdim, int dim, int spacedim>
+bool
+InvalidAccessor<structdim, dim, spacedim>::has_children () const
 {
-  return child_index(i);
+                                  // nothing to do here. we could
+                                  // throw an exception but we can't
+                                  // get here without first creating
+                                  // an object which would have
+                                  // already thrown
+  return false;
 }
 
 
 
-template <int dim>
-inline
-TriaIterator<dim,TriaObjectAccessor<1,dim> >
-TriaObjectAccessor<1,dim>::child (const unsigned int i) const
-{
-  Assert (i<2, ExcIndexRange(i,0,2));
+template <int structdim, int dim, int spacedim>
+void
+InvalidAccessor<structdim, dim, spacedim>::operator ++ () const
+{}
 
-  TriaIterator<dim,TriaObjectAccessor<1,dim> >
-    q (this->tria,
-       (dim == 1 ? this->level() + 1 : 0),
-       child_index (i));
 
-  Assert ((q.state() == IteratorState::past_the_end) || q->used(),
-         TriaAccessorExceptions::ExcUnusedCellAsChild());
 
-  return q;
-}
+template <int structdim, int dim, int spacedim>
+void
+InvalidAccessor<structdim, dim, spacedim>::operator -- () const
+{}
 
 
 
-template <int dim>
-inline
-TriaIterator<dim,TriaObjectAccessor<1,dim> >
-TriaObjectAccessor<1,dim>::isotropic_child (const unsigned int i) const
-{
-                                  // no anisotropic refinement in 1D
-  return child(i);
-}
+/*------------------------ Functions: TriaAccessor ---------------------------*/
 
 
+/**
+ * A class with the same purpose as the similarly named class of the
+ * Triangulation class. See there for more information.
+ */
+template <int xstructdim, int xdim, int xspacedim>
+struct TriaAccessor<xstructdim,xdim,xspacedim>::Implementation
+{
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int dim, int spacedim>
+    static
+    unsigned int
+    line_index (const TriaAccessor<1, dim, spacedim> &,
+               const unsigned int)
+      {
+       Assert (false,
+               ExcMessage ("You can't ask for the index of a line bounding "
+                           "a one-dimensional cell because it is not "
+                           "bounded by lines."));
+       return numbers::invalid_unsigned_int;
+      }
 
-template <int dim>
-inline
-unsigned int
-TriaObjectAccessor<1,dim>::n_children () const
-{
-  return (has_children() ? GeometryInfo<1>::max_children_per_cell : 0);
-}
 
+    template <int dim, int spacedim>
+    static
+    unsigned int
+    line_index (const TriaAccessor<2, dim, spacedim> &accessor,
+               const unsigned int i)
+      {
+       return accessor.objects().cells[accessor.present_index].face(i);
+      }
 
+    
+    template <int dim, int spacedim>
+    static
+    unsigned int
+    line_index (const TriaAccessor<3, dim, spacedim> &accessor,
+               const unsigned int i)
+      {
+                                        // get the line index by asking the
+                                        // quads. first assume standard orientation
+                                        //
+                                        // 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
+       static const unsigned int lookup_table[12][2] =
+         { { 4, 0 }, // take first four lines from bottom face
+           { 4, 1 },
+           { 4, 2 },
+           { 4, 3 },
+
+           { 5, 0 }, // second four lines from top face
+           { 5, 1 },
+           { 5, 2 },
+           { 5, 3 },
+
+           { 0, 0 }, // the rest randomly
+           { 1, 0 },
+           { 0, 1 },
+           { 1, 1 }};
+
+                                        // respect non-standard faces by calling the
+                                        // reordering function from GeometryInfo
+
+       const unsigned int quad_index=lookup_table[i][0];
+       const unsigned int std_line_index=lookup_table[i][1];
+  
+       const unsigned int line_index=GeometryInfo<dim>::standard_to_real_face_line(
+         std_line_index,
+         accessor.face_orientation(quad_index),
+         accessor.face_flip(quad_index),
+         accessor.face_rotation(quad_index));
 
-template <int dim>
-inline
-unsigned int
-TriaObjectAccessor<1,dim>::middle_vertex_index () const
-{
-  if (has_children())
-    return child(0)->vertex_index(1);
-  return numbers::invalid_unsigned_int;
-}
+       return (accessor.quad(quad_index)->line_index(line_index));
+      }
 
 
 
-template <int dim>
-inline
-unsigned int
-TriaObjectAccessor<1,dim>::max_refinement_depth () const
-{
-  if (!has_children())
-    return 0;
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int structdim, int dim, int spacedim>
+    static
+    unsigned int
+    quad_index (const TriaAccessor<structdim, dim, spacedim> &,
+               const unsigned int)
+      {
+       Assert (false,
+               ExcMessage ("You can't ask for the index of a quad bounding "
+                           "a one- or two-dimensional cell because it is not "
+                           "bounded by quads."));
+       return numbers::invalid_unsigned_int;
+      }
 
-  const unsigned int depths[2] = { child(0)->max_refinement_depth() + 1,
-                                  child(1)->max_refinement_depth() + 1  };
-  return std::max (depths[0], depths[1]);
-}
+    
+    template <int dim, int spacedim>
+    static
+    unsigned int
+    quad_index (const TriaAccessor<3, dim, spacedim> &accessor,
+               const unsigned int i)
+      {
+       Assert (i<GeometryInfo<3>::quads_per_cell,
+               ExcIndexRange(i,0,GeometryInfo<3>::quads_per_cell));
+       return accessor.tria->levels[accessor.present_level]
+         ->cells.cells[accessor.present_index].face(i);
+      }
 
 
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<1,dim>::face_orientation (const unsigned int) const
-{
-  return true;
-}
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int structdim, int dim, int spacedim>
+    static
+    bool
+    face_orientation (const TriaAccessor<structdim, dim, spacedim> &,
+                     const unsigned int)
+      {
+       return true;
+      }
+    
 
+    template <int dim, int spacedim>
+    static
+    bool
+    face_orientation (const TriaAccessor<3, dim, spacedim> &accessor,
+                     const unsigned int face)
+      {
+       return (accessor.tria->levels[accessor.present_level]
+               ->cells.face_orientation(accessor.present_index, face));
+      }
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<1,dim>::face_flip (const unsigned int) const
-{
-  return false;
-}
 
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<1,dim>::face_rotation (const unsigned int) const
-{
-  return false;
-}
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int structdim, int dim, int spacedim>
+    static
+    bool
+    face_flip (const TriaAccessor<structdim, dim, spacedim> &,
+              const unsigned int)
+      {
+       return true;
+      }
+    
 
+    template <int dim, int spacedim>
+    static
+    bool
+    face_flip (const TriaAccessor<3, dim, spacedim> &accessor,
+              const unsigned int face)
+      {
+       Assert (face<GeometryInfo<3>::faces_per_cell,
+               ExcIndexRange (face, 0, GeometryInfo<3>::faces_per_cell));
+       Assert (accessor.present_index * GeometryInfo<3>::faces_per_cell + face
+               < accessor.tria->levels[accessor.present_level]
+               ->cells.face_flips.size(),
+               ExcInternalError());
+  
+       return (accessor.tria->levels[accessor.present_level]
+               ->cells.face_flips[accessor.present_index *
+                                  GeometryInfo<3>::faces_per_cell
+                                  + face]);
+      }
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<1,dim>::line_orientation (const unsigned int) const
-{
-  return true;
-}
 
 
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int structdim, int dim, int spacedim>
+    static
+    bool
+    face_rotation (const TriaAccessor<structdim, dim, spacedim> &,
+                  const unsigned int)
+      {
+       return true;
+      }
+    
 
-template <int dim>
-inline
-void
-TriaObjectAccessor<1,dim>::operator ++ ()
-{
-  ++this->present_index;
-                                  // is index still in the range of
-                                  // the vector? (note that we don't
-                                  // have to set the level, since
-                                  // dim!=1 and the object therefore
-                                  // has no level)
-  if (this->present_index
-      >=
-      static_cast<int>(objects().cells.size()))
-    this->present_index = -1;
-}
+    template <int dim, int spacedim>
+    static
+    bool
+    face_rotation (const TriaAccessor<3, dim, spacedim> &accessor,
+              const unsigned int face)
+      {
+       Assert (face<GeometryInfo<3>::faces_per_cell,
+               ExcIndexRange (face, 0, GeometryInfo<3>::faces_per_cell));
+       Assert (accessor.present_index * GeometryInfo<3>::faces_per_cell + face
+               < accessor.tria->levels[accessor.present_level]
+               ->cells.face_rotations.size(),
+               ExcInternalError());
+      
+       return (accessor.tria->levels[accessor.present_level]
+               ->cells.face_rotations[accessor.present_index *
+                                      GeometryInfo<3>::faces_per_cell
+                                      + face]);
+      }
 
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int dim, int spacedim>
+    static
+    bool
+    line_orientation (const TriaAccessor<1, dim, spacedim> &,
+                     const unsigned int)
+      {
+       return true;
+      }
+    
 
+    template <int spacedim>
+    static
+    bool
+    line_orientation (const TriaAccessor<2, 2, spacedim> &,
+                     const unsigned int)
+      {
+                                        // quads in 2d have no
+                                        // non-standard orientation
+       return true;
+      }
 
-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]->cells.cells.size()))
-    {
-                                      // no -> go one level up until we find
-                                      // one with more than zero cells
-      ++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 spacedim>
+    static
+    bool
+    line_orientation (const TriaAccessor<2, 3, spacedim> &accessor,
+                     const unsigned int line)
+      {
+                                        // quads as part of 3d hexes
+                                        // can have non-standard
+                                        // orientation
+//TODO: why is this face_orientation, not line_orientation as in the setter function?
+       return accessor.tria->faces->quads.face_orientation(accessor.present_index, line);
+      }
+    
 
+    template <int dim, int spacedim>
+    static
+    bool
+    line_orientation (const TriaAccessor<3, dim, spacedim> &accessor,
+                     const unsigned int line)
+      {
+       Assert (accessor.used(), TriaAccessorExceptions::ExcCellNotUsed());
+       Assert (line<GeometryInfo<3>::lines_per_cell,
+               ExcIndexRange (line, 0, GeometryInfo<3>::lines_per_cell));
+
+                                        // get the line index by asking the
+                                        // quads. first assume standard orientation
+                                        //
+                                        // 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
+       static const unsigned int lookup_table[12][2] =
+         { { 4, 0 }, // take first four lines from bottom face
+           { 4, 1 },
+           { 4, 2 },
+           { 4, 3 },
+
+           { 5, 0 }, // second four lines from top face
+           { 5, 1 },
+           { 5, 2 },
+           { 5, 3 },
+
+           { 0, 0 }, // the rest randomly
+           { 1, 0 },
+           { 0, 1 },
+           { 1, 1 }};
+
+       const unsigned int quad_index=lookup_table[line][0];
+       const unsigned int std_line_index=lookup_table[line][1];
+  
+       const unsigned int line_index=GeometryInfo<dim>::standard_to_real_face_line(
+         std_line_index,
+         accessor.face_orientation(quad_index),
+         accessor.face_flip(quad_index),
+         accessor.face_rotation(quad_index));
+  
+                                        // now we got to the correct line and ask
+                                        // the quad for its line_orientation. however, if
+                                        // the face is rotated, it might be possible,
+                                        // that a standard orientation of the line
+                                        // with respect to the face corrsponds to a
+                                        // non-standard orientation for the line with
+                                        // respect to the cell.
+                                        //
+                                        // set up a table indicating if the two
+                                        // standard orientations coincide
+                                        //
+                                        // first index: two pairs of lines 0(lines
+                                        // 0/1) and 1(lines 2/3)
+                                        //
+                                        // second index: face_orientation; 0:
+                                        // opposite normal, 1: standard
+                                        //
+                                        // third index: face_flip; 0: standard, 1:
+                                        // face rotated by 180 degrees
+                                        //
+                                        // forth index: face_rotation: 0: standard,
+                                        // 1: face rotated by 90 degrees
+
+       static const bool bool_table[2][2][2][2] =
+         { { { { true, false },   // lines 0/1, face_orientation=false, face_flip=false, face_rotation=false and true
+               { false, true }},  // lines 0/1, face_orientation=false, face_flip=true, face_rotation=false and true
+             { { true, true },    // lines 0/1, face_orientation=true, face_flip=false, face_rotation=false and true
+               { false, false }}},// linea 0/1, face_orientation=true, face_flip=true, face_rotation=false and true
+
+           { { { true, true },    // lines 2/3 ...
+               { false, false }},
+             { { true, false },
+               { false, true }}}};
+  
+  
+       return (accessor.quad(quad_index)
+               ->line_orientation(line_index)
+               == bool_table[std_line_index/2]
+               [accessor.face_orientation(quad_index)]
+               [accessor.face_flip(quad_index)]
+               [accessor.face_rotation(quad_index)]);
+      }
 
-template <int dim>
-inline
-void
-TriaObjectAccessor<1,dim>::operator -- ()
-{
-  --this->present_index;
-                                  // is index still in the range of
-                                  // the vector? (note that we don't
-                                  // have to set the level, since
-                                  // dim!=1 and the object therefore
-                                  // has no level)
-  if (this->present_index < 0) 
-    this->present_index = -1;
-  return;
-}
 
 
-template <>
-inline
-void
-TriaObjectAccessor<1,1>::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]->cells.cells.size()-1;
-    }
-}
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int structdim, int dim, int spacedim>
+    static
+    void
+    set_face_orientation (const TriaAccessor<structdim, dim, spacedim> &,
+                         const unsigned int,
+                         const bool)
+      {
+       Assert (false, ExcInternalError());
+      }
+    
+
+    template <int dim, int spacedim>
+    static
+    void
+    set_face_orientation (const TriaAccessor<3, dim, spacedim> &accessor,
+                         const unsigned int face,
+                         const bool value)
+      {
+       Assert (accessor.used(), TriaAccessorExceptions::ExcCellNotUsed());
+       Assert (face<GeometryInfo<3>::faces_per_cell,
+               ExcIndexRange (face, 0, GeometryInfo<3>::faces_per_cell));
+       Assert (accessor.present_index * GeometryInfo<3>::faces_per_cell + face
+               < accessor.tria->levels[accessor.present_level]
+               ->cells.face_orientations.size(),
+               ExcInternalError());
+       accessor.tria->levels[accessor.present_level]
+         ->cells.face_orientations[accessor.present_index *
+                              GeometryInfo<3>::faces_per_cell
+                              +
+                              face] = value;
+      }
+
+
+
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int structdim, int dim, int spacedim>
+    static
+    void
+    set_face_flip (const TriaAccessor<structdim, dim, spacedim> &,
+                  const unsigned int,
+                  const bool)
+      {
+       Assert (false, ExcInternalError());
+      }
+    
+
+    template <int dim, int spacedim>
+    static
+    void
+    set_face_flip (const TriaAccessor<3, dim, spacedim> &accessor,
+                  const unsigned int face,
+                  const bool value)
+      {
+       Assert (face<GeometryInfo<3>::faces_per_cell,
+               ExcIndexRange (face, 0, GeometryInfo<3>::faces_per_cell));
+       Assert (accessor.present_index * GeometryInfo<3>::faces_per_cell + face
+               < accessor.tria->levels[accessor.present_level]
+               ->cells.face_flips.size(),
+               ExcInternalError());
+  
+       accessor.tria->levels[accessor.present_level]
+         ->cells.face_flips[accessor.present_index *
+                            GeometryInfo<3>::faces_per_cell
+                            + face] = value;
+      }
 
 
-/*------------------------ Functions: QuadAccessor ---------------------------*/
 
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int structdim, int dim, int spacedim>
+    static
+    void
+    set_face_rotation (const TriaAccessor<structdim, dim, spacedim> &,
+                      const unsigned int,
+                      const bool)
+      {
+       Assert (false, ExcInternalError());
+      }
+    
+
+    template <int dim, int spacedim>
+    static
+    void
+    set_face_rotation (const TriaAccessor<3, dim, spacedim> &accessor,
+                      const unsigned int face,
+                      const bool value)
+      {
+       Assert (face<GeometryInfo<3>::faces_per_cell,
+               ExcIndexRange (face, 0, GeometryInfo<3>::faces_per_cell));
+       Assert (accessor.present_index * GeometryInfo<3>::faces_per_cell + face
+               < accessor.tria->levels[accessor.present_level]
+               ->cells.face_rotations.size(),
+               ExcInternalError());
+      
+       accessor.tria->levels[accessor.present_level]
+         ->cells.face_rotations[accessor.present_index *
+                                GeometryInfo<3>::faces_per_cell
+                                + face] = value;
+      }
 
-template <int dim>
-inline
-TriaObjectAccessor<2,dim>::TriaObjectAccessor (
-  const Triangulation<dim> *parent,
-  const int                 level,
-  const int                 index,
-  const AccessorData       *local_data)
-                :
-                TriaAccessor<2,dim> (parent, level, index, local_data)
-{
-  if (dim!=2)
-    Assert(level <= 0, ExcInternalError());
-}
+                                    /**
+                                     * Implementation of the function
+                                     * of some name in the mother
+                                     * class.
+                                     */
+    template <int dim, int spacedim>
+    static
+    void
+    set_line_orientation (const TriaAccessor<1, dim, spacedim> &,
+                         const unsigned int,
+                         const bool)
+      {
+       Assert (false, ExcInternalError());
+      }
+    
+
+    template <int spacedim>
+    static
+    void
+    set_line_orientation (const TriaAccessor<2, 2, spacedim> &,
+                         const unsigned int,
+                         const bool)
+      {
+                                        // quads in 2d have no
+                                        // non-standard orientation
+       Assert (false, ExcInternalError());
+      }
 
 
+    template <int spacedim>
+    static
+    void
+    set_line_orientation (const TriaAccessor<2, 3, spacedim> &accessor,
+                         const unsigned int line,
+                         const bool value)
+      {
+       Assert (accessor.used(), TriaAccessorExceptions::ExcCellNotUsed());
+       Assert (line<GeometryInfo<3>::lines_per_face,
+               ExcIndexRange (line, 0, GeometryInfo<3>::lines_per_face));
+       Assert (accessor.present_index * GeometryInfo<3>::lines_per_face + line
+               < accessor.tria->faces->quads.line_orientations.size(),
+               ExcInternalError());
+                                        // quads as part of 3d hexes
+                                        // can have non-standard
+                                        // orientation
+       accessor.tria->faces->quads.line_orientations[accessor.present_index *
+                                                     GeometryInfo<3>::lines_per_face
+                                                     + line]
+         = value;
+      }
+    
+
+    template <int dim, int spacedim>
+    static
+    void
+    set_line_orientation (const TriaAccessor<3, dim, spacedim> &,
+                         const unsigned int,
+                         const bool)
+      {
+                                        // it seems like we don't need this
+                                        // one
+       Assert (false, ExcNotImplemented());
+      }
 
-// first implement the quads functions as they are used by many
-// subsequent accessor functions
-template <>
-inline
-internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<2> > &
-TriaObjectAccessor<2,2>::objects() const
-{
-  return this->tria->levels[this->present_level]->cells;
-}
 
+                                    /**
+                                     * Implementation of the function of same
+                                     * name in the enclosing class.
+                                     */
+    template <int dim, int spacedim>
+    static
+    unsigned int
+    vertex_index (const TriaAccessor<1,dim,spacedim> &accessor,
+                 const unsigned int corner)
+      {
+       return accessor.objects().cells[accessor.present_index].face (corner);
+      }
 
 
-template <int dim>
+    template <int dim, int spacedim>
+    static
+    unsigned int
+    vertex_index (const TriaAccessor<2,dim,spacedim> &accessor,
+                 const unsigned int corner)
+      {
+                                        // table used to switch the vertices, if the
+                                        // line orientation is wrong,
+                                        //
+                                        // first index: line orientation 0: false or
+                                        // 1: true=standard
+                                        //
+                                        // second index: vertex index to be switched
+                                        // (or not)
+  
+       static const unsigned int switch_table[2][2]={{1,0},{0,1}};
+  
+       return accessor.line(corner%2)
+         ->vertex_index(switch_table[accessor.line_orientation(corner%2)][corner/2]);
+      }
+
+
+
+    template <int dim, int spacedim>
+    static
+    unsigned int
+    vertex_index (const TriaAccessor<3,dim,spacedim> &accessor,
+                 const unsigned int corner)
+      {
+                                        // get the corner indices by asking either
+                                        // the bottom or the top face for its
+                                        // vertices. handle non-standard faces by
+                                        // calling the vertex reordering function
+                                        // from GeometryInfo
+
+                                        // bottom face (4) for first four vertices,
+                                        // top face (5) for the rest
+       const unsigned int face_index=4+corner/4;
+
+       return accessor.quad(face_index)
+         ->vertex_index(GeometryInfo<dim>
+                        ::standard_to_real_face_vertex(corner%4,
+                                                       accessor.face_orientation(face_index),
+                                                       accessor.face_flip(face_index),
+                                                       accessor.face_rotation(face_index)));
+      }
+};
+
+
+
+
+template <int structdim, int dim, int spacedim>
 inline
-internal::Triangulation::TriaObjects<internal::Triangulation::TriaObject<2> > &
-TriaObjectAccessor<2,dim>::objects() const
-{
-  return this->tria->faces->quads;
-}
+TriaAccessor<structdim, dim, spacedim>::
+TriaAccessor (const Triangulation<dim,spacedim> *parent,
+              const int                 level,
+              const int                 index,
+              const AccessorData       *local_data)
+               :
+               TriaAccessorBase<structdim,dim,spacedim> (parent, level, index, local_data)
+{}
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
 bool
-TriaObjectAccessor<2,dim>::used () const
+TriaAccessor<structdim,dim,spacedim>::used () const 
 {
   Assert (this->state() == IteratorState::valid,
          TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  return objects().used[this->present_index];
+  return this->objects().used[this->present_index];
 }
 
 
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<2,dim>::user_flag_set () const
+template <int structdim, int dim, int spacedim>
+unsigned int
+TriaAccessor<structdim, dim, spacedim>::
+vertex_index (const unsigned int corner) const
 {
-  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return objects().user_flags[this->present_index];
+  Assert (corner<GeometryInfo<structdim>::vertices_per_cell,
+         ExcIndexRange(corner,0,GeometryInfo<structdim>::vertices_per_cell));
+  
+  return Implementation::vertex_index (*this, corner);
 }
 
 
 
-template <int dim>
-inline
-void
-TriaObjectAccessor<2,dim>::set_user_flag () const
+template <int structdim, int dim, int spacedim>
+Point<spacedim> &
+TriaAccessor<structdim, dim, spacedim>::vertex (const unsigned int i) const
 {
-  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_flags[this->present_index] = true;
+  return const_cast<Point<spacedim> &> (this->tria->vertices[vertex_index(i)]);
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-void
-TriaObjectAccessor<2,dim>::clear_user_flag () const
+typename internal::Triangulation::Iterators<dim,spacedim>::line_iterator
+TriaAccessor<structdim,dim,spacedim>::line (const unsigned int i) const
 {
-  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_flags[this->present_index] = false;
+                                  // checks happen in line_index
+  return typename internal::Triangulation::Iterators<dim,spacedim>::line_iterator
+    (this->tria, 0, line_index (i));
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-TriaIterator<dim,TriaObjectAccessor<1,dim> >
-TriaObjectAccessor<2,dim>::line (const unsigned int i) const
+unsigned int
+TriaAccessor<structdim,dim,spacedim>::line_index (const unsigned int i) const
 {
-  return
-    TriaIterator<dim,TriaObjectAccessor<1,dim> >
-    (
-      this->tria,
-      0,
-      line_index (i)
-    );
+  Assert (i < GeometryInfo<structdim>::lines_per_cell,
+         ExcIndexRange (i, 0, GeometryInfo<structdim>::lines_per_cell));
+
+  return Implementation::line_index (*this, i);
 }
 
 
 
-template <int dim>
+
+template <int structdim, int dim, int spacedim>
 inline
-unsigned int
-TriaObjectAccessor<2,dim>::line_index (const unsigned int i) const
+typename internal::Triangulation::Iterators<dim,spacedim>::quad_iterator
+TriaAccessor<structdim,dim,spacedim>::quad (const unsigned int i) const
 {
-  Assert (i<4, ExcIndexRange(i,0,4));
-  return objects().cells[this->present_index].face(i);
+                                  // checks happen in quad_index
+  return typename internal::Triangulation::Iterators<dim,spacedim>::quad_iterator
+    (this->tria, 0, quad_index (i));
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-RefinementCase<2>
-TriaObjectAccessor<2, dim>::refinement_case () const
+unsigned int
+TriaAccessor<structdim,dim,spacedim>::quad_index (const unsigned int i) const
 {
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  Assert (static_cast<unsigned int> (this->present_index) <
-         objects().refinement_cases.size(),
-         ExcIndexRange(this->present_index, 0,
-                       objects().refinement_cases.size()));
-
-  return objects().refinement_cases[this->present_index];
+  return Implementation::quad_index (*this, i);
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-void
-TriaObjectAccessor<2, dim>::set_refinement_case (const RefinementCase<2> &refinement_case) const
+bool
+TriaAccessor<structdim,dim,spacedim>::face_orientation (const unsigned int face) const
 {
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  Assert (static_cast<unsigned int> (this->present_index) <
-         objects().refinement_cases.size(),
-         ExcIndexRange(this->present_index, 0,
-                       objects().refinement_cases.size()));
-
-  objects().refinement_cases[this->present_index] = refinement_case;
+  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
+  
+  return Implementation::face_orientation (*this, face);
 }
 
 
-template <int dim>
+
+template <int structdim, int dim, int spacedim>
 inline
-void
-TriaObjectAccessor<2, dim>::clear_refinement_case () const
+bool
+TriaAccessor<structdim,dim,spacedim>::face_flip (const unsigned int face) const
 {
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  Assert (static_cast<unsigned int> (this->present_index) <
-         objects().refinement_cases.size(),
-         ExcIndexRange(this->present_index, 0,
-                       objects().refinement_cases.size()));
-
-  objects().refinement_cases[this->present_index] = RefinementCase<2>::no_refinement;
+  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
+  
+  return Implementation::face_flip (*this, face);
 }
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
 bool
-TriaObjectAccessor<2,dim>::has_children () const
+TriaAccessor<structdim,dim,spacedim>::face_rotation (const unsigned int face) const
 {
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  return (objects().children[2*this->present_index] != -1);
+  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
+
+  return Implementation::face_rotation (*this, face);
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-int TriaObjectAccessor<2,dim>::child_index (const unsigned int i) const
+bool
+TriaAccessor<structdim,dim,spacedim>::line_orientation (const unsigned int line) const
 {
-  Assert (i<4, ExcIndexRange(i,0,4));
-  Assert (has_children(), TriaAccessorExceptions::ExcCellHasNoChildren());
-  return objects().children[2*this->present_index+i/2]+i%2;
+  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
+  Assert (line<GeometryInfo<structdim>::lines_per_cell,
+         ExcIndexRange (line, 0, GeometryInfo<structdim>::lines_per_cell));
+
+  return Implementation::line_orientation (*this, line);
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-int TriaObjectAccessor<2,dim>::isotropic_child_index (const unsigned int i) const
+void
+TriaAccessor<structdim,dim,spacedim>::set_face_orientation (const unsigned int face,
+                                                            const bool value) const
 {
-  switch (static_cast<unsigned char> (refinement_case()))
-    {
-      case RefinementCase<dim>::cut_x:
-                                            // this cell is refined with cut_x,
-                                            // so the child has to be refined
-                                            // with cut_y
-           if(child(i%2)->refinement_case()==RefinementCase<dim>::cut_y)
-             return child(i%2)->child_index(i/2);
-           else
-            Assert(false, ExcMessage("This cell has no grandchildren equivalent to isotropic refinement"));
-           break;
-      case RefinementCase<dim>::cut_y:
-                                            // this cell is refined with cut_y,
-                                            // so the child has to be refined
-                                            // with cut_x
-           if (child(i/2)->refinement_case()==RefinementCase<dim>::cut_x)
-             return child(i/2)->child_index(i%2);
-           else
-             Assert(false, ExcMessage("This cell has no grandchildren equivalent to isotropic refinement"));
-           break;
-      case RefinementCase<dim>::cut_xy:
-           return child_index(i);
-           break;
-      default:
-           Assert(false, TriaAccessorExceptions::ExcCellHasNoChildren());
-           break;
-    }
-  return -1;
+  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
+  
+  Implementation::set_face_orientation (*this, face, value);
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-TriaIterator<dim,TriaObjectAccessor<2,dim> >
-TriaObjectAccessor<2,dim>::child (const unsigned int i) const
+void
+TriaAccessor<structdim,dim,spacedim>::set_face_flip (const unsigned int face,
+                                                     const bool value) const
 {
-  Assert (i<4, ExcIndexRange(i,0,4));
-  
-  TriaIterator<dim,TriaObjectAccessor<2,dim> >
-    q (this->tria,
-       (dim == 2 ? this->level() + 1 : 0),
-       child_index (i));
+  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
   
-  Assert ((q.state() == IteratorState::past_the_end) || q->used(),
-         TriaAccessorExceptions::ExcUnusedCellAsChild());
-
-  return q;
+  Implementation::set_face_flip (*this, face, value);
 }
 
 
-
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-TriaIterator<dim,TriaObjectAccessor<2,dim> >
-TriaObjectAccessor<2,dim>::isotropic_child (const unsigned int i) const
+void
+TriaAccessor<structdim,dim,spacedim>::set_face_rotation (const unsigned int face,
+                                                         const bool value) const
 {
-  switch (static_cast<unsigned char> (refinement_case()))
-    {
-      case RefinementCase<dim>::cut_x:
-                                            // this cell is refined with cut_x,
-                                            // so the child has to be refined
-                                            // with cut_y
-           Assert(child(i%2)->refinement_case()==RefinementCase<dim>::cut_y,
-                  ExcMessage("This cell has no grandchildren equivalent to isotropic refinement"));
-           return child(i%2)->child(i/2);
-           break;
-      case RefinementCase<dim>::cut_y:
-                                            // this cell is refined with cut_y,
-                                            // so the child has to be refined
-                                            // with cut_x
-           Assert(child(i/2)->refinement_case()==RefinementCase<dim>::cut_x,
-                  ExcMessage("This cell has no grandchildren equivalent to isotropic refinement"));
-           return child(i/2)->child(i%2);
-           break;
-      default:
-           Assert(refinement_case()==RefinementCase<dim>::cut_xy,
-                  TriaAccessorExceptions::ExcCellHasNoChildren());
-           break;
-    }
-  return child(i);
+  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
+
+  Implementation::set_face_rotation (*this, face, value);
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-unsigned int
-TriaObjectAccessor<2,dim>::n_children () const
+void
+TriaAccessor<structdim,dim,spacedim>::set_line_orientation (const unsigned int line,
+                                                            const bool value) const
 {
-  Assert (static_cast<unsigned int> (this->present_index) <
-         objects().refinement_cases.size(),
-         ExcIndexRange(this->present_index, 0,
-                       objects().refinement_cases.size()));
-  return GeometryInfo<2>::n_children(refinement_case());
+  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
+  Assert (line<GeometryInfo<structdim>::lines_per_cell,
+         ExcIndexRange (line, 0, GeometryInfo<structdim>::lines_per_cell));
+
+  Implementation::set_line_orientation (*this, line, value);
 }
 
 
 
-template <int dim>
-inline
-unsigned int
-TriaObjectAccessor<2,dim>::middle_vertex_index () const
+template <int structdim, int dim, int spacedim>
+void TriaAccessor<structdim, dim, spacedim>::set_used_flag () const
 {
-  switch (static_cast<unsigned char> (refinement_case()))
-    {
-      case RefinementCase<dim>::cut_x:
-           return child(0)->line(1)->middle_vertex_index();
-           break;
-      case RefinementCase<dim>::cut_y:
-           return child(0)->line(3)->middle_vertex_index();
-           break;
-      case RefinementCase<dim>::cut_xy:
-           return child(0)->vertex_index(3);
-           break;
-      default:
-           break;
-    }
-  return numbers::invalid_unsigned_int;
+  Assert (this->state() == IteratorState::valid,
+         TriaAccessorExceptions::ExcDereferenceInvalidObject());
+  this->objects().used[this->present_index] = true;
 }
 
 
 
-template <int dim>
-inline
-unsigned int
-TriaObjectAccessor<2,dim>::max_refinement_depth () const
+template <int structdim, int dim, int spacedim>
+void
+TriaAccessor<structdim, dim, spacedim>::clear_used_flag () const
 {
-  if (!has_children())
-    return 0;
-
-  const unsigned int depths[4] = { child(0)->max_refinement_depth() + 1,
-                                  child(1)->max_refinement_depth() + 1,
-                                  child(2)->max_refinement_depth() + 1,
-                                  child(3)->max_refinement_depth() + 1 };
-  return std::max (std::max (depths[0], depths[1]),
-                  std::max (depths[2], depths[3]));
+  Assert (this->state() == IteratorState::valid,
+         TriaAccessorExceptions::ExcDereferenceInvalidObject());
+  this->objects().used[this->present_index] = false;
 }
 
 
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<2,dim>::face_orientation (const unsigned int) const
+template <int structdim, int dim, int spacedim>
+int
+TriaAccessor<structdim, dim, spacedim>::
+child_index (const unsigned int i) const
 {
-  return true;
+  Assert (has_children(), TriaAccessorExceptions::ExcCellHasNoChildren());
+  Assert (i<n_children(),
+         ExcIndexRange (i, 0, n_children()));
+  
+                                  // each set of two children are stored
+                                  // consecutively, so we only have to find
+                                  // the location of the set of children
+  const unsigned int n_sets_of_two = GeometryInfo<structdim>::max_children_per_cell/2;
+  return this->objects().children[n_sets_of_two*this->present_index+i/2]+i%2;
 }
 
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<2,dim>::face_flip (const unsigned int) const
+
+template <int structdim, int dim, int spacedim>
+int
+TriaAccessor<structdim, dim, spacedim>::
+isotropic_child_index (const unsigned int i) const
 {
-  return false;
-}
+  Assert (i<GeometryInfo<structdim>::max_children_per_cell,
+         ExcIndexRange (i, 0, GeometryInfo<structdim>::max_children_per_cell));
 
+  switch (structdim)
+    {
+      case 1:
+           return child_index (i);
+      case 2:
+      {
+       const RefinementCase<2> this_refinement_case =
+         static_cast<RefinementCase<2> >(refinement_case());
+
+       Assert (this_refinement_case != RefinementCase<2>::no_refinement,
+               TriaAccessorExceptions::ExcCellHasNoChildren());
+       
+       if (this_refinement_case == RefinementCase<2>::cut_xy)
+         return child_index(i);
+       else if ((this_refinement_case == RefinementCase<2>::cut_x)
+                &&
+                (child(i%2)->refinement_case()==RefinementCase<2>::cut_y))
+         return child(i%2)->child_index(i/2);
+       else if ((this_refinement_case == RefinementCase<2>::cut_y)
+                &&
+                (child(i/2)->refinement_case()==RefinementCase<2>::cut_x))
+         return child(i/2)->child_index(i%2);
+       else
+         Assert(false,
+                ExcMessage("This cell has no grandchildren equivalent to isotropic refinement"));
+      }
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<2,dim>::face_rotation (const unsigned int) const
-{
-  return false;
+      case 3:
+           Assert (false, ExcNotImplemented());
+    }
+  return -1;
 }
 
 
-template <>
-inline
-bool
-TriaObjectAccessor<2,3>::line_orientation (const unsigned int line) const
+
+template <int structdim, int dim, int spacedim>
+RefinementCase<structdim>
+TriaAccessor<structdim, dim, spacedim>::refinement_case() const
 {
-                                  // we cannot use the objects() function here,
-                                  // since it returns a reference to
-                                  // TriaObjects<Quad>, but we need a
-                                  // (reference to) TriaObjectsQuad3D
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return this->tria->faces->quads.face_orientation(this->present_index, line);
-}
+  Assert (this->state() == IteratorState::valid,
+         TriaAccessorExceptions::ExcDereferenceInvalidObject());
 
+  switch (structdim)
+    {
+      case 1:
+           return (static_cast<RefinementCase<structdim> >
+                   (this->objects().children[this->present_index] != -1
+                    ?
+                    RefinementCase<1>::cut_x :
+                    RefinementCase<1>::no_refinement));
 
-template <int dim>
-inline
-bool
-TriaObjectAccessor<2,dim>::line_orientation (const unsigned int) const
-{
-  return true;
+      default:
+           Assert (static_cast<unsigned int> (this->present_index) <
+                   this->objects().refinement_cases.size(),
+                   ExcIndexRange(this->present_index, 0,
+                                 this->objects().refinement_cases.size()));
+
+           return (static_cast<RefinementCase<structdim> >
+                   (this->objects().refinement_cases[this->present_index]));
+    }
 }
 
 
-template <int dim>
+
+
+template <int structdim, int dim, int spacedim>
 inline
-void
-TriaObjectAccessor<2,dim>::operator ++ ()
+TriaIterator<TriaAccessor<structdim,dim,spacedim> >
+TriaAccessor<structdim,dim,spacedim>::child (const unsigned int i) const
+
 {
-  ++this->present_index;
-                                  // is index still in the range of
-                                  // the vector? (note that we don't
-                                  // have to set the level, since
-                                  // dim!=1 and the object therefore
-                                  // has no level)
-  if (this->present_index
-      >=
-      static_cast<int>(objects().cells.size()))
-    this->present_index = -1;
+                                  // checking of 'i' happens in child_index
+  const TriaIterator<TriaAccessor<structdim,dim,spacedim> >
+    q (this->tria,
+       (dim == structdim ? this->level() + 1 : 0),
+       child_index (i));
+
+  Assert ((q.state() == IteratorState::past_the_end) || q->used(),
+         TriaAccessorExceptions::ExcUnusedCellAsChild());
+
+  return q;
 }
 
 
 
-template <>
+template <int structdim, int dim, int spacedim>
 inline
-void
-TriaObjectAccessor<2,2>::operator ++ ()
+TriaIterator<TriaAccessor<structdim,dim,spacedim> >
+TriaAccessor<structdim,dim,spacedim>::
+isotropic_child (const unsigned int i) const
 {
-  ++this->present_index;
-                                  // is index still in the range of
-                                  // the vector?
-  while (this->present_index
-        >=
-        static_cast<int>(objects().cells.size()))
+                                  // checking of 'i' happens in child() or
+                                  // child_index() called below
+  switch (structdim)
     {
-                                      // 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;
-       }
+      case 1:
+                                            // no anisotropic refinement in 1D
+           return child(i);
+
+      case 2:
+      {
+       const RefinementCase<2> this_refinement_case =
+         static_cast<RefinementCase<2> >(refinement_case());
+
+       Assert (this_refinement_case != RefinementCase<2>::no_refinement,
+               TriaAccessorExceptions::ExcCellHasNoChildren());
+       
+       if (this_refinement_case == RefinementCase<2>::cut_xy)
+         return child(i);
+       else if ((this_refinement_case == RefinementCase<2>::cut_x)
+                &&
+                (child(i%2)->refinement_case()==RefinementCase<2>::cut_y))
+         return child(i%2)->child(i/2);
+       else if ((this_refinement_case == RefinementCase<2>::cut_y)
+                &&
+                (child(i/2)->refinement_case()==RefinementCase<2>::cut_x))
+         return child(i/2)->child(i%2);
+       else
+         Assert(false,
+                ExcMessage("This cell has no grandchildren equivalent to isotropic refinement"));      
+      }
+
+      default:
+           Assert (false, ExcNotImplemented());
     }
+                                  // we don't get here but have to return
+                                  // something...
+  return child(0);
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-void
-TriaObjectAccessor<2,dim>::operator -- ()
+bool
+TriaAccessor<structdim,dim,spacedim>::has_children () const
 {
-  --this->present_index;
-                                  // is index still in the range of
-                                  // the vector? (note that we don't
-                                  // have to set the level, since
-                                  // dim!=1 and the object therefore
-                                  // has no level)
-  if (this->present_index < 0)
-    this->present_index = -1;
+  Assert (this->state() == IteratorState::valid,
+         TriaAccessorExceptions::ExcDereferenceInvalidObject());
+
+                                  // each set of two children are stored
+                                  // consecutively, so we only have to find
+                                  // the location of the set of children
+  const unsigned int n_sets_of_two = GeometryInfo<structdim>::max_children_per_cell/2;
+  return (this->objects().children[n_sets_of_two * this->present_index] != -1);
 }
 
 
-template <>
+
+
+template <int structdim, int dim, int spacedim>
 inline
-void
-TriaObjectAccessor<2,2>::operator -- ()
+unsigned int
+TriaAccessor<structdim,dim,spacedim>::n_children () const
 {
-  --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 = objects().cells.size()-1;
-    }
+  return GeometryInfo<structdim>::n_children(refinement_case());
 }
 
 
-/*------------------------ Functions: HexAccessor ---------------------------*/
-
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-TriaObjectAccessor<3,dim>::TriaObjectAccessor (
-  const Triangulation<dim> *parent,
-  const int                 level,
-  const int                 index,
-  const AccessorData       *local_data)
-                :
-                TriaAccessor<3,dim> (parent, level, index, local_data)
+void
+TriaAccessor<structdim, dim, spacedim>::
+set_refinement_case (const RefinementCase<structdim> &refinement_case) const
 {
-  if (dim!=3)
-    Assert(level <= 0, ExcInternalError());
-}
+  Assert (this->state() == IteratorState::valid,
+         TriaAccessorExceptions::ExcDereferenceInvalidObject());
+  Assert (static_cast<unsigned int> (this->present_index) <
+         this->objects().refinement_cases.size(),
+         ExcIndexRange(this->present_index, 0,
+                       this->objects().refinement_cases.size()));
 
+  this->objects().refinement_cases[this->present_index] = refinement_case;
+}
 
 
-template <>
+template <int structdim, int dim, int spacedim>
 inline
-bool
-TriaObjectAccessor<3,3>::used () const
+void
+TriaAccessor<structdim, dim, spacedim>::clear_refinement_case () const
 {
   Assert (this->state() == IteratorState::valid,
          TriaAccessorExceptions::ExcDereferenceInvalidObject());
-   return this->tria->levels[this->present_level]->cells.used[this->present_index];
+  Assert (static_cast<unsigned int> (this->present_index) <
+         this->objects().refinement_cases.size(),
+         ExcIndexRange(this->present_index, 0,
+                       this->objects().refinement_cases.size()));
+
+  this->objects().refinement_cases[this->present_index]
+    = RefinementCase<structdim>::no_refinement;
 }
 
 
 
-template <>
-inline
-bool
-TriaObjectAccessor<3,3>::user_flag_set () const
+
+
+template <int structdim, int dim, int spacedim>
+void
+TriaAccessor<structdim, dim, spacedim>::set_children (const unsigned int i,
+                                                      const int index) const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return this->tria->levels[this->present_level]->cells.user_flags[this->present_index];
+  Assert (i%2==0, TriaAccessorExceptions::ExcSetOnlyEvenChildren(i));
+
+                                  // each set of two children are stored
+                                  // consecutively, so we only have to find
+                                  // the location of the set of children
+  const unsigned int n_sets_of_two = GeometryInfo<structdim>::max_children_per_cell/2;  
+
+  Assert ((index==-1) ||
+         (i==0 && !this->has_children() && (index>=0)) ||
+         (i>0  &&  this->has_children() && (index>=0) &&
+          this->objects().children[n_sets_of_two*this->present_index+i/2] == -1),
+         TriaAccessorExceptions::ExcCantSetChildren(index));
+  
+  this->objects().children[n_sets_of_two*this->present_index+i/2] = index;
 }
 
 
 
-template <>
-inline
+template <int structdim, int dim, int spacedim>
 void
-TriaObjectAccessor<3,3>::set_user_flag () const
+TriaAccessor<structdim, dim, spacedim>::clear_children () const
 {
-  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  this->tria->levels[this->present_level]->cells.user_flags[this->present_index] = true;
+                                  // each set of two children are stored
+                                  // consecutively, so we only have to find
+                                  // the location of the set of children
+  const unsigned int n_sets_of_two = GeometryInfo<structdim>::max_children_per_cell/2;
+
+  for (unsigned int i=0; i<n_sets_of_two; ++i)
+    set_children (2*i,-1);
 }
 
 
 
-template <>
+template <int structdim, int dim, int spacedim>
 inline
-void TriaObjectAccessor<3,3>::clear_user_flag () const
+bool
+TriaAccessor<structdim,dim,spacedim>::user_flag_set () const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  this->tria->levels[this->present_level]->cells.user_flags[this->present_index] = false;
+  return this->objects().user_flags[this->present_index];
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-TriaIterator<dim,TriaObjectAccessor<1,dim> >
-TriaObjectAccessor<3,dim>::line (const unsigned int i) const
+void
+TriaAccessor<structdim,dim,spacedim>::set_user_flag () const 
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return
-    TriaIterator<dim,TriaObjectAccessor<1,dim> >
-    (
-      this->tria,
-      0,
-      line_index (i)
-    );
+  this->objects().user_flags[this->present_index] = true;
 }
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 inline
-TriaIterator<dim,TriaObjectAccessor<2,dim> >
-TriaObjectAccessor<3,dim>::quad (const unsigned int i) const
+void
+TriaAccessor<structdim,dim,spacedim>::clear_user_flag () const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return
-    TriaIterator<dim,TriaObjectAccessor<2,dim> >
-    (
-      this->tria,
-      0,
-      quad_index (i)
-    );
+  this->objects().user_flags[this->present_index] = false;
+}
+
+
+template <int structdim, int dim, int spacedim>
+void TriaAccessor<structdim,dim,spacedim>::recursively_set_user_flag () const
+{
+  set_user_flag ();
+
+  if (this->has_children())
+    for (unsigned int c=0; c<this->n_children(); ++c)
+      this->child(c)->recursively_set_user_flag ();
 }
 
 
 
-template <int dim>
-inline
-unsigned int
-TriaObjectAccessor<3,dim>::line_index (const unsigned int i) const
-{
-  Assert (i<12, ExcIndexRange(i,0,12));
-
-                                   // get the line index by asking the
-                                   // quads. first assume standard orientation
-                                   //
-                                   // 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
-  static const unsigned int lookup_table[12][2] =
-    { { 4, 0 }, // take first four lines from bottom face
-      { 4, 1 },
-      { 4, 2 },
-      { 4, 3 },
-
-      { 5, 0 }, // second four lines from top face
-      { 5, 1 },
-      { 5, 2 },
-      { 5, 3 },
-
-      { 0, 0 }, // the rest randomly
-      { 1, 0 },
-      { 0, 1 },
-      { 1, 1 }};
-
-                                  // respect non-standard faces by calling the
-                                  // reordering function from GeometryInfo
-
-  const unsigned int quad_index=lookup_table[i][0];
-  const unsigned int std_line_index=lookup_table[i][1];
-  
-  const unsigned int line_index=GeometryInfo<dim>::standard_to_real_face_line(
-    std_line_index,
-    face_orientation(quad_index),
-    face_flip(quad_index),
-    face_rotation(quad_index));
+template <int structdim, int dim, int spacedim>
+void TriaAccessor<structdim,dim,spacedim>::recursively_clear_user_flag () const
+{
+  clear_user_flag ();
 
-  return (this->quad(quad_index)
-          ->line_index(line_index));
+  if (this->has_children())
+    for (unsigned int c=0; c<this->n_children(); ++c)
+      this->child(c)->recursively_clear_user_flag ();
 }
 
 
 
-template <>
-inline
-unsigned int
-TriaObjectAccessor<3,3>::quad_index (const unsigned int i) const
+template <int structdim, int dim, int spacedim>
+void TriaAccessor<structdim,dim,spacedim>::clear_user_data () const
 {
-  Assert (i<6, ExcIndexRange(i,0,6));
+  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
+  this->objects().clear_user_data(this->present_index);
+}
+
 
-  return this->tria->levels[this->present_level]->cells.cells[this->present_index].face(i);
+
+template <int structdim, int dim, int spacedim>
+void TriaAccessor<structdim,dim,spacedim>::set_user_pointer (void *p) const
+{
+  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
+  this->objects().user_pointer(this->present_index) = p;
 }
 
 
 
-template <>
-inline
-RefinementCase<3>
-TriaObjectAccessor<3, 3>::refinement_case () const
+template <int structdim, int dim, int spacedim>
+void TriaAccessor<structdim,dim,spacedim>::clear_user_pointer () const
 {
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  Assert (static_cast<unsigned int> (this->present_index) <
-         this->tria->levels[this->present_level]->cells.refinement_cases.size(),
-         ExcIndexRange(this->present_index, 0,
-                       this->tria->levels[this->present_level]->
-                       cells.refinement_cases.size()));
+  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
+  this->objects().user_pointer(this->present_index) = 0;
+}
+
 
-  return this->tria->levels[this->present_level]->cells.refinement_cases[this->present_index];
+
+template <int structdim, int dim, int spacedim>
+void * TriaAccessor<structdim,dim,spacedim>::user_pointer () const
+{
+  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
+  return this->objects().user_pointer(this->present_index);
 }
 
 
 
-template <>
-inline
+template <int structdim, int dim, int spacedim>
 void
-TriaObjectAccessor<3, 3>::set_refinement_case (const RefinementCase<3> &refinement_case) const
+TriaAccessor<structdim,dim,spacedim>::recursively_set_user_pointer (void *p) const
 {
-  Assert (static_cast<unsigned int> (this->present_index) <
-         this->tria->levels[this->present_level]->cells.refinement_cases.size(),
-         ExcIndexRange(this->present_index, 0,
-                       this->tria->levels[this->present_level]->
-                       cells.refinement_cases.size()));
+  set_user_pointer (p);
 
-  this->tria->levels[this->present_level]->
-    cells.refinement_cases[this->present_index] = refinement_case;
+  if (this->has_children())
+    for (unsigned int c=0; c<this->n_children(); ++c)
+      this->child(c)->recursively_set_user_pointer (p);
 }
 
 
-template <>
-inline
+
+template <int structdim, int dim, int spacedim>
 void
-TriaObjectAccessor<3, 3>::clear_refinement_case () const
+TriaAccessor<structdim,dim,spacedim>::recursively_clear_user_pointer () const
 {
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  Assert (static_cast<unsigned int> (this->present_index) <
-         this->tria->levels[this->present_level]->cells.refinement_cases.size(),
-         ExcIndexRange(this->present_index, 0,
-                       this->tria->levels[this->present_level]->
-                       cells.refinement_cases.size()));
+  clear_user_pointer ();
 
-  this->tria->levels[this->present_level]->
-    cells.refinement_cases[this->present_index] = RefinementCase<3>::no_refinement;
+  if (this->has_children())
+    for (unsigned int c=0; c<this->n_children(); ++c)
+      this->child(c)->recursively_clear_user_pointer ();
 }
 
 
 
-template<>
-inline
-bool
-TriaObjectAccessor<3,3>::has_children () const
+template <int structdim, int dim, int spacedim>
+void TriaAccessor<structdim,dim,spacedim>::set_user_index (unsigned int p) const
 {
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-    return (this->tria->levels[this->present_level]->cells.children[4*this->present_index] != -1);
+  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
+  this->objects().user_index(this->present_index) = p;
 }
 
 
-template <>
-inline
-int TriaObjectAccessor<3,3>::child_index (const unsigned int i) const
+
+template <int structdim, int dim, int spacedim>
+void TriaAccessor<structdim,dim,spacedim>::clear_user_index () const
 {
-  Assert (i<8, ExcIndexRange(i,0,8));
-  Assert (has_children(), TriaAccessorExceptions::ExcCellHasNoChildren());
-  return this->tria->levels[this->present_level]->cells.children[4*this->present_index+i/2]+i%2;
+  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
+  this->objects().user_index(this->present_index) = 0;
 }
 
 
 
-template <>
-inline
-int TriaObjectAccessor<3,3>::isotropic_child_index (const unsigned int i) const
+template <int structdim, int dim, int spacedim>
+unsigned int TriaAccessor<structdim,dim,spacedim>::user_index () const
 {
-  AssertThrow(false, ExcNotImplemented());
-  return child_index(i);
+  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
+  return this->objects().user_index(this->present_index);
 }
 
 
 
-template <>
-inline
-TriaIterator<3,TriaObjectAccessor<3,3> >
-TriaObjectAccessor<3,3>::child (const unsigned int i) const
+template <int structdim, int dim, int spacedim>
+void
+TriaAccessor<structdim,dim,spacedim>::recursively_set_user_index (unsigned int p) const
 {
-  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(),
-         TriaAccessorExceptions::ExcUnusedCellAsChild());
+  set_user_index (p);
 
-  return q;
+  if (this->has_children())
+    for (unsigned int c=0; c<this->n_children(); ++c)
+      this->child(c)->recursively_set_user_index (p);
 }
 
 
 
-template <>
-inline
-TriaIterator<3,TriaObjectAccessor<3,3> >
-TriaObjectAccessor<3,3>::isotropic_child (const unsigned int i) const
+template <int structdim, int dim, int spacedim>
+void
+TriaAccessor<structdim,dim,spacedim>::recursively_clear_user_index () const
 {
-  AssertThrow(false, ExcNotImplemented());
-  return child(i);
+  clear_user_index ();
+
+  if (this->has_children())
+    for (unsigned int c=0; c<this->n_children(); ++c)
+      this->child(c)->recursively_clear_user_index ();
 }
 
 
 
-template <>
+template <int structdim, int dim, int spacedim>
 inline
 unsigned int
-TriaObjectAccessor<3,3>::n_children () const
+TriaAccessor<structdim,dim,spacedim>::max_refinement_depth () const
 {
-  Assert (static_cast<unsigned int> (this->present_index) <
-         this->tria->levels[this->present_level]->cells.refinement_cases.size(),
-         ExcIndexRange(this->present_index, 0,
-                       this->tria->levels[this->present_level]->
-                       cells.refinement_cases.size()));
+  if (!this->has_children())
+    return 0;
 
-  return GeometryInfo<3>::n_children(refinement_case());
+  unsigned int max_depth = 1;
+  for (unsigned int c=0; c<n_children(); ++c)
+    max_depth = std::max (max_depth,
+                         child(c)->max_refinement_depth() + 1);
+  return max_depth;
 }
 
 
 
-template <int dim>
-inline
+template <int structdim, int dim, int spacedim>
 unsigned int
-TriaObjectAccessor<3,dim>::middle_vertex_index () const
+TriaAccessor<structdim, dim, spacedim>::number_of_children () const
 {
-  switch (static_cast<unsigned char> (refinement_case()))
+  if (!this->has_children())
+    return 1;
+  else
     {
-      case RefinementCase<dim>::cut_x:
-           return child(0)->quad(1)->middle_vertex_index();
-           break;
-      case RefinementCase<dim>::cut_y:
-           return child(0)->quad(3)->middle_vertex_index();
-           break;
-      case RefinementCase<dim>::cut_z:
-           return child(0)->quad(5)->middle_vertex_index();
-           break;
-      case RefinementCase<dim>::cut_xy:
-           return child(0)->line(11)->middle_vertex_index();
-           break;
-      case RefinementCase<dim>::cut_xz:
-           return child(0)->line(5)->middle_vertex_index();
-           break;
-      case RefinementCase<dim>::cut_yz:
-           return child(0)->line(7)->middle_vertex_index();
-           break;
-      case RefinementCase<dim>::cut_xyz:
-           return child(0)->vertex_index(7);
-           break;
-      default:
-           break;
+      unsigned int sum = 0;
+      for (unsigned int c=0; c<n_children(); ++c)
+       sum += this->child(c)->number_of_children();
+      return sum;
     }
-  return numbers::invalid_unsigned_int;
 }
 
 
 
-template <int dim>
-inline
-unsigned int
-TriaObjectAccessor<3,dim>::max_refinement_depth () const
+template <int structdim, int dim, int spacedim>
+unsigned char
+TriaAccessor<structdim, dim, spacedim>::boundary_indicator () const
 {
-  if (!has_children())
-    return 0;
+  Assert (structdim<dim, ExcImpossibleInDim(dim));
+  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
 
-  const unsigned int depths[8] = { child(0)->max_refinement_depth() + 1,
-                                  child(1)->max_refinement_depth() + 1,
-                                  child(2)->max_refinement_depth() + 1,
-                                  child(3)->max_refinement_depth() + 1,
-                                  child(4)->max_refinement_depth() + 1,
-                                  child(5)->max_refinement_depth() + 1,
-                                  child(6)->max_refinement_depth() + 1,
-                                  child(7)->max_refinement_depth() + 1  };
-  return std::max (std::max (std::max (depths[0], depths[1]),
-                            std::max (depths[2], depths[3])),
-                  std::max (std::max (depths[4], depths[5]),
-                            std::max (depths[6], depths[7])));
+  return this->objects().material_id[this->present_index];
 }
 
 
 
-template <>
-inline
-bool
-TriaObjectAccessor<3, 3>::face_orientation (const unsigned int face) const
+template <int structdim, int dim, int spacedim>
+void
+TriaAccessor<structdim, dim, spacedim>::
+set_boundary_indicator (const unsigned char boundary_ind) const
 {
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());  
-  return (this->tria->levels[this->present_level]
-         ->cells.face_orientation(this->present_index, face));
+  Assert (structdim<dim, ExcImpossibleInDim(dim));
+  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
+
+  this->objects().material_id[this->present_index] = boundary_ind;
 }
 
 
-template <>
-inline
-bool
-TriaObjectAccessor<3, 3>::face_flip (const unsigned int face) const
+
+template <int structdim, int dim, int spacedim>
+void
+TriaAccessor<structdim, dim, spacedim>::
+set_all_boundary_indicators (const unsigned char boundary_ind) const
 {
-  Assert (used(), TriaAccessorExceptions::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]
-         ->cells.face_flips.size(),
-         ExcInternalError());
-  
-  return (this->tria->levels[this->present_level]
-         ->cells.face_flips[this->present_index *
-                            GeometryInfo<3>::faces_per_cell
-                            + face]);
-}
+  set_boundary_indicator (boundary_ind);
+  set_boundary_indicator (boundary_ind);
 
+  switch (structdim)
+    {
+      case 1:
+                                            // 1d objects have no sub-objects
+                                            // where we have to do anything
+           break;
 
-template <>
-inline
-bool
-TriaObjectAccessor<3, 3>::face_rotation (const unsigned int face) const
-{
-  Assert (used(), TriaAccessorExceptions::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]
-         ->cells.face_rotations.size(),
-         ExcInternalError());
-      
-  return (this->tria->levels[this->present_level]
-         ->cells.face_rotations[this->present_index *
-                                GeometryInfo<3>::faces_per_cell
-                                + face]);
+      case 2:
+                                            // for boundary quads also set
+                                            // boundary_id of bounding lines
+           for (unsigned int i=0; i<4; ++i)
+             this->line(i)->set_boundary_indicator (boundary_ind);
+           break;
+
+      default:
+           Assert (false, ExcNotImplemented());
+    }
 }
 
 
-template <>
-inline
+
+template <int structdim, int dim, int spacedim>
 bool
-TriaObjectAccessor<3, 3>::line_orientation (const unsigned int line) const
+TriaAccessor<structdim, dim, spacedim>::at_boundary () const
 {
-  const int dim=3;
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  Assert (line<GeometryInfo<3>::lines_per_cell,
-          ExcIndexRange (line, 0, GeometryInfo<3>::lines_per_cell));
-
-                                   // get the line index by asking the
-                                   // quads. first assume standard orientation
-                                   //
-                                   // 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
-  static const unsigned int lookup_table[12][2] =
-    { { 4, 0 }, // take first four lines from bottom face
-      { 4, 1 },
-      { 4, 2 },
-      { 4, 3 },
-
-      { 5, 0 }, // second four lines from top face
-      { 5, 1 },
-      { 5, 2 },
-      { 5, 3 },
-
-      { 0, 0 }, // the rest randomly
-      { 1, 0 },
-      { 0, 1 },
-      { 1, 1 }};
-
-  const unsigned int quad_index=lookup_table[line][0];
-  const unsigned int std_line_index=lookup_table[line][1];
-  
-  const unsigned int line_index=GeometryInfo<dim>::standard_to_real_face_line(
-    std_line_index,
-    face_orientation(quad_index),
-    face_flip(quad_index),
-    face_rotation(quad_index));
-  
-                                  // now we got to the correct line and ask
-                                  // the quad for its line_orientation. however, if
-                                  // the face is rotated, it might be possible,
-                                  // that a standard orientation of the line
-                                  // with respect to the face corrsponds to a
-                                  // non-standard orientation for the line with
-                                  // respect to the cell.
-                                  //
-                                  // set up a table indicating if the two
-                                  // standard orientations coincide
-                                  //
-                                  // first index: two pairs of lines 0(lines
-                                  // 0/1) and 1(lines 2/3)
-                                  //
-                                  // second index: face_orientation; 0:
-                                  // opposite normal, 1: standard
-                                  //
-                                  // third index: face_flip; 0: standard, 1:
-                                  // face rotated by 180 degrees
-                                  //
-                                  // forth index: face_rotation: 0: standard,
-                                  // 1: face rotated by 90 degrees
-
-  static const bool bool_table[2][2][2][2] =
-    { { { { true, false },   // lines 0/1, face_orientation=false, face_flip=false, face_rotation=false and true
-         { false, true }},  // lines 0/1, face_orientation=false, face_flip=true, face_rotation=false and true
-       { { true, true },    // lines 0/1, face_orientation=true, face_flip=false, face_rotation=false and true
-         { false, false }}},// linea 0/1, face_orientation=true, face_flip=true, face_rotation=false and true
-
-      { { { true, true },    // lines 2/3 ...
-         { false, false }},
-       { { true, false },
-         { false, true }}}};
-  
-  
-  return (this->quad(quad_index)
-          ->line_orientation(line_index)
-         == bool_table[std_line_index/2]
-         [face_orientation(quad_index)]
-         [face_flip(quad_index)]
-         [face_rotation(quad_index)]);
+                                  // error checking is done
+                                  // in boundary_indicator()
+  return (boundary_indicator() != 255);
 }
 
 
 
-template <>
-inline
-void
-TriaObjectAccessor<3,3>::operator ++ ()
+template <int structdim, int dim, int spacedim>
+double
+TriaAccessor<structdim, dim, spacedim>::diameter () const
 {
-  ++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]->cells.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;
-         }
-      }
+  switch (structdim)
+    {
+      case 1:
+           return std::sqrt((this->vertex(1)-this->vertex(0)).square());
+      case 2:
+           return std::sqrt(std::max((this->vertex(3)-this->vertex(0)).square(),
+                                     (this->vertex(2)-this->vertex(1)).square()));
+      case 3:
+           return std::sqrt(std::max( std::max((this->vertex(7)-this->vertex(0)).square(),
+                                               (this->vertex(6)-this->vertex(1)).square()),
+                                      std::max((this->vertex(2)-this->vertex(5)).square(),
+                                               (this->vertex(3)-this->vertex(4)).square()) ));
+      default:
+           Assert (false, ExcNotImplemented());
+           return -1e10;
+    }
 }
 
 
-
-template <>
-inline
-void
-TriaObjectAccessor<3,3>::operator -- ()
+template <int structdim, int dim, int spacedim>
+Point<spacedim>
+TriaAccessor<structdim, dim, spacedim>::center () const
 {
-  --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]->cells.cells.size()-1;
-      }
+  Point<spacedim> p;
+  for (unsigned int v=0; v<GeometryInfo<structdim>::vertices_per_cell; ++v)
+    p += vertex(v);
+  return p/GeometryInfo<structdim>::vertices_per_cell;
 }
 
 
-/*------------------------ Functions: CellAccessor<dim> -----------------------*/
+/*------------------------ Functions: CellAccessor<dim,spacedim> -----------------------*/
+
+
+template <int dim, int spacedim>
+inline
+CellAccessor<dim,spacedim>::
+CellAccessor (const Triangulation<dim,spacedim> *parent,
+             const int                 level,
+             const int                 index,
+             const AccessorData       *local_data)
+                :
+    TriaAccessor<dim, dim, spacedim> (parent, level, index, local_data)
+{}
 
 
-template <int dim>
+
+template <int dim, int spacedim>
 inline
-CellAccessor<dim>::CellAccessor (
-  const Triangulation<dim> *parent,
-  const int                 level,
-  const int                 index,
-  const AccessorData       *local_data)
+CellAccessor<dim,spacedim>::
+CellAccessor (const CellAccessor &cell_accessor)
                 :
-                TriaObjectAccessor<dim,dim> (parent, level, index, local_data)
+               TriaAccessor<dim, dim, spacedim> (static_cast<const TriaAccessor<dim, dim, spacedim>&>(cell_accessor))
 {}
 
 
 
 template <>
 inline
-TriaIterator<1,TriaObjectAccessor<0, 1> >
-CellAccessor<1>::face (const unsigned int) const 
+TriaIterator<TriaAccessor<0, 1, 1> >
+CellAccessor<1,1>::face (const unsigned int) const 
+{
+  Assert (false, ExcImpossibleInDim(1));
+  return TriaIterator<TriaAccessor<0, 1, 1> >();
+}
+
+
+
+template <>
+inline
+TriaIterator<TriaAccessor<0, 1, 2> >
+CellAccessor<1,2>::face (const unsigned int) const 
 {
   Assert (false, ExcImpossibleInDim(1));
-  return TriaIterator<1,TriaObjectAccessor<0, 1> >();
+  return TriaIterator<TriaAccessor<0, 1, 2> >();
 }
 
 
+template <>
+inline
+Triangulation<2,2>::face_iterator
+CellAccessor<2,2>::face (const unsigned int i) const 
+{
+  return this->line(i);
+}
 
 template <>
 inline
-Triangulation<2>::face_iterator
-CellAccessor<2>::face (const unsigned int i) const 
+Triangulation<2,3>::face_iterator
+CellAccessor<2,3>::face (const unsigned int i) const 
 {
   return this->line(i);
 }
@@ -1600,7 +1940,7 @@ CellAccessor<2>::face (const unsigned int i) const
 template <>
 inline
 Triangulation<3>::face_iterator
-CellAccessor<3>::face (const unsigned int i) const 
+CellAccessor<3,3>::face (const unsigned int i) const 
 {
   return this->quad(i);
 }
@@ -1610,18 +1950,34 @@ CellAccessor<3>::face (const unsigned int i) const
 template <>
 inline
 unsigned int
-CellAccessor<1>::face_index (const unsigned int) const 
+CellAccessor<1,1>::face_index (const unsigned int) const 
+{
+  Assert (false, ExcImpossibleInDim(1));
+  return numbers::invalid_unsigned_int;
+}
+
+template <>
+inline
+unsigned int
+CellAccessor<1,2>::face_index (const unsigned int) const 
 {
   Assert (false, ExcImpossibleInDim(1));
   return numbers::invalid_unsigned_int;
 }
 
+template <>
+inline
+unsigned int
+CellAccessor<2,2>::face_index (const unsigned int i) const 
+{
+  return this->line_index(i);
+}
 
 
 template <>
 inline
 unsigned int
-CellAccessor<2>::face_index (const unsigned int i) const 
+CellAccessor<2,3>::face_index (const unsigned int i) const 
 {
   return this->line_index(i);
 }
@@ -1631,17 +1987,17 @@ CellAccessor<2>::face_index (const unsigned int i) const
 template <>
 inline
 unsigned int
-CellAccessor<3>::face_index (const unsigned int i) const 
+CellAccessor<3,3>::face_index (const unsigned int i) const 
 {
   return this->quad_index(i);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 int
-CellAccessor<dim>::neighbor_index (const unsigned int i) const 
+CellAccessor<dim,spacedim>::neighbor_index (const unsigned int i) const 
 {
   Assert (i<GeometryInfo<dim>::faces_per_cell,
          TriaAccessorExceptions::ExcInvalidNeighbor(i));
@@ -1651,10 +2007,10 @@ CellAccessor<dim>::neighbor_index (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 int
-CellAccessor<dim>::neighbor_level (const unsigned int i) const
+CellAccessor<dim,spacedim>::neighbor_level (const unsigned int i) const
 {
   Assert (i<GeometryInfo<dim>::faces_per_cell,
          TriaAccessorExceptions::ExcInvalidNeighbor(i));
@@ -1664,10 +2020,10 @@ CellAccessor<dim>::neighbor_level (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 RefinementCase<dim>
-CellAccessor<dim>::refine_flag_set () const
+CellAccessor<dim,spacedim>::refine_flag_set () const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
                                   // cells flagged for refinement must be active
@@ -1682,10 +2038,10 @@ CellAccessor<dim>::refine_flag_set () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 void
-CellAccessor<dim>::set_refine_flag (const RefinementCase<dim> refinement_case) const
+CellAccessor<dim,spacedim>::set_refine_flag (const RefinementCase<dim> refinement_case) const
 {
   Assert (this->used() && this->active(), ExcRefineCellNotActive());
   Assert (!coarsen_flag_set(),
@@ -1696,10 +2052,10 @@ CellAccessor<dim>::set_refine_flag (const RefinementCase<dim> refinement_case) c
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 void
-CellAccessor<dim>::clear_refine_flag () const
+CellAccessor<dim,spacedim>::clear_refine_flag () const
 {
   Assert (this->used() && this->active(), ExcRefineCellNotActive());
   this->tria->levels[this->present_level]->refine_flags[this->present_index] =
@@ -1708,10 +2064,10 @@ CellAccessor<dim>::clear_refine_flag () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 bool
-CellAccessor<dim>::flag_for_face_refinement (const unsigned int face_no,
+CellAccessor<dim,spacedim>::flag_for_face_refinement (const unsigned int face_no,
                                             const RefinementCase<dim-1> &face_refinement_case) const
 {
   Assert (dim>1, ExcImpossibleInDim(dim));
@@ -1740,10 +2096,10 @@ CellAccessor<dim>::flag_for_face_refinement (const unsigned int face_no,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 bool
-CellAccessor<dim>::flag_for_line_refinement (const unsigned int line_no) const
+CellAccessor<dim,spacedim>::flag_for_line_refinement (const unsigned int line_no) const
 {
   Assert (dim>1, ExcImpossibleInDim(dim));
   Assert (line_no<GeometryInfo<dim>::lines_per_cell,
@@ -1773,6 +2129,14 @@ CellAccessor<1>::subface_case(const unsigned int) const
   return internal::SubfaceCase<1>::case_none;
 }
 
+template <>
+inline
+internal::SubfaceCase<1>
+CellAccessor<1,2>::subface_case(const unsigned int) const
+{
+  Assert(false, ExcImpossibleInDim(1));
+  return internal::SubfaceCase<1>::case_none;
+}
 
 
 template <>
@@ -1786,6 +2150,16 @@ CellAccessor<2>::subface_case(const unsigned int face_no) const
   return (face(face_no)->has_children()) ? internal::SubfaceCase<2>::case_x : internal::SubfaceCase<2>::case_none;
 }
 
+template <>
+inline
+internal::SubfaceCase<2>
+CellAccessor<2,3>::subface_case(const unsigned int face_no) const
+{
+  Assert(active(), TriaAccessorExceptions::ExcCellNotActive());
+  Assert(face_no<GeometryInfo<2>::faces_per_cell,
+        ExcIndexRange(face_no,0,GeometryInfo<2>::faces_per_cell));
+  return (face(face_no)->has_children()) ? internal::SubfaceCase<2>::case_x : internal::SubfaceCase<2>::case_none;
+}
 
 
 template <>
@@ -1865,10 +2239,10 @@ CellAccessor<3>::subface_case(const unsigned int face_no) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 bool
-CellAccessor<dim>::coarsen_flag_set () const
+CellAccessor<dim,spacedim>::coarsen_flag_set () const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
                                   // cells flagged for coarsening must be active
@@ -1883,10 +2257,10 @@ CellAccessor<dim>::coarsen_flag_set () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 void
-CellAccessor<dim>::set_coarsen_flag () const
+CellAccessor<dim,spacedim>::set_coarsen_flag () const
 {
   Assert (this->used() && this->active(), ExcRefineCellNotActive());
   Assert (!refine_flag_set(), ExcCellFlaggedForRefinement());
@@ -1896,10 +2270,10 @@ CellAccessor<dim>::set_coarsen_flag () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 void
-CellAccessor<dim>::clear_coarsen_flag () const
+CellAccessor<dim,spacedim>::clear_coarsen_flag () const
 {
   Assert (this->used() && this->active(), ExcRefineCellNotActive());
   this->tria->levels[this->present_level]->coarsen_flags[this->present_index] = false;
@@ -1907,12 +2281,12 @@ CellAccessor<dim>::clear_coarsen_flag () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-TriaIterator<dim,CellAccessor<dim> >
-CellAccessor<dim>::neighbor (const unsigned int i) const
+TriaIterator<CellAccessor<dim,spacedim> >
+CellAccessor<dim,spacedim>::neighbor (const unsigned int i) const
 {
-  TriaIterator<dim,CellAccessor<dim> >
+    TriaIterator<CellAccessor<dim,spacedim> >
     q (this->tria, neighbor_level (i), neighbor_index (i));
 
   Assert ((q.state() == IteratorState::past_the_end) || q->used(),
@@ -1923,12 +2297,12 @@ CellAccessor<dim>::neighbor (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-TriaIterator<dim,CellAccessor<dim> >
-CellAccessor<dim>::child (const unsigned int i) const
+TriaIterator<CellAccessor<dim,spacedim> >
+CellAccessor<dim,spacedim>::child (const unsigned int i) const
 {
-  TriaIterator<dim,CellAccessor<dim> >
+    TriaIterator<CellAccessor<dim,spacedim> >
     q (this->tria, this->present_level+1, this->child_index (i));
 
   Assert ((q.state() == IteratorState::past_the_end) || q->used(),
@@ -1939,20 +2313,20 @@ CellAccessor<dim>::child (const unsigned int i) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 bool
-CellAccessor<dim>::active () const
+CellAccessor<dim,spacedim>::active () const
 {
   return !this->has_children();
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 unsigned int
-CellAccessor<dim>::neighbor_face_no (const unsigned int neighbor) const
+CellAccessor<dim,spacedim>::neighbor_face_no (const unsigned int neighbor) const
 {
   if (dim==1)
     return neighbor_of_neighbor(neighbor);
index 2ce14dc53b14bf9ec87e1be0103487d19df748d2..7fedc661a902ba8a2a873f09dc0bd8770850279f 100644 (file)
@@ -23,7 +23,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class Triangulation;
+template <int dim, int space_dim> class Triangulation;
 
 
 
@@ -75,7 +75,7 @@ template <int dim> class Triangulation;
  * @ingroup boundary
  *   @author Wolfgang Bangerth, 1999, 2001, Ralf Hartmann, 2001, 2008
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 class Boundary : public Subscriptor
 {
   public:
@@ -103,7 +103,7 @@ class Boundary : public Subscriptor
                                      * For obvious reasons, this
                                      * type is not useful in 1d.
                                      */
-    typedef Tensor<1,dim> FaceVertexNormals[GeometryInfo<dim>::vertices_per_face];
+    typedef Tensor<1,spacedim> FaceVertexNormals[GeometryInfo<dim>::vertices_per_face];
        
                                     /**
                                      * Destructor. Does nothing here, but
@@ -123,8 +123,8 @@ class Boundary : public Subscriptor
                                      * lines therefore is also on the
                                      * boundary).
                                      */
-    virtual Point<dim>
-    get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const = 0;
+    virtual Point<spacedim>
+    get_new_point_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line) const = 0;
 
                                     /**
                                      * Return the point which shall
@@ -152,8 +152,8 @@ class Boundary : public Subscriptor
                                      * default implementation throws
                                      * an error in any case, however.
                                      */
-    virtual Point<dim>
-    get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &quad) const;
+    virtual Point<spacedim>
+    get_new_point_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad) const;
 
                                     /**
                                      * Depending on <tt>dim=2</tt> or
@@ -167,8 +167,8 @@ class Boundary : public Subscriptor
                                      * allows dimension independent
                                      * programming.
                                      */
-    Point<dim>
-    get_new_point_on_face (const typename Triangulation<dim>::face_iterator &face) const;
+    Point<spacedim>
+    get_new_point_on_face (const typename Triangulation<dim,spacedim>::face_iterator &face) const;
 
                                     /**
                                      * Return equally spaced
@@ -195,8 +195,8 @@ class Boundary : public Subscriptor
                                      * an error in any case, however.
                                      */
     virtual void
-    get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
-                                    std::vector<Point<dim> > &points) const;
+    get_intermediate_points_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line,
+                                    std::vector<Point<spacedim> > &points) const;
     
                                     /**
                                      * Return equally spaced
@@ -229,8 +229,8 @@ class Boundary : public Subscriptor
                                      * an error in any case, however.
                                      */
     virtual void
-    get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &quad,
-                                    std::vector<Point<dim> > &points) const;
+    get_intermediate_points_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad,
+                                    std::vector<Point<spacedim> > &points) const;
 
                                     /**
                                      * Depending on <tt>dim=2</tt> or
@@ -246,8 +246,8 @@ class Boundary : public Subscriptor
                                      * programming.
                                      */
     void
-    get_intermediate_points_on_face (const typename Triangulation<dim>::face_iterator &face,
-                                    std::vector<Point<dim> > &points) const;
+    get_intermediate_points_on_face (const typename Triangulation<dim,spacedim>::face_iterator &face,
+                                    std::vector<Point<spacedim> > &points) const;
 
                                     /**
                                      * Compute the normal vectors to
@@ -278,14 +278,14 @@ class Boundary : public Subscriptor
                                      * the given face.
                                      */
     virtual void
-    get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
+    get_normals_at_vertices (const typename Triangulation<dim,spacedim>::face_iterator &face,
                             FaceVertexNormals &face_vertex_normals) const;
 };
 
 
 
 /**
- *   Specialization of Boundary<dim>, which places the new point
+ *   Specialization of Boundary<dim,spacedim>, which places the new point
  *   right into the middle of the given points. The middle is defined
  *   as the arithmetic mean of the points.
  *
@@ -299,8 +299,8 @@ class Boundary : public Subscriptor
  *
  *   @author Wolfgang Bangerth, 1998, 2001, Ralf Hartmann, 2001
  */
-template <int dim>
-class StraightBoundary : public Boundary<dim>
+template <int dim, int spacedim=dim>
+class StraightBoundary : public Boundary<dim,spacedim>
 {
   public:
                                     /**
@@ -321,8 +321,8 @@ class StraightBoundary : public Boundary<dim>
                                      * base class for more
                                      * information.
                                      */
-    virtual Point<dim>
-    get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const;
+    virtual Point<spacedim>
+    get_new_point_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line) const;
 
                                     /**
                                      * Let the new point be the
@@ -339,8 +339,8 @@ class StraightBoundary : public Boundary<dim>
                                      * base class for more
                                      * information.
                                      */
-    virtual Point<dim>
-    get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &quad) const;
+    virtual Point<spacedim>
+    get_new_point_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad) const;
 
                                     /**
                                      * Gives <tt>n=points.size()</tt>
@@ -355,8 +355,8 @@ class StraightBoundary : public Boundary<dim>
                                      * base class.
                                      */
     virtual void
-    get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
-                                    std::vector<Point<dim> > &points) const;
+    get_intermediate_points_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line,
+                                    std::vector<Point<spacedim> > &points) const;
 
                                     /**
                                      * Gives <tt>n=points.size()=m*m</tt>
@@ -371,8 +371,8 @@ class StraightBoundary : public Boundary<dim>
                                      * base class.
                                      */
     virtual void
-    get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &quad,
-                                    std::vector<Point<dim> > &points) const;
+    get_intermediate_points_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad,
+                                    std::vector<Point<spacedim> > &points) const;
 
                                     /**
                                      * Compute the normals to the
@@ -385,8 +385,8 @@ class StraightBoundary : public Boundary<dim>
                                      * base class.
                                      */
     virtual void
-    get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
-                            typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const;
+    get_normals_at_vertices (const typename Triangulation<dim,spacedim>::face_iterator &face,
+                            typename Boundary<dim,spacedim>::FaceVertexNormals &face_vertex_normals) const;
 };
 
 
@@ -397,68 +397,58 @@ class StraightBoundary : public Boundary<dim>
 
 template <>
 Point<1>
-Boundary<1>::
-get_new_point_on_face (const Triangulation<1>::face_iterator &) const;
-
-template <>
-Point<2>
-Boundary<2>::
-get_new_point_on_face (const Triangulation<2>::face_iterator &) const;
-
-template <>
-Point<3>
-Boundary<3>::
-get_new_point_on_face (const Triangulation<3>::face_iterator &) const;
+Boundary<1,1>::
+get_new_point_on_face (const Triangulation<1,1>::face_iterator &) const;
 
 template <>
 void
-Boundary<1>::
-get_intermediate_points_on_face (const Triangulation<1>::face_iterator &,
+Boundary<1,1>::
+get_intermediate_points_on_face (const Triangulation<1,1>::face_iterator &,
                                 std::vector<Point<1> > &) const;
 
 template <>
-void
-Boundary<2>::
-get_intermediate_points_on_face (const Triangulation<2>::face_iterator &,
-                                std::vector<Point<2> > &) const;
+Point<2>
+Boundary<1,2>::
+get_new_point_on_face (const Triangulation<1,2>::face_iterator &) const;
 
 template <>
 void
-Boundary<3>::
-get_intermediate_points_on_face (const Triangulation<3>::face_iterator &,
-                                std::vector<Point<3> > &) const;
+Boundary<1,2>::
+get_intermediate_points_on_face (const Triangulation<1,2>::face_iterator &,
+                                std::vector<Point<2> > &) const;
+
 
 template <>
 void
-StraightBoundary<1>::
-get_normals_at_vertices (const Triangulation<1>::face_iterator &,
-                        Boundary<1>::FaceVertexNormals &) const;
+StraightBoundary<1,1>::
+get_normals_at_vertices (const Triangulation<1,1>::face_iterator &,
+                        Boundary<1,1>::FaceVertexNormals &) const;
 template <>
 void
-StraightBoundary<2>::
-get_normals_at_vertices (const Triangulation<2>::face_iterator &face,
-                        Boundary<2>::FaceVertexNormals &face_vertex_normals) const;
+StraightBoundary<2,2>::
+get_normals_at_vertices (const Triangulation<2,2>::face_iterator &face,
+                        Boundary<2,2>::FaceVertexNormals &face_vertex_normals) const;
 template <>
 void
-StraightBoundary<3>::
-get_normals_at_vertices (const Triangulation<3>::face_iterator &face,
-                        Boundary<3>::FaceVertexNormals &face_vertex_normals) const;
+StraightBoundary<3,3>::
+get_normals_at_vertices (const Triangulation<3,3>::face_iterator &face,
+                        Boundary<3,3>::FaceVertexNormals &face_vertex_normals) const;
 
 template <>
 Point<3>
-StraightBoundary<3>::
-get_new_point_on_quad (const Triangulation<3>::quad_iterator &quad) const;
+StraightBoundary<3,3>::
+get_new_point_on_quad (const Triangulation<3,3>::quad_iterator &quad) const;
 
 template <>
 void
-StraightBoundary<1>::
-get_intermediate_points_on_line (const Triangulation<1>::line_iterator &,
+StraightBoundary<1,1>::
+get_intermediate_points_on_line (const Triangulation<1,1>::line_iterator &,
                                 std::vector<Point<1> > &) const;
 
 template <>
 void
-StraightBoundary<3>::
-get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
+StraightBoundary<3,3>::
+get_intermediate_points_on_quad (const Triangulation<3,3>::quad_iterator &quad,
                                 std::vector<Point<3> > &points) const;
 
 #endif // DOXYGEN
index 6ad89a2349a81c8de7e19f8dbd3147ba734f3989..265eea60968e29fe4b11959e087abde5caf20a53 100644 (file)
@@ -204,14 +204,14 @@ class CylinderBoundary : public StraightBoundary<dim>
  *
  *   @author Wolfgang Bangerth, 1998, Ralf Hartmann, 2001
  */
-template <int dim>
-class HyperBallBoundary : public StraightBoundary<dim>
+template <int dim, int spacedim=dim>
+class HyperBallBoundary : public StraightBoundary<dim,spacedim>
 {
   public:
                                     /**
                                      * Constructor
                                      */
-    HyperBallBoundary (const Point<dim> p      = Point<dim>(),
+    HyperBallBoundary (const Point<spacedim> p      = Point<spacedim>(),
                       const double     radius = 1.0);
 
                                     /**
@@ -219,16 +219,16 @@ class HyperBallBoundary : public StraightBoundary<dim>
                                      * this class and the documentation of the
                                      * base class.
                                      */
-    virtual Point<dim>
-    get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const;
+    virtual Point<spacedim>
+    get_new_point_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line) const;
 
                                     /**
                                      * Refer to the general documentation of
                                      * this class and the documentation of the
                                      * base class.
                                      */
-    virtual Point<dim>
-    get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &quad) const;
+    virtual Point<spacedim>
+    get_new_point_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad) const;
 
                                     /**
                                      * Refer to the general
@@ -240,8 +240,8 @@ class HyperBallBoundary : public StraightBoundary<dim>
                                      * @p get_intermediate_points_between_points.
                                      */
     virtual void
-    get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
-                                    std::vector<Point<dim> > &points) const;
+    get_intermediate_points_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line,
+                                    std::vector<Point<spacedim> > &points) const;
 
                                     /**
                                      * Refer to the general
@@ -253,8 +253,8 @@ class HyperBallBoundary : public StraightBoundary<dim>
                                      * and for <tt>points.size()==1</tt>.
                                      */
     virtual void
-    get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &quad,
-                                    std::vector<Point<dim> > &points) const;
+    get_intermediate_points_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad,
+                                    std::vector<Point<spacedim> > &points) const;
 
                                     /**
                                      * Compute the normals to the
@@ -267,13 +267,13 @@ class HyperBallBoundary : public StraightBoundary<dim>
                                      * base class.
                                      */
     virtual void
-    get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
-                            typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const;
+    get_normals_at_vertices (const typename Triangulation<dim,spacedim>::face_iterator &face,
+                            typename Boundary<dim,spacedim>::FaceVertexNormals &face_vertex_normals) const;
 
                                     /**
                                      * Return the center of the ball.
                                      */
-    Point<dim> get_center () const;
+    Point<spacedim> get_center () const;
 
                                     /**
                                      * Return the radius of the ball.
@@ -294,7 +294,7 @@ class HyperBallBoundary : public StraightBoundary<dim>
                                     /**
                                      * Center point of the hyperball.
                                      */
-    const Point<dim> center;
+    const Point<spacedim> center;
 
                                     /**
                                      * Radius of the hyperball.
@@ -334,8 +334,8 @@ class HyperBallBoundary : public StraightBoundary<dim>
                                      * in the documentation of the
                                      * base class.
                                      */
-    void get_intermediate_points_between_points (const Point<dim> &p0, const Point<dim> &p1,
-                                                std::vector<Point<dim> > &points) const;    
+    void get_intermediate_points_between_points (const Point<spacedim> &p0, const Point<spacedim> &p1,
+                                                std::vector<Point<spacedim> > &points) const;    
 };
 
 
index 9cf845c04e4c511705bea1da4d484601b038243d..5b11ada07641a4266582f406e0e49a3a91238aac 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <base/config.h>
 #include <base/exceptions.h>
+
 #include <base/point.h>
 #include <grid/tria_iterator_base.h>
 
 
 DEAL_II_NAMESPACE_OPEN
 
-//TODO: Instead of letting the Tria*Iterator classes take a dimension as first argument, deduce the space dimension from the TriaAccessor where necessary.
+template <int dim, int spacedim> class Triangulation;
+
+template <typename> class TriaRawIterator;
+template <typename> class TriaIterator;
+template <typename> class TriaActiveIterator;
+
 
 
-template <int dim> class Triangulation;
 
 // note: in non-debug mode, i.e. with optimizations, the file
 // tria_iterator.templates.h is included at the end of this file.
@@ -77,7 +82,7 @@ template <int dim> class Triangulation;
  * iterators is rather expensive compared to normal pointers.
  *   
  * The objects pointed to are accessors, derived from
- * TriaAccessor. Which kind of accessor is determined by the template
+ * TriaAccessorBase. Which kind of accessor is determined by the template
  * argument <em>Accessor</em>. These accessors are not so much data
  * structures as they are a collection of functions providing access
  * to the data stored in Tringulation or DoFHandler objects. Using
@@ -166,7 +171,7 @@ template <int dim> class Triangulation;
  * The accessors provided by the library are distributed in three
  * groups, determined by whether they access the data of
  * Triangulation, DoFHandler or MGDoFHandler. They are derived from
- * TriaObjectAccessor, DoFObjectAccessor and MGDoFObjectAccessor,
+ * TriaAccessor, DoFAccessor and MGDoFAccessor,
  * respectively. In each group, there is an accessor to cells, which
  * have more functionality.
  * 
@@ -177,7 +182,7 @@ template <int dim> class Triangulation;
  * triangulation.
  *
  * @note More information on valid and invalid iterators can be found
- * in the documentation of TriaAccessor, where the iterator states are
+ * in the documentation of TriaAccessorBase, where the iterator states are
  * checked and implemented.
  *
  * 
@@ -226,7 +231,7 @@ template <int dim> class Triangulation;
  * @author Wolfgang Bangerth, 1998
  * @author documentation update Guido Kanschat, 2004
  */
-template <int dim, typename Accessor>
+template <typename Accessor>
 class TriaRawIterator :
 #ifdef HAVE_STD_ITERATOR_CLASS  
                public std::iterator<std::bidirectional_iterator_tag,Accessor>
@@ -272,6 +277,15 @@ class TriaRawIterator :
                                      * @endverbatim
                                      */
     TriaRawIterator (const Accessor &a);
+
+                                    /**
+                                     * Constructor. Assumes that the
+                                     * other accessor type is
+                                     * convertible to the current
+                                     * one.
+                                     */
+    template <typename OtherAccessor>
+    TriaRawIterator (const OtherAccessor &a);
     
                                     /**
                                      *  Proper constructor, initialized
@@ -281,9 +295,9 @@ class TriaRawIterator :
                                      *  of a type declared by the accessor
                                      *  class.
                                      */
-    TriaRawIterator (const Triangulation<dim> *parent,
-                    const int                 level,
-                    const int                 index,
+    TriaRawIterator (const Triangulation<Accessor::dimension,Accessor::space_dimension> *parent,
+                    const int level,
+                    const int index,
                     const typename AccessorType::AccessorData *local_data = 0);
 
                                     /**
@@ -299,16 +313,30 @@ class TriaRawIterator :
                                      * a Triangulation@p ::raw_cell_iterator from
                                      * a DoFHandler@p ::raw_cell_iterator, since
                                      * the DoFAccessor class is derived from
-                                     * the TriaAccessor class.
-                                     *
-                                     * Since TriaIterator and
-                                     * TriaActiveIterator are derived classes
-                                     * of this class, this constructor also
-                                     * serves to convert these iterators with
-                                     * other accessor classes.
+                                     * the TriaAccessorBase class.
+                                     */
+    template <typename OtherAccessor>
+    TriaRawIterator (const TriaRawIterator<OtherAccessor> &i);
+
+                                    /**
+                                     * Conversion constructor. Same
+                                     * as above with the difference
+                                     * that it converts from
+                                     * TriaIterator classes (not
+                                     * TriaRawIterator).
                                      */
     template <typename OtherAccessor>
-    TriaRawIterator (const TriaRawIterator<dim,OtherAccessor> &i);
+    TriaRawIterator (const TriaIterator<OtherAccessor> &i);
+
+                                    /**
+                                     * Conversion constructor. Same
+                                     * as above with the difference
+                                     * that it converts from
+                                     * TriaActiveIterator classes
+                                     * (not TriaRawIterator).
+                                     */
+    template <typename OtherAccessor>
+    TriaRawIterator (const TriaActiveIterator<OtherAccessor> &i);
     
                                     /**
                                      *  @name Dereferencing
@@ -545,9 +573,9 @@ class TriaRawIterator :
                                      * accessor since then it says that would
                                      * be a artial specialization.
                                      */
-    template <int anydim, typename SomeAccessor> friend class TriaRawIterator;
-    template <int anydim, typename SomeAccessor> friend class TriaIterator;
-    template <int anydim, typename SomeAccessor> friend class TriaActiveIterator;
+    template <typename SomeAccessor> friend class TriaRawIterator;
+    template <typename SomeAccessor> friend class TriaIterator;
+    template <typename SomeAccessor> friend class TriaActiveIterator;
 };
 
 
@@ -558,8 +586,8 @@ class TriaRawIterator :
  * @ingroup grid
  * @ingroup Iterators
  */
-template <int dim, typename Accessor>
-class TriaIterator : public TriaRawIterator<dim,Accessor> 
+template <typename Accessor>
+class TriaIterator : public TriaRawIterator<Accessor> 
 {
   public:
                                     /**
@@ -571,7 +599,7 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
                                     /**
                                      *  Copy constructor.
                                      */
-    TriaIterator (const TriaIterator<dim,Accessor> &);
+    TriaIterator (const TriaIterator<Accessor> &);
 
                                     /**
                                      *  Cross copy constructor from
@@ -583,7 +611,7 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
                                      *  used, the debug version raises
                                      *  an error!
                                      */
-    TriaIterator (const TriaRawIterator<dim,Accessor> &);
+    TriaIterator (const TriaRawIterator<Accessor> &);
 
                                     /**
                                      *  Proper constructor, initialized
@@ -598,7 +626,7 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
                                      *  used, the debug version raises
                                      *  an error!
                                      */
-    TriaIterator (const Triangulation<dim> *parent,
+    TriaIterator (const Triangulation<Accessor::dimension,Accessor::space_dimension> *parent,
                  const int                 level,
                  const int                 index,
                  const typename Accessor::AccessorData *local_data = 0);
@@ -616,15 +644,10 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
                                      * a Triangulation@p ::cell_iterator from
                                      * a DoFHandler@p ::cell_iterator, since
                                      * the DoFAccessor class is derived from
-                                     * the TriaAccessor class.
-                                     *
-                                     * Since TriaActiveIterator is a derived
-                                     * class of this class, this constructor
-                                     * also serves to convert these iterators 
-                                     * with other accessor classes.
+                                     * the TriaAccessorBase class.
                                      */
     template <typename OtherAccessor>
-    TriaIterator (const TriaIterator<dim,OtherAccessor> &i);
+    TriaIterator (const TriaIterator<OtherAccessor> &i);
 
                                     /**
                                      * Similar conversion operator to the above
@@ -633,13 +656,22 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
                                      * which is necessary for raw iterators.
                                      */
     template <typename OtherAccessor>
-    TriaIterator (const TriaRawIterator<dim,OtherAccessor> &i);
+    TriaIterator (const TriaRawIterator<OtherAccessor> &i);
 
+                                    /**
+                                     * Similar conversion operator to
+                                     * the above one, but for
+                                     * conversion from active
+                                     * iterators.
+                                     */
+    template <typename OtherAccessor>
+    TriaIterator (const TriaActiveIterator<OtherAccessor> &i);
+    
                                     /**
                                      *  Assignment operator.
                                      */
-    TriaIterator<dim,Accessor> &
-    operator = (const TriaIterator<dim,Accessor> &);
+    TriaIterator<Accessor> &
+    operator = (const TriaIterator<Accessor> &);
 
                                     /**
                                      *  Cross assignment operator. This
@@ -647,8 +679,8 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
                                      *  given iterator points to a used
                                      *  element.
                                      */
-    TriaIterator<dim,Accessor> &
-    operator = (const TriaRawIterator<dim,Accessor> &);
+    TriaIterator<Accessor> &
+    operator = (const TriaRawIterator<Accessor> &);
 
                                     /**@name Advancement of iterators*/
                                     /*@{*/
@@ -658,7 +690,7 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
                                      *  the next used element and returns
                                      *  a reference to <tt>*this</tt>.
                                      */
-    TriaIterator<dim,Accessor> & operator ++ ();
+    TriaIterator<Accessor> & operator ++ ();
 
                                     /**
                                      *  Postfix <tt>++</tt> operator: <tt>i++</tt>. This
@@ -677,7 +709,7 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
                                      *  you normally never need the
                                      *  returned value.
                                      */
-    TriaIterator<dim,Accessor> operator ++ (int);
+    TriaIterator<Accessor> operator ++ (int);
 
                                     /**
                                      *  Prefix @p -- operator: @p --i. This
@@ -685,12 +717,12 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
                                      *  the previous used element and returns
                                      *  a reference to <tt>*this</tt>.
                                      */
-    TriaIterator<dim,Accessor> & operator -- ();
+    TriaIterator<Accessor> & operator -- ();
 
                                     /**
                                      *  Postfix @p -- operator: @p i--.
                                      */
-    TriaIterator<dim,Accessor> operator -- (int);
+    TriaIterator<Accessor> operator -- (int);
                                     /*@}*/
     
                                     /**
@@ -709,8 +741,8 @@ class TriaIterator : public TriaRawIterator<dim,Accessor>
  * @ingroup grid
  * @ingroup Iterators
  */
-template <int dim, typename Accessor>
-class TriaActiveIterator : public TriaIterator<dim,Accessor> 
+template <typename Accessor>
+class TriaActiveIterator : public TriaIterator<Accessor> 
 {
   public:
                                     /**
@@ -722,7 +754,7 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                     /**
                                      *  Copy constructor.
                                      */
-    TriaActiveIterator (const TriaActiveIterator<dim,Accessor> &);
+    TriaActiveIterator (const TriaActiveIterator<Accessor> &);
 
                                     /**
                                      *  Cross copy constructor from
@@ -734,7 +766,7 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      *  active, the debug version raises
                                      *  an error!
                                      */
-    TriaActiveIterator (const TriaRawIterator<dim,Accessor> &);
+    TriaActiveIterator (const TriaRawIterator<Accessor> &);
 
                                     /**
                                      *  Cross copy constructor from
@@ -746,7 +778,7 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      *  active, the debug version raises
                                      *  an error!
                                      */
-    TriaActiveIterator (const TriaIterator<dim,Accessor> &);
+    TriaActiveIterator (const TriaIterator<Accessor> &);
 
                                     /**
                                      *  Proper constructor, initialized
@@ -761,9 +793,9 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      *  active, the debug version raises
                                      *  an error!
                                      */
-    TriaActiveIterator (const Triangulation<dim> *parent,
-                       const int                 level,
-                       const int                 index,
+    TriaActiveIterator (const Triangulation<Accessor::dimension,Accessor::space_dimension> *parent,
+                       const int level,
+                       const int index,
                        const typename Accessor::AccessorData *local_data = 0);
 
                                     /**
@@ -779,10 +811,10 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      * a Triangulation@p ::active_cell_iterator from
                                      * a DoFHandler@p ::active_cell_iterator, since
                                      * the DoFAccessor class is derived from
-                                     * the TriaAccessor class.
+                                     * the TriaAccessorBase class.
                                      */
     template <typename OtherAccessor>
-    TriaActiveIterator (const TriaActiveIterator<dim,OtherAccessor> &i);
+    TriaActiveIterator (const TriaActiveIterator<OtherAccessor> &i);
 
                                     /**
                                      * Similar conversion operator to the above
@@ -792,16 +824,16 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      * raw iterators. Since usual iterators
                                      * are also raw iterators, this constructor
                                      * works also for parameters of type
-                                     * <tt>TriaIterator<dim,OtherAccessor></tt>.
+                                     * <tt>TriaIterator<OtherAccessor></tt>.
                                      */
     template <typename OtherAccessor>
-    TriaActiveIterator (const TriaRawIterator<dim,OtherAccessor> &i);
+    TriaActiveIterator (const TriaRawIterator<OtherAccessor> &i);
 
                                     /**
                                      *  Assignment operator.
                                      */
-    TriaActiveIterator<dim,Accessor> &
-    operator = (const TriaActiveIterator<dim,Accessor> &);
+    TriaActiveIterator<Accessor> &
+    operator = (const TriaActiveIterator<Accessor> &);
 
                                     /**
                                      *  Cross assignment operator. This
@@ -809,8 +841,8 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      *  given iterator points to an active
                                      *  element or past the end.
                                      */
-    TriaActiveIterator<dim,Accessor> &
-    operator = (const TriaRawIterator<dim,Accessor> &);
+    TriaActiveIterator<Accessor> &
+    operator = (const TriaRawIterator<Accessor> &);
 
                                     /**
                                      *  Cross assignment operator. This
@@ -818,8 +850,8 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      *  given iterator points to an active
                                      *  element or past the end.
                                      */
-    TriaActiveIterator<dim,Accessor> &
-    operator = (const TriaIterator<dim,Accessor> &);
+    TriaActiveIterator<Accessor> &
+    operator = (const TriaIterator<Accessor> &);
 
                                     /**
                                      *  Prefix <tt>++</tt> operator: <tt>++i</tt>. This
@@ -827,7 +859,7 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      *  the next active element and returns
                                      *  a reference to <tt>*this</tt>.
                                      */
-    TriaActiveIterator<dim,Accessor> & operator ++ ();
+    TriaActiveIterator<Accessor> & operator ++ ();
 
                                     /**@name Advancement of iterators*/
                                     /*@{*/
@@ -848,7 +880,7 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      *  you normally never need the
                                      *  returned value.
                                      */
-    TriaActiveIterator<dim,Accessor> operator ++ (int);
+    TriaActiveIterator<Accessor> operator ++ (int);
 
                                     /**
                                      *  Prefix @p -- operator: @p --i. This
@@ -856,12 +888,12 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
                                      *  the previous active element and
                                      *  returns a reference to <tt>*this</tt>.
                                      */
-    TriaActiveIterator<dim,Accessor> & operator -- ();
+    TriaActiveIterator<Accessor> & operator -- ();
 
                                     /**
                                      *  Postfix @p -- operator: @p i--.
                                      */
-    TriaActiveIterator<dim,Accessor> operator -- (int);
+    TriaActiveIterator<Accessor> operator -- (int);
                                     /*@}*/
     
                                     /**
@@ -874,32 +906,69 @@ class TriaActiveIterator : public TriaIterator<dim,Accessor>
 /*----------------------- Inline functions -------------------*/
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
+inline
+TriaRawIterator<Accessor>::
+TriaRawIterator (const Accessor &a)
+               :
+               accessor (a)
+{}
+
+
+
+template <typename Accessor>
+template <typename OtherAccessor>
 inline
-TriaRawIterator<dim,Accessor>::TriaRawIterator (const Accessor &a) :
+TriaRawIterator<Accessor>::
+TriaRawIterator (const OtherAccessor &a)
+               :
                accessor (a)
 {}
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
+template <typename OtherAccessor>
+inline
+TriaRawIterator<Accessor>::
+TriaRawIterator (const TriaRawIterator<OtherAccessor> &i)
+               :
+               accessor (i.accessor)
+{}
+
+
+
+template <typename Accessor>
 template <typename OtherAccessor>
 inline
-TriaRawIterator<dim,Accessor>::TriaRawIterator (const TriaRawIterator<dim,OtherAccessor> &i)
-               : accessor (i.accessor)
+TriaRawIterator<Accessor>::
+TriaRawIterator (const TriaIterator<OtherAccessor> &i)
+               :
+               accessor (i.accessor)
 {}
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
+template <typename OtherAccessor>
+inline
+TriaRawIterator<Accessor>::
+TriaRawIterator (const TriaActiveIterator<OtherAccessor> &i)
+               :
+               accessor (i.accessor)
+{}
+
+
+
+template <typename Accessor>
 inline
 const Accessor &
-TriaRawIterator<dim,Accessor>::operator * () const
+TriaRawIterator<Accessor>::operator * () const
 {
-  Assert (Accessor::objectdim!=dim ||
+  Assert (Accessor::structure_dimension!=Accessor::dimension ||
          state() == IteratorState::valid,
          ExcDereferenceInvalidCell(accessor));
-  Assert (Accessor::objectdim==dim ||
+  Assert (Accessor::structure_dimension==Accessor::dimension ||
          state() == IteratorState::valid,
          ExcDereferenceInvalidObject(accessor));
   
@@ -908,15 +977,15 @@ TriaRawIterator<dim,Accessor>::operator * () const
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 Accessor &
-TriaRawIterator<dim,Accessor>::operator * ()
+TriaRawIterator<Accessor>::operator * ()
 {
-  Assert (Accessor::objectdim!=dim ||
+  Assert (Accessor::structure_dimension!=Accessor::dimension ||
          state() == IteratorState::valid,
          ExcDereferenceInvalidCell(accessor));
-  Assert (Accessor::objectdim==dim ||
+  Assert (Accessor::structure_dimension==Accessor::dimension ||
          state() == IteratorState::valid,
          ExcDereferenceInvalidObject(accessor));
 
@@ -925,59 +994,59 @@ TriaRawIterator<dim,Accessor>::operator * ()
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 const Accessor *
-TriaRawIterator<dim,Accessor>::operator -> () const
+TriaRawIterator<Accessor>::operator -> () const
 {
   return &(this->operator* ());
 }
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 Accessor *
-TriaRawIterator<dim,Accessor>::operator -> ()
+TriaRawIterator<Accessor>::operator -> ()
 {
   return &(this->operator* ());
 }
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 IteratorState::IteratorStates
-TriaRawIterator<dim,Accessor>::state () const
+TriaRawIterator<Accessor>::state () const
 {
   return accessor.state ();
 }
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 bool
-TriaRawIterator<dim,Accessor>::operator < (const TriaRawIterator &i) const
+TriaRawIterator<Accessor>::operator < (const TriaRawIterator &i) const
 {
-  Assert (Accessor::objectdim!=dim ||
+  Assert (Accessor::structure_dimension!=Accessor::dimension ||
          state() != IteratorState::invalid,
          ExcDereferenceInvalidCell(accessor));
-  Assert (Accessor::objectdim==dim ||
+  Assert (Accessor::structure_dimension==Accessor::dimension ||
          state() != IteratorState::invalid,
          ExcDereferenceInvalidObject(accessor));
 
-  Assert (Accessor::objectdim!=dim ||
+  Assert (Accessor::structure_dimension!=Accessor::dimension ||
          i.state() != IteratorState::invalid,
          ExcDereferenceInvalidCell(i.accessor));
-  Assert (Accessor::objectdim==dim ||
+  Assert (Accessor::structure_dimension==Accessor::dimension ||
          i.state() != IteratorState::invalid,
          ExcDereferenceInvalidObject(i.accessor));
 
   Assert (&accessor.get_triangulation() == &i.accessor.get_triangulation(),
          ExcInvalidComparison());
 
-  if (Accessor::objectdim==dim)
+  if (Accessor::structure_dimension==Accessor::dimension)
     return ((((accessor.level() < i.accessor.level()) ||
              ((accessor.level() == i.accessor.level()) &&
               (accessor.index() < i.accessor.index()))        ) &&
@@ -994,10 +1063,10 @@ TriaRawIterator<dim,Accessor>::operator < (const TriaRawIterator &i) const
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaRawIterator<dim,Accessor> &
-TriaRawIterator<dim,Accessor>::operator ++ ()
+TriaRawIterator<Accessor> &
+TriaRawIterator<Accessor>::operator ++ ()
 {
   Assert (state() == IteratorState::valid, ExcAdvanceInvalidObject());
 
@@ -1007,10 +1076,10 @@ TriaRawIterator<dim,Accessor>::operator ++ ()
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaRawIterator<dim,Accessor> &
-TriaRawIterator<dim,Accessor>::operator -- ()
+TriaRawIterator<Accessor> &
+TriaRawIterator<Accessor>::operator -- ()
 {
   Assert (state() == IteratorState::valid, ExcAdvanceInvalidObject());
 
@@ -1020,12 +1089,12 @@ TriaRawIterator<dim,Accessor>::operator -- ()
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 void
-TriaRawIterator<dim,Accessor>::print (std::ostream &out) const
+TriaRawIterator<Accessor>::print (std::ostream &out) const
 {
-  if (Accessor::objectdim==dim)
+  if (Accessor::structure_dimension==Accessor::dimension)
     out << accessor.level() << "." << accessor.index();
   else
     out << accessor.index();
@@ -1033,30 +1102,42 @@ TriaRawIterator<dim,Accessor>::print (std::ostream &out) const
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 unsigned int
-TriaRawIterator<dim,Accessor>::memory_consumption () const
+TriaRawIterator<Accessor>::memory_consumption () const
 {
-  return sizeof(TriaRawIterator<dim,Accessor>);
+  return sizeof(TriaRawIterator<Accessor>);
 }
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
+template <typename OtherAccessor>
+inline
+TriaIterator<Accessor>::TriaIterator (const TriaIterator<OtherAccessor> &i)
+               :
+               TriaRawIterator<Accessor> (i.accessor)
+{}
+
+
+
+template <typename Accessor>
 template <typename OtherAccessor>
 inline
-TriaIterator<dim,Accessor>::TriaIterator (const TriaIterator<dim,OtherAccessor> &i)
-               : TriaRawIterator<dim,Accessor> (static_cast<TriaIterator<dim,OtherAccessor> >(i))
+TriaIterator<Accessor>::TriaIterator (const TriaActiveIterator<OtherAccessor> &i)
+               :
+               TriaRawIterator<Accessor> (i.accessor)
 {}
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 template <typename OtherAccessor>
 inline
-TriaIterator<dim,Accessor>::TriaIterator (const TriaRawIterator<dim,OtherAccessor> &i)
-               : TriaRawIterator<dim,Accessor> (static_cast<TriaRawIterator<dim,OtherAccessor> >(i))
+TriaIterator<Accessor>::TriaIterator (const TriaRawIterator<OtherAccessor> &i)
+               :
+               TriaRawIterator<Accessor> (i.accessor)
 {
 #ifdef DEBUG
                                   // do this like this, because:
@@ -1073,20 +1154,22 @@ TriaIterator<dim,Accessor>::TriaIterator (const TriaRawIterator<dim,OtherAccesso
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 template <typename OtherAccessor>
 inline
-TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaActiveIterator<dim,OtherAccessor> &i)
-               : TriaIterator<dim,Accessor> (static_cast<TriaIterator<dim,OtherAccessor> >(i))
+TriaActiveIterator<Accessor>::TriaActiveIterator (const TriaActiveIterator<OtherAccessor> &i)
+               :
+               TriaIterator<Accessor> (i.accessor)
 {}
 
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 template <typename OtherAccessor>
 inline
-TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaRawIterator<dim,OtherAccessor> &i)
-               : TriaIterator<dim,Accessor> (i)
+TriaActiveIterator<Accessor>::TriaActiveIterator (const TriaRawIterator<OtherAccessor> &i)
+               :
+               TriaIterator<Accessor> (i)
 {
 #ifdef DEBUG
                                   // do this like this, because:
@@ -1111,10 +1194,10 @@ TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaRawIterator<dim,
  *
  * @author Wolfgang Bangerth, 1998
  */
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 std::ostream & operator << (std::ostream                        &out,
-                           const TriaRawIterator<dim,Accessor> &i)
+                           const TriaRawIterator<Accessor> &i)
 {
   i.print(out);
   return out;
@@ -1130,10 +1213,10 @@ std::ostream & operator << (std::ostream                        &out,
  *
  * @author Wolfgang Bangerth, 1998
  */
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 std::ostream & operator << (std::ostream                     &out,
-                           const TriaIterator<dim,Accessor> &i)
+                           const TriaIterator<Accessor> &i)
 {
   i.print(out);
   return out;
@@ -1149,10 +1232,10 @@ std::ostream & operator << (std::ostream                     &out,
  *
  * @author Wolfgang Bangerth, 1998
  */
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 std::ostream & operator << (std::ostream                           &out,
-                           const TriaActiveIterator<dim,Accessor> &i)
+                           const TriaActiveIterator<Accessor> &i)
 {
   i.print(out);
   return out;
index 449638e15eaed19a88d9f27e3885e1ca90f87f62..396bdd34d10861173a0ddb9b60ae46af38b1acd9 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -30,49 +30,58 @@ DEAL_II_NAMESPACE_OPEN
 /*------------------------ Functions: TriaRawIterator ------------------*/
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaRawIterator<dim,Accessor>::TriaRawIterator () :
-               accessor (0, -2, -2, 0) {}
+TriaRawIterator<Accessor>::TriaRawIterator ()
+               :
+               accessor (0, -2, -2, 0)
+{}
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaRawIterator<dim,Accessor>::TriaRawIterator (const TriaRawIterator<dim,Accessor> &i) :
-               accessor (i.accessor) {}
+TriaRawIterator<Accessor>::TriaRawIterator (const TriaRawIterator<Accessor> &i)
+               :
+               accessor (i.accessor)
+{}
 
 
-template <int dim, typename Accessor>
+
+template <typename Accessor>
 inline
-TriaRawIterator<dim,Accessor>::TriaRawIterator (const Triangulation<dim> *parent,
-                                               const int                 level,
-                                               const int                 index,
-                                               const typename Accessor::AccessorData *local_data) :
-               accessor (parent, level, index, local_data) {}
+TriaRawIterator<Accessor>::
+TriaRawIterator (const Triangulation<Accessor::dimension,Accessor::space_dimension> *parent,
+                const int                 level,
+                const int                 index,
+                const typename Accessor::AccessorData *local_data)
+               :
+               accessor (parent, level, index, local_data)
+{}
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaRawIterator<dim,Accessor> &
-TriaRawIterator<dim,Accessor>::operator = (const TriaRawIterator<dim,Accessor> &i) {
+TriaRawIterator<Accessor> &
+TriaRawIterator<Accessor>::operator = (const TriaRawIterator<Accessor> &i)
+{
   accessor.copy_from (i.accessor);
   
   return *this;
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 bool
-TriaRawIterator<dim,Accessor>::operator == (const TriaRawIterator<dim,Accessor> &i) const {
+TriaRawIterator<Accessor>::operator == (const TriaRawIterator<Accessor> &i) const {
   return accessor == i.accessor;
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
 bool
-TriaRawIterator<dim,Accessor>::operator != (const TriaRawIterator<dim,Accessor> &i) const {
+TriaRawIterator<Accessor>::operator != (const TriaRawIterator<Accessor> &i) const {
                                   // Note that at times, there is a problem
                                   // with egcs 1.1 that makes it choose
                                   // the global STL operator != (which
@@ -88,22 +97,22 @@ TriaRawIterator<dim,Accessor>::operator != (const TriaRawIterator<dim,Accessor>
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaRawIterator<dim,Accessor>
-TriaRawIterator<dim,Accessor>::operator ++ (int) {
-  TriaRawIterator<dim,Accessor> tmp(*this);
+TriaRawIterator<Accessor>
+TriaRawIterator<Accessor>::operator ++ (int) {
+  TriaRawIterator<Accessor> tmp(*this);
   operator++ ();
   
   return tmp;
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaRawIterator<dim,Accessor>
-TriaRawIterator<dim,Accessor>::operator -- (int) {
-  TriaRawIterator<dim,Accessor> tmp(*this);
+TriaRawIterator<Accessor>
+TriaRawIterator<Accessor>::operator -- (int) {
+  TriaRawIterator<Accessor> tmp(*this);
   operator-- ();
   
   return tmp;
@@ -113,22 +122,24 @@ TriaRawIterator<dim,Accessor>::operator -- (int) {
 /*-----------------------  functions: TriaIterator ---------------*/
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor>::TriaIterator () :
-               TriaRawIterator<dim,Accessor> () {}
+TriaIterator<Accessor>::TriaIterator () :
+               TriaRawIterator<Accessor> () {}
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor>::TriaIterator (const TriaIterator<dim,Accessor> &i) :
-               TriaRawIterator<dim,Accessor> (static_cast<TriaRawIterator<dim,Accessor> >(i)) {}
+TriaIterator<Accessor>::TriaIterator (const TriaIterator<Accessor> &i)
+               :
+               TriaRawIterator<Accessor> (i.accessor) {}
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor>::TriaIterator (const TriaRawIterator<dim,Accessor> &i) :
-               TriaRawIterator<dim,Accessor> (i)
+TriaIterator<Accessor>::TriaIterator (const TriaRawIterator<Accessor> &i)
+               :
+               TriaRawIterator<Accessor> (i.accessor)
 {
 #ifdef DEBUG
                                   // do this like this, because:
@@ -144,13 +155,13 @@ TriaIterator<dim,Accessor>::TriaIterator (const TriaRawIterator<dim,Accessor> &i
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor>::TriaIterator (const Triangulation<dim> *parent,
+TriaIterator<Accessor>::TriaIterator (const Triangulation<Accessor::dimension,Accessor::space_dimension> *parent,
                                          const int                 level,
                                          const int                 index,
                                          const typename Accessor::AccessorData *local_data) :
-               TriaRawIterator<dim,Accessor> (parent, level, index, local_data)
+               TriaRawIterator<Accessor> (parent, level, index, local_data)
 {
 #ifdef DEBUG
                                   // do this like this, because:
@@ -166,19 +177,19 @@ TriaIterator<dim,Accessor>::TriaIterator (const Triangulation<dim> *parent,
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor> &
-TriaIterator<dim,Accessor>::operator = (const TriaIterator<dim,Accessor> &i) {
+TriaIterator<Accessor> &
+TriaIterator<Accessor>::operator = (const TriaIterator<Accessor> &i) {
   this->accessor.copy_from (i.accessor);
   return *this;
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor> &
-TriaIterator<dim,Accessor>::operator = (const TriaRawIterator<dim,Accessor> &i) {
+TriaIterator<Accessor> &
+TriaIterator<Accessor>::operator = (const TriaRawIterator<Accessor> &i) {
   this->accessor.copy_from (i.accessor);
 #ifdef DEBUG
                                   // do this like this, because:
@@ -195,10 +206,10 @@ TriaIterator<dim,Accessor>::operator = (const TriaRawIterator<dim,Accessor> &i)
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor> & TriaIterator<dim,Accessor>::operator ++ () {
-  while (TriaRawIterator<dim,Accessor>::operator++(),
+TriaIterator<Accessor> & TriaIterator<Accessor>::operator ++ () {
+  while (TriaRawIterator<Accessor>::operator++(),
         (this->state() == IteratorState::valid))
     if (this->accessor.used() == true)
       return *this;
@@ -206,21 +217,21 @@ TriaIterator<dim,Accessor> & TriaIterator<dim,Accessor>::operator ++ () {
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor>  TriaIterator<dim,Accessor>::operator ++ (int) {
-  TriaIterator<dim,Accessor> tmp(*this);
+TriaIterator<Accessor>  TriaIterator<Accessor>::operator ++ (int) {
+  TriaIterator<Accessor> tmp(*this);
   operator++ ();
   
   return tmp;
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor> &
-TriaIterator<dim,Accessor>::operator -- () {
-  while (TriaRawIterator<dim,Accessor>::operator--(),
+TriaIterator<Accessor> &
+TriaIterator<Accessor>::operator -- () {
+  while (TriaRawIterator<Accessor>::operator--(),
         (this->state() == IteratorState::valid))
     if (this->accessor.used() == true)
       return *this;
@@ -228,11 +239,11 @@ TriaIterator<dim,Accessor>::operator -- () {
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaIterator<dim,Accessor>
-TriaIterator<dim,Accessor>::operator -- (int) {
-  TriaIterator<dim,Accessor> tmp(*this);
+TriaIterator<Accessor>
+TriaIterator<Accessor>::operator -- (int) {
+  TriaIterator<Accessor> tmp(*this);
   operator-- ();
   
   return tmp;
@@ -242,22 +253,22 @@ TriaIterator<dim,Accessor>::operator -- (int) {
 /*-----------------------  functions: TriaActiveIterator ---------------*/
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor>::TriaActiveIterator () :
-               TriaIterator<dim,Accessor> () {}
+TriaActiveIterator<Accessor>::TriaActiveIterator () :
+               TriaIterator<Accessor> () {}
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaActiveIterator<dim,Accessor> &i) :
-               TriaIterator<dim,Accessor> (static_cast<TriaIterator<dim,Accessor> >(i)) {}
+TriaActiveIterator<Accessor>::TriaActiveIterator (const TriaActiveIterator<Accessor> &i) :
+               TriaIterator<Accessor> (static_cast<TriaIterator<Accessor> >(i)) {}
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaRawIterator<dim,Accessor> &i) :
-               TriaIterator<dim,Accessor> (i)
+TriaActiveIterator<Accessor>::TriaActiveIterator (const TriaRawIterator<Accessor> &i) :
+               TriaIterator<Accessor> (i)
 {
 #ifdef DEBUG
                                   // do this like this, because:
@@ -273,10 +284,10 @@ TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaRawIterator<dim,
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaIterator<dim,Accessor> &i) :
-               TriaIterator<dim,Accessor> (i)
+TriaActiveIterator<Accessor>::TriaActiveIterator (const TriaIterator<Accessor> &i) :
+               TriaIterator<Accessor> (i)
 {
 #ifdef DEBUG
                                   // do this like this, because:
@@ -292,13 +303,13 @@ TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const TriaIterator<dim,Acc
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const Triangulation<dim> *parent,
+TriaActiveIterator<Accessor>::TriaActiveIterator (const Triangulation<Accessor::dimension,Accessor::space_dimension> *parent,
                                                      const int                 level,
                                                      const int                 index,
                                                      const typename Accessor::AccessorData *local_data) :
-               TriaIterator<dim,Accessor> (parent, level, index, local_data)
+               TriaIterator<Accessor> (parent, level, index, local_data)
 {
 #ifdef DEBUG
                                   // do this like this, because:
@@ -314,19 +325,19 @@ TriaActiveIterator<dim,Accessor>::TriaActiveIterator (const Triangulation<dim> *
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor> &
-TriaActiveIterator<dim,Accessor>::operator = (const TriaActiveIterator<dim,Accessor> &i) {
+TriaActiveIterator<Accessor> &
+TriaActiveIterator<Accessor>::operator = (const TriaActiveIterator<Accessor> &i) {
   this->accessor.copy_from (i.accessor);
   return *this;
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor> &
-TriaActiveIterator<dim,Accessor>::operator = (const TriaRawIterator<dim,Accessor> &i) {
+TriaActiveIterator<Accessor> &
+TriaActiveIterator<Accessor>::operator = (const TriaRawIterator<Accessor> &i) {
   this->accessor.copy_from (i.accessor);
 #ifdef DEBUG
                                   // do this like this, because:
@@ -343,10 +354,10 @@ TriaActiveIterator<dim,Accessor>::operator = (const TriaRawIterator<dim,Accessor
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor> &
-TriaActiveIterator<dim,Accessor>::operator = (const TriaIterator<dim,Accessor> &i) {
+TriaActiveIterator<Accessor> &
+TriaActiveIterator<Accessor>::operator = (const TriaIterator<Accessor> &i) {
   this->accessor.copy_from (i.accessor);
 #ifdef DEBUG
                                   // do this like this, because:
@@ -363,11 +374,11 @@ TriaActiveIterator<dim,Accessor>::operator = (const TriaIterator<dim,Accessor> &
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor> &
-TriaActiveIterator<dim,Accessor>::operator ++ () {
-  while (TriaIterator<dim,Accessor>::operator++(),
+TriaActiveIterator<Accessor> &
+TriaActiveIterator<Accessor>::operator ++ () {
+  while (TriaIterator<Accessor>::operator++(),
         (this->state() == IteratorState::valid))
     if (this->accessor.has_children() == false)
       return *this;
@@ -375,22 +386,22 @@ TriaActiveIterator<dim,Accessor>::operator ++ () {
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor>
-TriaActiveIterator<dim,Accessor>::operator ++ (int) {
-  TriaActiveIterator<dim,Accessor> tmp(*this);
+TriaActiveIterator<Accessor>
+TriaActiveIterator<Accessor>::operator ++ (int) {
+  TriaActiveIterator<Accessor> tmp(*this);
   operator++ ();
   
   return tmp;
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor> &
-TriaActiveIterator<dim,Accessor>::operator -- () {
-  while (TriaIterator<dim,Accessor>::operator--(),
+TriaActiveIterator<Accessor> &
+TriaActiveIterator<Accessor>::operator -- () {
+  while (TriaIterator<Accessor>::operator--(),
         (this->state() == IteratorState::valid))
     if (this->accessor.has_children() == false)
       return *this;
@@ -398,10 +409,10 @@ TriaActiveIterator<dim,Accessor>::operator -- () {
 }
 
 
-template <int dim, typename Accessor>
+template <typename Accessor>
 inline
-TriaActiveIterator<dim,Accessor> TriaActiveIterator<dim,Accessor>::operator -- (int) {
-  TriaActiveIterator<dim,Accessor> tmp(*this);
+TriaActiveIterator<Accessor> TriaActiveIterator<Accessor>::operator -- (int) {
+  TriaActiveIterator<Accessor> tmp(*this);
   operator-- ();
   
   return tmp;
index 8d9dcc13cfedd351d6a9f9a41ab9bb92496dbd37..6319878ae2a250013961a0e69c013f888d397260 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class CellAccessor;
-template <int, int> class TriaAccessor;
-template <int dim> class TriaAccessor<dim,dim>;
-template <int, int> class TriaObjectAccessor;
-template <int dim>  class TriaObjectAccessor<0, dim>;
-template <int dim>  class TriaObjectAccessor<1, dim>;
-template <int dim>  class TriaObjectAccessor<2, dim>;
-template <int dim>  class TriaObjectAccessor<3, dim>;
-template <int dim, typename Accessor> class TriaRawIterator;
-template <int dim, typename Accessor> class TriaIterator;
-template <int dim, typename Accessor> class TriaActiveIterator;
+template <int dim, int spacedim> class CellAccessor;
+template <int, int, int> class TriaAccessorBase;
+template <int dim, int spacedim> class TriaAccessorBase<dim,dim,spacedim>;
+template <int, int, int> class InvalidAccessor;
+template <int, int, int> class TriaAccessor;
+template <int dim, int spacedim>  class TriaAccessor<0, dim, spacedim>;
+template <typename Accessor> class TriaRawIterator;
+template <typename Accessor> class TriaIterator;
+template <typename Accessor> class TriaActiveIterator;
 
 namespace internal 
 {
   namespace Triangulation
   {
-/**
- * Definition of the iterator types of the Triangulation.
- *
- * @note The actual definitions used are defined in specializations of
- * this class. The template is just here for documentation and shows a
- * generic case, while it is clear that for instance #quad_iterator is
- * of no use in one dimension.
- *
- * @author Wolfgang Bangerth, Guido Kanschat, 1998, 2006
- */
-    template <int dim>
-    struct Iterators
-    {
-                                         /// Iterate on raw lines
-        typedef TriaRawIterator<dim,TriaObjectAccessor<1, dim> > raw_line_iterator;
-                                         /// Iterate on raw lines
-        typedef TriaIterator<dim,TriaObjectAccessor<1, dim> > line_iterator;
-                                         /// Iterate on raw lines
-        typedef TriaActiveIterator<dim,TriaObjectAccessor<1, dim> > active_line_iterator;
-    
-                                         /// Iterate on raw quadrilaterals
-        typedef TriaRawIterator<dim,TriaObjectAccessor<2, dim> > raw_quad_iterator;
-                                         /// Iterate on quadrilaterals
-        typedef TriaIterator<dim,TriaObjectAccessor<2, dim> > quad_iterator;
-                                         /// Iterate on active quadrilaterals
-        typedef TriaActiveIterator<dim,TriaObjectAccessor<2, dim> > active_quad_iterator;
-
-                                         /// Iterate on raw hexahedra
-        typedef TriaRawIterator<dim,TriaObjectAccessor<3, dim> > raw_hex_iterator;
-                                         /// Iterate on hexahedra
-        typedef TriaIterator<dim,TriaObjectAccessor<3, dim> > hex_iterator;
-                                         /// Iterate on active hexahedra
-        typedef TriaActiveIterator<dim,TriaObjectAccessor<3, dim> > active_hex_iterator;
-
-                                         /// Iterate on raw cells
-        typedef TriaRawIterator<dim,CellAccessor<dim> > raw_cell_iterator;
-                                         /// Iterate on cells
-        typedef TriaIterator<dim,CellAccessor<dim> > cell_iterator;
-                                         /// Iterate on active cells
-        typedef TriaActiveIterator<dim,CellAccessor<dim> > active_cell_iterator;
-
-                                         /// Iterate on raw faces
-        typedef TriaRawIterator<dim,TriaObjectAccessor<dim-1, dim> > raw_face_iterator;
-                                         /// Iterate on faces
-        typedef TriaIterator<dim,TriaObjectAccessor<dim-1, dim> > face_iterator;
-                                         /// Iterate on active faces
-        typedef TriaActiveIterator<dim,TriaObjectAccessor<dim-1, dim> > active_face_iterator;
-    };
-
-
+    template <int dim, int spacedim>
+    struct Iterators;
 
 /**
  *  This class implements some types which differ between the dimensions.
- *  These are the declararions for the 1D case only.
+ *  These are the declararions for the 1D case only. See the @ref Iterators
+ *  module for more information.
  *
  *  A @p line_iterator is typdef'd to an iterator operating on the
  *  @p lines member variable of a <tt>Triangulation<1></tt> object. An
@@ -103,9 +54,9 @@ namespace internal
  *
  *  To enable the declaration of @p begin_quad and the like in
  *  <tt>Triangulation<1></tt>, the @p quad_iterators are declared as
- *  <tt>void *</tt>. Thus these types exist, but are useless and will
- *  certainly make any involuntary use visible. The same holds
- *  for hexahedron iterators.
+ *  iterators over InvalidAccessor. Thus these types exist, but
+ *  are useless and will certainly make any involuntary use
+ *  visible. The same holds for hexahedron iterators.
  *
  *  The same applies for the @p face_iterator types, since lines
  *  have no substructures apart from vertices, which are handled in
@@ -113,35 +64,36 @@ namespace internal
  *
  * @author Wolfgang Bangerth, 1998
  */
-    template <>
-    struct Iterators<1>
+    template <int spacedim>
+    struct Iterators<1,spacedim>
     {
-        typedef TriaRawIterator<1,CellAccessor<1> >    raw_line_iterator;
-        typedef TriaIterator<1,CellAccessor<1> >       line_iterator;
-        typedef TriaActiveIterator<1,CellAccessor<1> > active_line_iterator;
+        typedef TriaRawIterator   <CellAccessor<1,spacedim> > raw_line_iterator;
+        typedef TriaIterator      <CellAccessor<1,spacedim> > line_iterator;
+        typedef TriaActiveIterator<CellAccessor<1,spacedim> > active_line_iterator;
 
-        typedef void * raw_quad_iterator;
-        typedef void * quad_iterator;
-        typedef void * active_quad_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<2,1,spacedim> > raw_quad_iterator;
+        typedef TriaIterator      <InvalidAccessor<2,1,spacedim> > quad_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<2,1,spacedim> > active_quad_iterator;
 
-        typedef void * raw_hex_iterator;
-        typedef void * hex_iterator;
-        typedef void * active_hex_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<3,1,spacedim> > raw_hex_iterator;
+        typedef TriaIterator      <InvalidAccessor<3,1,spacedim> > hex_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<3,1,spacedim> > active_hex_iterator;
 
         typedef raw_line_iterator    raw_cell_iterator;
         typedef line_iterator        cell_iterator;
         typedef active_line_iterator active_cell_iterator;
 
-        typedef void * raw_face_iterator;
-        typedef void * face_iterator;
-        typedef void * active_face_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<0,1,spacedim> > raw_face_iterator;
+        typedef TriaIterator      <InvalidAccessor<0,1,spacedim> > face_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<0,1,spacedim> > active_face_iterator;
     };
 
 
 
 /**
  *  This class implements some types which differ between the dimensions.
- *  These are the declararions for the 2D case only.
+ *  These are the declararions for the 2D case only. See the @ref Iterators
+ *  module for more information.
  *
  *  A @p line_iterator is typdef'd to an iterator operating on the
  *  @p lines member variable of a <tt>Triangulation<2></tt> object. An
@@ -157,8 +109,8 @@ namespace internal
  *  
  *  To enable the declaration of @p begin_hex and the like in
  *  <tt>Triangulation<[12]></tt>, the @p hex_iterators are declared as
- *  <tt>void *</tt>. Thus these types exist, but are useless and will
- *  certainly make any involuntary use visible.
+ *  iterators over InvalidAccessor. Thus these types exist, but
+ *  are useless and will certainly make any involuntary use visible.
  *
  *  Since we are in two dimension, the following identities are declared:
  *  @verbatim
@@ -173,20 +125,20 @@ namespace internal
  *
  * @author Wolfgang Bangerth, 1998
  */
-    template <>
-    struct Iterators<2>
+    template <int spacedim>
+    struct Iterators<2,spacedim>
     {
-        typedef TriaRawIterator<2,TriaObjectAccessor<1, 2> >    raw_line_iterator;
-        typedef TriaIterator<2,TriaObjectAccessor<1, 2> >       line_iterator;
-        typedef TriaActiveIterator<2,TriaObjectAccessor<1, 2> > active_line_iterator;
+        typedef TriaRawIterator   <TriaAccessor<1, 2, spacedim> > raw_line_iterator;
+        typedef TriaIterator      <TriaAccessor<1, 2, spacedim> > line_iterator;
+        typedef TriaActiveIterator<TriaAccessor<1, 2, spacedim> > active_line_iterator;
     
-        typedef TriaRawIterator<2,CellAccessor<2> >    raw_quad_iterator;
-        typedef TriaIterator<2,CellAccessor<2> >       quad_iterator;
-        typedef TriaActiveIterator<2,CellAccessor<2> > active_quad_iterator;
+        typedef TriaRawIterator   <CellAccessor<2, spacedim> > raw_quad_iterator;
+        typedef TriaIterator      <CellAccessor<2, spacedim> > quad_iterator;
+        typedef TriaActiveIterator<CellAccessor<2, spacedim> > active_quad_iterator;
 
-        typedef void * raw_hex_iterator;
-        typedef void * hex_iterator;
-        typedef void * active_hex_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<3,2,spacedim> > raw_hex_iterator;
+        typedef TriaIterator      <InvalidAccessor<3,2,spacedim> > hex_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<3,2,spacedim> > active_hex_iterator;
 
         typedef raw_quad_iterator    raw_cell_iterator;
         typedef quad_iterator        cell_iterator;
@@ -198,10 +150,10 @@ namespace internal
     };
 
 
-
 /**
  *  This class implements some types which differ between the dimensions.
- *  These are the declararions for the 3D case only.
+ *  These are the declararions for the 3D case only. See the @ref Iterators
+ *  module for more information.
  *
  *  For the declarations of the data types, more or less the same holds
  *  as for lower dimensions (see <tt>Iterators<[12]></tt>). The
@@ -218,20 +170,20 @@ namespace internal
  *
  * @author Wolfgang Bangerth, 1998
  */
-    template <>
-    struct Iterators<3>
+    template <int spacedim>
+    struct Iterators<3,spacedim>
     {
-        typedef TriaRawIterator<3,TriaObjectAccessor<1, 3> >    raw_line_iterator;
-        typedef TriaIterator<3,TriaObjectAccessor<1, 3> >       line_iterator;
-        typedef TriaActiveIterator<3,TriaObjectAccessor<1, 3> > active_line_iterator;
+        typedef TriaRawIterator   <TriaAccessor<1, 3, spacedim> > raw_line_iterator;
+        typedef TriaIterator      <TriaAccessor<1, 3, spacedim> > line_iterator;
+        typedef TriaActiveIterator<TriaAccessor<1, 3, spacedim> > active_line_iterator;
     
-        typedef TriaRawIterator<3,TriaObjectAccessor<2, 3> >    raw_quad_iterator;
-        typedef TriaIterator<3,TriaObjectAccessor<2, 3> >       quad_iterator;
-        typedef TriaActiveIterator<3,TriaObjectAccessor<2, 3> > active_quad_iterator;
+        typedef TriaRawIterator   <TriaAccessor<2, 3, spacedim> > raw_quad_iterator;
+        typedef TriaIterator      <TriaAccessor<2, 3, spacedim> > quad_iterator;
+        typedef TriaActiveIterator<TriaAccessor<2, 3, spacedim> > active_quad_iterator;
 
-        typedef TriaRawIterator<3,CellAccessor<3> >    raw_hex_iterator;
-        typedef TriaIterator<3,CellAccessor<3> >       hex_iterator;
-        typedef TriaActiveIterator<3,CellAccessor<3> > active_hex_iterator;
+        typedef TriaRawIterator   <CellAccessor<3, spacedim> > raw_hex_iterator;
+        typedef TriaIterator      <CellAccessor<3, spacedim> > hex_iterator;
+        typedef TriaActiveIterator<CellAccessor<3, spacedim> > active_hex_iterator;
 
         typedef raw_hex_iterator    raw_cell_iterator;
         typedef hex_iterator        cell_iterator;
index 31a591e48d0b92b20457b27090258e3b766cca1e..e6860dbca4f9c26d111fc51507a62701bc85a266 100644 (file)
@@ -29,7 +29,7 @@ DEAL_II_NAMESPACE_OPEN
 // declares mainly additional data. This would have to be changed in case of a
 // partial specialization.
 
-template <int dim> class Triangulation;
+template <int dim, int spacedim> class Triangulation;
 
 
 namespace internal
@@ -79,7 +79,7 @@ namespace internal
                                          *  stored in this list. An object is
                                          *  called active if it has no
                                          *  children. The function
-                                         *  TriaAccessor::has_children()
+                                         *  TriaAccessorBase::has_children()
                                          *  tests for this.
                                          */
        std::vector<int>  children;
@@ -178,8 +178,8 @@ namespace internal
                                          * <code>G=TriaObject<1>
                                          * </code>.
                                          */
-       template <int dim>
-       typename dealii::Triangulation<dim>::raw_line_iterator next_free_single_line (const dealii::Triangulation<dim> &tria);
+       template <int dim, int spacedim>
+       typename dealii::Triangulation<dim,spacedim>::raw_line_iterator next_free_single_line (const dealii::Triangulation<dim,spacedim> &tria);
 
                                         /**
                                          * Return an iterator to the
@@ -188,8 +188,8 @@ namespace internal
                                          * for <code>G=TriaObject<1>
                                          * </code>.
                                          */
-       template <int dim>
-       typename dealii::Triangulation<dim>::raw_line_iterator next_free_pair_line (const dealii::Triangulation<dim> &tria);
+       template <int dim, int spacedim>
+       typename dealii::Triangulation<dim,spacedim>::raw_line_iterator next_free_pair_line (const dealii::Triangulation<dim,spacedim> &tria);
        
                                         /**
                                          * Return an iterator to the
@@ -199,8 +199,8 @@ namespace internal
                                          * <code>G=TriaObject@<2@>
                                          * </code>.
                                          */
-       template <int dim>
-       typename dealii::Triangulation<dim>::raw_quad_iterator next_free_single_quad (const dealii::Triangulation<dim> &tria);
+       template <int dim, int spacedim>
+       typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator next_free_single_quad (const dealii::Triangulation<dim,spacedim> &tria);
 
                                         /**
                                          * Return an iterator to the
@@ -209,8 +209,8 @@ namespace internal
                                          * for <code>G=TriaObject@<2@>
                                          * </code>.
                                          */
-       template <int dim>
-       typename dealii::Triangulation<dim>::raw_quad_iterator next_free_pair_quad (const dealii::Triangulation<dim> &tria);
+       template <int dim, int spacedim>
+       typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator next_free_pair_quad (const dealii::Triangulation<dim,spacedim> &tria);
        
                                         /**
                                          * Return an iterator to the
@@ -219,8 +219,8 @@ namespace internal
                                          * for
                                          * <code>G=Hexahedron</code>.
                                          */
-       template <int dim>
-       typename dealii::Triangulation<dim>::raw_hex_iterator next_free_hex (const dealii::Triangulation<dim> &tria,
+       template <int dim, int spacedim>
+       typename dealii::Triangulation<dim,spacedim>::raw_hex_iterator next_free_hex (const dealii::Triangulation<dim,spacedim> &tria,
                                                                             const unsigned int               level);
 
                                         /**
index 0dad67d400d4f4f49b89682898b440be0d9aa91c..be6d12c8af905a84fae363d40026c7780ada5ca1 100644 (file)
@@ -25,7 +25,7 @@ DEAL_II_NAMESPACE_OPEN
 
 namespace hp
 {
-  template <int dim>
+  template <int dim, int spacedim>
   class FECollection;
 }
 
index b2a495dae5254b36766f05ce05dc5bc03f4ac64f..992fd68a5dc0c87d5be98d01606445e63fc72cb9 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -48,13 +48,16 @@ namespace hp
  * Manage the distribution and numbering of the degrees of freedom for
  * hp-FEM algorithms.
  *
+ * This class has not yet been implemented for the use in the codimension
+ * one case (<tt>spacedim != dim </tt>).
+ *
  * @ingroup hp
  */
-  template <int dim>
+  template <int dim, int spacedim=dim>
   class DoFHandler : public Subscriptor,
-                     protected Triangulation<dim>::RefinementListener
+                     protected Triangulation<dim,spacedim>::RefinementListener
   {
-      typedef internal::DoFHandler::Iterators<DoFHandler<dim> > IteratorSelector;
+      typedef internal::DoFHandler::Iterators<DoFHandler<dim,spacedim> > IteratorSelector;
     public:
       typedef typename IteratorSelector::raw_line_iterator raw_line_iterator;
       typedef typename IteratorSelector::line_iterator line_iterator;
@@ -80,13 +83,19 @@ namespace hp
                                         * Alias the @p FunctionMap type
                                         * declared elsewhere.
                                         */
-      typedef typename FunctionMap<dim>::type FunctionMap;
+      typedef typename FunctionMap<spacedim>::type FunctionMap;
     
                                        /**
                                         * Make the dimension available
                                         * in function templates.
                                         */
       static const unsigned int dimension = dim;
+
+                                       /**
+                                        * Make the space dimension available
+                                        * in function templates.
+                                        */
+      static const unsigned int space_dimension = spacedim;
     
                                        /**
                                         * When the arrays holding the
@@ -134,7 +143,7 @@ namespace hp
                                         * Constructor. Take @p tria as the
                                         * triangulation to work on.
                                         */
-      DoFHandler (const Triangulation<dim> &tria);
+      DoFHandler (const Triangulation<dim,spacedim> &tria);
     
                                        /**
                                         * Destructor.
@@ -160,7 +169,7 @@ namespace hp
                                         * releases the lock of this
                                         * object to the finite element.
                                         */
-      virtual void distribute_dofs (const hp::FECollection<dim> &fe);
+      virtual void distribute_dofs (const hp::FECollection<dim,spacedim> &fe);
 
                                        /**
                                         * Clear all data of this object and
@@ -799,13 +808,13 @@ namespace hp
                                         * objects that are used by this
                                         * @p DoFHandler.
                                         */
-      const hp::FECollection<dim> & get_fe () const;
+      const hp::FECollection<dim,spacedim> & get_fe () const;
 
                                        /**
                                         * Return a constant reference to the
                                         * triangulation underlying this object.
                                         */
-      const Triangulation<dim> & get_tria () const;
+      const Triangulation<dim,spacedim> & get_tria () const;
     
                                        /**
                                         * Determine an estimate for the
@@ -866,6 +875,25 @@ namespace hp
                      << "The mesh contains a cell with an active_fe_index of "
                      << arg1 << ", but the finite element collection only has "
                      << arg2 << " elements");
+                                      /**
+                                       *  Exception
+                                       */
+      DeclException1 (ExcInvalidLevel,
+                     int,
+                     << "The given level " << arg1
+                     << " is not in the valid range!");
+                                      /**
+                                       * Exception
+                                       */
+      DeclException0 (ExcFacesHaveNoLevel);
+                                      /**
+                                       * The triangulation level you
+                                       * accessed is empty.
+                                       */
+      DeclException1 (ExcEmptyLevel,
+                     int,
+                     << "You tried to do something on level " << arg1
+                     << ", but this level is empty.");
       
     protected:
     
@@ -873,7 +901,7 @@ namespace hp
                                         * Address of the triangulation to
                                         * work on.
                                         */
-      SmartPointer<const Triangulation<dim> > tria;
+      SmartPointer<const Triangulation<dim,spacedim> > tria;
 
                                        /**
                                         * Store a pointer to the finite
@@ -890,7 +918,7 @@ namespace hp
                                         * (this clears all data of this
                                         * object as well, though).
                                         */
-      SmartPointer<const hp::FECollection<dim> > finite_elements;
+      SmartPointer<const hp::FECollection<dim,spacedim> > finite_elements;
 
     private:
 
@@ -916,48 +944,10 @@ namespace hp
                                         */
       DoFHandler & operator = (const DoFHandler &);
 
-                                       /**
-                                        * Reserve enough space in the 
-                                        * <tt>levels[]</tt> objects to store the
-                                        * numbers of the degrees of freedom
-                                        * needed for the given element. The
-                                        * given element is that one which
-                                        * was selected when calling
-                                        * @p distribute_dofs the last time.
-                                        */
-      void reserve_space ();
-
-                                      /**
-                                       * Do that part of reserving
-                                       * space that pertains to
-                                       * vertices, since this is the
-                                       * same in all space
-                                       * dimensions.
-                                       */
-      void reserve_space_vertices ();
-      
                                        /**
                                         * Free all used memory.
                                         */
       void clear_space ();
-    
-                                       /**
-                                        * Distribute dofs on the given cell,
-                                        * with new dofs starting with index
-                                        * @p next_free_dof. Return the next
-                                        * unused index number. The finite
-                                        * element used is the one given to
-                                        * @p distribute_dofs, which is copied
-                                        * to @p selected_fe.
-                                        *
-                                        * This function is excluded from the
-                                        * @p distribute_dofs function since
-                                        * it can not be implemented dimension
-                                        * independent.
-                                        */
-      unsigned int distribute_dofs_on_cell (active_cell_iterator &cell,
-                                            unsigned int next_free_dof);
-
 
                                        /**
                                         *  Create default tables for
@@ -987,8 +977,8 @@ namespace hp
                                         *  active_fe_fields during the
                                         *  spatial refinement.
                                         */
-      virtual void pre_refinement_notification (const Triangulation<dim> &tria);
-      virtual void post_refinement_notification (const Triangulation<dim> &tria);
+      virtual void pre_refinement_notification (const Triangulation<dim,spacedim> &tria);
+      virtual void post_refinement_notification (const Triangulation<dim,spacedim> &tria);
 
                                       /**
                                        * Set the @p local_index-th
@@ -1262,16 +1252,21 @@ namespace hp
                                         * refinement.
                                         */
       std::vector<std::vector<bool> *> has_children;
-                                     
-                                       /**
-                                        * Make accessor objects friends.
-                                        */
-      template <int structdim, class DH> friend class dealii::DoFAccessor;
 
+                                      /**
+                                       * Forward declaration of a class
+                                       * into which we put significant
+                                       * parts of the implementation.
+                                       *
+                                       * See the .cc file for more
+                                       * information.
+                                       */
+      struct Implementation;
+      
                                        /**
                                         * Make accessor objects friends.
                                         */
-      template <int dim1, class DH> friend class dealii::DoFObjectAccessor;
+      template <int structdim, class DH> friend class dealii::DoFAccessor;
 
                                        /**
                                         * Make accessor objects friends.
@@ -1288,6 +1283,7 @@ namespace hp
       template <int> friend class internal::hp::DoFLevel;
       template <int> friend class internal::hp::DoFObjects;
 
+      friend class Triangulation<dim,spacedim>::Implementation;
   };
 
 
@@ -1300,114 +1296,14 @@ namespace hp
   template <> unsigned int DoFHandler<1>::n_boundary_dofs () const;
   template <> unsigned int DoFHandler<1>::n_boundary_dofs (const FunctionMap &) const;
   template <> unsigned int DoFHandler<1>::n_boundary_dofs (const std::set<unsigned char> &) const;
-  template <> unsigned int DoFHandler<1>::max_couplings_between_dofs () const;
-  template <> unsigned int DoFHandler<1>::max_couplings_between_boundary_dofs () const;
-  template <> unsigned int DoFHandler<2>::max_couplings_between_dofs () const;
-  template <> unsigned int DoFHandler<2>::max_couplings_between_boundary_dofs () const;
-  template <> unsigned int DoFHandler<3>::max_couplings_between_dofs () const;
-  template <> unsigned int DoFHandler<3>::max_couplings_between_boundary_dofs () const;
-
-  template <> DoFHandler<1>::raw_cell_iterator DoFHandler<1>::begin_raw (const unsigned int level) const;
-  template <> DoFHandler<1>::cell_iterator DoFHandler<1>::begin (const unsigned int level) const;
-  template <> DoFHandler<1>::active_cell_iterator DoFHandler<1>::begin_active (const unsigned int level) const;
-  template <> DoFHandler<1>::raw_cell_iterator DoFHandler<1>::end () const;
-  template <> DoFHandler<1>::raw_cell_iterator DoFHandler<1>::last_raw () const;
-  template <> DoFHandler<1>::raw_cell_iterator DoFHandler<1>::last_raw (const unsigned int level) const;
-  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;
-  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>::face_iterator DoFHandler<1>::last_face () const;
-  template <> DoFHandler<1>::active_face_iterator DoFHandler<1>::last_active_face () 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;
-  template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::end_quad () const;
-  template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::last_raw_quad (const unsigned int) const;
-  template <> DoFHandler<1>::quad_iterator DoFHandler<1>::last_quad (const unsigned int) const;
-  template <> DoFHandler<1>::active_quad_iterator DoFHandler<1>::last_active_quad (const unsigned int) const;
-  template <> DoFHandler<1>::raw_quad_iterator DoFHandler<1>::last_raw_quad () const;
-  template <> DoFHandler<1>::quad_iterator DoFHandler<1>::last_quad () const;
-  template <> DoFHandler<1>::active_quad_iterator DoFHandler<1>::last_active_quad () const;
-  template <> DoFHandler<1>::raw_hex_iterator DoFHandler<1>::begin_raw_hex (const unsigned int) const;
-  template <> DoFHandler<1>::hex_iterator DoFHandler<1>::begin_hex (const unsigned int) const;
-  template <> DoFHandler<1>::active_hex_iterator DoFHandler<1>::begin_active_hex (const unsigned int) const;
-  template <> DoFHandler<1>::raw_hex_iterator DoFHandler<1>::end_hex () const;
-  template <> DoFHandler<1>::raw_hex_iterator DoFHandler<1>::last_raw_hex (const unsigned int) const;
-  template <> DoFHandler<1>::raw_hex_iterator DoFHandler<1>::last_raw_hex () const;
-  template <> DoFHandler<1>::hex_iterator DoFHandler<1>::last_hex (const unsigned int) const;
-  template <> DoFHandler<1>::hex_iterator DoFHandler<1>::last_hex () const;
-  template <> DoFHandler<1>::active_hex_iterator DoFHandler<1>::last_active_hex (const unsigned int) const;
-  template <> DoFHandler<1>::active_hex_iterator DoFHandler<1>::last_active_hex () const;
-  template <> DoFHandler<2>::raw_cell_iterator DoFHandler<2>::begin_raw (const unsigned int level) const;
-  template <> DoFHandler<2>::cell_iterator DoFHandler<2>::begin (const unsigned int level) const;
-  template <> DoFHandler<2>::active_cell_iterator DoFHandler<2>::begin_active (const unsigned int level) const;
-  template <> DoFHandler<2>::raw_cell_iterator DoFHandler<2>::end () const;
-  template <> DoFHandler<2>::raw_cell_iterator DoFHandler<2>::last_raw () const;
-  template <> DoFHandler<2>::raw_cell_iterator DoFHandler<2>::last_raw (const unsigned int level) const;
-  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;
-  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>::face_iterator DoFHandler<2>::last_face () const;
-  template <> DoFHandler<2>::active_face_iterator DoFHandler<2>::last_active_face () 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;
-  template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::end_hex () const;
-  template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::last_raw_hex (const unsigned int) const;
-  template <> DoFHandler<2>::raw_hex_iterator DoFHandler<2>::last_raw_hex () const;
-  template <> DoFHandler<2>::hex_iterator DoFHandler<2>::last_hex (const unsigned int) const;
-  template <> DoFHandler<2>::hex_iterator DoFHandler<2>::last_hex () const;
-  template <> DoFHandler<2>::active_hex_iterator DoFHandler<2>::last_active_hex (const unsigned int) const;
-  template <> DoFHandler<2>::active_hex_iterator DoFHandler<2>::last_active_hex () const;
-  template <> DoFHandler<3>::raw_cell_iterator DoFHandler<3>::begin_raw (const unsigned int level) const;
-  template <> DoFHandler<3>::cell_iterator DoFHandler<3>::begin (const unsigned int level) const;
-  template <> DoFHandler<3>::active_cell_iterator DoFHandler<3>::begin_active (const unsigned int level) const;
-  template <> DoFHandler<3>::raw_cell_iterator DoFHandler<3>::end () const;
-  template <> DoFHandler<3>::raw_cell_iterator DoFHandler<3>::last_raw () const;
-  template <> DoFHandler<3>::raw_cell_iterator DoFHandler<3>::last_raw (const unsigned int level) const;
-  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;
-  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>::face_iterator DoFHandler<3>::last_face () const;
-  template <> DoFHandler<3>::active_face_iterator DoFHandler<3>::last_active_face () const;
-
-  template <>
-  unsigned int DoFHandler<1>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                                         unsigned int          next_free_dof);
-  template <>
-  unsigned int DoFHandler<2>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                                         unsigned int          next_free_dof);
-  template <>
-  unsigned int DoFHandler<3>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                                         unsigned int          next_free_dof);
-  template <> void DoFHandler<1>::reserve_space ();
-  template <> void DoFHandler<2>::reserve_space ();
-  template <> void DoFHandler<3>::reserve_space ();
+
 
 /* ----------------------- Inline functions ---------------------------------- */
 
-  template <int dim>
+  template<int dim, int spacedim>
   inline
   unsigned int
-  DoFHandler<dim>::n_dofs () const
+  DoFHandler<dim,spacedim>::n_dofs () const
   {
     Assert (finite_elements != 0,
            ExcMessage ("No finite element collection is associated with "
@@ -1417,10 +1313,10 @@ namespace hp
 
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   inline
-  const hp::FECollection<dim> &
-  DoFHandler<dim>::get_fe () const
+  const hp::FECollection<dim,spacedim> &
+  DoFHandler<dim,spacedim>::get_fe () const
   {
     Assert (finite_elements != 0,
            ExcMessage ("No finite element collection is associated with "
@@ -1429,25 +1325,25 @@ namespace hp
   }
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   inline
-  const Triangulation<dim> &
-  DoFHandler<dim>::get_tria () const
+  const Triangulation<dim,spacedim> &
+  DoFHandler<dim,spacedim>::get_tria () const
   {
     return *tria;
   }
 
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   inline
   unsigned int
-  DoFHandler<dim>::
+  DoFHandler<dim,spacedim>::
   get_vertex_dof_index (const unsigned int vertex_index,
                        const unsigned int fe_index,
                        const unsigned int local_index) const
   {
-    Assert (fe_index != dealii::hp::DoFHandler<dim>::default_fe_index,
+    Assert ( (fe_index != dealii::hp::DoFHandler<dim,spacedim>::default_fe_index),
            ExcMessage ("You need to specify a FE index when working "
                        "with hp DoFHandlers"));
     Assert (finite_elements != 0,
@@ -1491,16 +1387,16 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   inline
   void
-  DoFHandler<dim>::
+  DoFHandler<dim,spacedim>::
   set_vertex_dof_index (const unsigned int vertex_index,
                        const unsigned int fe_index,
                        const unsigned int local_index,
                        const unsigned int global_index)
   {
-    Assert (fe_index != dealii::hp::DoFHandler<dim>::default_fe_index,
+    Assert ( (fe_index != dealii::hp::DoFHandler<dim,spacedim>::default_fe_index),
            ExcMessage ("You need to specify a FE index when working "
                        "with hp DoFHandlers"));
     Assert (finite_elements != 0,
@@ -1547,10 +1443,10 @@ namespace hp
 
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   inline
   unsigned int
-  DoFHandler<dim>::
+  DoFHandler<dim,spacedim>::
   n_active_vertex_fe_indices (const unsigned int vertex_index) const
   {
     Assert (finite_elements != 0,
@@ -1589,10 +1485,10 @@ namespace hp
 
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   inline
   unsigned int
-  DoFHandler<dim>::
+  DoFHandler<dim,spacedim>::
   nth_active_vertex_fe_index (const unsigned int vertex_index,
                              const unsigned int n) const
   {
@@ -1639,14 +1535,14 @@ namespace hp
   
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   inline
   bool
-  DoFHandler<dim>::
+  DoFHandler<dim,spacedim>::
   fe_is_active_on_vertex (const unsigned int vertex_index,
                          const unsigned int fe_index) const
   {
-    Assert (fe_index != dealii::hp::DoFHandler<dim>::default_fe_index,
+    Assert ( (fe_index != dealii::hp::DoFHandler<dim,spacedim>::default_fe_index),
            ExcMessage ("You need to specify a FE index when working "
                        "with hp DoFHandlers"));
     Assert (finite_elements != 0,
index da45c679a406e0d259b9b9bd2f8e83132fa7c0f5..5eff463c14510a4ef71db1ec0ff61dd0e5b3d01d 100644 (file)
@@ -180,7 +180,7 @@ namespace internal
                                           * resize arrays as
                                           * necessary.
                                           */
-        template <int> friend class dealii::hp::DoFHandler;
+        template <int, int> friend class dealii::hp::DoFHandler;
     };
 
 
@@ -214,7 +214,7 @@ namespace internal
                                           * resize arrays as
                                           * necessary.
                                           */
-        template <int> friend class dealii::hp::DoFHandler;
+        template <int, int> friend class dealii::hp::DoFHandler;
     };
 
 
@@ -249,7 +249,7 @@ namespace internal
                                           * resize arrays as
                                           * necessary.
                                           */
-        template <int> friend class dealii::hp::DoFHandler;
+        template <int, int> friend class dealii::hp::DoFHandler;
     };
 
   } // namespace hp
index a393750e2ae9faed16286e2dc882fa92bb17d122..bdf6106c56b4f6dea5480dea9b3610fd8e35556d 100644 (file)
@@ -141,9 +141,9 @@ namespace internal
                                           * class template for more
                                           * information.
                                          */
-        template <int spacedim>
+        template <int dimm, int spacedim>
         void
-        set_dof_index (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+        set_dof_index (const dealii::hp::DoFHandler<dimm,spacedim> &dof_handler,
                       const unsigned int               obj_index,
                       const unsigned int               fe_index,
                       const unsigned int               local_index,
@@ -173,9 +173,9 @@ namespace internal
                                           * class template for more
                                           * information.
                                          */
-        template <int spacedim>
+        template <int dimm, int spacedim>
         unsigned int
-        get_dof_index (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+        get_dof_index (const dealii::hp::DoFHandler<dimm,spacedim> &dof_handler,
                       const unsigned int               obj_index,
                       const unsigned int               fe_index,
                       const unsigned int               local_index,
@@ -204,9 +204,9 @@ namespace internal
                                          * been distributed and zero
                                          * is returned.
                                           */
-        template <int spacedim>
+        template <int dimm, int spacedim>
         unsigned int
-        n_active_fe_indices (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+        n_active_fe_indices (const dealii::hp::DoFHandler<dimm,spacedim> &dof_handler,
                              const unsigned int               obj_index) const;
 
                                         /**
@@ -214,9 +214,9 @@ namespace internal
                                          * n-th active finite element
                                          * on this object.
                                          */
-        template <int spacedim>
+        template <int dimm, int spacedim>
         unsigned int
-        nth_active_fe_index (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+        nth_active_fe_index (const dealii::hp::DoFHandler<dimm,spacedim> &dof_handler,
                             const unsigned int               obj_level,
                              const unsigned int               obj_index,
                             const unsigned int               n) const;
@@ -227,9 +227,9 @@ namespace internal
                                           * used on the present
                                           * object or not.
                                           */
-        template <int spacedim>
+        template <int dimm, int spacedim>
         bool
-        fe_index_is_active (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+        fe_index_is_active (const dealii::hp::DoFHandler<dimm,spacedim> &dof_handler,
                             const unsigned int               obj_index,
                             const unsigned int               fe_index,
                            const unsigned int               obj_level) const;
@@ -254,17 +254,17 @@ namespace internal
 // --------------------- inline and template functions ------------------
 
     template <int dim>
-    template <int spacedim>
+    template <int dimm, int spacedim>
     inline
     unsigned int
     DoFObjects<dim>::
-    get_dof_index (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+    get_dof_index (const dealii::hp::DoFHandler<dimm,spacedim> &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 != dealii::hp::DoFHandler<spacedim>::default_fe_index,
+      Assert ((fe_index != dealii::hp::DoFHandler<dimm,spacedim>::default_fe_index),
               ExcMessage ("You need to specify a FE index when working "
                           "with hp DoFHandlers"));
       Assert (&dof_handler != 0,
@@ -290,7 +290,7 @@ namespace internal
                           "information for an object on which no such "
                           "information is available"));
 
-      if (dim == spacedim)
+      if (dim == dimm)
         {
                                            // if we are on a cell, then
                                            // the only set of indices we
@@ -335,18 +335,18 @@ namespace internal
 
 
     template <int dim>
-    template <int spacedim>
+    template <int dimm, int spacedim>
     inline
     void
     DoFObjects<dim>::
-    set_dof_index (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+    set_dof_index (const dealii::hp::DoFHandler<dimm,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)
     {
-      Assert (fe_index != dealii::hp::DoFHandler<spacedim>::default_fe_index,
+      Assert ((fe_index != dealii::hp::DoFHandler<dimm,spacedim>::default_fe_index),
               ExcMessage ("You need to specify a FE index when working "
                           "with hp DoFHandlers"));
       Assert (&dof_handler != 0,
@@ -372,7 +372,7 @@ namespace internal
                           "information for an object on which no such "
                           "information is available"));
 
-      if (dim == spacedim)
+      if (dim == dimm)
         {
                                            // if we are on a cell, then
                                            // the only set of indices we
@@ -420,14 +420,14 @@ namespace internal
 
 
     template <int dim>
-    template <int spacedim>
+    template <int dimm, int spacedim>
     inline
     unsigned int
     DoFObjects<dim>::
-    n_active_fe_indices (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+    n_active_fe_indices (const dealii::hp::DoFHandler<dimm,spacedim> &dof_handler,
                          const unsigned int                obj_index) const
     {
-      Assert (dim <= spacedim, ExcInternalError());
+      Assert (dim <= dimm, ExcInternalError());
       Assert (&dof_handler != 0,
               ExcMessage ("No DoFHandler is specified for this iterator"));
       Assert (&dof_handler.get_fe() != 0,
@@ -446,7 +446,7 @@ namespace internal
                                        // only set of indices we store
                                        // is the one for the cell,
                                        // which is unique
-      if (dim == spacedim)
+      if (dim == dimm)
         return 1;
       else
         {
@@ -483,16 +483,16 @@ namespace internal
 
 
     template <int dim>
-    template <int spacedim>
+    template <int dimm, int spacedim>
     inline
     unsigned int
     DoFObjects<dim>::
-    nth_active_fe_index (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+    nth_active_fe_index (const dealii::hp::DoFHandler<dimm,spacedim> &dof_handler,
                          const unsigned int                obj_level,
                          const unsigned int                obj_index,
                          const unsigned int                n) const
     {
-      Assert (dim <= spacedim, ExcInternalError());
+      Assert (dim <= dimm, ExcInternalError());
       Assert (&dof_handler != 0,
               ExcMessage ("No DoFHandler is specified for this iterator"));
       Assert (&dof_handler.get_fe() != 0,
@@ -509,7 +509,7 @@ namespace internal
                           "information for an object on which no such "
                           "information is available"));
 
-      if (dim == spacedim)
+      if (dim == dimm)
         {
                                            // this is a cell, so there
                                            // is only a single
@@ -563,11 +563,11 @@ namespace internal
 
 
     template <int dim>
-    template <int spacedim>
+    template <int dimm, int spacedim>
     inline
     bool
     DoFObjects<dim>::
-    fe_index_is_active (const dealii::hp::DoFHandler<spacedim> &dof_handler,
+    fe_index_is_active (const dealii::hp::DoFHandler<dimm,spacedim> &dof_handler,
                         const unsigned int                obj_index,
                         const unsigned int                fe_index,
                         const unsigned int                obj_level) const
@@ -579,7 +579,7 @@ namespace internal
                           "this DoFHandler"));
       Assert (obj_index < dof_offsets.size(),
               ExcIndexRange (obj_index, 0, dof_offsets.size()));
-      Assert (fe_index != dealii::hp::DoFHandler<spacedim>::default_fe_index,
+      Assert ((fe_index != dealii::hp::DoFHandler<dimm,spacedim>::default_fe_index),
               ExcMessage ("You need to specify a FE index when working "
                           "with hp DoFHandlers"));
       Assert (fe_index < dof_handler.get_fe().size(),
@@ -593,7 +593,7 @@ namespace internal
                           "information for an object on which no such "
                           "information is available"));
 
-      if (dim == spacedim)
+      if (dim == dimm)
         {
                                            // if we are on a cell,
                                            // then the only set of
index 4d5288fdd801e704f5de9817de57d1b56173e014..d9f839b4332b5ef2c23309cff67079b08d71ac5f 100644 (file)
@@ -35,12 +35,15 @@ namespace hp
  * vertex, line, etc, to allow allocation of as much memory as is necessary in
  * the worst case when using the finite elements associated with the cells of
  * a triangulation.
+ *
+ * This class has not yet been implemented for the use in the codimension
+ * one case (<tt>spacedim != dim </tt>).
  * 
  * @ingroup hp hpcollection
  * 
  * @author Wolfgang Bangerth, 2003
  */
-  template <int dim>
+  template <int dim, int spacedim=dim>
   class FECollection : public Subscriptor
   {
     public:
@@ -63,12 +66,12 @@ namespace hp
                                         * probably be clearer to add
                                         * all mappings the same way.
                                         */
-      explicit FECollection (const FiniteElement<dim> &fe);
+      explicit FECollection (const FiniteElement<dim,spacedim> &fe);
 
                                        /**
                                         * Copy constructor.
                                         */
-      FECollection (const FECollection<dim> &fe_collection);
+      FECollection (const FECollection<dim,spacedim> &fe_collection);
 
                                        /**
                                         * Add a finite element. This
@@ -87,7 +90,7 @@ namespace hp
                                         * as all other elements
                                         * already in the collection.
                                         */
-      void push_back (const FiniteElement<dim> &new_fe);
+      void push_back (const FiniteElement<dim,spacedim> &new_fe);
 
                                        /**
                                         * Get a reference to the given
@@ -98,7 +101,7 @@ namespace hp
                                         * of elements of the
                                         * collection.
                                         */
-      const FiniteElement<dim> &
+      const FiniteElement<dim,spacedim> &
       operator[] (const unsigned int index) const;
 
                                        /**
@@ -212,36 +215,36 @@ namespace hp
                                         * Array of pointers to the finite
                                         * elements stored by this collection.
                                         */
-      std::vector<boost::shared_ptr<const FiniteElement<dim> > > finite_elements;
+      std::vector<boost::shared_ptr<const FiniteElement<dim,spacedim> > > finite_elements;
   };
 
 
 
 /* --------------- inline functions ------------------- */
 
-  template <int dim>
+  template <int dim, int spacedim>
   inline
   unsigned int
-  FECollection<dim>::size () const 
+  FECollection<dim,spacedim>::size () const 
   {
     return finite_elements.size();
   }
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   inline
   unsigned int
-  FECollection<dim>::n_components () const
+  FECollection<dim,spacedim>::n_components () const
   {
     Assert (finite_elements.size () > 0, ExcNoFiniteElements());
     return finite_elements[0]->n_components ();
   }
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   inline
-  const FiniteElement<dim> &
-  FECollection<dim>::operator[] (const unsigned int index) const 
+  const FiniteElement<dim,spacedim> &
+  FECollection<dim,spacedim>::operator[] (const unsigned int index) const 
   {
     Assert (index < finite_elements.size(),
             ExcIndexRange (index, 0, finite_elements.size()));
@@ -250,9 +253,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   unsigned int
-  FECollection<dim>::max_dofs_per_vertex () const 
+  FECollection<dim,spacedim>::max_dofs_per_vertex () const 
   {
     Assert (finite_elements.size() > 0, ExcNoFiniteElements());
   
@@ -266,9 +269,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   unsigned int
-  FECollection<dim>::max_dofs_per_line () const 
+  FECollection<dim,spacedim>::max_dofs_per_line () const 
   {
     Assert (finite_elements.size() > 0, ExcNoFiniteElements());
   
@@ -282,9 +285,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   unsigned int
-  FECollection<dim>::max_dofs_per_quad () const 
+  FECollection<dim,spacedim>::max_dofs_per_quad () const 
   {
     Assert (finite_elements.size() > 0, ExcNoFiniteElements());
   
@@ -298,9 +301,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   unsigned int
-  FECollection<dim>::max_dofs_per_hex () const 
+  FECollection<dim,spacedim>::max_dofs_per_hex () const 
   {
     Assert (finite_elements.size() > 0, ExcNoFiniteElements());
   
@@ -314,9 +317,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   unsigned int
-  FECollection<dim>::max_dofs_per_face () const 
+  FECollection<dim,spacedim>::max_dofs_per_face () const 
   {
     Assert (finite_elements.size() > 0, ExcNoFiniteElements());
   
@@ -330,9 +333,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   unsigned int
-  FECollection<dim>::max_dofs_per_cell () const 
+  FECollection<dim,spacedim>::max_dofs_per_cell () const 
   {
     Assert (finite_elements.size() > 0, ExcNoFiniteElements());
   
@@ -345,9 +348,9 @@ namespace hp
   }
   
 
-  template <int dim>
+  template <int dim, int spacedim>
   bool
-  FECollection<dim>::hp_constraints_are_implemented () const 
+  FECollection<dim,spacedim>::hp_constraints_are_implemented () const 
   {
     Assert (finite_elements.size() > 0, ExcNoFiniteElements());
   
index ba36a94d52c453a1f2d4cfec8cfe7c03a1eba65e..4cfde4c097f4a8fd8801be5d2bb6721343bbfdfb 100644 (file)
@@ -25,8 +25,8 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MappingQ1;
-template <int dim> class FiniteElement;
+template <int dim, int spacedim> class MappingQ1;
+template <int dim, int spacedim> class FiniteElement;
 
 
 
@@ -65,8 +65,8 @@ namespace internal
                                           * indicated by the parameters
                                           * to the constructor.
                                           */
-        FEValuesBase (const dealii::hp::MappingCollection<dim> &mapping_collection,
-                      const dealii::hp::FECollection<dim>      &fe_collection,
+      FEValuesBase (const dealii::hp::MappingCollection<dim,FEValues::space_dimension> &mapping_collection,
+                   const dealii::hp::FECollection<dim,FEValues::space_dimension>      &fe_collection,
                       const dealii::hp::QCollection<q_dim>     &q_collection,
                       const UpdateFlags             update_flags);
                                          /**
@@ -78,7 +78,7 @@ namespace internal
                                           * object for the mapping
                                           * object.
                                           */
-        FEValuesBase (const dealii::hp::FECollection<dim> &fe_collection,
+      FEValuesBase (const dealii::hp::FECollection<dim,FEValues::space_dimension> &fe_collection,
                       const dealii::hp::QCollection<q_dim> &q_collection,
                       const UpdateFlags         update_flags);
         
@@ -121,14 +121,14 @@ namespace internal
                                           * collection of finite
                                           * elements to be used.
                                           */
-        const SmartPointer<const dealii::hp::FECollection<dim> > fe_collection;
+        const SmartPointer<const dealii::hp::FECollection<dim,FEValues::space_dimension> > fe_collection;
         
                                          /**
                                           * A pointer to the
                                           * collection of mappings to
                                           * be used.
                                           */
-        const SmartPointer<const dealii::hp::MappingCollection<dim> > mapping_collection;
+        const SmartPointer<const dealii::hp::MappingCollection<dim, FEValues::space_dimension> > mapping_collection;
     
                                          /**
                                           * Copy of the quadrature
@@ -229,13 +229,21 @@ namespace hp
  * finite element, quadrature formula and mapping, but only those that will
  * actually be needed.
  *
+ * This class has not yet been implemented for the use in the codimension
+ * one case (<tt>spacedim != dim </tt>).
+ *
  * @ingroup hp hpcollection
  * @author Wolfgang Bangerth, 2003
  */  
-  template <int dim>
-  class FEValues : public internal::hp::FEValuesBase<dim,dim,dealii::FEValues<dim> >
+  template <int dim, int spacedim=dim>
+    class FEValues : public internal::hp::FEValuesBase<dim,dim,dealii::FEValues<dim,spacedim> >
   {
     public:
+    static const unsigned int dimension = dim;
+
+    static const unsigned int space_dimension = spacedim;
+
                                        /**
                                         * Constructor. Initialize this
                                         * object with the given
@@ -256,8 +264,8 @@ namespace hp
                                         * <tt>DoFHandler::get_fe()</tt>
                                         * function.
                                         */
-      FEValues (const dealii::hp::MappingCollection<dim> &mapping_collection,
-                const dealii::hp::FECollection<dim>  &fe_collection,
+    FEValues (const dealii::hp::MappingCollection<dim,spacedim> &mapping_collection,
+             const dealii::hp::FECollection<dim,spacedim>  &fe_collection,
                 const dealii::hp::QCollection<dim>       &q_collection,
                 const UpdateFlags             update_flags);
 
@@ -284,7 +292,7 @@ namespace hp
                                         * <tt>DoFHandler::get_fe()</tt>
                                         * function.
                                         */
-      FEValues (const hp::FECollection<dim> &fe_collection,
+    FEValues (const hp::FECollection<dim,spacedim> &fe_collection,
                 const hp::QCollection<dim>      &q_collection,
                 const UpdateFlags            update_flags);
 
@@ -389,7 +397,7 @@ namespace hp
                                         * this argument is specified.
                                         */
       void
-      reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell,
+      reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
               const unsigned int q_index = numbers::invalid_unsigned_int,
               const unsigned int mapping_index = numbers::invalid_unsigned_int,
               const unsigned int fe_index = numbers::invalid_unsigned_int);
@@ -424,7 +432,7 @@ namespace hp
                                         * these last three arguments.
                                         */
       void
-      reinit (const typename dealii::DoFHandler<dim>::cell_iterator &cell,
+      reinit (const typename dealii::DoFHandler<dim,spacedim>::cell_iterator &cell,
               const unsigned int q_index = numbers::invalid_unsigned_int,
               const unsigned int mapping_index = numbers::invalid_unsigned_int,
               const unsigned int fe_index = numbers::invalid_unsigned_int);
@@ -459,7 +467,7 @@ namespace hp
                                         * these last three arguments.
                                         */
       void
-      reinit (const typename MGDoFHandler<dim>::cell_iterator &cell,
+      reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
               const unsigned int q_index = numbers::invalid_unsigned_int,
               const unsigned int mapping_index = numbers::invalid_unsigned_int,
               const unsigned int fe_index = numbers::invalid_unsigned_int);
@@ -495,10 +503,12 @@ namespace hp
                                         * three arguments.
                                         */
       void
-      reinit (const typename Triangulation<dim>::cell_iterator &cell,
+      reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
               const unsigned int q_index = numbers::invalid_unsigned_int,
               const unsigned int mapping_index = numbers::invalid_unsigned_int,
               const unsigned int fe_index = numbers::invalid_unsigned_int);
+
+
   };
 
 
index 63929c5e782923c3d738157a737300bd713391b1..496c2eed3b6cb82dfb1979410714b33b497c6ce9 100644 (file)
@@ -48,7 +48,7 @@ namespace hp
  * 
  * @author Oliver Kayser-Herold, 2005
  */
-  template <int dim>
+  template<int dim, int spacedim=dim>
   class MappingCollection : public Subscriptor
   {
     public:
@@ -71,12 +71,12 @@ namespace hp
                                         * clearer to add all mappings
                                         * the same way.
                                         */
-      explicit MappingCollection (const Mapping<dim> &mapping);
+      explicit MappingCollection (const Mapping<dim,spacedim> &mapping);
 
                                        /**
                                         * Copy constructor.
                                         */
-      MappingCollection (const MappingCollection<dim> &mapping_collection);
+      MappingCollection (const MappingCollection<dim,spacedim> &mapping_collection);
       
                                        /**
                                         * Adds a new mapping to the
@@ -91,7 +91,7 @@ namespace hp
                                         * object for active_fe_index
                                         * 1.
                                         */
-      void push_back (const Mapping<dim> &new_mapping);
+      void push_back (const Mapping<dim,spacedim> &new_mapping);
 
                                        /**
                                         * Returns the mapping object
@@ -105,7 +105,7 @@ namespace hp
                                         * of elements of the
                                         * collection.
                                         */
-      const Mapping<dim> &
+      const Mapping<dim,spacedim> &
       operator[] (const unsigned int index) const;
 
                                        /**
@@ -128,7 +128,7 @@ namespace hp
                                         * pointers to the different Mapping
                                         * objects.
                                         */
-      std::vector<boost::shared_ptr<const Mapping<dim> > > mappings;
+      std::vector<boost::shared_ptr<const Mapping<dim,spacedim> > > mappings;
   };
 
 
@@ -139,7 +139,7 @@ namespace hp
  * MappingQ1 mapping object once and for all places where it is
  * needed.
  */
-  template <int dim>
+  template<int dim, int spacedim=dim>
   struct StaticMappingQ1
   {
     private:
@@ -153,7 +153,7 @@ namespace hp
                                         * constructor for the present
                                         * static object.
                                         */
-      static MappingQ1<dim> mapping_q1;
+      static MappingQ1<dim,spacedim> mapping_q1;
       
     public:
                                        /**
@@ -161,26 +161,26 @@ namespace hp
                                         * static Q1 mapping collection
                                         * object.
                                         */
-      static MappingCollection<dim> mapping_collection;
+      static MappingCollection<dim,spacedim> mapping_collection;
   };
 
 
 /* --------------- inline functions ------------------- */
 
-  template <int dim>
+  template<int dim, int spacedim>
   inline
   unsigned int
-  MappingCollection<dim>::size () const 
+  MappingCollection<dim,spacedim>::size () const 
   {
     return mappings.size();
   }
 
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   inline
-  const Mapping<dim> &
-  MappingCollection<dim>::operator[] (const unsigned int index) const
+  const Mapping<dim,spacedim> &
+  MappingCollection<dim,spacedim>::operator[] (const unsigned int index) const
   {
     Assert (index < mappings.size (),
             ExcIndexRange (index, 0, mappings.size ()));
index a7cce9d46ed61ba0679b1082e4a7ac8fc2057172..e7672173b37fac726aff8b4088ae8a4ed221aabe 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
 
 #include <base/config.h>
 #include <dofs/dof_accessor.h>
+#include <multigrid/mg_dof_iterator_selector.h>
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MGDoFHandler;
+template <int dim, int spacedim> class MGDoFHandler;
 
-template <int celldim, int dim> class MGDoFObjectAccessor;
-template <int dim>              class MGDoFObjectAccessor<0, dim>;
-template <int dim>              class MGDoFObjectAccessor<1, dim>;
-template <int dim>              class MGDoFObjectAccessor<2, dim>;
-template <int dim>              class MGDoFObjectAccessor<3, dim>;
+template <int celldim, int dim, int spacedim=dim> class MGDoFAccessor;
 
 /*!@addtogroup mg */
 /*@{*/
 
+
+namespace internal
+{
+  namespace MGDoFAccessor
+  {
 /**
  * This is a switch class which only declares a @p typedef. It is meant to
  * determine which class aMGDoFAccessor class is to be derived
  * from. By default, <tt>MGDoFAccessor<celldim,dim></tt> derives from
- * the @p typedef in the general <tt>MGDoFObjectAccessor_Inheritance<celldim,dim></tt>
- * class, which is <tt>DoFObjectAccessor<celldim,dim></tt>,
- * but if <tt>celldim==dim</tt>, then the specialization <tt>MGDoFObjectAccessor_Inheritance<dim,dim></tt>
+ * the @p typedef in the general <tt>MGDoFAccessor_Inheritance<celldim,dim></tt>
+ * class, which is <tt>DoFAccessor<celldim,dim></tt>,
+ * but if <tt>celldim==dim</tt>, then the specialization <tt>MGDoFAccessor_Inheritance<dim,dim></tt>
  * is used which declares its local type to be <tt>DoFCellAccessor<dim></tt>. Therefore,
  * the inheritance is automatically chosen to be from @p DoFCellAccessor if the
  * object under consideration has full dimension, i.e. constitutes a cell.
  *
  * @author Wolfgang Bangerth, 1999
  */
-template <int celldim, int dim>
-class MGDoFObjectAccessor_Inheritance 
-{
-  public:
-                                    /**
-                                     * Declaration of the @p typedef.
-                                     * See the full documentation for
-                                     * more information.
-                                     */
-    typedef DoFObjectAccessor<celldim,DoFHandler<dim> > BaseClass;
-};
+    template <int celldim, int dim, int spacedim>
+    struct Inheritance 
+    {
+                                        /**
+                                         * Declaration of the @p typedef.
+                                         * See the full documentation for
+                                         * more information.
+                                         */
+       typedef dealii::DoFAccessor<celldim, dealii::DoFHandler<dim,spacedim> > BaseClass;
+    };
 
 
 /**
@@ -61,10 +62,10 @@ class MGDoFObjectAccessor_Inheritance
  * meant to determine which class a DoFAccessor class is to be
  * derived from. By default, DoFAccessor<structdim,dim>
  * derives from the @p typedef in the general
- * <tt>DoFObjectAccessor_Inheritance<celldim,dim></tt> class, which is
- * <tt>TriaObjectAccessor<celldim,dim></tt>, but if
+ * <tt>DoFAccessor_Inheritance<celldim,dim></tt> class, which is
+ * <tt>TriaAccessor<celldim,dim></tt>, but if
  * <tt>celldim==dim</tt>, then the specialization
- * <tt>TriaObjectAccessor<dim,dim></tt> is used which declares its
+ * <tt>TriaAccessor<dim,dim></tt> is used which declares its
  * local type to be <tt>CellAccessor<dim></tt>. Therefore, the
  * inheritance is automatically chosen to be from @p CellAccessor if
  * the object under consideration has full dimension, i.e. constitutes
@@ -72,17 +73,18 @@ class MGDoFObjectAccessor_Inheritance
  *
  * @author Wolfgang Bangerth, 1999
  */
-template <int dim>
-class MGDoFObjectAccessor_Inheritance<dim,dim>
-{
-  public:
-                                    /**
-                                     * Declaration of the @p typedef.
-                                     * See the full documentation for
-                                     * more information.
-                                     */
-    typedef DoFCellAccessor<DoFHandler<dim> > BaseClass;
-};
+    template <int dim, int spacedim>
+    struct Inheritance<dim,dim,spacedim>
+    {
+                                        /**
+                                         * Declaration of the @p typedef.
+                                         * See the full documentation for
+                                         * more information.
+                                         */
+       typedef dealii::DoFCellAccessor<dealii::DoFHandler<dim,spacedim> > BaseClass;
+    };
+  }
+}
 
 
 /* -------------------------------------------------------------------------- */
@@ -90,22 +92,58 @@ class MGDoFObjectAccessor_Inheritance<dim,dim>
 
 
 /**
- * Define the basis for accessors to the degrees of freedom for
- * a multigrid DoF handler object.
+ * A class that gives access to the degrees of freedom stored in a
+ * MGDoFHandler.  Accessors are used to, well, access the data that pertains
+ * to edges, faces, and cells of a triangulation. The concept is explained in
+ * more detail in connection to @ref Iterators.
  *
- * This class is very similar to the DoFAccessor class, and the same
- * holds for the classes derived from the present one. In essence, the
- * classes here simply extend the classes of the DoFAccessor hierarchy
- * by providing access to the multilevel degrees of freedom managed by
- * the MGDoFHandler class. See the DoFAccessor class for more
- * information on the structure of inheritance and other aspects.
+ * This class follows mainly the route laid out by the accessor library
+ * declared in the triangulation library (TriaAccessor). It enables the user
+ * to access the degrees of freedom on lines, quads, or hexes, as well as the
+ * multigrid degrees of freedom associated with these objects. The first
+ * template argument of this class determines the dimensionality of the object
+ * under consideration: 1 for lines, 2 for quads, and 3 for hexes. The second
+ * template argument determines the dimensionality of the triangulation to
+ * which this object belongs, and the third the dimensionality of the space in
+ * which it is embedded.
  *
- * @ingroup mg
+ * Depending on whether the structural dimension of the object
+ * accessed equals the dimension on which the DoF handler object
+ * operates, this class is derived from CellAccessor or
+ * TriaAccessor. This means that, for example accessors to quads
+ * in 2d have access to all the mesh aspects of cells, whereas
+ * accessors to quads in 3d can only access things that make sense for
+ * faces.
+ *
+ *
+ * <h3>Usage</h3>
+ *
+ * Usage is best to happen through the typedefs to the various kinds
+ * of iterators provided by the MGDoFHandler class,
+ * since they are more secure to changes in the class naming and
+ * template interface as well as providing easier typing (much less
+ * complicated names!).
+ * 
+ *
+ * <h3>Inheritance</h3>
+ *
+ * If the structural dimension given by the first template argument
+ * equals the dimension of the MGDoFHandler (given as the second
+ * template argument), then we are obviously dealing with cells,
+ * rather than lower-dimensional objects. In that case, inheritance is
+ * from DoFCellAccessor, to provide access to all the cell specific
+ * information afforded by that class. Otherwise, i.e. for
+ * lower-dimensional objects, inheritance is from DoFAccessor.
+ *
+ * There is a MGDoFCellAccessor class that provides the
+ * equivalent to the CellAccessor and DoFCellAccessor classes.
+ *
+ * @ingroup dofs
  * @ingroup Accessors
- * @author Wolfgang Bangerth, 1998, 2006
+ * @author Wolfgang Bangerth, 1998, 2006, 2008
  */
-template <int structdim, int dim>
-class MGDoFAccessor : public MGDoFObjectAccessor_Inheritance<structdim, dim>::BaseClass
+template <int structdim, int dim, int spacedim>
+class MGDoFAccessor : public internal::MGDoFAccessor::Inheritance<structdim,dim,spacedim>::BaseClass
 {
   public:
                                     /**
@@ -115,15 +153,22 @@ class MGDoFAccessor : public MGDoFObjectAccessor_Inheritance<structdim, dim>::Ba
                                      * simpler.
                                      */    
     typedef
-    typename MGDoFObjectAccessor_Inheritance<structdim, dim>::BaseClass
+    typename internal::MGDoFAccessor::Inheritance<structdim,dim,spacedim>::BaseClass
     BaseClass;
 
                                     /**
                                      * A typedef necessary for the
                                      * iterator classes.
                                      */
-    typedef MGDoFHandler<dim> AccessorData;
+    typedef MGDoFHandler<dim,spacedim> AccessorData;
     
+                                    /**
+                                     * @name Constructors
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
                                     /**
                                      * Default constructor. Creates
                                      * an object that is not
@@ -134,159 +179,61 @@ class MGDoFAccessor : public MGDoFObjectAccessor_Inheritance<structdim, dim>::Ba
                                     /**
                                      * Constructor.
                                      */
-    MGDoFAccessor (const Triangulation<dim> *tria,
+    MGDoFAccessor (const Triangulation<dim,spacedim> *tria,
                   const int                 level,
                   const int                 index,
                   const AccessorData       *local_data);
 
                                     /**
-                                     * Reset the DoF handler pointer.
-                                     */
-    void set_mg_dof_handler (MGDoFHandler<dim> *dh);
+                                     * Conversion constructor. This
+                                     * constructor exists to make certain
+                                     * constructs simpler to write in
+                                     * dimension independent code. For
+                                     * example, it allows assigning a face
+                                     * iterator to a line iterator, an
+                                     * operation that is useful in 2d but
+                                     * doesn't make any sense in 3d. The
+                                     * constructor here exists for the
+                                     * purpose of making the code conform to
+                                     * C++ but it will unconditionally abort;
+                                     * in other words, assigning a face
+                                     * iterator to a line iterator is better
+                                     * put into an if-statement that checks
+                                     * that the dimension is two, and assign
+                                     * to a quad iterator in 3d (an operator
+                                     * that, without this constructor would
+                                     * be illegal if we happen to compile for
+                                     * 2d).
+                                     */
+    template <int structdim2, int dim2, int spacedim2>
+    MGDoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &);
 
                                     /**
-                                     * Copy operator.
+                                     * Another conversion operator
+                                     * between objects that don't
+                                     * make sense, just like the
+                                     * previous one.
                                      */
-    MGDoFAccessor & operator = (const MGDoFAccessor &da);
-    
-                                    /**
-                                     * Return the index of the @p ith
-                                     * degree on the @p vertexth
-                                     * vertex for the level this
-                                     * object lives on.
-                                     */
-    unsigned int mg_vertex_dof_index (const int level,
-                                     const unsigned int vertex,
-                                     const unsigned int i) const;
+    template <int structdim2, int dim2, int spacedim2>
+    MGDoFAccessor (const MGDoFAccessor<structdim2,dim2,spacedim2> &);    
 
                                     /**
-                                     * Set the index of the @p ith degree
-                                     * on the @p vertexth vertex to @p index
-                                     * for the level this object lives on.
+                                     * @}
                                      */
-    void set_mg_vertex_dof_index (const int level,
-                                 const unsigned int vertex,
-                                 const unsigned int i,
-                                 const unsigned int index) const;
 
                                     /**
-                                     * Return the index of the @p ith
-                                     * degree of freedom of this line
-                                     * on the level this line lives
-                                     * on.
+                                     *  @name Accessing the DoF indices of this object
                                      */
-    unsigned int mg_dof_index (const int level,
-                              const unsigned int i) const;
-
-                                    /**
-                                     * Set the index of the @p ith degree
-                                     * of freedom of this line on the
-                                     * level this line lives on to @p index.
-                                     */
-    void set_mg_dof_index (const int level,
-                          const unsigned int i,
-                          const unsigned int index) const;
-
                                     /**
-                                     * Return an iterator to the @p
-                                     * i-th child.
-                                     */
-    TriaIterator<dim,MGDoFObjectAccessor<structdim, dim> >
-    child (const unsigned int) const;
-    
-                                    /**
-                                     * Implement the copy operator needed
-                                     * for the iterator classes.
+                                     * @{
                                      */
-    void copy_from (const MGDoFAccessor &a);
-
-                                    /**
-                                     * Exception for child classes
-                                     */
-    DeclException0 (ExcInvalidObject);
-
-  protected:
-                                    /**
-                                     * Store the address of the @p MGDoFHandler object
-                                     * to be accessed.
-                                     */
-    MGDoFHandler<dim> *mg_dof_handler;  
-};
-
-
-/* -------------------------------------------------------------------------- */
-
-/**
- * Closure class. Unused, but necessary for some template games.
- */
-template<int dim>
-class MGDoFObjectAccessor<0, dim>
-{
-  public:
-    typedef void AccessorData;
-
-                                    /**
-                                     * Constructor. Should never be called
-                                     * and thus throws an error.
-                                     */
-    MGDoFObjectAccessor (const Triangulation<dim> *,
-                        const int,
-                        const int,
-                        const AccessorData *);
-};
-
-
-/**
- * Grant access to those aspects of multilevel degrees of freedom located on
- * lines that are dimension specific. See the MGDoFAccessor class for
- * more information.
- *
- * @ingroup mg
- * @ingroup Accessors
- * @author Wolfgang Bangerth, 1998, 2006
- */
-template <int dim>
-class MGDoFObjectAccessor<1, dim> :  public MGDoFAccessor<1,dim>
-{
-  public:
-                                    /**
-                                     * Declare a typedef to the base
-                                     * class to make accessing some
-                                     * of the exception classes
-                                     * simpler.
-                                     */    
-    typedef
-    typename MGDoFObjectAccessor_Inheritance<1, dim>::BaseClass
-    BaseClass;
-
-                                    /**
-                                     * Declare the data type that this accessor
-                                     * class expects to get passed from the
-                                     * iterator classes.
-                                     */
-    typedef MGDoFHandler<dim> AccessorData;
-    
-                                    /**
-                                     * Default constructor, unused thus
-                                     * not implemented.
-                                     */
-    MGDoFObjectAccessor ();
-    
-                                    /**
-                                     * Constructor. The @p local_data
-                                     * argument is assumed to be a pointer
-                                     * to an MGDoFHandler object.
-                                     */
-    MGDoFObjectAccessor (const Triangulation<dim> *tria,
-                        const int                 level,
-                        const int                 index,
-                        const AccessorData       *local_data);
 
                                     /**
                                      * Return the indices of the dofs of this
-                                     * line in the standard ordering: dofs
-                                     * on vertex 0, dofs on vertex 1, 
-                                     * dofs on line.
+                                     * object in the standard ordering: dofs
+                                     * on vertex 0, dofs on vertex 1, ...
+                                     * dofs on line 0, dofs on line 1, ...,
+                                     * then quads, then hexes.
                                      *
                                      * It is assumed that the vector already
                                      * has the right size beforehand. The
@@ -317,204 +264,120 @@ class MGDoFObjectAccessor<1, dim> :  public MGDoFAccessor<1,dim>
     void get_mg_dof_values (const int level,
                            const Vector<number> &values,
                            Vector<number>       &dof_values) const;
-};
 
-
-/**
- * Grant access to those aspects of multilevel degrees of freedom located on
- * quads that are dimension specific. See the MGDoFAccessor class for
- * more information.
- *
- * @ingroup mg
- * @ingroup Accessors
- * @author Wolfgang Bangerth, 1998, 2006
- */
-template <int dim>
-class MGDoFObjectAccessor<2, dim> :  public MGDoFAccessor<2,dim>
-{
-  public:
                                     /**
-                                     * Declare a typedef to the base
-                                     * class to make accessing some
-                                     * of the exception classes
-                                     * simpler.
-                                     */    
-    typedef
-    typename MGDoFObjectAccessor_Inheritance<2, dim>::BaseClass
-    BaseClass;
+                                     * Return the index of the @p ith
+                                     * degree on the @p vertexth
+                                     * vertex for the level this
+                                     * object lives on.
+                                     */
+    unsigned int mg_vertex_dof_index (const int level,
+                                     const unsigned int vertex,
+                                     const unsigned int i) const;
 
                                     /**
-                                     * Declare the data type that this accessor
-                                     * class expects to get passed from the
-                                     * iterator classes.
+                                     * Return the index of the @p ith
+                                     * degree of freedom of this line
+                                     * on the level this line lives
+                                     * on.
                                      */
-    typedef MGDoFHandler<dim> AccessorData;
+    unsigned int mg_dof_index (const int level,
+                              const unsigned int i) const;
 
                                     /**
-                                     * Default constructor, unused thus
-                                     * not implemented.
+                                     * @}
                                      */
-    MGDoFObjectAccessor ();
 
-                                    /**
-                                     * Constructor. The @p local_data
-                                     * argument is assumed to be a pointer
-                                     * to an MGDoFHandler object.
+                                    /**
+                                     *  @name Accessing sub-objects
                                      */
-    MGDoFObjectAccessor (const Triangulation<dim> *tria,
-                        const int                 level,
-                        const int                 index,
-                        const AccessorData       *local_data);
-
-                                    /**
-                                     * Return the indices of the dofs of this
-                                     * quad in the standard ordering: dofs
-                                     * on vertex 0, dofs on vertex 1, etc,
-                                     * dofs on line 0, dofs on line 1, etc,
-                                     * dofs on quad 0, etc.
-                                     *
-                                     * It is assumed that the vector already
-                                     * has the right size beforehand. The
-                                     * indices refer to the local numbering
-                                     * for the level this quad lives on.
+                                    /**
+                                     * @{
                                      */
-    void get_mg_dof_indices (const int level,
-                            std::vector<unsigned int> &dof_indices) const;
-                                    /**
-                                     * Return the value of the given vector
-                                     * restricted to the dofs of this
-                                     * cell in the standard ordering: dofs
-                                     * on vertex 0, dofs on vertex 1, etc,
-                                     * dofs on line 0, dofs on line 1, etc,
-                                     * dofs on quad 0, etc.
-                                     *
-                                     * It is assumed that the vector already
-                                     * has the right size beforehand. The
-                                     * indices refer to the multilevel
-                                     * numbering local to the present
-                                     * level of this cell. The vector shall
-                                     * therefore have the same number of
-                                     * entries as there are degrees of
-                                     * freedom on this level.
+
+                                    /**
+                                     * Return an iterator to the @p
+                                     * i-th child.
                                      */
-    template <typename number>
-    void get_mg_dof_values (const int level,
-                           const Vector<number> &values,
-                           Vector<number>       &dof_values) const;
+    TriaIterator<MGDoFAccessor<structdim,dim,spacedim> >
+    child (const unsigned int) const;
 
-                                    /**
+                                    /**
                                      * Return a pointer to the @p ith line
-                                     * bounding this @p Quad.
+                                     * bounding this @p Hex.
                                      */
-    TriaIterator<dim,MGDoFObjectAccessor<1, dim> >
+    typename internal::MGDoFHandler::Iterators<dim,spacedim>::line_iterator
     line (const unsigned int i) const;
-};
-
 
-/**
- * Grant access to those aspects of multilevel degrees of freedom located on
- * hexes that are dimension specific. See the MGDoFAccessor class for
- * more information.
- *
- * @ingroup mg
- * @ingroup Accessors
- * @author Wolfgang Bangerth, 1998, 2006
- */
-template <int dim>
-class MGDoFObjectAccessor<3, dim> :  public MGDoFAccessor<3,dim>
-{
-  public:
                                     /**
-                                     * Declare a typedef to the base
-                                     * class to make accessing some
-                                     * of the exception classes
-                                     * simpler.
-                                     */    
-    typedef
-    typename MGDoFObjectAccessor_Inheritance<3, dim>::BaseClass
-    BaseClass;
+                                     * Return a pointer to the @p ith quad
+                                     * bounding this @p Hex.
+                                     */
+    typename internal::MGDoFHandler::Iterators<dim,spacedim>::quad_iterator
+    quad (const unsigned int i) const;
 
-    
                                     /**
-                                     * Declare the data type that this accessor
-                                     * class expects to get passed from the
-                                     * iterator classes.
+                                     * @}
                                      */
-    typedef MGDoFHandler<dim> AccessorData;
-
+    
                                     /**
-                                     * Default constructor, unused thus
-                                     * not implemented.
+                                     * Implement the copy operator needed
+                                     * for the iterator classes.
                                      */
-    MGDoFObjectAccessor ();
+    void copy_from (const MGDoFAccessor &a);
 
                                     /**
-                                     * Constructor. The @p local_data
-                                     * argument is assumed to be a pointer
-                                     * to an MGDoFHandler object.
+                                     * Exception for child classes
                                      */
-    MGDoFObjectAccessor (const Triangulation<dim> *tria,
-                        const int                 level,
-                        const int                 index,
-                        const AccessorData       *local_data);
+    DeclException0 (ExcInvalidObject);
 
-                                    /**
-                                     * Return the indices of the dofs of this
-                                     * hex in the standard ordering: dofs
-                                     * on vertex 0, dofs on vertex 1, etc,
-                                     * dofs on line 0, dofs on line 1, etc,
-                                     * dofs on quad 0, etc.
-                                     *
-                                     * It is assumed that the vector already
-                                     * has the right size beforehand. The
-                                     * indices refer to the local numbering
-                                     * for the level this hex lives on.
+  protected:
+                                    /**
+                                     * Store the address of the @p MGDoFHandler object
+                                     * to be accessed.
                                      */
-    void get_mg_dof_indices (const int level,
-                            std::vector<unsigned int> &dof_indices) const;
+    MGDoFHandler<dim,spacedim> *mg_dof_handler;  
 
-                                    /**
-                                     * Return the value of the given vector
-                                     * restricted to the dofs of this
-                                     * cell in the standard ordering: dofs
-                                     * on vertex 0, dofs on vertex 1, etc,
-                                     * dofs on line 0, dofs on line 1, etc,
-                                     * dofs on quad 0, etc.
-                                     *
-                                     * It is assumed that the vector already
-                                     * has the right size beforehand. The
-                                     * indices refer to the multilevel
-                                     * numbering local to the present
-                                     * level of this cell. The vector shall
-                                     * therefore have the same number of
-                                     * entries as there are degrees of
-                                     * freedom on this level.
+                                    /**
+                                     * Reset the DoF handler pointer.
                                      */
-    template <typename number>
-    void get_mg_dof_values (const int level,
-                           const Vector<number> &values,
-                           Vector<number>       &dof_values) const;
+    void set_mg_dof_handler (MGDoFHandler<dim,spacedim> *dh);
+
+                                    /**
+                                     * Set the index of the @p ith degree
+                                     * on the @p vertexth vertex to @p index
+                                     * for the level this object lives on.
+                                     */
+    void set_mg_vertex_dof_index (const int level,
+                                 const unsigned int vertex,
+                                 const unsigned int i,
+                                 const unsigned int index) const;
 
                                     /**
-                                     * Return a pointer to the @p ith line
-                                     * bounding this @p Hex.
+                                     * Set the index of the @p ith degree
+                                     * of freedom of this line on the
+                                     * level this line lives on to @p index.
                                      */
-    TriaIterator<dim,MGDoFObjectAccessor<1, dim> >
-    line (const unsigned int i) const;
+    void set_mg_dof_index (const int level,
+                          const unsigned int i,
+                          const unsigned int index) const;
 
                                     /**
-                                     * Return a pointer to the @p ith quad
-                                     * bounding this @p Hex.
+                                     * Copy operator.
                                      */
-    TriaIterator<dim,MGDoFObjectAccessor<2, dim> >
-    quad (const unsigned int i) const;
+    MGDoFAccessor & operator = (const MGDoFAccessor &da);
+
+    template <int, int> friend class MGDoFHandler;
 };
 
 
+/* -------------------------------------------------------------------------- */
+
+
+
 /**
  * Grant access to the degrees of freedom on cells, as far as this
- * isn't already covered by the MGDoFAccessor and MGDoFObjectAccessor
+ * isn't already covered by the MGDoFAccessor and MGDoFAccessor
  * classes from which the present class is derived. In particular,
  * this function overloads functions from CellAccessor and
  * DoFCellAccessor that return iterators to other objects, such as the
@@ -527,31 +390,82 @@ class MGDoFObjectAccessor<3, dim> :  public MGDoFAccessor<3,dim>
  * @ingroup Accessors
  * @author Wolfgang Bangerth, 1998, 2006
  */
-template <int dim>
-class MGDoFCellAccessor :  public MGDoFObjectAccessor<dim, dim>
+template <int dim, int spacedim=dim>
+class MGDoFCellAccessor :  public MGDoFAccessor<dim,dim,spacedim>
 {
   public:
                                     /**
                                      * Type of faces.
                                      */
     typedef
-    TriaIterator<dim, MGDoFObjectAccessor<dim-1, dim> >
+    TriaIterator< MGDoFAccessor<dim-1,dim,spacedim> >
     face_iterator;
                                     /**
                                      * Declare the data type that this accessor
                                      * class expects to get passed from the
                                      * iterator classes.
                                      */
-    typedef typename MGDoFObjectAccessor<dim, dim>::AccessorData  AccessorData;
+    typedef typename MGDoFAccessor<dim,dim,spacedim>::AccessorData  AccessorData;
     
+                                    /**
+                                     * @name Constructors
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
                                     /**
                                      * Constructor
                                      */
-    MGDoFCellAccessor (const Triangulation<dim> *tria,
+    MGDoFCellAccessor (const Triangulation<dim,spacedim> *tria,
                       const int                 level,
                       const int                 index,
                       const AccessorData       *local_data);
 
+                                    /**
+                                     * Conversion constructor. This
+                                     * constructor exists to make certain
+                                     * constructs simpler to write in
+                                     * dimension independent code. For
+                                     * example, it allows assigning a face
+                                     * iterator to a line iterator, an
+                                     * operation that is useful in 2d but
+                                     * doesn't make any sense in 3d. The
+                                     * constructor here exists for the
+                                     * purpose of making the code conform to
+                                     * C++ but it will unconditionally abort;
+                                     * in other words, assigning a face
+                                     * iterator to a line iterator is better
+                                     * put into an if-statement that checks
+                                     * that the dimension is two, and assign
+                                     * to a quad iterator in 3d (an operator
+                                     * that, without this constructor would
+                                     * be illegal if we happen to compile for
+                                     * 2d).
+                                     */
+    template <int structdim2, int dim2, int spacedim2>
+    MGDoFCellAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &);
+
+                                    /**
+                                     * Another conversion operator
+                                     * between objects that don't
+                                     * make sense, just like the
+                                     * previous one.
+                                     */
+    template <int dim2, class DH2>
+    MGDoFCellAccessor (const DoFAccessor<dim2, DH2> &);
+
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Accessing the DoF indices of this object
+                                     */
+                                    /**
+                                     * @{
+                                     */
+
                                     /**
                                      * Return the indices of the dofs of this
                                      * hex in the standard ordering: dofs
@@ -587,6 +501,14 @@ class MGDoFCellAccessor :  public MGDoFObjectAccessor<dim, dim>
     void get_mg_dof_values (const Vector<number> &values,
                            Vector<number>       &dof_values) const;
 
+                                    /**
+                                     * @}
+                                     */
+
+                                    /**
+                                     *  @name Accessing sub-objects and neighbors
+                                     */
+
                                     /**
                                      * Return the @p ith neighbor as a MGDoF cell
                                      * iterator. This function is needed since
@@ -594,7 +516,7 @@ class MGDoFCellAccessor :  public MGDoFObjectAccessor<dim, dim>
                                      * class returns a cell accessor without
                                      * access to the MGDoF data.
                                      */
-    TriaIterator<dim,MGDoFCellAccessor<dim> >
+    TriaIterator<MGDoFCellAccessor<dim,spacedim> >
     neighbor (const unsigned int) const;
 
                                     /**
@@ -604,7 +526,7 @@ class MGDoFCellAccessor :  public MGDoFObjectAccessor<dim, dim>
                                      * class returns a cell accessor without
                                      * access to the DoF data.
                                      */
-    TriaIterator<dim,MGDoFCellAccessor<dim> >
+    TriaIterator<MGDoFCellAccessor<dim,spacedim> >
     child (const unsigned int) const;
 
                                     /**
@@ -612,9 +534,9 @@ class MGDoFCellAccessor :  public MGDoFObjectAccessor<dim, dim>
                                      * of this cell.
                                      *
                                      * This function is not implemented in 1D,
-                                     * and maps to MGDoFObjectAccessor<2, dim>::line in 2D.
+                                     * and maps to MGDoFAccessor<2, dim>::line in 2D.
                                      */
-    face_iterator
+    typename internal::MGDoFHandler::Iterators<dim,spacedim>::face_iterator
     face (const unsigned int i) const;
 
                                     /**
@@ -628,21 +550,18 @@ class MGDoFCellAccessor :  public MGDoFObjectAccessor<dim, dim>
                                      * access to the triangulation
                                      * data).
                                      */
-    TriaIterator<dim,MGDoFCellAccessor<dim> >
+    typename internal::MGDoFHandler::Iterators<dim,spacedim>::cell_iterator
     neighbor_child_on_subface (const unsigned int face_no,
                                const unsigned int subface_no) const;
+
+                                    /**
+                                     * @}
+                                     */
 };
 
 /*@}*/
 
 
-template<> MGDoFCellAccessor<1>::face_iterator
-MGDoFCellAccessor<1>::face (const unsigned int i) const;
-template<> MGDoFCellAccessor<2>::face_iterator
-MGDoFCellAccessor<2>::face (const unsigned int i) const;
-template<> MGDoFCellAccessor<3>::face_iterator
-MGDoFCellAccessor<3>::face (const unsigned int i) const;
-
 DEAL_II_NAMESPACE_CLOSE
 
 #endif
index 7c152eea998b5b38180ebae07dab6051d0e831d3..6eb2faf514fae1cf65871692006329c71cc44e5a 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -33,45 +33,51 @@ DEAL_II_NAMESPACE_OPEN
  *
  * At present, multilevel algorithms are not fully functional, so this
  * documentation is still very brief.
+ *
+ * This class has not yet been implemented for the use in the codimension
+ * one case (<tt>spacedim != dim </tt>).
+ *
 //TODO:[WB] Extend MGDoFHandler doc 
  *
  * @author Wolfgang Bangerth, 1998, 1999
  */
-template <int dim>
-class MGDoFHandler : public DoFHandler<dim>
+template <int dim, int spacedim=dim>
+class MGDoFHandler : public DoFHandler<dim,spacedim>
 {
   public:
-    typedef typename internal::MGDoFHandler::Iterators<dim>::raw_line_iterator raw_line_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::line_iterator line_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::active_line_iterator active_line_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::raw_line_iterator raw_line_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::line_iterator line_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::active_line_iterator active_line_iterator;
 
-    typedef typename internal::MGDoFHandler::Iterators<dim>::raw_quad_iterator raw_quad_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::quad_iterator quad_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::active_quad_iterator active_quad_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::raw_quad_iterator raw_quad_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::quad_iterator quad_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::active_quad_iterator active_quad_iterator;
 
-    typedef typename internal::MGDoFHandler::Iterators<dim>::raw_hex_iterator raw_hex_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::hex_iterator hex_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::active_hex_iterator active_hex_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::raw_hex_iterator raw_hex_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::hex_iterator hex_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::active_hex_iterator active_hex_iterator;
 
-    typedef typename internal::MGDoFHandler::Iterators<dim>::raw_cell_iterator raw_cell_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::cell_iterator cell_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::active_cell_iterator active_cell_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::raw_cell_iterator raw_cell_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::cell_iterator cell_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::active_cell_iterator active_cell_iterator;
 
-    typedef typename internal::MGDoFHandler::Iterators<dim>::raw_face_iterator raw_face_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::face_iterator face_iterator;
-    typedef typename internal::MGDoFHandler::Iterators<dim>::active_face_iterator active_face_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::raw_face_iterator raw_face_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::face_iterator face_iterator;
+    typedef typename internal::MGDoFHandler::Iterators<dim,spacedim>::active_face_iterator active_face_iterator;
 
                                     /**
-                                     * Make the dimension available
+                                     * Make the dimension and the space_dimension available
                                      * in function templates.
                                      */
     static const unsigned int dimension = dim;
 
+    static const unsigned int space_dimension = spacedim;
+
                                     /**
                                      * Constructor. Take @p tria as
                                      * the triangulation to work on.
                                      */
-    MGDoFHandler (const Triangulation<dim> &tria);
+    MGDoFHandler (const Triangulation<dim, spacedim> &tria);
 
                                     /**
                                      * Destructor
@@ -92,7 +98,7 @@ class MGDoFHandler : public DoFHandler<dim>
                                      * A copy of the transferred
                                      * finite element is stored.
                                      */
-    virtual void distribute_dofs (const FiniteElement<dim> &,
+    virtual void distribute_dofs (const FiniteElement<dim,spacedim> &,
                                  const unsigned int offset = 0);
 
                                     /**
@@ -727,11 +733,24 @@ class MGDoFHandler : public DoFHandler<dim>
 
 
                                     /**
-                                     * Exception.
+                                     *  Exception
                                      */
     DeclException1 (ExcInvalidLevel,
                    int,
-                   << "The level index " << arg1 << "was not in the valid range.");
+                   << "The given level " << arg1
+                   << " is not in the valid range!");
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcFacesHaveNoLevel);
+                                    /**
+                                     * The triangulation level you
+                                     * accessed is empty.
+                                     */
+    DeclException1 (ExcEmptyLevel,
+                   int,
+                   << "You tried to do something on level " << arg1
+                   << ", but this level is empty.");
     
   private:
 
@@ -995,25 +1014,24 @@ class MGDoFHandler : public DoFHandler<dim>
                                     /**
                                      * Make accessor objects friends.
                                      */
-    template <int dim1, int dim2> friend class MGDoFAccessor;
-    template <int dim1, int dim2> friend class MGDoFObjectAccessor;
+    template <int dim1, int dim2, int dim3> friend class MGDoFAccessor;
 };
 
 /*@}*/
 
 /* ----------------------- Inline functions of MGDoFHandler -------------------*/
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-unsigned int MGDoFHandler<dim>::n_dofs() const
+unsigned int MGDoFHandler<dim,spacedim>::n_dofs() const
 {
   return DoFHandler<dim>::n_dofs();
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-void MGDoFHandler<dim>::renumber_dofs (const std::vector<unsigned int> &new_numbers)
+void MGDoFHandler<dim,spacedim>::renumber_dofs (const std::vector<unsigned int> &new_numbers)
 {
   return DoFHandler<dim>::renumber_dofs (new_numbers);
 }
@@ -1021,9 +1039,9 @@ void MGDoFHandler<dim>::renumber_dofs (const std::vector<unsigned int> &new_numb
 
 /* ----------------------- Inline functions of MGVertexDoFs -------------------*/
 
-template <int dim>
+template <int dim, int spacedim>
 inline
-void MGDoFHandler<dim>::MGVertexDoFs::set_index  (const unsigned int level,
+void MGDoFHandler<dim,spacedim>::MGVertexDoFs::set_index  (const unsigned int level,
                                                  const unsigned int dof_number,
                                                  const unsigned int dofs_per_vertex,
                                                  const unsigned int index) {
@@ -1036,10 +1054,10 @@ void MGDoFHandler<dim>::MGVertexDoFs::set_index  (const unsigned int level,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 inline
 unsigned int
-MGDoFHandler<dim>::MGVertexDoFs::get_index  (const unsigned int level,
+MGDoFHandler<dim,spacedim>::MGVertexDoFs::get_index  (const unsigned int level,
                                             const unsigned int dof_number,
                                             const unsigned int dofs_per_vertex) const {
   Assert ((level >= coarsest_level) && (level <= finest_level),
@@ -1051,252 +1069,6 @@ MGDoFHandler<dim>::MGVertexDoFs::get_index  (const unsigned int level,
 }
 
 
-template <>
-MGDoFHandler<1>::raw_cell_iterator
-MGDoFHandler<1>::begin_raw (const unsigned int level) const;
-template <>
-MGDoFHandler<1>::cell_iterator
-MGDoFHandler<1>::begin (const unsigned int level) const;
-template <>
-MGDoFHandler<1>::active_cell_iterator
-MGDoFHandler<1>::begin_active (const unsigned int level) const;
-template <>
-MGDoFHandler<1>::raw_cell_iterator
-MGDoFHandler<1>::end () const;
-template <>
-MGDoFHandler<1>::raw_cell_iterator
-MGDoFHandler<1>::last_raw () const;
-template <>
-MGDoFHandler<1>::raw_cell_iterator
-MGDoFHandler<1>::last_raw (const unsigned int level) const;
-template <>
-MGDoFHandler<1>::cell_iterator
-MGDoFHandler<1>::last () const;
-template <>
-MGDoFHandler<1>::cell_iterator
-MGDoFHandler<1>::last (const unsigned int level) const;
-template <>
-MGDoFHandler<1>::active_cell_iterator
-MGDoFHandler<1>::last_active () const;
-template <>
-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;
-template <>
-internal::MGDoFHandler::Iterators<1>::face_iterator
-MGDoFHandler<1>::begin_face () const;
-template <>
-internal::MGDoFHandler::Iterators<1>::active_face_iterator
-MGDoFHandler<1>::begin_active_face () const;
-template <>
-internal::MGDoFHandler::Iterators<1>::raw_face_iterator
-MGDoFHandler<1>::end_face () const;
-template <>
-internal::MGDoFHandler::Iterators<1>::raw_face_iterator
-MGDoFHandler<1>::last_raw_face () const;
-template <>
-internal::MGDoFHandler::Iterators<1>::face_iterator
-MGDoFHandler<1>::last_face () const;
-template <>
-internal::MGDoFHandler::Iterators<1>::active_face_iterator
-MGDoFHandler<1>::last_active_face () const;
-template <>
-MGDoFHandler<1>::raw_quad_iterator
-MGDoFHandler<1>::begin_raw_quad (const unsigned int) const;
-template <>
-MGDoFHandler<1>::quad_iterator
-MGDoFHandler<1>::begin_quad (const unsigned int) const;
-template <>
-MGDoFHandler<1>::active_quad_iterator
-MGDoFHandler<1>::begin_active_quad (const unsigned int) const;
-template <>
-MGDoFHandler<1>::raw_quad_iterator
-MGDoFHandler<1>::end_quad () const;
-template <>
-MGDoFHandler<1>::raw_quad_iterator
-MGDoFHandler<1>::last_raw_quad (const unsigned int) const;
-template <>
-MGDoFHandler<1>::quad_iterator
-MGDoFHandler<1>::last_quad (const unsigned int) const;
-template <>
-MGDoFHandler<1>::active_quad_iterator
-MGDoFHandler<1>::last_active_quad (const unsigned int) const;
-template <>
-MGDoFHandler<1>::raw_quad_iterator
-MGDoFHandler<1>::last_raw_quad () const;
-template <>
-MGDoFHandler<1>::quad_iterator
-MGDoFHandler<1>::last_quad () const;
-template <>
-MGDoFHandler<1>::active_quad_iterator
-MGDoFHandler<1>::last_active_quad () const;
-template <>
-MGDoFHandler<1>::raw_hex_iterator
-MGDoFHandler<1>::begin_raw_hex (const unsigned int) const;
-template <>
-MGDoFHandler<1>::hex_iterator
-MGDoFHandler<1>::begin_hex (const unsigned int) const;
-template <>
-MGDoFHandler<1>::active_hex_iterator
-MGDoFHandler<1>::begin_active_hex (const unsigned int) const;
-template <>
-MGDoFHandler<1>::raw_hex_iterator
-MGDoFHandler<1>::end_hex () const;
-template <>
-MGDoFHandler<1>::raw_hex_iterator
-MGDoFHandler<1>::last_raw_hex (const unsigned int) const;
-template <>
-MGDoFHandler<1>::hex_iterator
-MGDoFHandler<1>::last_hex (const unsigned int) const;
-template <>
-MGDoFHandler<1>::active_hex_iterator
-MGDoFHandler<1>::last_active_hex (const unsigned int) const;
-template <>
-MGDoFHandler<1>::raw_hex_iterator
-MGDoFHandler<1>::last_raw_hex () const;
-template <>
-MGDoFHandler<1>::hex_iterator
-MGDoFHandler<1>::last_hex () const;
-template <>
-MGDoFHandler<1>::active_hex_iterator
-MGDoFHandler<1>::last_active_hex () const;
-//======================================================================//
-template <>
-MGDoFHandler<2>::raw_cell_iterator
-MGDoFHandler<2>::begin_raw (const unsigned int level) const;
-template <>
-MGDoFHandler<2>::cell_iterator
-MGDoFHandler<2>::begin (const unsigned int level) const;
-template <>
-MGDoFHandler<2>::active_cell_iterator
-MGDoFHandler<2>::begin_active (const unsigned int level) const;
-template <>
-MGDoFHandler<2>::raw_cell_iterator
-MGDoFHandler<2>::end () const;
-template <>
-MGDoFHandler<2>::raw_cell_iterator
-MGDoFHandler<2>::last_raw () const;
-template <>
-MGDoFHandler<2>::raw_cell_iterator
-MGDoFHandler<2>::last_raw (const unsigned int level) const;
-template <>
-MGDoFHandler<2>::cell_iterator
-MGDoFHandler<2>::last () const;
-template <>
-MGDoFHandler<2>::cell_iterator
-MGDoFHandler<2>::last (const unsigned int level) const;
-template <>
-MGDoFHandler<2>::active_cell_iterator
-MGDoFHandler<2>::last_active () const;
-template <>
-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;
-template <>
-internal::MGDoFHandler::Iterators<2>::face_iterator
-MGDoFHandler<2>::begin_face () const;
-template <>
-internal::MGDoFHandler::Iterators<2>::active_face_iterator
-MGDoFHandler<2>::begin_active_face () const;
-template <>
-internal::MGDoFHandler::Iterators<2>::raw_face_iterator
-MGDoFHandler<2>::end_face () const;
-template <>
-internal::MGDoFHandler::Iterators<2>::raw_face_iterator
-MGDoFHandler<2>::last_raw_face () const;
-template <>
-internal::MGDoFHandler::Iterators<2>::face_iterator
-MGDoFHandler<2>::last_face () const;
-template <>
-internal::MGDoFHandler::Iterators<2>::active_face_iterator
-MGDoFHandler<2>::last_active_face () const;
-template <>
-MGDoFHandler<2>::raw_hex_iterator
-MGDoFHandler<2>::begin_raw_hex (const unsigned int) const;
-template <>
-MGDoFHandler<2>::hex_iterator
-MGDoFHandler<2>::begin_hex (const unsigned int) const;
-template <>
-MGDoFHandler<2>::active_hex_iterator
-MGDoFHandler<2>::begin_active_hex (const unsigned int) const;
-template <>
-MGDoFHandler<2>::raw_hex_iterator
-MGDoFHandler<2>::end_hex () const;
-template <>
-MGDoFHandler<2>::raw_hex_iterator
-MGDoFHandler<2>::last_raw_hex (const unsigned int) const;
-template <>
-MGDoFHandler<2>::hex_iterator
-MGDoFHandler<2>::last_hex (const unsigned int) const;
-template <>
-MGDoFHandler<2>::active_hex_iterator
-MGDoFHandler<2>::last_active_hex (const unsigned int) const;
-template <>
-MGDoFHandler<2>::raw_hex_iterator
-MGDoFHandler<2>::last_raw_hex () const;
-template <>
-MGDoFHandler<2>::hex_iterator
-MGDoFHandler<2>::last_hex () const;
-template <>
-MGDoFHandler<2>::active_hex_iterator
-MGDoFHandler<2>::last_active_hex () const;
-//======================================================================//
-template <>
-MGDoFHandler<3>::raw_cell_iterator
-MGDoFHandler<3>::begin_raw (const unsigned int level) const;
-template <>
-MGDoFHandler<3>::cell_iterator
-MGDoFHandler<3>::begin (const unsigned int level) const;
-template <>
-MGDoFHandler<3>::active_cell_iterator
-MGDoFHandler<3>::begin_active (const unsigned int level) const;
-template <>
-MGDoFHandler<3>::raw_cell_iterator
-MGDoFHandler<3>::end () const;
-template <>
-MGDoFHandler<3>::raw_cell_iterator
-MGDoFHandler<3>::last_raw () const;
-template <>
-MGDoFHandler<3>::raw_cell_iterator
-MGDoFHandler<3>::last_raw (const unsigned int level) const;
-template <>
-MGDoFHandler<3>::cell_iterator
-MGDoFHandler<3>::last () const;
-template <>
-MGDoFHandler<3>::cell_iterator
-MGDoFHandler<3>::last (const unsigned int level) const;
-template <>
-MGDoFHandler<3>::active_cell_iterator
-MGDoFHandler<3>::last_active () const;
-template <>
-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;
-template <>
-internal::MGDoFHandler::Iterators<3>::face_iterator
-MGDoFHandler<3>::begin_face () const;
-template <>
-internal::MGDoFHandler::Iterators<3>::active_face_iterator
-MGDoFHandler<3>::begin_active_face () const;
-template <>
-internal::MGDoFHandler::Iterators<3>::raw_face_iterator
-MGDoFHandler<3>::end_face () const;
-template <>
-internal::MGDoFHandler::Iterators<3>::raw_face_iterator
-MGDoFHandler<3>::last_raw_face () const;
-template <>
-internal::MGDoFHandler::Iterators<3>::face_iterator
-MGDoFHandler<3>::last_face () const;
-template <>
-internal::MGDoFHandler::Iterators<3>::active_face_iterator
-MGDoFHandler<3>::last_active_face () const;
-
 
 template <>
 void MGDoFHandler<1>::renumber_dofs (const unsigned int  level,
index 319edfa2fd3ed486b8cd57f221df16eea9bc62c7..6a3038c05a9ac67e6e837dced557689c608d19fa 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
 
 #include <base/config.h>
 
+
 DEAL_II_NAMESPACE_OPEN
 
-template <int celldim, int dim> class MGDoFAccessor;
-template <int celldim, int dim> class MGDoFObjectAccessor;
-template <int dim>              class MGDoFObjectAccessor<0, dim>;
-template <int dim>              class MGDoFObjectAccessor<1, dim>;
-template <int dim>              class MGDoFObjectAccessor<2, dim>;
-template <int dim>              class MGDoFObjectAccessor<3, dim>;
-template <int dim> class MGDoFCellAccessor;
+template <int celldim, int dim, int spacedim> class MGDoFAccessor;
+template <int dim, int spacedim> class MGDoFCellAccessor;
+template <int, int, int> class InvalidAccessor;
 
-template <int dim, typename Accessor> class TriaRawIterator;
-template <int dim, typename Accessor> class TriaIterator;
-template <int dim, typename Accessor> class TriaActiveIterator;
+template <typename Accessor> class TriaRawIterator;
+template <typename Accessor> class TriaIterator;
+template <typename Accessor> class TriaActiveIterator;
 
 
 namespace internal
@@ -38,129 +35,60 @@ namespace internal
 /*!@addtogroup mg */
 /*@{*/
 
-/**
- * Depending on the dimension, this class defines the iterator types for
- * MGDoFHandler objects.
- *
- * @note The typedefs in this class are only for reference. Their real
- * values are to be found in the specializations for different
- * dimensions.
- */
-    template <int dim>
-    class Iterators
-    {
-                                         /// Line iterator for internal use
-        typedef void * raw_line_iterator;
-                                         /// Line iterator for all lines of hierarchy
-        typedef void * line_iterator;
-                                         /// Iterator for active lines
-        typedef void * active_line_iterator;
-    
-                                         /// Quad iterator for internal use
-        typedef void * raw_quad_iterator;
-                                         /// Quad iterator for all quadrilaterals of hierarchy
-        typedef void * quad_iterator;
-                                         /// Iterator for active quadrilaterals
-        typedef void * active_quad_iterator;
-
-                                         /// Hex iterator for internal use
-        typedef void * raw_hex_iterator;
-                                         /// Hex iterator for all hexahedra of hierarchy
-        typedef void * hex_iterator;
-                                         /// Iterator for active hexahedra
-        typedef void * active_hex_iterator;
-
-                                         /** Cell iterator for internal
-                                          * use. It is defined as one of
-                                          * the raw iterators above,
-                                          * depending on the dimension.
-                                          */
-        typedef void * raw_cell_iterator;
-                                         /** Cell iterator for all cells
-                                          * of hierarchy. It is defined as
-                                          * one of the iterators above,
-                                          * depending on the dimension.
-                                          */
-        typedef void * cell_iterator;
-                                         /** Iterator for active cells. It
-                                          * is defined as one of the
-                                          * active iterators above,
-                                          * depending on the dimension.
-                                          */
-        typedef void * active_cell_iterator;
-
-                                         /** Face iterator for internal
-                                          * use. It is defined as one of
-                                          * the raw iterators above,
-                                          * depending on the dimension.
-                                          */
-        typedef void * raw_face_iterator;
-                                         /** Face iterator for all faces
-                                          * of hierarchy. It is defined as
-                                          * one of the iterators above,
-                                          * depending on the dimension.
-                                          */
-        typedef void * face_iterator;
-                                         /** Iterator for active faces. It
-                                          * is defined as one of the
-                                          * active iterators above,
-                                          * depending on the dimension.
-                                          */
-        typedef void * active_face_iterator;
-    };
-
+    template <int dim, int spacedim>
+    class Iterators;
 
 
 /**
- * Iterators for MGDofHandler in one dimension. See the template
- * Iterators for further explanation.
+ * Iterators for MGDofHandler in one dimension. See the @ref Iterators module
+ * for more information.
  */
-    template <>
-    class Iterators<1>
+    template <int spacedim>
+    class Iterators<1,spacedim>
     {
       public:
-        typedef TriaRawIterator<1,MGDoFCellAccessor<1> >    raw_line_iterator;
-        typedef TriaIterator<1,MGDoFCellAccessor<1> >       line_iterator;
-        typedef TriaActiveIterator<1,MGDoFCellAccessor<1> > active_line_iterator;
+        typedef TriaRawIterator<MGDoFCellAccessor<1,spacedim> >    raw_line_iterator;
+        typedef TriaIterator<MGDoFCellAccessor<1,spacedim> >       line_iterator;
+        typedef TriaActiveIterator<MGDoFCellAccessor<1,spacedim> > active_line_iterator;
 
-        typedef void * raw_quad_iterator;
-        typedef void * quad_iterator;
-        typedef void * active_quad_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<2,1,spacedim> > raw_quad_iterator;
+        typedef TriaIterator      <InvalidAccessor<2,1,spacedim> > quad_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<2,1,spacedim> > active_quad_iterator;
 
-        typedef void * raw_hex_iterator;
-        typedef void * hex_iterator;
-        typedef void * active_hex_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<3,1,spacedim> > raw_hex_iterator;
+        typedef TriaIterator      <InvalidAccessor<3,1,spacedim> > hex_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<3,1,spacedim> > active_hex_iterator;
 
         typedef raw_line_iterator    raw_cell_iterator;
         typedef line_iterator        cell_iterator;
         typedef active_line_iterator active_cell_iterator;
 
-        typedef void * raw_face_iterator;
-        typedef void * face_iterator;
-        typedef void * active_face_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<0,1,spacedim> > raw_face_iterator;
+        typedef TriaIterator      <InvalidAccessor<0,1,spacedim> > face_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<0,1,spacedim> > active_face_iterator;
     };
 
 
 
 /**
- * Iterators for MGDofHandler in one dimension. See the template
- * Iterators for further explanation.
+ * Iterators for MGDofHandler in two dimensions. See the @ref Iterators module
+ * for more information.
  */
-    template <>
-    class Iterators<2>
+    template <int spacedim>
+    class Iterators<2,spacedim>
     {
       public:
-        typedef TriaRawIterator<2,MGDoFObjectAccessor<1, 2> >    raw_line_iterator;
-        typedef TriaIterator<2,MGDoFObjectAccessor<1, 2> >       line_iterator;
-        typedef TriaActiveIterator<2,MGDoFObjectAccessor<1, 2> > active_line_iterator;
+        typedef TriaRawIterator<MGDoFAccessor<1,2,spacedim> >    raw_line_iterator;
+        typedef TriaIterator<MGDoFAccessor<1,2,spacedim> >       line_iterator;
+        typedef TriaActiveIterator<MGDoFAccessor<1,2,spacedim> > active_line_iterator;
     
-        typedef TriaRawIterator<2,MGDoFCellAccessor<2> >         raw_quad_iterator;
-        typedef TriaIterator<2,MGDoFCellAccessor<2> >            quad_iterator;
-        typedef TriaActiveIterator<2,MGDoFCellAccessor<2> >      active_quad_iterator;
+        typedef TriaRawIterator<MGDoFCellAccessor<2,spacedim> >         raw_quad_iterator;
+        typedef TriaIterator<MGDoFCellAccessor<2,spacedim> >            quad_iterator;
+        typedef TriaActiveIterator<MGDoFCellAccessor<2,spacedim> >      active_quad_iterator;
 
-        typedef void * raw_hex_iterator;
-        typedef void * hex_iterator;
-        typedef void * active_hex_iterator;
+        typedef TriaRawIterator   <InvalidAccessor<3,2,spacedim> > raw_hex_iterator;
+        typedef TriaIterator      <InvalidAccessor<3,2,spacedim> > hex_iterator;
+        typedef TriaActiveIterator<InvalidAccessor<3,2,spacedim> > active_hex_iterator;
 
         typedef raw_quad_iterator    raw_cell_iterator;
         typedef quad_iterator        cell_iterator;
@@ -174,24 +102,24 @@ namespace internal
 
 
 /**
- * Iterators for MGDofHandler in one dimension. See the template
- * Iterators for further explanation.
+ * Iterators for MGDofHandler in three dimensions. See the @ref Iterators module
+ * for more information.
  */
-    template <>
-    class Iterators<3>
+    template <int spacedim>
+    class Iterators<3,spacedim>
     {
       public:
-        typedef TriaRawIterator<3,MGDoFObjectAccessor<1, 3> >    raw_line_iterator;
-        typedef TriaIterator<3,MGDoFObjectAccessor<1, 3> >       line_iterator;
-        typedef TriaActiveIterator<3,MGDoFObjectAccessor<1, 3> > active_line_iterator;
+        typedef TriaRawIterator<MGDoFAccessor<1,3,spacedim> >    raw_line_iterator;
+        typedef TriaIterator<MGDoFAccessor<1,3,spacedim> >       line_iterator;
+        typedef TriaActiveIterator<MGDoFAccessor<1,3,spacedim> > active_line_iterator;
 
-        typedef TriaRawIterator<3,MGDoFObjectAccessor<2, 3> >    raw_quad_iterator;
-        typedef TriaIterator<3,MGDoFObjectAccessor<2, 3> >       quad_iterator;
-        typedef TriaActiveIterator<3,MGDoFObjectAccessor<2, 3> > active_quad_iterator;
+        typedef TriaRawIterator<MGDoFAccessor<2,3,spacedim> >    raw_quad_iterator;
+        typedef TriaIterator<MGDoFAccessor<2,3,spacedim> >       quad_iterator;
+        typedef TriaActiveIterator<MGDoFAccessor<2,3,spacedim> > active_quad_iterator;
 
-        typedef TriaRawIterator<3,MGDoFCellAccessor<3> >               raw_hex_iterator;
-        typedef TriaIterator<3,MGDoFCellAccessor<3> >                  hex_iterator;
-        typedef TriaActiveIterator<3,MGDoFCellAccessor<3> >            active_hex_iterator;
+        typedef TriaRawIterator<MGDoFCellAccessor<3,spacedim> >        raw_hex_iterator;
+        typedef TriaIterator<MGDoFCellAccessor<3,spacedim> >           hex_iterator;
+        typedef TriaActiveIterator<MGDoFCellAccessor<3,spacedim> >     active_hex_iterator;
 
         typedef raw_hex_iterator    raw_cell_iterator;
         typedef hex_iterator        cell_iterator;
index fd184f972bcb44aa9317220cec90f708ae6dc603..1604120e9d69c4377c11a1d3716555a8157460d7 100644 (file)
@@ -24,7 +24,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class MGDoFHandler;
+template <int dim, int spacedim> class MGDoFHandler;
 
 
 /*
@@ -106,7 +106,7 @@ class MGSmootherContinuous : public MGSmootherBase<VECTOR>
                                      * about this text is, that there
                                      * is no 1d implementation.
                                      */
-    MGSmootherContinuous (const MGDoFHandler<1> &mg_dof,
+    MGSmootherContinuous (const MGDoFHandler<1,1> &mg_dof,
                          const unsigned int     steps);
 
                                     /**
@@ -122,8 +122,8 @@ class MGSmootherContinuous : public MGSmootherBase<VECTOR>
                                      * the number of smoothing steps
                                      * to be executed by @p smooth.
                                      */
-    template <int dim>
-    MGSmootherContinuous (const MGDoFHandler<dim> &mg_dof,
+    template <int dim, int spacedim>
+    MGSmootherContinuous (const MGDoFHandler<dim,spacedim> &mg_dof,
                          const unsigned int       steps);    
 
                                     /**
index 40de401816b33fa8cfbaab67bc2709b86326e283..e750f812333283f783a627a433216a1638ee11ab 100644 (file)
@@ -25,7 +25,7 @@
 DEAL_II_NAMESPACE_OPEN
 
 template <class Object> class MGLevelObject;
-template <int dim> class MGDoFHandler;
+template <int dim, int spacedim> class MGDoFHandler;
 template <typename number> class Vector;
 template <typename number> class SparseMatrix;
 template <typename number> class BlockVector;
@@ -56,10 +56,10 @@ class MGTools
                                      * Compute row length vector for
                                      * multilevel methods.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     void compute_row_length_vector(
-      const MGDoFHandler<dim>& dofs,
+      const MGDoFHandler<dim,spacedim>& dofs,
       const unsigned int level,
       std::vector<unsigned int>& row_lengths,
       const DoFTools::Coupling flux_couplings = DoFTools::none);
@@ -70,10 +70,10 @@ class MGTools
                                      * optimization for block
                                      * couplings.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
     void compute_row_length_vector(
-      const MGDoFHandler<dim>& dofs,
+      const MGDoFHandler<dim,spacedim>& dofs,
       const unsigned int level,
       std::vector<unsigned int>& row_lengths,
       const Table<2,DoFTools::Coupling>& couplings,
@@ -93,9 +93,9 @@ class MGTools
                                      * hanging nodes here, since only
                                      * one level is considered.
                                      */
-    template <int dim, class SparsityPattern>
+    template <int dim, class SparsityPattern, int spacedim>
     static void
-    make_sparsity_pattern (const MGDoFHandler<dim> &dof_handler,
+    make_sparsity_pattern (const MGDoFHandler<dim,spacedim> &dof_handler,
                           SparsityPattern         &sparsity,
                           const unsigned int       level);
 
@@ -105,9 +105,9 @@ class MGTools
                                      * @ref make_sparsity_pattern
                                      * @ref DoFTools
                                      */
-    template <int dim, class SparsityPattern>
+    template <int dim, class SparsityPattern, int spacedim>
     static void
-    make_flux_sparsity_pattern (const MGDoFHandler<dim> &dof_handler,
+    make_flux_sparsity_pattern (const MGDoFHandler<dim,spacedim> &dof_handler,
                                SparsityPattern         &sparsity,
                                const unsigned int       level);
 
@@ -121,9 +121,9 @@ class MGTools
                                      *
                                      * make_flux_sparsity_pattern()
                                      */
-    template <int dim, class SparsityPattern>
+    template <int dim, class SparsityPattern, int spacedim>
     static void
-    make_flux_sparsity_pattern_edge (const MGDoFHandler<dim> &dof_handler,
+    make_flux_sparsity_pattern_edge (const MGDoFHandler<dim,spacedim> &dof_handler,
                                     SparsityPattern         &sparsity,
                                     const unsigned int       level);
 
@@ -144,9 +144,9 @@ class MGTools
                                      * for the couplings occuring in
                                      * fluxes.
                                      */
-    template <int dim, class SparsityPattern>
+    template <int dim, class SparsityPattern, int spacedim>
     static void
-    make_flux_sparsity_pattern (const MGDoFHandler<dim> &dof,
+    make_flux_sparsity_pattern (const MGDoFHandler<dim,spacedim> &dof,
                                SparsityPattern       &sparsity,
                                const unsigned int level,
                                const Table<2,DoFTools::Coupling> &int_mask,
@@ -164,9 +164,9 @@ class MGTools
                                      *
                                      * make_flux_sparsity_pattern()
                                      */
-    template <int dim, class SparsityPattern>
+    template <int dim, class SparsityPattern, int spacedim>
     static void
-    make_flux_sparsity_pattern_edge (const MGDoFHandler<dim> &dof_handler,
+    make_flux_sparsity_pattern_edge (const MGDoFHandler<dim,spacedim> &dof_handler,
                                     SparsityPattern         &sparsity,
                                     const unsigned int       level,
                                     const Table<2,DoFTools::Coupling> &flux_mask);
@@ -181,9 +181,9 @@ class MGTools
                                      * for each block (access is
                                      * <tt>result[level][block]</tt>).
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
       static void count_dofs_per_block (
-       const MGDoFHandler<dim> &mg_dof,
+       const MGDoFHandler<dim,spacedim> &mg_dof,
        std::vector<std::vector<unsigned int> > &result,
        std::vector<unsigned int> target_block = std::vector<unsigned int>());
 
@@ -197,9 +197,9 @@ class MGTools
                                      * for each component (access is
                                      * <tt>result[level][component]</tt>).
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
       static void count_dofs_per_component (
-       const MGDoFHandler<dim> &mg_dof,
+       const MGDoFHandler<dim,spacedim> &mg_dof,
        std::vector<std::vector<unsigned int> > &result,
        const bool only_once = false,
        std::vector<unsigned int> target_component = std::vector<unsigned int>());
@@ -209,9 +209,9 @@ class MGTools
                                      * other function with same name,
                                      * introduced for compatibility.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
       static void count_dofs_per_component (
-       const MGDoFHandler<dim> &mg_dof,
+       const MGDoFHandler<dim,spacedim> &mg_dof,
        std::vector<std::vector<unsigned int> > &result,
        std::vector<unsigned int> target_component);
 
@@ -237,9 +237,9 @@ class MGTools
                                      * length has to match the number
                                      * of levels.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static void make_boundary_list(
-      const MGDoFHandler<dim>& mg_dof,
+      const MGDoFHandler<dim,spacedim>& mg_dof,
       const typename FunctionMap<dim>::type& function_map,
       std::vector<std::set<unsigned int> >& boundary_indices,
       const std::vector<bool>& component_mask = std::vector<bool>());
@@ -264,9 +264,9 @@ class MGTools
                                      * @p reinit each level vector
                                      * to this length.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
       static void
-      reinit_vector (const MGDoFHandler<dim> &mg_dof,
+      reinit_vector (const MGDoFHandler<dim,spacedim> &mg_dof,
                     MGLevelObject<Vector<number> > &vector);
 
                                     /**
@@ -277,9 +277,9 @@ class MGTools
                                      * @p reinit each level vector
                                      * to this length.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
       static void
-      reinit_vector (const MGDoFHandler<dim> &mg_dof,
+      reinit_vector (const MGDoFHandler<dim,spacedim> &mg_dof,
                     MGLevelObject<BlockVector<number> > &vector);
 
 
@@ -290,10 +290,10 @@ class MGTools
                                      * counted by block and only the
                                      * block selected is used.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static void
     reinit_vector_by_blocks (
-      const MGDoFHandler<dim> &mg_dof,
+      const MGDoFHandler<dim,spacedim> &mg_dof,
       MGLevelObject<Vector<number> > &v,
       const unsigned int selected,
       std::vector<std::vector<unsigned int> >& cached_sizes);
@@ -304,10 +304,10 @@ class MGTools
                                      * degrees of freedom on each
                                      * level are counted by block.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static void
     reinit_vector_by_blocks (
-      const MGDoFHandler<dim> &mg_dof,
+      const MGDoFHandler<dim,spacedim> &mg_dof,
       MGLevelObject<BlockVector<number> > &v,
       const std::vector<bool> &selected,
       std::vector<std::vector<unsigned int> >& cached_sizes);
@@ -346,9 +346,9 @@ class MGTools
                                      *
                                      * 
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
       static void
-      reinit_vector_by_components (const MGDoFHandler<dim>& mg_dof,
+      reinit_vector_by_components (const MGDoFHandler<dim,spacedim>& mg_dof,
                                   MGLevelObject<BlockVector<number> >& v,
                                   const std::vector<bool>& selected,
                                   const std::vector<unsigned int>& target_component,
@@ -379,10 +379,10 @@ class MGTools
                                      * as in
                                      * DoFRenumbering::component_wise.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
       static void
       reinit_vector_by_components (
-       const MGDoFHandler<dim> &mg_dof,
+       const MGDoFHandler<dim,spacedim> &mg_dof,
        MGLevelObject<Vector<number> > &v,
        const std::vector<bool> &selected,
        const std::vector<unsigned int> &target_component,
index 9bb9fc1f8e5e130135f7b00ba9d3a31eea492bce..a7a21639939eff7d3093b75f2e1aa6cc612835b7 100644 (file)
@@ -38,7 +38,7 @@
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int dim> class MGDoFHandler;
+template <int dim, int spacedim> class MGDoFHandler;
 
 /*
  * MGTransferBase is defined in mg_base.h
@@ -72,8 +72,8 @@ class MGTransferPrebuilt : public MGTransferBase<VECTOR>
                                      * Actually build the prolongation
                                      * matrices for each level.
                                      */
-    template <int dim>
-    void build_matrices (const MGDoFHandler<dim> &mg_dof);
+    template <int dim, int spacedim>
+    void build_matrices (const MGDoFHandler<dim,spacedim> &mg_dof);
 
     virtual void prolongate (const unsigned int    to_level,
                             VECTOR       &dst,
@@ -89,9 +89,9 @@ class MGTransferPrebuilt : public MGTransferBase<VECTOR>
                                      * on each of the levels
                                      * separately, i.a. an @p MGVector.
                                      */
-    template <int dim, class InVector>
+    template <int dim, class InVector, int spacedim>
     void
-    copy_to_mg (const MGDoFHandler<dim>& mg_dof,
+    copy_to_mg (const MGDoFHandler<dim,spacedim>& mg_dof,
                MGLevelObject<VECTOR>& dst,
                const InVector& src) const;
 
@@ -107,9 +107,9 @@ class MGTransferPrebuilt : public MGTransferBase<VECTOR>
                                      * constrained degrees of freedom
                                      * are set to zero.
                                      */
-    template <int dim, class OutVector>
+    template <int dim, class OutVector, int spacedim>
     void
-    copy_from_mg (const MGDoFHandler<dim>& mg_dof,
+    copy_from_mg (const MGDoFHandler<dim,spacedim>& mg_dof,
                  OutVector& dst,
                  const MGLevelObject<VECTOR> &src) const;
 
@@ -121,9 +121,9 @@ class MGTransferPrebuilt : public MGTransferBase<VECTOR>
                                      * function, but probably not for
                                      * continuous elements.
                                      */
-    template <int dim, class OutVector>
+    template <int dim, class OutVector, int spacedim>
     void
-    copy_from_mg_add (const MGDoFHandler<dim>& mg_dof,
+    copy_from_mg_add (const MGDoFHandler<dim,spacedim>& mg_dof,
                      OutVector& dst,
                      const MGLevelObject<VECTOR>& src) const;
 
index 750a69bbca462891a219491b95719ebc45020ef8..defcfc4b3d49c825df3322f3f065b3e1bb17887b 100644 (file)
@@ -34,10 +34,10 @@ typedef std::map<unsigned int, unsigned int>::const_iterator IT;
 
 
 template <class VECTOR>
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 void
 MGTransferPrebuilt<VECTOR>::copy_to_mg (
-  const MGDoFHandler<dim>& mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>& mg_dof_handler,
   MGLevelObject<VECTOR>& dst,
   const InVector& src) const
 {
@@ -58,10 +58,10 @@ MGTransferPrebuilt<VECTOR>::copy_to_mg (
 
 
 template <class VECTOR>
-template <int dim, class OutVector>
+template <int dim, class OutVector, int spacedim>
 void
 MGTransferPrebuilt<VECTOR>::copy_from_mg(
-  const MGDoFHandler<dim>&       mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&       mg_dof_handler,
   OutVector&                     dst,
   const MGLevelObject<VECTOR>& src) const
 {
@@ -74,10 +74,10 @@ MGTransferPrebuilt<VECTOR>::copy_from_mg(
 
 
 template <class VECTOR>
-template <int dim, class OutVector>
+template <int dim, class OutVector, int spacedim>
 void
 MGTransferPrebuilt<VECTOR>::copy_from_mg_add (
-  const MGDoFHandler<dim>              &mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>              &mg_dof_handler,
   OutVector                            &dst,
   const MGLevelObject<VECTOR> &src) const
 {
index 1e39f1756259112576b7e70b9d73f0a18d7bde0f..11f6f991170389ec0b4674a91e497f2fbe33abc3 100644 (file)
@@ -39,7 +39,7 @@
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int dim> class MGDoFHandler;
+template <int dim, int spacedim> class MGDoFHandler;
 
 /*
  * MGTransferBase is defined in mg_base.h
@@ -78,9 +78,9 @@ class MGTransferBlockBase
                                      * restrict the transfer matrices
                                      * to certain blocks.
                                      */
-    template <int dim>
-    void build_matrices (const DoFHandler<dim>& dof,
-                        const MGDoFHandler<dim>& mg_dof);
+    template <int dim, int spacedim>
+    void build_matrices (const DoFHandler<dim,spacedim>& dof,
+                        const MGDoFHandler<dim,spacedim>& mg_dof);
 
                                   /**
                                    * Flag of selected blocks.
@@ -214,9 +214,9 @@ class MGTransferBlock : public MGTransferBase<BlockVector<number> >,
                                      * for the same function in
                                      * MGTransferBlockBase.
                                      */
-    template <int dim>
-    void build_matrices (const DoFHandler<dim> &dof,
-                        const MGDoFHandler<dim> &mg_dof,
+    template<int dim, int spacedim>
+    void build_matrices (const DoFHandler<dim,spacedim> &dof,
+                        const MGDoFHandler<dim,spacedim> &mg_dof,
                         const std::vector<bool>& selected);
 
     virtual void prolongate (const unsigned int    to_level,
@@ -242,9 +242,9 @@ class MGTransferBlock : public MGTransferBase<BlockVector<number> >,
                                      * restricted down to the
                                      * coarsest level.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_to_mg (const MGDoFHandler<dim>& mg_dof,
+    copy_to_mg (const MGDoFHandler<dim,spacedim>& mg_dof,
                MGLevelObject<BlockVector<number> >& dst,
                const BlockVector<number2>& src) const;
 
@@ -257,9 +257,9 @@ class MGTransferBlock : public MGTransferBase<BlockVector<number> >,
                                      * vector into the respective
                                      * positions of a global vector.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg (const MGDoFHandler<dim>& mg_dof,
+    copy_from_mg (const MGDoFHandler<dim,spacedim>& mg_dof,
                  BlockVector<number2>& dst,
                  const MGLevelObject<BlockVector<number> > &src) const;
 
@@ -271,9 +271,9 @@ class MGTransferBlock : public MGTransferBase<BlockVector<number> >,
                                      * function, but probably not for
                                      * continuous elements.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg_add (const MGDoFHandler<dim>& mg_dof,
+    copy_from_mg_add (const MGDoFHandler<dim,spacedim>& mg_dof,
                      BlockVector<number2>& dst,
                      const MGLevelObject<BlockVector<number> > &src) const;
 
@@ -339,9 +339,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * transfer matrices should be
                                      * built.
                                      */
-    template <int dim>
-    void build_matrices (const DoFHandler<dim> &dof,
-                        const MGDoFHandler<dim> &mg_dof,
+    template<int dim, int spacedim>
+    void build_matrices (const DoFHandler<dim,spacedim> &dof,
+                        const MGDoFHandler<dim,spacedim> &mg_dof,
                         unsigned int selected);
 
                                     /**
@@ -363,9 +363,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * vector on the global grid to a
                                      * multilevel vector.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_to_mg (const MGDoFHandler<dim>        &mg_dof,
+    copy_to_mg (const MGDoFHandler<dim,spacedim>        &mg_dof,
                MGLevelObject<Vector<number> > &dst,
                const Vector<number2>          &src) const;
 
@@ -378,9 +378,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * vector into the respective
                                      * positions of a Vector.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg (const MGDoFHandler<dim>              &mg_dof,
+    copy_from_mg (const MGDoFHandler<dim,spacedim>              &mg_dof,
                  Vector<number2>                      &dst,
                  const MGLevelObject<Vector<number> > &src) const;
 
@@ -392,9 +392,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * function, but probably not for
                                      * continuous elements.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg_add (const MGDoFHandler<dim>              &mg_dof,
+    copy_from_mg_add (const MGDoFHandler<dim,spacedim>              &mg_dof,
                      Vector<number2>                      &dst,
                      const MGLevelObject<Vector<number> > &src) const;
 
@@ -404,9 +404,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * multilevel vectors. Only the
                                      * block selected is transfered.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_to_mg (const MGDoFHandler<dim>        &mg_dof,
+    copy_to_mg (const MGDoFHandler<dim,spacedim>        &mg_dof,
                MGLevelObject<Vector<number> > &dst,
                const BlockVector<number2>     &src) const;
 
@@ -420,9 +420,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * positions of a global
                                      * BlockVector.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg (const MGDoFHandler<dim>              &mg_dof,
+    copy_from_mg (const MGDoFHandler<dim,spacedim>              &mg_dof,
                  BlockVector<number2>                 &dst,
                  const MGLevelObject<Vector<number> > &src) const;
 
@@ -434,9 +434,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * function, but probably not for
                                      * continuous elements.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg_add (const MGDoFHandler<dim>              &mg_dof,
+    copy_from_mg_add (const MGDoFHandler<dim,spacedim>              &mg_dof,
                      BlockVector<number2>                 &dst,
                      const MGLevelObject<Vector<number> > &src) const;
 
@@ -450,9 +450,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * Implementation of the public
                                      * function.
                                      */
-    template <int dim, class OutVector>
+    template <int dim, class OutVector, int spacedim>
     void
-    do_copy_from_mg (const MGDoFHandler<dim>              &mg_dof,
+    do_copy_from_mg (const MGDoFHandler<dim,spacedim>              &mg_dof,
                     OutVector                            &dst,
                     const MGLevelObject<Vector<number> > &src,
                     const unsigned int offset) const;
@@ -461,9 +461,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * Implementation of the public
                                      * function.
                                      */
-    template <int dim, class OutVector>
+    template <int dim, class OutVector, int spacedim>
     void
-    do_copy_from_mg_add (const MGDoFHandler<dim>              &mg_dof,
+    do_copy_from_mg_add (const MGDoFHandler<dim,spacedim>              &mg_dof,
                         OutVector                            &dst,
                         const MGLevelObject<Vector<number> > &src,
                         const unsigned int offset) const;
@@ -472,9 +472,9 @@ class MGTransferBlockSelect : public MGTransferBase<Vector<number> >,
                                      * Actual implementation of
                                      * copy_to_mg().
                                      */
-    template <int dim, class InVector>
+    template <int dim, class InVector, int spacedim>
     void
-    do_copy_to_mg (const MGDoFHandler<dim>        &mg_dof,
+    do_copy_to_mg (const MGDoFHandler<dim,spacedim>        &mg_dof,
                   MGLevelObject<Vector<number> > &dst,
                   const InVector                 &src,
                   const unsigned int              offset) const;
index d9ff8a47b5084fc9d5c8c79c0fc201a377c42eea..9ac0705c2a9ea99a1c81f22ae16b03157264d683 100644 (file)
@@ -35,10 +35,10 @@ typedef std::map<unsigned int, unsigned int>::const_iterator IT;
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferBlockSelect<number>::copy_to_mg (
-  const MGDoFHandler<dim>        &mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>        &mg_dof_handler,
   MGLevelObject<Vector<number> > &dst,
   const BlockVector<number2>     &src) const
 {
@@ -63,10 +63,10 @@ MGTransferBlockSelect<number>::copy_to_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferBlockSelect<number>::copy_to_mg (
-  const MGDoFHandler<dim>        &mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>        &mg_dof_handler,
   MGLevelObject<Vector<number> > &dst,
   const Vector<number2>          &src) const
 {
@@ -90,10 +90,10 @@ MGTransferBlockSelect<number>::copy_to_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferBlockSelect<number>::copy_from_mg (
-  const MGDoFHandler<dim>&              mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&              mg_dof_handler,
   BlockVector<number2>&                 dst,
   const MGLevelObject<Vector<number> >& src) const
 {
@@ -106,10 +106,10 @@ MGTransferBlockSelect<number>::copy_from_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferBlockSelect<number>::copy_from_mg (
-  const MGDoFHandler<dim>&              mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&              mg_dof_handler,
   Vector<number2>&                      dst,
   const MGLevelObject<Vector<number> >& src) const
 {
@@ -122,10 +122,10 @@ MGTransferBlockSelect<number>::copy_from_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferBlockSelect<number>::copy_from_mg_add (
-  const MGDoFHandler<dim>&              mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&              mg_dof_handler,
   BlockVector<number2>&                 dst,
   const MGLevelObject<Vector<number> >& src) const
 {
@@ -138,10 +138,10 @@ MGTransferBlockSelect<number>::copy_from_mg_add (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferBlockSelect<number>::copy_from_mg_add (
-  const MGDoFHandler<dim>&              mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&              mg_dof_handler,
   Vector<number2>&                      dst,
   const MGLevelObject<Vector<number> >& src) const
 {
@@ -166,10 +166,10 @@ MGTransferBlockSelect<number>::memory_consumption () const
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferBlock<number>::copy_to_mg (
-  const MGDoFHandler<dim>& mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>& mg_dof_handler,
   MGLevelObject<BlockVector<number> >& dst,
   const BlockVector<number2>& src) const
 {
@@ -193,10 +193,10 @@ MGTransferBlock<number>::copy_to_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferBlock<number>::copy_from_mg (
-  const MGDoFHandler<dim>& mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>& mg_dof_handler,
   BlockVector<number2>& dst,
   const MGLevelObject<BlockVector<number> >& src) const
 {
@@ -211,10 +211,10 @@ MGTransferBlock<number>::copy_from_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferBlock<number>::copy_from_mg_add (
-  const MGDoFHandler<dim>& mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>& mg_dof_handler,
   BlockVector<number2>& dst,
   const MGLevelObject<BlockVector<number> >& src) const
 {
index 23ac1643a3af1835b48665cf88bf485bbd1f279c..6384012c2107d5a31093d32819670dc78b379bd4 100644 (file)
@@ -38,7 +38,7 @@
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int dim> class MGDoFHandler;
+template <int dim, int spacedim> class MGDoFHandler;
 
 /*
  * MGTransferBase is defined in mg_base.h
@@ -82,9 +82,9 @@ class MGTransferComponentBase
                                      * re-ordering and grouping of
                                      * components.
                                      */
-    template <int dim>
-    void build_matrices (const DoFHandler<dim>& dof,
-                        const MGDoFHandler<dim>& mg_dof);
+    template <int dim, int spacedim>
+    void build_matrices (const DoFHandler<dim,spacedim>& dof,
+                        const MGDoFHandler<dim,spacedim>& mg_dof);
 
                                   /**
                                    * Flag of selected components.
@@ -234,9 +234,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * also affects the behavior of
                                      * the <tt>selected</tt> argument
                                      */
-    template <int dim>
-    void build_matrices (const DoFHandler<dim> &dof,
-                        const MGDoFHandler<dim> &mg_dof,
+    template <int dim, int spacedim>
+    void build_matrices (const DoFHandler<dim,spacedim> &dof,
+                        const MGDoFHandler<dim,spacedim> &mg_dof,
                         unsigned int selected,
                         unsigned int mg_selected,
                         const std::vector<unsigned int>& target_component
@@ -263,9 +263,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * Transfer from a vector on the
                                      * global grid to a multilevel vector.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_to_mg (const MGDoFHandler<dim>        &mg_dof,
+    copy_to_mg (const MGDoFHandler<dim,spacedim>        &mg_dof,
                MGLevelObject<Vector<number> > &dst,
                const Vector<number2>          &src) const;
 
@@ -278,9 +278,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * vector into the respective
                                      * positions of a Vector.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg (const MGDoFHandler<dim>              &mg_dof,
+    copy_from_mg (const MGDoFHandler<dim,spacedim>              &mg_dof,
                  Vector<number2>                      &dst,
                  const MGLevelObject<Vector<number> > &src) const;
 
@@ -292,9 +292,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * function, but probably not for
                                      * continuous elements.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg_add (const MGDoFHandler<dim>              &mg_dof,
+    copy_from_mg_add (const MGDoFHandler<dim,spacedim>              &mg_dof,
                      Vector<number2>                      &dst,
                      const MGLevelObject<Vector<number> > &src) const;
 
@@ -302,9 +302,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * Transfer from a vector on the
                                      * global grid to multilevel vectors.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_to_mg (const MGDoFHandler<dim>        &mg_dof,
+    copy_to_mg (const MGDoFHandler<dim,spacedim>        &mg_dof,
                MGLevelObject<Vector<number> > &dst,
                const BlockVector<number2>     &src) const;
 
@@ -318,9 +318,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * positions of a global
                                      * BlockVector.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg (const MGDoFHandler<dim>              &mg_dof,
+    copy_from_mg (const MGDoFHandler<dim,spacedim>              &mg_dof,
                  BlockVector<number2>                 &dst,
                  const MGLevelObject<Vector<number> > &src) const;
 
@@ -332,9 +332,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * function, but probably not for
                                      * continuous elements.
                                      */
-    template <int dim, typename number2>
+    template <int dim, typename number2, int spacedim>
     void
-    copy_from_mg_add (const MGDoFHandler<dim>              &mg_dof,
+    copy_from_mg_add (const MGDoFHandler<dim,spacedim>              &mg_dof,
                      BlockVector<number2>                 &dst,
                      const MGLevelObject<Vector<number> > &src) const;
 
@@ -348,9 +348,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * Implementation of the public
                                      * function.
                                      */
-    template <int dim, class OutVector>
+    template <int dim, class OutVector, int spacedim>
     void
-    do_copy_from_mg (const MGDoFHandler<dim>              &mg_dof,
+    do_copy_from_mg (const MGDoFHandler<dim,spacedim>              &mg_dof,
                     OutVector                            &dst,
                     const MGLevelObject<Vector<number> > &src,
                     const unsigned int offset) const;
@@ -359,9 +359,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * Implementation of the public
                                      * function.
                                      */
-    template <int dim, class OutVector>
+    template <int dim, class OutVector, int spacedim>
     void
-    do_copy_from_mg_add (const MGDoFHandler<dim>              &mg_dof,
+    do_copy_from_mg_add (const MGDoFHandler<dim,spacedim>              &mg_dof,
                         OutVector                            &dst,
                         const MGLevelObject<Vector<number> > &src,
                         const unsigned int offset) const;
@@ -370,9 +370,9 @@ class MGTransferSelect : public MGTransferBase<Vector<number> >,
                                      * Actual implementation of
                                      * copy_to_mg().
                                      */
-    template <int dim, class InVector>
+    template <int dim, class InVector, int spacedim>
     void
-    do_copy_to_mg (const MGDoFHandler<dim>        &mg_dof,
+    do_copy_to_mg (const MGDoFHandler<dim,spacedim>        &mg_dof,
                   MGLevelObject<Vector<number> > &dst,
                   const InVector                 &src,
                   const unsigned int              offset) const;
index 1c4667ecf776a495b89be92d307f22fedd87d557..a8b23c023b97095a0521be66e40aa85220066017 100644 (file)
@@ -32,10 +32,10 @@ DEAL_II_NAMESPACE_OPEN
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferSelect<number>::copy_to_mg (
-  const MGDoFHandler<dim>        &mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>        &mg_dof_handler,
   MGLevelObject<Vector<number> > &dst,
   const BlockVector<number2>     &src) const
 {
@@ -45,10 +45,10 @@ MGTransferSelect<number>::copy_to_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferSelect<number>::copy_to_mg (
-  const MGDoFHandler<dim>        &mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>        &mg_dof_handler,
   MGLevelObject<Vector<number> > &dst,
   const Vector<number2>          &src) const
 {
@@ -58,10 +58,10 @@ MGTransferSelect<number>::copy_to_mg (
 
 
 template <typename number>
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 void
 MGTransferSelect<number>::do_copy_to_mg (
-  const MGDoFHandler<dim>&        mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&        mg_dof_handler,
   MGLevelObject<Vector<number> >& dst,
   const InVector&                 src,
   const unsigned int              offset) const
@@ -111,9 +111,9 @@ MGTransferSelect<number>::do_copy_to_mg (
   for (int level=maxlevel; level>=static_cast<signed int>(minlevel); --level)
     {
 
-  typename MGDoFHandler<dim>::active_cell_iterator
+  typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_cell = mg_dof_handler.begin_active(level);
-      const typename MGDoFHandler<dim>::active_cell_iterator
+      const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_end  = mg_dof_handler.end_active(level);
                                       // Compute coarse level right hand side
                                       // by restricting from fine level.
@@ -158,10 +158,10 @@ MGTransferSelect<number>::do_copy_to_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferSelect<number>::copy_from_mg (
-  const MGDoFHandler<dim>&              mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&              mg_dof_handler,
   BlockVector<number2>&                 dst,
   const MGLevelObject<Vector<number> >& src) const
 {
@@ -171,10 +171,10 @@ MGTransferSelect<number>::copy_from_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferSelect<number>::copy_from_mg (
-  const MGDoFHandler<dim>&              mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&              mg_dof_handler,
   Vector<number2>&                      dst,
   const MGLevelObject<Vector<number> >& src) const
 {
@@ -185,10 +185,10 @@ MGTransferSelect<number>::copy_from_mg (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferSelect<number>::copy_from_mg_add (
-  const MGDoFHandler<dim>&              mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&              mg_dof_handler,
   BlockVector<number2>&                 dst,
   const MGLevelObject<Vector<number> >& src) const
 {
@@ -198,10 +198,10 @@ MGTransferSelect<number>::copy_from_mg_add (
 
 
 template <typename number>
-template <int dim, typename number2>
+template <int dim, typename number2, int spacedim>
 void
 MGTransferSelect<number>::copy_from_mg_add (
-  const MGDoFHandler<dim>&              mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>&              mg_dof_handler,
   Vector<number2>&                      dst,
   const MGLevelObject<Vector<number> >& src) const
 {
@@ -212,10 +212,10 @@ MGTransferSelect<number>::copy_from_mg_add (
 
 
 template <typename number>
-template <int dim, class OutVector>
+template <int dim, class OutVector, int spacedim>
 void
 MGTransferSelect<number>::do_copy_from_mg (
-  const MGDoFHandler<dim>              &mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>              &mg_dof_handler,
   OutVector                            &dst,
   const MGLevelObject<Vector<number> > &src,
   const unsigned int offset) const
@@ -226,9 +226,9 @@ MGTransferSelect<number>::do_copy_from_mg (
   std::vector<unsigned int> global_dof_indices (dofs_per_cell);
   std::vector<unsigned int> level_dof_indices (dofs_per_cell);
 
-  typename MGDoFHandler<dim>::active_cell_iterator
+  typename MGDoFHandler<dim,spacedim>::active_cell_iterator
     level_cell = mg_dof_handler.begin_active();
-  const typename MGDoFHandler<dim>::active_cell_iterator
+  const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
     endc = mg_dof_handler.end();
 
                                   // traverse all cells and copy the
@@ -268,10 +268,10 @@ MGTransferSelect<number>::do_copy_from_mg (
 
 
 template <typename number>
-template <int dim, class OutVector>
+template <int dim, class OutVector, int spacedim>
 void
 MGTransferSelect<number>::do_copy_from_mg_add (
-  const MGDoFHandler<dim>              &mg_dof_handler,
+  const MGDoFHandler<dim,spacedim>              &mg_dof_handler,
   OutVector                            &dst,
   const MGLevelObject<Vector<number> > &src,
   const unsigned int offset) const
@@ -282,9 +282,9 @@ MGTransferSelect<number>::do_copy_from_mg_add (
   std::vector<unsigned int> global_dof_indices (dofs_per_cell);
   std::vector<unsigned int> level_dof_indices (dofs_per_cell);
 
-  typename MGDoFHandler<dim>::active_cell_iterator
+  typename MGDoFHandler<dim,spacedim>::active_cell_iterator
     level_cell = mg_dof_handler.begin_active();
-  const typename MGDoFHandler<dim>::active_cell_iterator
+  const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
     endc = mg_dof_handler.end();
 
                                   // traverse all cells and copy the
index 1d135a8c0015e9e70eda2190e6641cd8e5def4de..ca48ba1d90b74fe03e57d5a8433dfe324ad47cf3 100644 (file)
@@ -28,7 +28,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int> class FEValuesBase;
+template <int, int> class FEValuesBase;
 
 namespace internal
 {
@@ -69,7 +69,7 @@ namespace internal
        unsigned int n_datasets;
        unsigned int n_subdivisions;
        unsigned int n_patches_per_circle;
-       SmartPointer<const Mapping<dim> >              mapping;
+       SmartPointer<const Mapping<dim,spacedim> >     mapping;
        std::vector<double>                            patch_values;
        std::vector<Vector<double> >                   patch_values_system;
        std::vector<Tensor<1,spacedim> >               patch_gradients;
@@ -486,7 +486,7 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                      */
     template <class VECTOR>
     void add_data_vector (const VECTOR                           &data,
-                         const DataPostprocessor<DH::dimension> &data_postprocessor);
+                         const DataPostprocessor<DH::space_dimension> &data_postprocessor);
 
                                     /**
                                      * Release the pointers to the
@@ -707,7 +707,7 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                          * vector declarations are going to
                                          * be aquired from the postprocessor.
                                          */
-       DataEntryBase (const DataPostprocessor<DH::dimension> *data_postprocessor);
+       DataEntryBase (const DataPostprocessor<DH::space_dimension> *data_postprocessor);
        
                                          /**
                                           * Destructor made virtual.
@@ -731,7 +731,7 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_values (const FEValuesBase<DH::dimension> &fe_patch_values,
+        get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
                              std::vector<double>             &patch_values) const = 0;
         
                                          /**
@@ -744,7 +744,7 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_values (const FEValuesBase<DH::dimension> &fe_patch_values,
+        get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
                              std::vector<Vector<double> >    &patch_values_system) const = 0;
 
                                          /**
@@ -755,8 +755,8 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_gradients (const FEValuesBase<DH::dimension> &fe_patch_values,
-                               std::vector<Tensor<1,DH::dimension> >       &patch_gradients) const = 0;
+        get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                               std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const = 0;
         
                                          /**
                                           * Given a FEValuesBase object,
@@ -768,8 +768,8 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_gradients (const FEValuesBase<DH::dimension> &fe_patch_values,
-                               std::vector<std::vector<Tensor<1,DH::dimension> > > &patch_gradients_system) const = 0;
+        get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                               std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const = 0;
 
                                          /**
                                           * Given a FEValuesBase object, extract
@@ -779,8 +779,8 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_hessians (const FEValuesBase<DH::dimension> &fe_patch_values,
-                              std::vector<Tensor<2,DH::dimension> >       &patch_hessians) const = 0;
+        get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                              std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const = 0;
         
                                          /**
                                           * Given a FEValuesBase object, extract
@@ -792,8 +792,8 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_hessians (const FEValuesBase<DH::dimension> &fe_patch_values,
-                              std::vector<std::vector< Tensor<2,DH::dimension> > > &patch_hessians_system) const = 0;
+        get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                              std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const = 0;
 
                                          /**
                                           * Clear all references to the
@@ -830,7 +830,7 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                          * object which shall be applied to
                                          * this data vector.
                                          */
-       SmartPointer<const DataPostprocessor<DH::dimension> > postprocessor;
+       SmartPointer<const DataPostprocessor<DH::space_dimension> > postprocessor;
 
                                         /**
                                          * Number of output variables this
@@ -879,7 +879,7 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                          * be aquired from the postprocessor.
                                          */
        DataEntry (const VectorType                       *data,
-                  const DataPostprocessor<DH::dimension> *data_postprocessor);
+                  const DataPostprocessor<DH::space_dimension> *data_postprocessor);
 
                                          /**
                                           * Assuming that the stored vector is
@@ -898,7 +898,7 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_values (const FEValuesBase<DH::dimension> &fe_patch_values,
+        get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
                              std::vector<double>             &patch_values) const;
         
                                          /**
@@ -911,7 +911,7 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_values (const FEValuesBase<DH::dimension> &fe_patch_values,
+        get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
                              std::vector<Vector<double> >    &patch_values_system) const;
 
                                          /**
@@ -922,8 +922,8 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_gradients (const FEValuesBase<DH::dimension> &fe_patch_values,
-                               std::vector<Tensor<1,DH::dimension> >       &patch_gradients) const;
+        get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                               std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const;
         
                                          /**
                                           * Given a FEValuesBase object,
@@ -935,8 +935,8 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_gradients (const FEValuesBase<DH::dimension> &fe_patch_values,
-                               std::vector<std::vector<Tensor<1,DH::dimension> > > &patch_gradients_system) const;
+        get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                               std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const;
 
                                          /**
                                           * Given a FEValuesBase object, extract
@@ -946,8 +946,8 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_hessians (const FEValuesBase<DH::dimension> &fe_patch_values,
-                              std::vector<Tensor<2,DH::dimension> >       &patch_hessians) const;
+        get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                              std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const;
         
                                          /**
                                           * Given a FEValuesBase object, extract
@@ -959,8 +959,8 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
                                           */
         virtual
         void
-        get_function_hessians (const FEValuesBase<DH::dimension> &fe_patch_values,
-                              std::vector<std::vector< Tensor<2,DH::dimension> > > &patch_hessians_system) const;
+        get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                              std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const;
 
                                          /**
                                           * Clear all references to the
@@ -1160,7 +1160,7 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
  * @author Wolfgang Bangerth, 1999
  */
 template <int dim, class DH=DoFHandler<dim> >
-class DataOut : public DataOut_DoFData<DH, DH::dimension> 
+class DataOut : public DataOut_DoFData<DH, DH::dimension, DH::space_dimension
 {
   public:
                                     /**
@@ -1168,8 +1168,8 @@ class DataOut : public DataOut_DoFData<DH, DH::dimension>
                                      * of the dof handler class under
                                      * consideration.
                                      */
-    typedef typename DataOut_DoFData<DH,DH::dimension>::cell_iterator cell_iterator;
-    typedef typename DataOut_DoFData<DH,DH::dimension>::active_cell_iterator active_cell_iterator;
+    typedef typename DataOut_DoFData<DH,DH::dimension,DH::space_dimension>::cell_iterator cell_iterator;
+    typedef typename DataOut_DoFData<DH,DH::dimension,DH::space_dimension>::active_cell_iterator active_cell_iterator;
 
                                     /**
                                      * Enumeration describing the region of the
@@ -1261,7 +1261,7 @@ class DataOut : public DataOut_DoFData<DH, DH::dimension>
                                      * replaced by a hp::MappingCollection in
                                      * case of a hp::DoFHandler.
                                      */
-    virtual void build_patches (const Mapping<DH::dimension> &mapping,
+  virtual void build_patches (const Mapping<DH::dimension,DH::space_dimension> &mapping,
                                const unsigned int n_subdivisions = 0,
                                const unsigned int n_threads      = multithread_info.n_default_threads,
                                const CurvedCellRegion curved_region = curved_boundary);
@@ -1308,7 +1308,6 @@ class DataOut : public DataOut_DoFData<DH, DH::dimension>
                    << ", is not valid.");
     
   private:
-
                                     /**
                                      * Builds every @p n_threads's
                                      * patch. This function may be
@@ -1317,7 +1316,7 @@ class DataOut : public DataOut_DoFData<DH, DH::dimension>
                                      * used, the function is called
                                      * once and generates all patches.
                                      */
-    void build_some_patches (internal::DataOut::ParallelData<DH::dimension, DH::dimension> &data);
+    void build_some_patches (internal::DataOut::ParallelData<DH::dimension, DH::space_dimension> &data);
 
                                     /**
                                      * Store in which region cells shall be
index 593d07e151929cf8c9d2140cd8b4e8b82726be69..bd85379c91e989b0cae9d7b804c7f31c1708da15 100644 (file)
@@ -24,7 +24,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class DoFHandler;
+template <int dim, int spacedim> class DoFHandler;
 
 /**
  * This class is used to stack the output from several computations
@@ -86,7 +86,7 @@ template <int dim> class DoFHandler;
  *                                  // now do computations
  *   for (double parameter=0; ...)
  *     {
- *       DoFHandler<dim> dof_handler;
+ *       DoFHandler<dim,spacedim> dof_handler;
  *       ...                        // compute something
  *
  *                                  // now for output
@@ -103,7 +103,7 @@ template <int dim> class DoFHandler;
  * @ingroup output
  * @author Wolfgang Bangerth, 1999
  */
-template <int dim, class DH = DoFHandler<dim> >
+template <int dim, int spacedim=dim, class DH = DoFHandler<dim,spacedim> >
 class DataOutStack : public DataOutInterface<dim+1> 
 {
   public:
index dc16c01855d432ea1b84aa8d793528dca540b5b9..9f4496fa3a7efb3e590daf1353bc811c725b4253 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim> class DoFHandler;
+template <int dim, int spacedim> class DoFHandler;
 namespace hp
 {
-  template <int dim> class DoFHandler;
+  template <int dim, int spacedim> class DoFHandler;
 }
 
 
@@ -77,7 +77,7 @@ namespace hp
  * @code
  * --------------------------------------------------------
  * An error occurred in line <749> of file <source/numerics/derivative_approximation.cc> in function
- *     static void DerivativeApproximation::approximate(const Mapping<dim>&, const DH<dim>&, const InputVector&, unsigned int, const
+ *     static void DerivativeApproximation::approximate(const Mapping<dim,spacedim>&, const DH<dim,spacedim>&, const InputVector&, unsigned int, const
  *  std::pair<unsigned int, unsigned int>&, Vector<float>&) [with DerivativeDescription = DerivativeApproximation::Gradient<3>, int
  * dim = 3, DH = DoFHandler, InputVector = Vector<double>]
  * The violated condition was:
@@ -201,10 +201,10 @@ class DerivativeApproximation
                                      * number of vector components can be
                                      * given here.
                                      */
-    template <int dim, template <int> class DH, class InputVector>
+    template <int dim, template <int, int> class DH, class InputVector, int spacedim>
     static void
-    approximate_gradient (const Mapping<dim>    &mapping,
-                         const DH<dim>         &dof,
+    approximate_gradient (const Mapping<dim,spacedim>    &mapping,
+                         const DH<dim,spacedim>         &dof,
                          const InputVector     &solution,
                          Vector<float>         &derivative_norm,
                          const unsigned int     component = 0);
@@ -214,9 +214,9 @@ class DerivativeApproximation
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, template <int> class DH, class InputVector>
+    template <int dim, template <int, int> class DH, class InputVector, int spacedim>
     static void
-    approximate_gradient (const DH<dim>         &dof,
+    approximate_gradient (const DH<dim,spacedim>         &dof,
                          const InputVector     &solution,
                          Vector<float>         &derivative_norm,
                          const unsigned int     component = 0);
@@ -248,10 +248,10 @@ class DerivativeApproximation
                                      * number of vector components can be
                                      * given here.
                                      */
-    template <int dim, template <int> class DH, class InputVector>
+    template <int dim, template <int, int> class DH, class InputVector, int spacedim>
     static void
-    approximate_second_derivative (const Mapping<dim>    &mapping,
-                                  const DH<dim>         &dof,
+    approximate_second_derivative (const Mapping<dim,spacedim>    &mapping,
+                                  const DH<dim,spacedim>         &dof,
                                   const InputVector     &solution,
                                   Vector<float>         &derivative_norm,
                                   const unsigned int     component = 0);
@@ -261,9 +261,9 @@ class DerivativeApproximation
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, template <int> class DH, class InputVector>
+    template <int dim, template <int, int> class DH, class InputVector, int spacedim>
     static void
-    approximate_second_derivative (const DH<dim>         &dof,
+    approximate_second_derivative (const DH<dim,spacedim>         &dof,
                                   const InputVector     &solution,
                                   Vector<float>         &derivative_norm,
                                   const unsigned int     component = 0);
@@ -286,12 +286,12 @@ class DerivativeApproximation
                                      * given here.
                                      */
 
-    template <int dim, template <int> class DH, class InputVector, int order>
+    template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
     static void
-    approximate_derivative_tensor (const Mapping<dim>                           &mapping,
-                                  const DH<dim>                                &dof,
+    approximate_derivative_tensor (const Mapping<dim,spacedim>                           &mapping,
+                                  const DH<dim,spacedim>                                &dof,
                                   const InputVector                            &solution,
-                                  const typename DH<dim>::active_cell_iterator &cell,
+                                  const typename DH<dim,spacedim>::active_cell_iterator &cell,
                                   Tensor<order,dim>                            &derivative,
                                   const unsigned int                            component = 0);
 
@@ -300,11 +300,11 @@ class DerivativeApproximation
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
 
-    template <int dim, template <int> class DH, class InputVector, int order>
+    template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
     static void
-    approximate_derivative_tensor (const DH<dim>                                &dof,
+    approximate_derivative_tensor (const DH<dim,spacedim>                                &dof,
                                   const InputVector                            &solution,
-                                  const typename DH<dim>::active_cell_iterator &cell,
+                                  const typename DH<dim,spacedim>::active_cell_iterator &cell,
                                   Tensor<order,dim>                            &derivative,
                                   const unsigned int                            component = 0);
 
@@ -379,9 +379,9 @@ class DerivativeApproximation
                                          * field at the center of each
                                          * cell).
                                          */
-       template <class InputVector>
+       template <class InputVector, int spacedim>
        static ProjectedDerivative
-       get_projected_derivative (const FEValues<dim>  &fe_values,
+       get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
                                  const InputVector    &solution,
                                  const unsigned int    component);
     
@@ -460,9 +460,9 @@ class DerivativeApproximation
                                          * field at the center of each
                                          * cell).
                                          */
-       template <class InputVector>
+       template <class InputVector, int spacedim>
        static ProjectedDerivative
-       get_projected_derivative (const FEValues<dim>  &fe_values,
+       get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
                                  const InputVector    &solution,
                                  const unsigned int    component);
        
@@ -538,9 +538,9 @@ class DerivativeApproximation
                                          * field at the center of each
                                          * cell).
                                          */
-       template <class InputVector>
+       template <class InputVector, int spacedim>
        static ProjectedDerivative
-       get_projected_derivative (const FEValues<dim>  &fe_values,
+       get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
                                  const InputVector    &solution,
                                  const unsigned int    component);
        
@@ -652,10 +652,10 @@ class DerivativeApproximation
                                      * on.
                                      */
     template <class DerivativeDescription, int dim,
-              template <int> class DH, class InputVector>
+              template <int, int> class DH, class InputVector, int spacedim>
     static void
-    approximate_derivative (const Mapping<dim>    &mapping,
-                           const DH<dim>         &dof,
+    approximate_derivative (const Mapping<dim,spacedim>    &mapping,
+                           const DH<dim,spacedim>         &dof,
                            const InputVector     &solution,
                            const unsigned int     component,
                            Vector<float>         &derivative_norm);
@@ -670,10 +670,10 @@ class DerivativeApproximation
                                      * tensors on each cell.
                                      */
     template <class DerivativeDescription, int dim,
-              template <int> class DH, class InputVector>
+              template <int, int> class DH, class InputVector, int spacedim>
     static void
-    approximate (const Mapping<dim>    &mapping,
-                const DH<dim>         &dof,
+    approximate (const Mapping<dim,spacedim>    &mapping,
+                const DH<dim,spacedim>         &dof,
                 const InputVector     &solution,
                 const unsigned int     component,
                 const IndexInterval   &index_interval,
@@ -685,13 +685,13 @@ class DerivativeApproximation
                                      * derivative tensor.
                                      */
     template <class DerivativeDescription, int dim,
-              template <int> class DH, class InputVector>
+              template <int, int> class DH, class InputVector, int spacedim>
     static void
-    approximate_cell (const Mapping<dim>                            &mapping,
-                     const DH<dim>                                 &dof,
+    approximate_cell (const Mapping<dim,spacedim>                            &mapping,
+                     const DH<dim,spacedim>                                 &dof,
                      const InputVector                             &solution,
                      const unsigned int                             component,
-                     const typename DH<dim>::active_cell_iterator  &cell,
+                     const typename DH<dim,spacedim>::active_cell_iterator  &cell,
                      typename DerivativeDescription::Derivative    &derivative);    
 };
 
index e2cfa91e73963097f9bfb1fd4d35cc33f0babead..71c0333daedff26044ab0e8d13799c37f5469a0f 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int> class DoFHandler;
-template <int> class Mapping;
+template <int, int> class DoFHandler;
+template <int, int> class Mapping;
 template <int> class Quadrature;
 
 namespace hp
 {
-  template <int> class DoFHandler;
+  template <int, int> class DoFHandler;
   template <int> class QCollection;
-  template <int> class MappingCollection;
+  template <int, int> class MappingCollection;
   template <int dim> class FEFaceValues;
   template <int dim> class FESubfaceValues;
 }
@@ -215,7 +215,7 @@ namespace hp
  *  @ingroup numerics
  *  @author Wolfgang Bangerth, 1998, 1999, 2000, 2004, 2006; parallelization by Thomas Richter, 2000
  */
-template <int dim>
+template <int dim, int spacedim=dim>
 class KellyErrorEstimator
 {
   public:
@@ -309,7 +309,7 @@ class KellyErrorEstimator
                                      * id.
                                      */
     template <typename InputVector, class DH>
-    static void estimate (const Mapping<dim>      &mapping,
+    static void estimate (const Mapping<dim, spacedim>      &mapping,
                          const DH                &dof,
                          const Quadrature<dim-1> &quadrature,
                          const typename FunctionMap<dim>::type &neumann_bc,
@@ -366,7 +366,7 @@ class KellyErrorEstimator
                                      * vector of pointers.)
                                      */
     template <typename InputVector, class DH>
-    static void estimate (const Mapping<dim>          &mapping,
+    static void estimate (const Mapping<dim, spacedim>          &mapping,
                          const DH                    &dof,
                          const Quadrature<dim-1>     &quadrature,
                          const typename FunctionMap<dim>::type &neumann_bc,
@@ -403,7 +403,7 @@ class KellyErrorEstimator
                                      * element dof handlers.
                                      */
     template <typename InputVector, class DH>
-    static void estimate (const Mapping<dim>      &mapping,
+    static void estimate (const Mapping<dim, spacedim>      &mapping,
                          const DH                &dof,
                          const hp::QCollection<dim-1> &quadrature,
                          const typename FunctionMap<dim>::type &neumann_bc,
@@ -442,7 +442,7 @@ class KellyErrorEstimator
                                      * element dof handlers.
                                      */
     template <typename InputVector, class DH>
-    static void estimate (const Mapping<dim>          &mapping,
+    static void estimate (const Mapping<dim, spacedim>          &mapping,
                          const DH                    &dof,
                          const hp::QCollection<dim-1> &quadrature,
                          const typename FunctionMap<dim>::type &neumann_bc,
@@ -693,7 +693,7 @@ class KellyErrorEstimator
                                      * seperatly.
                                      */
     template <typename InputVector, class DH>
-    static void estimate_some (const hp::MappingCollection<dim>    &mapping,
+    static void estimate_some (const hp::MappingCollection<dim, spacedim>    &mapping,
                                const DH                            &dof_handler,
                                const hp::QCollection<dim-1>         &quadrature,
                                const typename FunctionMap<dim>::type &neumann_bc,
@@ -794,8 +794,8 @@ class KellyErrorEstimator
  *
  * @author Wolfgang Bangerth, 1998, 2004.
  */
-template <>
-class KellyErrorEstimator<1>
+template <int spacedim>
+class KellyErrorEstimator<1,spacedim>
 {
   public:
                                     /**
@@ -846,7 +846,7 @@ class KellyErrorEstimator<1>
                                      * general case.
                                      */
     template <typename InputVector, class DH>
-    static void estimate (const Mapping<1>      &mapping,
+    static void estimate (const Mapping<1,spacedim>  &mapping,
                          const DH   &dof,
                          const Quadrature<0> &quadrature,
                          const FunctionMap<1>::type &neumann_bc,
@@ -903,7 +903,7 @@ class KellyErrorEstimator<1>
                                      * vector of pointers.)
                                      */
     template <typename InputVector, class DH>
-    static void estimate (const Mapping<1>          &mapping,
+    static void estimate (const Mapping<1,spacedim>          &mapping,
                          const DH       &dof,
                          const Quadrature<0>     &quadrature,
                          const FunctionMap<1>::type &neumann_bc,
@@ -940,7 +940,7 @@ class KellyErrorEstimator<1>
                                      * element dof handlers.
                                      */
     template <typename InputVector, class DH>
-    static void estimate (const Mapping<1>      &mapping,
+    static void estimate (const Mapping<1,spacedim>      &mapping,
                          const DH                &dof,
                          const hp::QCollection<0> &quadrature,
                          const typename FunctionMap<1>::type &neumann_bc,
@@ -979,7 +979,7 @@ class KellyErrorEstimator<1>
                                      * element dof handlers.
                                      */
     template <typename InputVector, class DH>
-    static void estimate (const Mapping<1>          &mapping,
+    static void estimate (const Mapping<1,spacedim>          &mapping,
                          const DH                    &dof,
                          const hp::QCollection<0> &quadrature,
                          const typename FunctionMap<1>::type &neumann_bc,
index 6f540a497f1dc599cea3ed0f0906efb869f516d8..1fd1f6b784af89012a3d71ea23069c738cea18a2 100644 (file)
@@ -34,16 +34,16 @@ template<typename number> class SparseMatrix;
 template <typename number> class BlockSparseMatrix;
 template <typename Number> class BlockVector;
 
-template <int dim> class Mapping;
-template <int dim> class DoFHandler;
-template <int dim> class MGDoFHandler;
-template <int dim> class FEValues;
+template <int dim, int spacedim> class Mapping;
+template <int dim, int spacedim> class DoFHandler;
+template <int dim, int spacedim> class MGDoFHandler;
+template <int dim, int spacedim> class FEValues;
 
 namespace hp
 {
   template <int> class QCollection;
-  template <int> class MappingCollection;
-  template <int> class DoFHandler;
+  template <int, int> class MappingCollection;
+  template <int, int> class DoFHandler;
 }
 
 
@@ -224,23 +224,23 @@ class MatrixCreator
                                      * See the general doc of this class
                                      * for more information.
                                      */
-    template <int dim, typename number>
-    static void create_mass_matrix (const Mapping<dim>       &mapping,
-                                   const DoFHandler<dim>    &dof,
+    template <int dim, typename number, int spacedim>
+    static void create_mass_matrix (const Mapping<dim, spacedim>       &mapping,
+                                   const DoFHandler<dim,spacedim>    &dof,
                                    const Quadrature<dim>    &q,
                                    SparseMatrix<number>     &matrix,
-                                   const Function<dim> * const a = 0);
+                                   const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Calls the create_mass_matrix()
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, typename number>
-    static void create_mass_matrix (const DoFHandler<dim>    &dof,
+    template <int dim, typename number, int spacedim>
+    static void create_mass_matrix (const DoFHandler<dim,spacedim>    &dof,
                                    const Quadrature<dim>    &q,
                                    SparseMatrix<number>     &matrix,
-                                   const Function<dim> * const a = 0);
+                                   const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Assemble the mass matrix and a
@@ -255,72 +255,72 @@ class MatrixCreator
                                      * See the general doc of this
                                      * class for more information.
                                      */
-    template <int dim, typename number>
-    static void create_mass_matrix (const Mapping<dim>       &mapping,
-                                   const DoFHandler<dim>    &dof,
+    template <int dim, typename number, int spacedim>
+    static void create_mass_matrix (const Mapping<dim, spacedim>       &mapping,
+                                   const DoFHandler<dim,spacedim>    &dof,
                                    const Quadrature<dim>    &q,
                                    SparseMatrix<number>     &matrix,
-                                   const Function<dim>      &rhs,
+                                   const Function<spacedim>      &rhs,
                                    Vector<double>           &rhs_vector,
-                                   const Function<dim> * const a = 0);
+                                   const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Calls the create_mass_matrix()
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, typename number>
-    static void create_mass_matrix (const DoFHandler<dim>    &dof,
+    template <int dim, typename number, int spacedim>
+    static void create_mass_matrix (const DoFHandler<dim,spacedim>    &dof,
                                    const Quadrature<dim>    &q,
                                    SparseMatrix<number>     &matrix,
-                                   const Function<dim>      &rhs,
+                                   const Function<spacedim>      &rhs,
                                    Vector<double>           &rhs_vector,
-                                   const Function<dim> * const a = 0);
+                                   const Function<spacedim> * const a = 0);
                                     /**
                                      * Same function as above, but for hp
                                      * objects.
                                      */
-    template <int dim, typename number>
-    static void create_mass_matrix (const hp::MappingCollection<dim>       &mapping,
-                                   const hp::DoFHandler<dim>    &dof,
+    template <int dim, typename number, int spacedim>
+    static void create_mass_matrix (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                   const hp::DoFHandler<dim,spacedim>    &dof,
                                    const hp::QCollection<dim>    &q,
                                    SparseMatrix<number>     &matrix,
-                                   const Function<dim> * const a = 0);
+                                   const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Same function as above, but for hp
                                      * objects.
                                      */
-    template <int dim, typename number>
-    static void create_mass_matrix (const hp::DoFHandler<dim>    &dof,
+    template <int dim, typename number, int spacedim>
+    static void create_mass_matrix (const hp::DoFHandler<dim,spacedim>    &dof,
                                    const hp::QCollection<dim>    &q,
                                    SparseMatrix<number>     &matrix,
-                                   const Function<dim> * const a = 0);
+                                   const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Same function as above, but for hp
                                      * objects.
                                      */
-    template <int dim, typename number>
-    static void create_mass_matrix (const hp::MappingCollection<dim>       &mapping,
-                                   const hp::DoFHandler<dim>    &dof,
+    template <int dim, typename number, int spacedim>
+    static void create_mass_matrix (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                   const hp::DoFHandler<dim,spacedim>    &dof,
                                    const hp::QCollection<dim>    &q,
                                    SparseMatrix<number>     &matrix,
-                                   const Function<dim>      &rhs,
+                                   const Function<spacedim>      &rhs,
                                    Vector<double>           &rhs_vector,
-                                   const Function<dim> * const a = 0);
+                                   const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Same function as above, but for hp
                                      * objects.
                                      */
-    template <int dim, typename number>
-    static void create_mass_matrix (const hp::DoFHandler<dim>    &dof,
+    template <int dim, typename number, int spacedim>
+    static void create_mass_matrix (const hp::DoFHandler<dim,spacedim>    &dof,
                                    const hp::QCollection<dim>    &q,
                                    SparseMatrix<number>     &matrix,
-                                   const Function<dim>      &rhs,
+                                   const Function<spacedim>      &rhs,
                                    Vector<double>           &rhs_vector,
-                                   const Function<dim> * const a = 0);
+                                   const Function<spacedim> * const a = 0);
 
     
                                     /**
@@ -362,64 +362,102 @@ class MatrixCreator
                                      * work for finite elements with
                                      * cell-dependent shape functions.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void create_boundary_mass_matrix (const Mapping<dim>       &mapping,
-                                     const DoFHandler<dim>    &dof,
+    void create_boundary_mass_matrix (const Mapping<dim, spacedim>       &mapping,
+                                     const DoFHandler<dim,spacedim>    &dof,
                                      const Quadrature<dim-1>  &q,
                                      SparseMatrix<double>     &matrix,
-                                     const typename FunctionMap<dim>::type &boundary_functions,
+                                     const typename FunctionMap<spacedim>::type &boundary_functions,
                                      Vector<double>           &rhs_vector,
                                      std::vector<unsigned int>&dof_to_boundary_mapping,
-                                     const Function<dim> * const weight = 0,
+                                     const Function<spacedim> * const weight = 0,
                                      std::vector<unsigned int> component_mapping = std::vector<unsigned int>());
-    
-                                    /**
+
+//                                   * Same function, but for 1d.
+//                                   */
+//     static
+//     void create_boundary_mass_matrix (const Mapping<1,1>       &mapping,
+//                                   const DoFHandler<1,1>    &dof,
+//                                   const Quadrature<0>    &q,
+//                                   SparseMatrix<double>   &matrix,
+//                                   const FunctionMap<1>::type &boundary_functions,
+//                                   Vector<double>         &rhs_vector,
+//                                   std::vector<unsigned int>&dof_to_boundary_mapping,
+//                                   const Function<1> * const a = 0);
+// //codimension 1
+//     static
+//     void create_boundary_mass_matrix (const Mapping<1,2>       &mapping,
+//                                   const DoFHandler<1,2>    &dof,
+//                                   const Quadrature<0>    &q,
+//                                   SparseMatrix<double>   &matrix,
+//                                   const FunctionMap<2>::type &boundary_functions,
+//                                   Vector<double>         &rhs_vector,
+//                                   std::vector<unsigned int>&dof_to_boundary_mapping,
+//                                   const Function<2> * const a = 0);
+
+
+
+                                    /**
                                      * Calls the
                                      * create_boundary_mass_matrix()
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void create_boundary_mass_matrix (const DoFHandler<dim>    &dof,
+    void create_boundary_mass_matrix (const DoFHandler<dim,spacedim>    &dof,
                                      const Quadrature<dim-1>  &q,
                                      SparseMatrix<double>     &matrix,
-                                     const typename FunctionMap<dim>::type        &boundary_functions,
+                                     const typename FunctionMap<spacedim>::type        &boundary_functions,
                                      Vector<double>           &rhs_vector,
                                      std::vector<unsigned int>&dof_to_boundary_mapping,
-                                     const Function<dim> * const a = 0,
+                                     const Function<spacedim> * const a = 0,
                                      std::vector<unsigned int> component_mapping = std::vector<unsigned int>());
 
                                     /**
                                      * Same function as above, but for hp
                                      * objects.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void create_boundary_mass_matrix (const hp::MappingCollection<dim>       &mapping,
-                                     const hp::DoFHandler<dim>    &dof,
+    void create_boundary_mass_matrix (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                     const hp::DoFHandler<dim,spacedim>    &dof,
                                      const hp::QCollection<dim-1>  &q,
                                      SparseMatrix<double>     &matrix,
-                                     const typename FunctionMap<dim>::type &boundary_functions,
+                                     const typename FunctionMap<spacedim>::type &boundary_functions,
                                      Vector<double>           &rhs_vector,
                                      std::vector<unsigned int>&dof_to_boundary_mapping,
-                                     const Function<dim> * const a = 0,
+                                     const Function<spacedim> * const a = 0,
                                      std::vector<unsigned int> component_mapping = std::vector<unsigned int>());
 
                                     /**
                                      * Same function as above, but for hp
                                      * objects.
                                      */
-    template <int dim>
+//     static
+//     void create_boundary_mass_matrix (const hp::MappingCollection<1,1>       &mapping,
+//                                   const hp::DoFHandler<1,1>    &dof,
+//                                   const hp::QCollection<0>    &q,
+//                                   SparseMatrix<double>   &matrix,
+//                                   const FunctionMap<1>::type &boundary_functions,
+//                                   Vector<double>         &rhs_vector,
+//                                   std::vector<unsigned int>&dof_to_boundary_mapping,
+//                                   const Function<1> * const a = 0);
+
+                                    /**
+                                     * Same function as above, but for hp
+                                     * objects.
+                                     */
+    template <int dim, int spacedim>
     static
-    void create_boundary_mass_matrix (const hp::DoFHandler<dim>    &dof,
+    void create_boundary_mass_matrix (const hp::DoFHandler<dim,spacedim>    &dof,
                                      const hp::QCollection<dim-1>  &q,
                                      SparseMatrix<double>     &matrix,
-                                     const typename FunctionMap<dim>::type        &boundary_functions,
+                                     const typename FunctionMap<spacedim>::type        &boundary_functions,
                                      Vector<double>           &rhs_vector,
                                      std::vector<unsigned int>&dof_to_boundary_mapping,
-                                     const Function<dim> * const a = 0,
+                                     const Function<spacedim> * const a = 0,
                                      std::vector<unsigned int> component_mapping = std::vector<unsigned int>());
 
                                     /**
@@ -435,12 +473,12 @@ class MatrixCreator
                                      * See the general doc of this
                                      * class for more information.
                                      */
-    template <int dim>
-    static void create_laplace_matrix (const Mapping<dim>       &mapping,
-                                      const DoFHandler<dim>    &dof,
+    template <int dim, int spacedim>
+    static void create_laplace_matrix (const Mapping<dim, spacedim>       &mapping,
+                                      const DoFHandler<dim,spacedim>    &dof,
                                       const Quadrature<dim>    &q,
                                       SparseMatrix<double>     &matrix,
-                                      const Function<dim> * const a = 0);
+                                      const Function<spacedim> * const a = 0);
     
                                     /**
                                      * Calls the
@@ -448,11 +486,11 @@ class MatrixCreator
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim>
-    static void create_laplace_matrix (const DoFHandler<dim>    &dof,
+    template <int dim, int spacedim>
+    static void create_laplace_matrix (const DoFHandler<dim,spacedim>    &dof,
                                       const Quadrature<dim>    &q,
                                       SparseMatrix<double>     &matrix,
-                                      const Function<dim> * const a = 0);
+                                      const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Assemble the Laplace matrix
@@ -468,14 +506,14 @@ class MatrixCreator
                                      * See the general doc of this
                                      * class for more information.
                                      */
-    template <int dim>
-    static void create_laplace_matrix (const Mapping<dim>       &mapping,
-                                      const DoFHandler<dim>    &dof,
+    template <int dim, int spacedim>
+    static void create_laplace_matrix (const Mapping<dim, spacedim>       &mapping,
+                                      const DoFHandler<dim,spacedim>    &dof,
                                       const Quadrature<dim>    &q,
                                       SparseMatrix<double>     &matrix,
-                                      const Function<dim>      &rhs,
+                                      const Function<spacedim>      &rhs,
                                       Vector<double>           &rhs_vector,
-                                      const Function<dim> * const a = 0);
+                                      const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Calls the
@@ -483,63 +521,63 @@ class MatrixCreator
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim>
-    static void create_laplace_matrix (const DoFHandler<dim>    &dof,
+    template <int dim, int spacedim>
+    static void create_laplace_matrix (const DoFHandler<dim,spacedim>    &dof,
                                       const Quadrature<dim>    &q,
                                       SparseMatrix<double>     &matrix,
-                                      const Function<dim>      &rhs,
+                                      const Function<spacedim>      &rhs,
                                       Vector<double>           &rhs_vector,
-                                      const Function<dim> * const a = 0);
+                                      const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Like the functions above, but for hp
                                      * dof handlers, mappings, and quadrature
                                      * collections.
                                      */
-    template <int dim>
-    static void create_laplace_matrix (const hp::MappingCollection<dim>       &mapping,
-                                      const hp::DoFHandler<dim>    &dof,
+    template <int dim, int spacedim>
+    static void create_laplace_matrix (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                      const hp::DoFHandler<dim,spacedim>    &dof,
                                       const hp::QCollection<dim>    &q,
                                       SparseMatrix<double>     &matrix,
-                                      const Function<dim> * const a = 0);
+                                      const Function<spacedim> * const a = 0);
     
                                     /**
                                      * Like the functions above, but for hp
                                      * dof handlers, mappings, and quadrature
                                      * collections.
                                      */
-    template <int dim>
-    static void create_laplace_matrix (const hp::DoFHandler<dim>    &dof,
+    template <int dim, int spacedim>
+    static void create_laplace_matrix (const hp::DoFHandler<dim,spacedim>    &dof,
                                       const hp::QCollection<dim>    &q,
                                       SparseMatrix<double>     &matrix,
-                                      const Function<dim> * const a = 0);
+                                      const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Like the functions above, but for hp
                                      * dof handlers, mappings, and quadrature
                                      * collections.
                                      */
-    template <int dim>
-    static void create_laplace_matrix (const hp::MappingCollection<dim>       &mapping,
-                                      const hp::DoFHandler<dim>    &dof,
+    template <int dim, int spacedim>
+    static void create_laplace_matrix (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                      const hp::DoFHandler<dim,spacedim>    &dof,
                                       const hp::QCollection<dim>    &q,
                                       SparseMatrix<double>     &matrix,
-                                      const Function<dim>      &rhs,
+                                      const Function<spacedim>      &rhs,
                                       Vector<double>           &rhs_vector,
-                                      const Function<dim> * const a = 0);
+                                      const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Like the functions above, but for hp
                                      * dof handlers, mappings, and quadrature
                                      * collections.
                                      */
-    template <int dim>
-    static void create_laplace_matrix (const hp::DoFHandler<dim>    &dof,
+    template <int dim, int spacedim>
+    static void create_laplace_matrix (const hp::DoFHandler<dim,spacedim>    &dof,
                                       const hp::QCollection<dim>    &q,
                                       SparseMatrix<double>     &matrix,
-                                      const Function<dim>      &rhs,
+                                      const Function<spacedim>      &rhs,
                                       Vector<double>           &rhs_vector,
-                                      const Function<dim> * const a = 0);
+                                      const Function<spacedim> * const a = 0);
 
                                     /**
                                      * Exception
@@ -602,14 +640,14 @@ class MatrixCreator
                                      * used to synchronise access to
                                      * the matrix.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static
-    void create_mass_matrix_1 (const Mapping<dim>       &mapping,
-                              const DoFHandler<dim>    &dof,
+    void create_mass_matrix_1 (const Mapping<dim, spacedim>       &mapping,
+                              const DoFHandler<dim,spacedim>    &dof,
                               const Quadrature<dim>    &q,
                               SparseMatrix<number>     &matrix,
-                              const Function<dim> * const a,
-                              const IteratorRange<DoFHandler<dim> >  range,
+                              const Function<spacedim> * const a,
+                              const IteratorRange<DoFHandler<dim,spacedim> >  range,
                               Threads::ThreadMutex     &mutex);
 
                                     /**
@@ -622,42 +660,42 @@ class MatrixCreator
                                      * used to synchronise access to
                                      * the matrix.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static
-    void create_mass_matrix_2 (const Mapping<dim>       &mapping,
-                              const DoFHandler<dim>    &dof,
+    void create_mass_matrix_2 (const Mapping<dim, spacedim>       &mapping,
+                              const DoFHandler<dim,spacedim>    &dof,
                               const Quadrature<dim>    &q,
                               SparseMatrix<number>     &matrix,
-                              const Function<dim>      &rhs,
+                              const Function<spacedim>      &rhs,
                               Vector<double>           &rhs_vector,
-                              const Function<dim> * const a,
-                              const IteratorRange<DoFHandler<dim> >  range,
+                              const Function<spacedim> * const a,
+                              const IteratorRange<DoFHandler<dim,spacedim> >  range,
                               Threads::ThreadMutex     &mutex);
 
                                     /**
                                      * Same function as above, but for hp
                                      * objects.
                                      */
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static
-    void create_mass_matrix_1 (const hp::MappingCollection<dim>       &mapping,
-                              const hp::DoFHandler<dim>    &dof,
+    void create_mass_matrix_1 (const hp::MappingCollection<dim,spacedim>       &mapping,
+                              const hp::DoFHandler<dim,spacedim>    &dof,
                               const hp::QCollection<dim>    &q,
                               SparseMatrix<number>     &matrix,
-                              const Function<dim> * const a,
-                              const IteratorRange<hp::DoFHandler<dim> >  range,
+                              const Function<spacedim> * const a,
+                              const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                               Threads::ThreadMutex     &mutex);
 
-    template <int dim, typename number>
+    template <int dim, typename number, int spacedim>
     static
-    void create_mass_matrix_2 (const hp::MappingCollection<dim>       &mapping,
-                              const hp::DoFHandler<dim>    &dof,
+    void create_mass_matrix_2 (const hp::MappingCollection<dim,spacedim>       &mapping,
+                              const hp::DoFHandler<dim,spacedim>    &dof,
                               const hp::QCollection<dim>    &q,
                               SparseMatrix<number>     &matrix,
-                              const Function<dim>      &rhs,
+                              const Function<spacedim>      &rhs,
                               Vector<double>           &rhs_vector,
-                              const Function<dim> * const a,
-                              const IteratorRange<hp::DoFHandler<dim> >  range,
+                              const Function<spacedim> * const a,
+                              const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                               Threads::ThreadMutex     &mutex);
 
 
@@ -671,14 +709,14 @@ class MatrixCreator
                                      * used to synchronise access to
                                      * the matrix.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void create_laplace_matrix_1 (const Mapping<dim>       &mapping,
-                                 const DoFHandler<dim>    &dof,
+    void create_laplace_matrix_1 (const Mapping<dim, spacedim>       &mapping,
+                                 const DoFHandler<dim,spacedim>    &dof,
                                  const Quadrature<dim>    &q,
                                  SparseMatrix<double>     &matrix,
-                                 const Function<dim> * const a,
-                                 const IteratorRange<DoFHandler<dim> >  range,
+                                 const Function<spacedim> * const a,
+                                 const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                  Threads::ThreadMutex     &mutex);
 
                                     /**
@@ -691,16 +729,16 @@ class MatrixCreator
                                      * used to synchronise access to
                                      * the matrix.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void create_laplace_matrix_2 (const Mapping<dim>       &mapping,
-                                 const DoFHandler<dim>    &dof,
+    void create_laplace_matrix_2 (const Mapping<dim, spacedim>       &mapping,
+                                 const DoFHandler<dim,spacedim>    &dof,
                                  const Quadrature<dim>    &q,
                                  SparseMatrix<double>     &matrix,
-                                 const Function<dim>      &rhs,
+                                 const Function<spacedim>      &rhs,
                                  Vector<double>           &rhs_vector,
-                                 const Function<dim> * const a,
-                                 const IteratorRange<DoFHandler<dim> >  range,
+                                 const Function<spacedim> * const a,
+                                 const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                  Threads::ThreadMutex     &mutex);
 
                                     /**
@@ -713,14 +751,14 @@ class MatrixCreator
                                      * used to synchronise access to
                                      * the matrix.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void create_laplace_matrix_1 (const hp::MappingCollection<dim>       &mapping,
-                                 const hp::DoFHandler<dim>    &dof,
+    void create_laplace_matrix_1 (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                 const hp::DoFHandler<dim,spacedim>    &dof,
                                  const hp::QCollection<dim>    &q,
                                  SparseMatrix<double>     &matrix,
-                                 const Function<dim> * const a,
-                                 const IteratorRange<hp::DoFHandler<dim> >  range,
+                                 const Function<spacedim> * const a,
+                                 const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                  Threads::ThreadMutex     &mutex);
 
                                     /**
@@ -733,16 +771,16 @@ class MatrixCreator
                                      * used to synchronise access to
                                      * the matrix.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void create_laplace_matrix_2 (const hp::MappingCollection<dim>       &mapping,
-                                 const hp::DoFHandler<dim>    &dof,
+    void create_laplace_matrix_2 (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                 const hp::DoFHandler<dim,spacedim>    &dof,
                                  const hp::QCollection<dim>    &q,
                                  SparseMatrix<double>     &matrix,
-                                 const Function<dim>      &rhs,
+                                 const Function<spacedim>      &rhs,
                                  Vector<double>           &rhs_vector,
-                                 const Function<dim> * const a,
-                                 const IteratorRange<hp::DoFHandler<dim> >  range,
+                                 const Function<spacedim> * const a,
+                                 const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                  Threads::ThreadMutex     &mutex);
     
                                     /**
@@ -755,35 +793,35 @@ class MatrixCreator
                                      * used to synchronise access to
                                      * the matrix.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void create_boundary_mass_matrix_1 (boost::tuple<const Mapping<dim>&,
-                                       const DoFHandler<dim>&,
-                                       const Quadrature<dim-1>&> commons,
+    void create_boundary_mass_matrix_1 (boost::tuple<const Mapping<dim,spacedim> &,
+                                       const DoFHandler<dim,spacedim> &,
+                                       const Quadrature<dim-1> & > commons,
                                        SparseMatrix<double>     &matrix,
-                                       const typename FunctionMap<dim>::type        &boundary_functions,
+                                       const typename FunctionMap<spacedim>::type        &boundary_functions,
                                        Vector<double>           &rhs_vector,
                                        std::vector<unsigned int>&dof_to_boundary_mapping,
-                                       const Function<dim> * const a,
+                                       const Function<spacedim> * const coefficient,
                                        const std::vector<unsigned int>& component_mapping,
-                                       const IteratorRange<DoFHandler<dim> >  range,
+                                       const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                        Threads::ThreadMutex     &mutex);
 
                                     /**
                                      * Same as above, but for hp.
                                      */
-    template <int dim>
+    template <int dim, int spacedim>
     static
-    void create_boundary_mass_matrix_1 (boost::tuple<const hp::MappingCollection<dim>&,
-                                       const hp::DoFHandler<dim>&,
-                                       const hp::QCollection<dim-1>&> commons,
+    void create_boundary_mass_matrix_1 (boost::tuple<const hp::MappingCollection<dim,spacedim> &,
+                                       const hp::DoFHandler<dim,spacedim>&,
+                                       const hp::QCollection<dim-1> & > commons,
                                        SparseMatrix<double>     &matrix,
-                                       const typename FunctionMap<dim>::type        &boundary_functions,
+                                       const typename FunctionMap<spacedim>::type        &boundary_functions,
                                        Vector<double>           &rhs_vector,
                                        std::vector<unsigned int>&dof_to_boundary_mapping,
-                                       const Function<dim> * const a,
+                                       const Function<spacedim> * const coefficient,
                                        const std::vector<unsigned int>& component_mapping,
-                                       const IteratorRange<hp::DoFHandler<dim> >  range,
+                                       const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                        Threads::ThreadMutex     &mutex);
 };
 
index 8b6bc59bc63888d412b0828cfdd1f00f14d43c45..df3fd5fa21a668f531f41605d34c9b2d01bf3fdb 100644 (file)
@@ -30,7 +30,7 @@ DEAL_II_NAMESPACE_OPEN
 // forward declarations
 class TimeStepBase;
 template <typename number> class Vector;
-template <int dim> class Triangulation;
+template <int dim, int spacedim> class Triangulation;
 
 /**
  * This class provides an abstract interface to time dependent problems in that
@@ -1628,7 +1628,7 @@ class TimeStepBase_Tria : public TimeStepBase
                                      * function of this class.
                                      */
     TimeStepBase_Tria (const double              time,
-                      const Triangulation<dim> &coarse_grid,
+                      const Triangulation<dim, dim> &coarse_grid,
                       const Flags              &flags,
                       const RefinementFlags    &refinement_flags = RefinementFlags());
 
@@ -1795,7 +1795,7 @@ class TimeStepBase_Tria : public TimeStepBase
                                      * such a behaviour is specified
                                      * in the @p flags structure.
                                      */
-    SmartPointer<Triangulation<dim> > tria;
+    SmartPointer<Triangulation<dim, dim> > tria;
 
                                     /**
                                      * Pointer to a grid which is to
@@ -1806,7 +1806,7 @@ class TimeStepBase_Tria : public TimeStepBase
                                      * with the owner of this
                                      * management object.
                                      */
-    SmartPointer<const Triangulation<dim> > coarse_grid;
+    SmartPointer<const Triangulation<dim, dim> > coarse_grid;
     
                                     /**
                                      * Some flags about how this time level
index 4f936891e9bc02347be72b3bf5a5310f05c5d0f2..92c14cad838923b6f7acc645441ad7bc82a324db 100644 (file)
@@ -34,12 +34,12 @@ template <int dim> class QGauss;
 
 template <typename number> class Vector;
 template <typename number> class FullMatrix;
-template <int dim> class Mapping;
-template <int dim> class DoFHandler;
+template <int dim, int spacedim> class Mapping;
+template <int dim, int spacedim> class DoFHandler;
 namespace hp
 {
-  template <int dim> class DoFHandler;
-  template <int dim> class MappingCollection;
+  template <int dim, int spacedim> class DoFHandler;
+  template <int dim, int spacedim> class MappingCollection;
   template <int dim> class QCollection;
 }
 class ConstraintMatrix;
@@ -331,7 +331,7 @@ class VectorTools
                                      *  following possibilities are
                                      *  implemented:
                                     */
-    enum NormType
+  enum NormType
     {
                                           /**
                                            * The function or
@@ -339,13 +339,13 @@ class VectorTools
                                            * is integrated on each
                                            * cell.
                                            */
-         mean,
+      mean,
                                           /**
                                            * The absolute value of
                                            * the function is
                                            * integrated.
                                            */
-         L1_norm,
+      L1_norm,
                                           /**
                                            * The square of the
                                            * function is integrated
@@ -353,7 +353,7 @@ class VectorTools
                                            * of the result is
                                            * computed on each cell.
                                            */
-         L2_norm,
+      L2_norm,
                                           /**
                                            * The absolute value to
                                            * the <i>p</i>th power is
@@ -364,41 +364,41 @@ class VectorTools
                                            * parameter of the
                                            * function.
                                            */
-         Lp_norm,
+      Lp_norm,
                                           /**
                                            * The maximum absolute
                                            * value of the function.
                                            */
-         Linfty_norm,
+      Linfty_norm,
                                           /**
                                            * #L2_norm of the gradient.
                                            */
-         H1_seminorm,
+      H1_seminorm,
                                           /**
                                            * The square of this norm
                                            * is the square of the
                                            * #L2_norm plus the square
                                            * of the #H1_seminorm.
                                            */
-         H1_norm,
+      H1_norm,
                                           /**
                                            * #Lp_norm of the gradient.
                                            */
-         W1p_seminorm,
+      W1p_seminorm,
                                           /**
                                            * same as #H1_norm for
                                            * <i>L<sup>p</sup></i>.
                                            */
-         W1p_norm,
+      W1p_norm,
                                           /**
                                            * #Linfty_norm of the gradient.
                                            */
-         W1infty_seminorm,
+      W1infty_seminorm,
                                           /**
                                            * same as #H1_norm for
                                            * <i>L<sup>infty</sup></i>.
                                            */
-         W1infty_norm
+      W1infty_norm
 
     };
 /**
@@ -434,10 +434,10 @@ class VectorTools
                                      * replaced by a hp::MappingCollection in
                                      * case of a hp::DoFHandler.
                                      */
-    template <int dim, class VECTOR, class DH>
-    static void interpolate (const Mapping<dim>    &mapping,
+  template <class VECTOR, class DH>
+    static void interpolate (const Mapping<DH::dimension,DH::space_dimension>    &mapping,
                             const DH              &dof,
-                            const Function<dim>   &function,
+                            const Function<DH::space_dimension>   &function,
                             VECTOR                &vec);
 
                                     /**
@@ -445,10 +445,10 @@ class VectorTools
                                      * function above with
                                      * <tt>mapping=MappingQ1@<dim>@()</tt>.
                                      */
-    template <int dim, class VECTOR, class DH>
-    static void interpolate (const DH              &dof,
-                            const Function<dim>   &function,
-                            VECTOR                &vec);
+  template <class VECTOR, class DH>
+  static void interpolate (const DH              &dof,
+                          const Function<DH::space_dimension>   &function,
+                          VECTOR                &vec);
     
                                     /**
                                      * Interpolate different finite
@@ -478,12 +478,12 @@ class VectorTools
                                      * combinations must be instantiated by
                                      * hand.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void interpolate (const DoFHandler<dim>    &dof_1,
-                            const DoFHandler<dim>    &dof_2,
-                            const FullMatrix<double> &transfer,
-                            const InVector           &data_1,
-                            OutVector                &data_2);
+  template <int dim, class InVector, class OutVector, int spacedim>
+  static void interpolate (const DoFHandler<dim,spacedim>    &dof_1,
+                          const DoFHandler<dim,spacedim>    &dof_2,
+                          const FullMatrix<double> &transfer,
+                          const InVector           &data_1,
+                          OutVector                &data_2);
 
                                     /**
                                      * Compute the projection of
@@ -523,35 +523,35 @@ class VectorTools
                                      * boundary doesn't happen in
                                      * 1d.
                                      */
-    template <int dim, class VECTOR>
-    static void project (const Mapping<dim>       &mapping,
-                        const DoFHandler<dim>    &dof,
-                        const ConstraintMatrix   &constraints,
-                        const Quadrature<dim>    &quadrature,
-                        const Function<dim>      &function,
-                        VECTOR                   &vec,
-                        const bool                enforce_zero_boundary = false,
-                        const Quadrature<dim-1>  &q_boundary = (dim > 1 ?
-                                                                 QGauss<dim-1>(2) :
-                                                                 Quadrature<dim-1>(0)),
-                        const bool                project_to_boundary_first = false);
+  template <int dim, class VECTOR, int spacedim>
+  static void project (const Mapping<dim, spacedim>       &mapping,
+                      const DoFHandler<dim,spacedim>    &dof,
+                      const ConstraintMatrix   &constraints,
+                      const Quadrature<dim>    &quadrature,
+                      const Function<spacedim>      &function,
+                      VECTOR                   &vec,
+                      const bool                enforce_zero_boundary = false,
+                      const Quadrature<dim-1>  &q_boundary = (dim > 1 ?
+                                                              QGauss<dim-1>(2) :
+                                                              Quadrature<dim-1>(0)),
+                      const bool                project_to_boundary_first = false);
 
                                     /**
                                      * Calls the project()
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, class VECTOR>
-    static void project (const DoFHandler<dim>    &dof,
-                        const ConstraintMatrix   &constraints,
-                        const Quadrature<dim>    &quadrature,
-                        const Function<dim>      &function,
-                        VECTOR                   &vec,
-                        const bool                enforce_zero_boundary = false,
-                        const Quadrature<dim-1>  &q_boundary = (dim > 1 ?
-                                                                 QGauss<dim-1>(2) :
-                                                                 Quadrature<dim-1>(0)),
-                        const bool                project_to_boundary_first = false);
+  template <int dim, class VECTOR, int spacedim>
+  static void project (const DoFHandler<dim,spacedim>    &dof,
+                      const ConstraintMatrix   &constraints,
+                      const Quadrature<dim>    &quadrature,
+                      const Function<spacedim>      &function,
+                      VECTOR                   &vec,
+                      const bool                enforce_zero_boundary = false,
+                      const Quadrature<dim-1>  &q_boundary = (dim > 1 ?
+                                                              QGauss<dim-1>(2) :
+                                                              Quadrature<dim-1>(0)),
+                      const bool                project_to_boundary_first = false);
 
                                     /**
                                      * Prepare Dirichlet boundary
@@ -621,15 +621,15 @@ class VectorTools
                                      * See the general doc for more
                                      * information.
                                      */
-    template <int dim, template <int> class DH>
-    static
-    void
-    interpolate_boundary_values (const Mapping<dim>            &mapping,
-                                 const DH<dim>                 &dof,
-                                 const typename FunctionMap<dim>::type &function_map,
-                                 std::map<unsigned int,double> &boundary_values,
-                                 const std::vector<bool>       &component_mask = std::vector<bool>());
-
+  template <class DH>
+  static
+  void
+  interpolate_boundary_values (const Mapping<DH::dimension,DH::space_dimension>            &mapping,
+                              const DH                 &dof,
+                              const typename FunctionMap<DH::space_dimension>::type &function_map,
+                              std::map<unsigned int,double> &boundary_values,
+                              const std::vector<bool>       &component_mask = std::vector<bool>());
+  
                                     /**
                                      * @deprecated This function is there mainly
                                      * for backward compatibility.
@@ -643,15 +643,15 @@ class VectorTools
                                      * arguments.
                                      *
                                      */
-    template <int dim, template <int> class DH>
-    static
-    void
-    interpolate_boundary_values (const Mapping<dim>            &mapping,
-                                 const DH<dim>                 &dof,
-                                 const unsigned char            boundary_component,
-                                 const Function<dim>           &boundary_function,
-                                 std::map<unsigned int,double> &boundary_values,
-                                 const std::vector<bool>       &component_mask = std::vector<bool>());
+  template <class DH>
+  static
+  void
+  interpolate_boundary_values (const Mapping<DH::dimension,DH::space_dimension>            &mapping,
+                              const DH                 &dof,
+                              const unsigned char            boundary_component,
+                              const Function<DH::space_dimension>           &boundary_function,
+                              std::map<unsigned int,double> &boundary_values,
+                              const std::vector<bool>       &component_mask = std::vector<bool>());
 
                                     /**
                                      * Calls the other
@@ -659,14 +659,14 @@ class VectorTools
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, template <int> class DH>
-    static
-    void
-    interpolate_boundary_values (const DH<dim>                 &dof,
-                                 const unsigned char            boundary_component,
-                                 const Function<dim>           &boundary_function,
-                                 std::map<unsigned int,double> &boundary_values,
-                                 const std::vector<bool>       &component_mask = std::vector<bool>());
+  template <class DH>
+  static
+  void
+  interpolate_boundary_values (const DH        &dof,
+                              const unsigned char            boundary_component,
+                              const Function<DH::space_dimension>           &boundary_function,
+                              std::map<unsigned int,double> &boundary_values,
+                              const std::vector<bool>       &component_mask = std::vector<bool>());
 
     
                                     /**
@@ -675,14 +675,14 @@ class VectorTools
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, template <int> class DH>
-    static
-    void
-    interpolate_boundary_values (const DH<dim>                 &dof,
-                                 const typename FunctionMap<dim>::type &function_map,
-                                 std::map<unsigned int,double> &boundary_values,
-                                 const std::vector<bool>       &component_mask = std::vector<bool>());
-    
+  template <class DH>
+  static
+  void
+  interpolate_boundary_values (const DH                &dof,
+                              const typename FunctionMap<DH::space_dimension>::type &function_map,
+                              std::map<unsigned int,double>         &boundary_values,
+                              const std::vector<bool>               &component_mask = std::vector<bool>());
+  
     
                                     /**
                                      * Project a function to the boundary
@@ -731,26 +731,25 @@ class VectorTools
                                      * default, no remapping is
                                      * applied.
                                      */
-    template <int dim>
-    static void project_boundary_values (const Mapping<dim>       &mapping,
-                                        const DoFHandler<dim>    &dof,
-                                        const typename FunctionMap<dim>::type &boundary_functions,
-                                        const Quadrature<dim-1>  &q,
-                                        std::map<unsigned int,double> &boundary_values,
-                                        std::vector<unsigned int> component_mapping = std::vector<unsigned int>());
+  template <int dim, int spacedim>
+  static void project_boundary_values (const Mapping<dim, spacedim>       &mapping,
+                                      const DoFHandler<dim,spacedim>    &dof,
+                                      const typename FunctionMap<spacedim>::type &boundary_functions,
+                                      const Quadrature<dim-1>  &q,
+                                      std::map<unsigned int,double> &boundary_values,
+                                      std::vector<unsigned int> component_mapping = std::vector<unsigned int>());
 
                                     /**
                                      * Calls the project_boundary_values()
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim>
-    static void project_boundary_values (const DoFHandler<dim>    &dof,
-                                        const typename FunctionMap<dim>::type &boundary_function,
-                                        const Quadrature<dim-1>  &q,
-                                        std::map<unsigned int,double> &boundary_values,
-                                        std::vector<unsigned int> component_mapping = std::vector<unsigned int>());
-
+  template <int dim, int spacedim>
+  static void project_boundary_values (const DoFHandler<dim,spacedim>    &dof,
+                                      const typename FunctionMap<spacedim>::type &boundary_function,
+                                      const Quadrature<dim-1>  &q,
+                                      std::map<unsigned int,double> &boundary_values,
+                                      std::vector<unsigned int> component_mapping = std::vector<unsigned int>());
 
                                     /**
                                      * Compute the constraints that
@@ -1048,14 +1047,14 @@ class VectorTools
                                      * constrained to be zero at
                                      * these points.
                                      */
-    template <int dim, template <int> class DH>
-    static
-    void
-    compute_no_normal_flux_constraints (const DH<dim>         &dof_handler,
-                                       const unsigned int     first_vector_component,
-                                       const std::set<unsigned char> &boundary_ids,
-                                       ConstraintMatrix      &constraints,
-                                       const Mapping<dim>    &mapping = StaticMappingQ1<dim>::mapping);
+  template <int dim, template <int, int> class DH, int spacedim>
+  static
+  void
+  compute_no_normal_flux_constraints (const DH<dim,spacedim>         &dof_handler,
+                                     const unsigned int     first_vector_component,
+                                     const std::set<unsigned char> &boundary_ids,
+                                     ConstraintMatrix      &constraints,
+                                     const Mapping<dim, spacedim>    &mapping = StaticMappingQ1<dim>::mapping);
     
     
                                     //@}
@@ -1073,11 +1072,11 @@ class VectorTools
                                      * See the general documentation of this
                                      * class for further information.
                                      */
-    template <int dim>
-    static void create_right_hand_side (const Mapping<dim>    &mapping,
-                                       const DoFHandler<dim> &dof,
+    template <int dim, int spacedim>
+    static void create_right_hand_side (const Mapping<dim, spacedim>    &mapping,
+                                       const DoFHandler<dim,spacedim> &dof,
                                        const Quadrature<dim> &q,
-                                       const Function<dim>   &rhs,
+                                       const Function<spacedim>   &rhs,
                                        Vector<double>        &rhs_vector);
 
                                     /**
@@ -1085,31 +1084,31 @@ class VectorTools
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim>
-    static void create_right_hand_side (const DoFHandler<dim> &dof,
+    template <int dim, int spacedim>
+    static void create_right_hand_side (const DoFHandler<dim,spacedim> &dof,
                                        const Quadrature<dim> &q,
-                                       const Function<dim>   &rhs,
+                                       const Function<spacedim>   &rhs,
                                        Vector<double>        &rhs_vector);
 
                                     /**
                                      * Like the previous set of functions,
                                      * but for hp objects.
                                      */
-    template <int dim>
-    static void create_right_hand_side (const hp::MappingCollection<dim>    &mapping,
-                                       const hp::DoFHandler<dim> &dof,
+    template <int dim, int spacedim>
+    static void create_right_hand_side (const hp::MappingCollection<dim,spacedim>    &mapping,
+                                       const hp::DoFHandler<dim,spacedim> &dof,
                                        const hp::QCollection<dim> &q,
-                                       const Function<dim>   &rhs,
+                                       const Function<spacedim>   &rhs,
                                        Vector<double>        &rhs_vector);
 
                                     /**
                                      * Like the previous set of functions,
                                      * but for hp objects.
                                      */
-    template <int dim>
-    static void create_right_hand_side (const hp::DoFHandler<dim> &dof,
+    template <int dim, int spacedim>
+    static void create_right_hand_side (const hp::DoFHandler<dim,spacedim> &dof,
                                        const hp::QCollection<dim> &q,
-                                       const Function<dim>   &rhs,
+                                       const Function<spacedim>   &rhs,
                                        Vector<double>        &rhs_vector);
     
                                     /**
@@ -1122,10 +1121,10 @@ class VectorTools
                                      * See the general documentation of this
                                      * class for further information.
                                      */
-    template <int dim>
-    static void create_point_source_vector(const Mapping<dim>    &mapping,
-                                           const DoFHandler<dim> &dof,
-                                           const Point<dim>      &p,
+    template <int dim, int spacedim>
+    static void create_point_source_vector(const Mapping<dim,spacedim>    &mapping,
+                                           const DoFHandler<dim,spacedim> &dof,
+                                           const Point<spacedim>      &p,
                                            Vector<double>        &rhs_vector);
 
                                     /**
@@ -1133,18 +1132,18 @@ class VectorTools
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim>
-    static void create_point_source_vector(const DoFHandler<dim> &dof,
-                                           const Point<dim>      &p,
+    template <int dim, int spacedim>
+    static void create_point_source_vector(const DoFHandler<dim,spacedim> &dof,
+                                           const Point<spacedim>      &p,
                                            Vector<double>        &rhs_vector);
 
                                     /**
                                      * Like the previous set of functions,
                                      * but for hp objects.
                                      */
-    template <int dim>
-    static void create_point_source_vector(const hp::MappingCollection<dim>    &mapping,
-                                           const hp::DoFHandler<dim> &dof,
+    template <int dim, int spacedim>
+    static void create_point_source_vector(const hp::MappingCollection<dim,spacedim>    &mapping,
+                                           const hp::DoFHandler<dim,spacedim> &dof,
                                            const Point<dim>      &p,
                                            Vector<double>        &rhs_vector);
 
@@ -1158,8 +1157,8 @@ class VectorTools
                                      * that provides a mapping object for
                                      * each active fe index.
                                      */
-    template <int dim>
-    static void create_point_source_vector(const hp::DoFHandler<dim> &dof,
+    template <int dim, int spacedim>
+    static void create_point_source_vector(const hp::DoFHandler<dim,spacedim> &dof,
                                            const Point<dim>      &p,
                                            Vector<double>        &rhs_vector);
     
@@ -1173,9 +1172,9 @@ class VectorTools
                                      * See the general documentation of this
                                      * class for further information.
                                      */
-    template <int dim>
-    static void create_boundary_right_hand_side (const Mapping<dim>      &mapping,
-                                                const DoFHandler<dim>   &dof,
+    template <int dim, int spacedim>
+    static void create_boundary_right_hand_side (const Mapping<dim,spacedim>      &mapping,
+                                                const DoFHandler<dim,spacedim>   &dof,
                                                 const Quadrature<dim-1> &q,
                                                 const Function<dim>     &rhs,
                                                 Vector<double>          &rhs_vector,
@@ -1187,8 +1186,8 @@ class VectorTools
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim>
-    static void create_boundary_right_hand_side (const DoFHandler<dim>   &dof,
+    template <int dim, int spacedim>
+    static void create_boundary_right_hand_side (const DoFHandler<dim,spacedim>   &dof,
                                                 const Quadrature<dim-1> &q,
                                                 const Function<dim>     &rhs,
                                                 Vector<double>          &rhs_vector,
@@ -1198,9 +1197,9 @@ class VectorTools
                                      * Same as the set of functions above,
                                      * but for hp objects.
                                      */
-    template <int dim>
-    static void create_boundary_right_hand_side (const hp::MappingCollection<dim>      &mapping,
-                                                const hp::DoFHandler<dim>   &dof,
+    template <int dim, int spacedim>
+    static void create_boundary_right_hand_side (const hp::MappingCollection<dim,spacedim>      &mapping,
+                                                const hp::DoFHandler<dim,spacedim>   &dof,
                                                 const hp::QCollection<dim-1> &q,
                                                 const Function<dim>     &rhs,
                                                 Vector<double>          &rhs_vector,
@@ -1216,8 +1215,8 @@ class VectorTools
                                      * the only active fe index in
                                      * use is zero.
                                      */
-    template <int dim>
-    static void create_boundary_right_hand_side (const hp::DoFHandler<dim>   &dof,
+    template <int dim, int spacedim>
+    static void create_boundary_right_hand_side (const hp::DoFHandler<dim,spacedim>   &dof,
                                                 const hp::QCollection<dim-1> &q,
                                                 const Function<dim>     &rhs,
                                                 Vector<double>          &rhs_vector,
@@ -1296,9 +1295,9 @@ class VectorTools
                                      * OutVector only Vector<double> and
                                      * Vector<float>.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void integrate_difference (const Mapping<dim>    &mapping,
-                                     const DoFHandler<dim> &dof,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void integrate_difference (const Mapping<dim,spacedim>    &mapping,
+                                     const DoFHandler<dim,spacedim> &dof,
                                      const InVector        &fe_function,
                                      const Function<dim>   &exact_solution,
                                      OutVector             &difference,
@@ -1312,8 +1311,8 @@ class VectorTools
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void integrate_difference (const DoFHandler<dim> &dof,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void integrate_difference (const DoFHandler<dim,spacedim> &dof,
                                      const InVector        &fe_function,
                                      const Function<dim>   &exact_solution,
                                      OutVector             &difference,
@@ -1322,9 +1321,9 @@ class VectorTools
                                      const Function<dim>   *weight=0,
                                      const double exponent = 2.);
 
-    template <int dim, class InVector, class OutVector>
-    static void integrate_difference (const hp::MappingCollection<dim>    &mapping,
-                                     const hp::DoFHandler<dim> &dof,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void integrate_difference (const hp::MappingCollection<dim,spacedim>    &mapping,
+                                     const hp::DoFHandler<dim,spacedim> &dof,
                                      const InVector        &fe_function,
                                      const Function<dim>   &exact_solution,
                                      OutVector             &difference,
@@ -1338,8 +1337,8 @@ class VectorTools
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, class InVector, class OutVector>
-    static void integrate_difference (const hp::DoFHandler<dim> &dof,
+    template <int dim, class InVector, class OutVector, int spacedim>
+    static void integrate_difference (const hp::DoFHandler<dim,spacedim> &dof,
                                      const InVector        &fe_function,
                                      const Function<dim>   &exact_solution,
                                      OutVector             &difference,
@@ -1364,8 +1363,8 @@ class VectorTools
                                       * boundaries to call the other
                                       * point_difference() function.
                                      */
-    template <int dim, class InVector>
-    static void point_difference (const DoFHandler<dim>& dof,
+    template <int dim, class InVector, int spacedim>
+    static void point_difference (const DoFHandler<dim,spacedim>& dof,
                                  const InVector&        fe_function,
                                  const Function<dim>&   exact_solution,
                                  Vector<double>&        difference,
@@ -1388,9 +1387,9 @@ class VectorTools
                                       * arbitrary mapping to evaluate
                                       * the difference.
                                      */
-    template <int dim, class InVector>
-    static void point_difference (const Mapping<dim>    &mapping,
-                                  const DoFHandler<dim>& dof,
+    template <int dim, class InVector, int spacedim>
+    static void point_difference (const Mapping<dim, spacedim>    &mapping,
+                                  const DoFHandler<dim,spacedim>& dof,
                                  const InVector&        fe_function,
                                  const Function<dim>&   exact_solution,
                                  Vector<double>&        difference,
@@ -1411,12 +1410,12 @@ class VectorTools
                                       * boundaries to call the other
                                       * point_difference() function.
                                      */
-    template <int dim, class InVector>
+    template <int dim, class InVector, int spacedim>
     static
     void
-    point_value (const DoFHandler<dim> &dof,
+    point_value (const DoFHandler<dim,spacedim> &dof,
                 const InVector        &fe_function,
-                const Point<dim>      &point,
+                const Point<spacedim>      &point,
                 Vector<double>        &value);
 
                                     /**
@@ -1432,12 +1431,12 @@ class VectorTools
                                       * this is a wrapper function using
                                       * a Q1-mapping for cells.
                                      */
-    template <int dim, class InVector>
+    template <int dim, class InVector, int spacedim>
     static
     double
-    point_value (const DoFHandler<dim> &dof,
+    point_value (const DoFHandler<dim,spacedim> &dof,
                 const InVector        &fe_function,
-                const Point<dim>      &point);
+                const Point<spacedim>      &point);
     
                                     /**
                                      * Evaluate a possibly
@@ -1454,13 +1453,13 @@ class VectorTools
                                       * this function uses an arbitrary
                                       * mapping to evaluate the difference.
                                      */
-    template <int dim, class InVector>
+    template <int dim, class InVector, int spacedim>
     static
     void
-    point_value (const Mapping<dim>    &mapping,
-                 const DoFHandler<dim> &dof,
+    point_value (const Mapping<dim, spacedim>    &mapping,
+                 const DoFHandler<dim,spacedim> &dof,
                 const InVector        &fe_function,
-                const Point<dim>      &point,
+                const Point<spacedim>      &point,
                 Vector<double>        &value);
 
                                     /**
@@ -1476,13 +1475,13 @@ class VectorTools
                                       * this function uses an arbitrary
                                       * mapping to evaluate the difference.
                                      */
-    template <int dim, class InVector>
+    template <int dim, class InVector, int spacedim>
     static
     double
-    point_value (const Mapping<dim>    &mapping,
-                 const DoFHandler<dim> &dof,
+    point_value (const Mapping<dim,spacedim>    &mapping,
+                 const DoFHandler<dim,spacedim> &dof,
                 const InVector        &fe_function,
-                const Point<dim>      &point);
+                const Point<spacedim>      &point);
     
                                     //@}
                                     /**
@@ -1552,9 +1551,9 @@ class VectorTools
                                      * Stokes with complete Dirichlet
                                      * boundaries for the velocities.
                                      */
-    template <int dim, class InVector>
-    static double compute_mean_value (const Mapping<dim>    &mapping,
-                                     const DoFHandler<dim> &dof,
+    template <int dim, class InVector, int spacedim>
+    static double compute_mean_value (const Mapping<dim, spacedim>    &mapping,
+                                     const DoFHandler<dim,spacedim> &dof,
                                      const Quadrature<dim> &quadrature,
                                      const InVector        &v,
                                      const unsigned int     component);
@@ -1564,8 +1563,8 @@ class VectorTools
                                      * function, see above, with
                                      * <tt>mapping=MappingQ1@<dim@>()</tt>.
                                      */
-    template <int dim, class InVector>
-    static double compute_mean_value (const DoFHandler<dim> &dof,
+    template <int dim, class InVector, int spacedim>
+    static double compute_mean_value (const DoFHandler<dim,spacedim> &dof,
                                      const Quadrature<dim> &quadrature,
                                      const InVector        &v,
                                      const unsigned int     component);
index 070afd6006f33b523a7bab931b4872a2bbfb3c09..e911b304e877599d4c241e88d5a99f30eea23c3f 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
-
-
-template <int dim, class VECTOR, class DH>
-void VectorTools::interpolate (const Mapping<dim>    &mapping,
+template <class VECTOR, class DH>
+void VectorTools::interpolate (const Mapping<DH::dimension,DH::space_dimension>    &mapping,
                               const DH              &dof,
-                              const Function<dim>   &function,
+                              const Function<DH::space_dimension>   &function,
                               VECTOR                &vec)
 {
+  const unsigned int dim=DH::dimension;
+
   Assert (dof.get_fe().n_components() == function.n_components,
          ExcDimensionMismatch(dof.get_fe().n_components(),
                               function.n_components));
   
-  const hp::FECollection<dim> fe (dof.get_fe());
+  const hp::FECollection<DH::dimension,DH::space_dimension> fe (dof.get_fe());
   const unsigned int          n_components = fe.n_components();
   const bool                  fe_is_system = (n_components != 1);
   
@@ -154,7 +154,7 @@ void VectorTools::interpolate (const Mapping<dim>    &mapping,
   const unsigned int max_rep_points = *std::max_element (n_rep_points.begin(),
                                                         n_rep_points.end());
   std::vector<unsigned int> dofs_on_cell (fe.max_dofs_per_cell());
-  std::vector<Point<dim> >  rep_points (max_rep_points);
+  std::vector<Point<DH::space_dimension> >  rep_points (max_rep_points);
   
                                   // get space for the values of the
                                   // function at the rep support points.
@@ -173,9 +173,9 @@ void VectorTools::interpolate (const Mapping<dim>    &mapping,
 
                                   // Transformed support points are computed by
                                   // FEValues
-  hp::MappingCollection<dim> mapping_collection (mapping);
+  hp::MappingCollection<dim,DH::space_dimension> mapping_collection (mapping);
   
-  hp::FEValues<dim> fe_values (mapping_collection,
+  hp::FEValues<dim, DH::space_dimension> fe_values (mapping_collection,
                               fe, support_quadrature, update_quadrature_points);
   
   for (; cell!=endc; ++cell)
@@ -186,7 +186,7 @@ void VectorTools::interpolate (const Mapping<dim>    &mapping,
                                       // get location of finite element
                                       // support_points
       fe_values.reinit(cell);
-      const std::vector<Point<dim> >& support_points =
+      const std::vector<Point<DH::space_dimension> >& support_points =
        fe_values.get_present_fe_values().get_quadrature_points();
       
                                       // pick out the representative
@@ -242,22 +242,23 @@ void VectorTools::interpolate (const Mapping<dim>    &mapping,
 }
 
 
-template <int dim, class VECTOR, class DH>
+template <class VECTOR, class DH>
 void VectorTools::interpolate (const DH              &dof,
-                              const Function<dim>   &function,
+                              const Function<DH::space_dimension>   &function,
                               VECTOR                &vec)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  interpolate(StaticMappingQ1<dim>::mapping, dof, function, vec);
+  interpolate(StaticMappingQ1<DH::dimension, DH::space_dimension>::mapping, 
+             dof, function, vec);
 }
 
 
 
 
-template <int dim, class InVector, class OutVector>
+template <int dim, class InVector, class OutVector, int spacedim>
 void
-VectorTools::interpolate (const DoFHandler<dim>           &dof_1,
-                         const DoFHandler<dim>           &dof_2,
+VectorTools::interpolate (const DoFHandler<dim,spacedim>           &dof_1,
+                         const DoFHandler<dim,spacedim>           &dof_2,
                          const FullMatrix<double>        &transfer,
                          const InVector                  &data_1,
                          OutVector                       &data_2)
@@ -268,9 +269,9 @@ VectorTools::interpolate (const DoFHandler<dim>           &dof_1,
   std::vector<short unsigned int> touch_count (dof_2.n_dofs(), 0);
   std::vector<unsigned int>       local_dof_indices (dof_2.get_fe().dofs_per_cell);
   
-  typename DoFHandler<dim>::active_cell_iterator h = dof_1.begin_active();
-  typename DoFHandler<dim>::active_cell_iterator l = dof_2.begin_active();
-  const typename DoFHandler<dim>::cell_iterator endh = dof_1.end();
+  typename DoFHandler<dim,spacedim>::active_cell_iterator h = dof_1.begin_active();
+  typename DoFHandler<dim,spacedim>::active_cell_iterator l = dof_2.begin_active();
+  const typename DoFHandler<dim,spacedim>::cell_iterator endh = dof_1.end();
   
   for(; h != endh; ++h, ++l)
   {
@@ -332,14 +333,37 @@ namespace internal
         }
     }
 
+
+//codimension 1
+    void
+      interpolate_zero_boundary_values (const dealii::DoFHandler<1,2>         &dof_handler,
+                                      std::map<unsigned int,double> &boundary_values)
+    {
+                                       // we only need to find the
+                                       // left-most and right-most
+                                       // vertex and query its vertex
+                                       // dof indices. that's easy :-)
+      for (unsigned direction=0; direction<2; ++direction)
+        {
+          dealii::DoFHandler<1,2>::cell_iterator
+              cell = dof_handler.begin(0);
+          while (!cell->at_boundary(direction))
+            cell = cell->neighbor(direction);
+
+          for (unsigned int i=0; i<dof_handler.get_fe().dofs_per_vertex; ++i)
+            boundary_values[cell->vertex_dof_index (direction, i)] = 0.;
+        }
+    }
+
+
 #else
     
-    template <int dim>
+    template <int dim, int spacedim>
     void
-    interpolate_zero_boundary_values (const dealii::DoFHandler<dim>       &dof_handler,
+    interpolate_zero_boundary_values (const dealii::DoFHandler<dim,spacedim>       &dof_handler,
                                       std::map<unsigned int,double> &boundary_values)
     {
-      const FiniteElement<dim> &fe = dof_handler.get_fe();
+      const FiniteElement<dim,spacedim> &fe = dof_handler.get_fe();
 
                                       // loop over all boundary faces
                                       // to get all dof indices of
@@ -362,7 +386,7 @@ namespace internal
                                       // that is actually wholly on
                                       // the boundary, not only by
                                       // one line or one vertex
-      typename dealii::DoFHandler<dim>::active_face_iterator
+      typename dealii::DoFHandler<dim,spacedim>::active_face_iterator
         face = dof_handler.begin_active_face(),
         endf = dof_handler.end_face();
       std::vector<unsigned int> face_dof_indices (fe.dofs_per_face);
@@ -387,12 +411,12 @@ namespace internal
 
 
 
-template <int dim, class VECTOR>
-void VectorTools::project (const Mapping<dim>       &mapping,
-                          const DoFHandler<dim>    &dof,
+template <int dim, class VECTOR, int spacedim>
+void VectorTools::project (const Mapping<dim, spacedim>       &mapping,
+                          const DoFHandler<dim,spacedim>    &dof,
                           const ConstraintMatrix   &constraints,
                           const Quadrature<dim>    &quadrature,
-                          const Function<dim>      &function,
+                          const Function<spacedim>      &function,
                           VECTOR                   &vec_result,
                           const bool                enforce_zero_boundary,
                           const Quadrature<dim-1>  &q_boundary,
@@ -427,7 +451,7 @@ void VectorTools::project (const Mapping<dim>       &mapping,
                                         // parts. We want the
                                         // function to hold on
                                         // all parts of the boundary
-       typename FunctionMap<dim>::type boundary_functions;
+       typename FunctionMap<spacedim>::type boundary_functions;
        for (unsigned char c=0; c<255; ++c)
          boundary_functions[c] = &function;
        project_boundary_values (dof, boundary_functions, q_boundary,
@@ -485,32 +509,32 @@ void VectorTools::project (const Mapping<dim>       &mapping,
 }
 
 
-template <int dim, class VECTOR>
-void VectorTools::project (const DoFHandler<dim>    &dof,
+template <int dim, class VECTOR, int spacedim>
+void VectorTools::project (const DoFHandler<dim,spacedim>    &dof,
                           const ConstraintMatrix   &constraints,
                           const Quadrature<dim>    &quadrature,
-                          const Function<dim>      &function,
+                          const Function<spacedim>      &function,
                           VECTOR                   &vec,
                           const bool                enforce_zero_boundary,
                           const Quadrature<dim-1>  &q_boundary,
                           const bool                project_to_boundary_first)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  project(StaticMappingQ1<dim>::mapping, dof, constraints, quadrature, function, vec,
+  project(StaticMappingQ1<dim,spacedim>::mapping, dof, constraints, quadrature, function, vec,
          enforce_zero_boundary, q_boundary, project_to_boundary_first);
 }
 
 
 
 
-template <int dim>
-void VectorTools::create_right_hand_side (const Mapping<dim>    &mapping,
-                                         const DoFHandler<dim> &dof_handler,
+template <int dim, int spacedim>
+void VectorTools::create_right_hand_side (const Mapping<dim, spacedim>    &mapping,
+                                         const DoFHandler<dim,spacedim> &dof_handler,
                                          const Quadrature<dim> &quadrature,
-                                         const Function<dim>   &rhs_function,
+                                         const Function<spacedim>   &rhs_function,
                                          Vector<double>        &rhs_vector)
 {
-  const FiniteElement<dim> &fe  = dof_handler.get_fe();
+  const FiniteElement<dim,spacedim> &fe  = dof_handler.get_fe();
   Assert (fe.n_components() == rhs_function.n_components,
          ExcDimensionMismatch(fe.n_components(), rhs_function.n_components));
   Assert (rhs_vector.size() == dof_handler.n_dofs(),
@@ -520,7 +544,7 @@ void VectorTools::create_right_hand_side (const Mapping<dim>    &mapping,
   UpdateFlags update_flags = UpdateFlags(update_values   |
                                         update_quadrature_points |
                                         update_JxW_values);
-  FEValues<dim> fe_values (mapping, fe, quadrature, update_flags);
+  FEValues<dim,spacedim> fe_values (mapping, fe, quadrature, update_flags);
 
   const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                     n_q_points    = fe_values.n_quadrature_points,
@@ -529,7 +553,7 @@ void VectorTools::create_right_hand_side (const Mapping<dim>    &mapping,
   std::vector<unsigned int> dofs (dofs_per_cell);
   Vector<double> cell_vector (dofs_per_cell);
 
-  typename DoFHandler<dim>::active_cell_iterator
+  typename DoFHandler<dim,spacedim>::active_cell_iterator
     cell = dof_handler.begin_active(),
     endc = dof_handler.end();
 
@@ -614,28 +638,28 @@ void VectorTools::create_right_hand_side (const Mapping<dim>    &mapping,
 
 
 
-template <int dim>
-void VectorTools::create_right_hand_side (const DoFHandler<dim>    &dof_handler,
+template <int dim, int spacedim>
+void VectorTools::create_right_hand_side (const DoFHandler<dim,spacedim>    &dof_handler,
                                          const Quadrature<dim>    &quadrature,
-                                         const Function<dim>      &rhs_function,
+                                         const Function<spacedim>      &rhs_function,
                                          Vector<double>           &rhs_vector)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  create_right_hand_side(StaticMappingQ1<dim>::mapping, dof_handler, quadrature,
+  create_right_hand_side(StaticMappingQ1<dim,spacedim>::mapping, dof_handler, quadrature,
                         rhs_function, rhs_vector);
 }
 
 
 
 
-template <int dim>
-void VectorTools::create_right_hand_side (const hp::MappingCollection<dim>    &mapping,
-                                         const hp::DoFHandler<dim> &dof_handler,
+template <int dim, int spacedim>
+void VectorTools::create_right_hand_side (const hp::MappingCollection<dim,spacedim>    &mapping,
+                                         const hp::DoFHandler<dim,spacedim> &dof_handler,
                                          const hp::QCollection<dim> &quadrature,
-                                         const Function<dim>   &rhs_function,
+                                         const Function<spacedim>   &rhs_function,
                                          Vector<double>        &rhs_vector)
 {
-  const hp::FECollection<dim> &fe  = dof_handler.get_fe();
+  const hp::FECollection<dim,spacedim> &fe  = dof_handler.get_fe();
   Assert (fe.n_components() == rhs_function.n_components,
          ExcDimensionMismatch(fe.n_components(), rhs_function.n_components));
   Assert (rhs_vector.size() == dof_handler.n_dofs(),
@@ -645,14 +669,14 @@ void VectorTools::create_right_hand_side (const hp::MappingCollection<dim>    &m
   UpdateFlags update_flags = UpdateFlags(update_values   |
                                         update_quadrature_points |
                                         update_JxW_values);
-  hp::FEValues<dim> x_fe_values (mapping, fe, quadrature, update_flags);
+  hp::FEValues<dim,spacedim> x_fe_values (mapping, fe, quadrature, update_flags);
 
   const unsigned int n_components  = fe.n_components();
   
   std::vector<unsigned int> dofs (fe.max_dofs_per_cell());
   Vector<double> cell_vector (fe.max_dofs_per_cell());
 
-  typename hp::DoFHandler<dim>::active_cell_iterator
+  typename hp::DoFHandler<dim,spacedim>::active_cell_iterator
     cell = dof_handler.begin_active(),
     endc = dof_handler.end();
 
@@ -664,7 +688,7 @@ void VectorTools::create_right_hand_side (const hp::MappingCollection<dim>    &m
        {
          x_fe_values.reinit(cell);
 
-         const FEValues<dim> &fe_values = x_fe_values.get_present_fe_values();
+         const FEValues<dim,spacedim> &fe_values = x_fe_values.get_present_fe_values();
          
          const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                             n_q_points    = fe_values.n_quadrature_points;
@@ -698,7 +722,7 @@ void VectorTools::create_right_hand_side (const hp::MappingCollection<dim>    &m
        {
          x_fe_values.reinit(cell);
 
-         const FEValues<dim> &fe_values = x_fe_values.get_present_fe_values();
+         const FEValues<dim,spacedim> &fe_values = x_fe_values.get_present_fe_values();
          
          const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                             n_q_points    = fe_values.n_quadrature_points;
@@ -753,14 +777,14 @@ void VectorTools::create_right_hand_side (const hp::MappingCollection<dim>    &m
 
 
 
-template <int dim>
-void VectorTools::create_right_hand_side (const hp::DoFHandler<dim>    &dof_handler,
+template <int dim, int spacedim>
+void VectorTools::create_right_hand_side (const hp::DoFHandler<dim,spacedim>    &dof_handler,
                                          const hp::QCollection<dim>    &quadrature,
-                                         const Function<dim>      &rhs_function,
+                                         const Function<spacedim>      &rhs_function,
                                          Vector<double>           &rhs_vector)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  create_right_hand_side(hp::StaticMappingQ1<dim>::mapping_collection, 
+  create_right_hand_side(hp::StaticMappingQ1<dim,spacedim>::mapping_collection, 
                         dof_handler, quadrature,
                         rhs_function, rhs_vector);
 }
@@ -768,10 +792,10 @@ void VectorTools::create_right_hand_side (const hp::DoFHandler<dim>    &dof_hand
 
 
 
-template <int dim>
-void VectorTools::create_point_source_vector (const Mapping<dim>       &mapping,
-                                              const DoFHandler<dim>    &dof_handler,
-                                              const Point<dim>         &p,
+template <int dim, int spacedim>
+void VectorTools::create_point_source_vector (const Mapping<dim, spacedim>       &mapping,
+                                              const DoFHandler<dim,spacedim>    &dof_handler,
+                                              const Point<spacedim>         &p,
                                               Vector<double>           &rhs_vector)
 {
    Assert (rhs_vector.size() == dof_handler.n_dofs(),
@@ -781,13 +805,13 @@ void VectorTools::create_point_source_vector (const Mapping<dim>       &mapping,
    
    rhs_vector = 0;
 
-   std::pair<typename DoFHandler<dim>::active_cell_iterator, Point<dim> >
+   std::pair<typename DoFHandler<dim,spacedim>::active_cell_iterator, Point<spacedim> >
       cell_point =
       GridTools::find_active_cell_around_point (mapping, dof_handler, p);
 
    Quadrature<dim> q(GeometryInfo<dim>::project_to_unit_cell(cell_point.second));
 
-   FEValues<dim> fe_values(mapping, dof_handler.get_fe(),
+   FEValues<dim,spacedim> fe_values(mapping, dof_handler.get_fe(),
                           q, UpdateFlags(update_values));
    fe_values.reinit(cell_point.first);
 
@@ -802,20 +826,20 @@ void VectorTools::create_point_source_vector (const Mapping<dim>       &mapping,
 
 
 
-template <int dim>
-void VectorTools::create_point_source_vector (const DoFHandler<dim>    &dof_handler,
-                                              const Point<dim>         &p,
+template <int dim, int spacedim>
+void VectorTools::create_point_source_vector (const DoFHandler<dim,spacedim>    &dof_handler,
+                                              const Point<spacedim>         &p,
                                               Vector<double>           &rhs_vector)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  create_point_source_vector(StaticMappingQ1<dim>::mapping, dof_handler,
+  create_point_source_vector(StaticMappingQ1<dim,spacedim>::mapping, dof_handler,
                              p, rhs_vector);
 }
 
 
-template <int dim>
-void VectorTools::create_point_source_vector (const hp::MappingCollection<dim>       &mapping,
-                                              const hp::DoFHandler<dim>    &dof_handler,
+template <int dim, int spacedim>
+void VectorTools::create_point_source_vector (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                              const hp::DoFHandler<dim,spacedim>    &dof_handler,
                                               const Point<dim>         &p,
                                               Vector<double>           &rhs_vector)
 {
@@ -826,7 +850,7 @@ void VectorTools::create_point_source_vector (const hp::MappingCollection<dim>
    
    rhs_vector = 0;
 
-   std::pair<typename hp::DoFHandler<dim>::active_cell_iterator, Point<dim> >
+   std::pair<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator, Point<dim> >
       cell_point =
       GridTools::find_active_cell_around_point (mapping, dof_handler, p);
 
@@ -847,8 +871,8 @@ void VectorTools::create_point_source_vector (const hp::MappingCollection<dim>
 
 
 
-template <int dim>
-void VectorTools::create_point_source_vector (const hp::DoFHandler<dim>    &dof_handler,
+template <int dim, int spacedim>
+void VectorTools::create_point_source_vector (const hp::DoFHandler<dim,spacedim>    &dof_handler,
                                               const Point<dim>         &p,
                                               Vector<double>           &rhs_vector)
 {
@@ -861,10 +885,10 @@ void VectorTools::create_point_source_vector (const hp::DoFHandler<dim>    &dof_
 
 #if deal_II_dimension != 1
 
-template <int dim>
+template <int dim, int spacedim>
 void
-VectorTools::create_boundary_right_hand_side (const Mapping<dim>      &mapping,
-                                             const DoFHandler<dim>   &dof_handler,
+VectorTools::create_boundary_right_hand_side (const Mapping<dim, spacedim>      &mapping,
+                                             const DoFHandler<dim,spacedim>   &dof_handler,
                                              const Quadrature<dim-1> &quadrature,
                                              const Function<dim>     &rhs_function,
                                              Vector<double>          &rhs_vector,
@@ -890,7 +914,7 @@ VectorTools::create_boundary_right_hand_side (const Mapping<dim>      &mapping,
   std::vector<unsigned int> dofs (dofs_per_cell);
   Vector<double> cell_vector (dofs_per_cell);
 
-  typename DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof_handler.begin_active(),
                                                 endc = dof_handler.end();
 
   if (n_components==1)
@@ -983,10 +1007,10 @@ VectorTools::create_boundary_right_hand_side (const Mapping<dim>      &mapping,
 #else
 
 // Implementation for 1D
-template <int dim>
+template <int dim, int spacedim>
 void
-VectorTools::create_boundary_right_hand_side (const Mapping<dim>    &,
-                                             const DoFHandler<dim> &,
+VectorTools::create_boundary_right_hand_side (const Mapping<dim, spacedim>    &,
+                                             const DoFHandler<dim,spacedim> &,
                                              const Quadrature<dim-1> &,
                                              const Function<dim>   &,
                                              Vector<double>      &,
@@ -997,9 +1021,9 @@ VectorTools::create_boundary_right_hand_side (const Mapping<dim>    &,
 
 #endif
 
-template <int dim>
+template <int dim, int spacedim>
 void
-VectorTools::create_boundary_right_hand_side (const DoFHandler<dim>   &dof_handler,
+VectorTools::create_boundary_right_hand_side (const DoFHandler<dim,spacedim>   &dof_handler,
                                              const Quadrature<dim-1> &quadrature,
                                              const Function<dim>     &rhs_function,
                                              Vector<double>          &rhs_vector,
@@ -1017,10 +1041,10 @@ VectorTools::create_boundary_right_hand_side (const DoFHandler<dim>   &dof_handl
 
 #if deal_II_dimension != 1
 
-template <int dim>
+template <int dim, int spacedim>
 void
-VectorTools::create_boundary_right_hand_side (const hp::MappingCollection<dim>      &mapping,
-                                             const hp::DoFHandler<dim>   &dof_handler,
+VectorTools::create_boundary_right_hand_side (const hp::MappingCollection<dim,spacedim>      &mapping,
+                                             const hp::DoFHandler<dim,spacedim>   &dof_handler,
                                              const hp::QCollection<dim-1> &quadrature,
                                              const Function<dim>     &rhs_function,
                                              Vector<double>          &rhs_vector,
@@ -1044,7 +1068,7 @@ VectorTools::create_boundary_right_hand_side (const hp::MappingCollection<dim>
   std::vector<unsigned int> dofs (fe.max_dofs_per_cell());
   Vector<double> cell_vector (fe.max_dofs_per_cell());
 
-  typename hp::DoFHandler<dim>::active_cell_iterator
+  typename hp::DoFHandler<dim,spacedim>::active_cell_iterator
     cell = dof_handler.begin_active(),
     endc = dof_handler.end();
 
@@ -1150,10 +1174,10 @@ VectorTools::create_boundary_right_hand_side (const hp::MappingCollection<dim>
 #else
 
 // Implementation for 1D
-template <int dim>
+template <int dim, int spacedim>
 void
-VectorTools::create_boundary_right_hand_side (const hp::MappingCollection<dim>    &,
-                                             const hp::DoFHandler<dim> &,
+VectorTools::create_boundary_right_hand_side (const hp::MappingCollection<dim,spacedim>    &,
+                                             const hp::DoFHandler<dim,spacedim> &,
                                              const hp::QCollection<dim-1> &,
                                              const Function<dim>   &,
                                              Vector<double>      &,
@@ -1164,9 +1188,9 @@ VectorTools::create_boundary_right_hand_side (const hp::MappingCollection<dim>
 
 #endif
 
-template <int dim>
+template <int dim, int spacedim>
 void
-VectorTools::create_boundary_right_hand_side (const hp::DoFHandler<dim>   &dof_handler,
+VectorTools::create_boundary_right_hand_side (const hp::DoFHandler<dim,spacedim>   &dof_handler,
                                              const hp::QCollection<dim-1> &quadrature,
                                              const Function<dim>     &rhs_function,
                                              Vector<double>          &rhs_vector,
@@ -1186,15 +1210,21 @@ VectorTools::create_boundary_right_hand_side (const hp::DoFHandler<dim>   &dof_h
 
 //TODO[?] Actually the Mapping object should be a MappingCollection object for the
 // hp::DoFHandler.
-template <int dim, template <int> class DH>
+
+//template <int dim, template <int, int> class DH, int spacedim>
+
+template <class DH>
 void
-VectorTools::interpolate_boundary_values (const Mapping<dim>         &,
-                                         const DH<dim>              &dof,
+VectorTools::interpolate_boundary_values (const Mapping<DH::dimension, DH::space_dimension>         &,
+                                         const DH              &dof,
                                          const unsigned char       boundary_component,
-                                         const Function<dim>        &boundary_function,
+                                         const Function<DH::space_dimension>        &boundary_function,
                                          std::map<unsigned int,double> &boundary_values,
                                          const std::vector<bool>       &component_mask_)
 {
+  const unsigned int dim=DH::dimension;
+  const unsigned int spacedim=DH::space_dimension;
+
   Assert (boundary_component != 255,
          ExcInvalidBoundaryIndicator());
   Assert ((component_mask_.size() == 0) ||
@@ -1218,7 +1248,7 @@ VectorTools::interpolate_boundary_values (const Mapping<dim>         &,
                                   // cell by first traversing the coarse
                                   // grid to its end and then going
                                   // to the children
-  typename DH<dim>::cell_iterator outermost_cell = dof.begin(0);
+  typename DH::cell_iterator outermost_cell = dof.begin(0);
   while (outermost_cell->neighbor(direction).state() == IteratorState::valid)
     outermost_cell = outermost_cell->neighbor(direction);
   
@@ -1227,7 +1257,7 @@ VectorTools::interpolate_boundary_values (const Mapping<dim>         &,
 
                                    // get the FE corresponding to this
                                    // cell
-  const FiniteElement<dim> &fe = outermost_cell->get_fe();
+  const FiniteElement<dim,spacedim> &fe = outermost_cell->get_fe();
   Assert (fe.n_components() == boundary_function.n_components,
          ExcDimensionMismatch(fe.n_components(), boundary_function.n_components));
 
@@ -1270,15 +1300,15 @@ VectorTools::interpolate_boundary_values (const Mapping<dim>         &,
 // hp::DoFHandler.
 
 // Implementation for 1D
-template <int dim, template <int> class DH>
+template <class DH>
 void
-VectorTools::interpolate_boundary_values (const Mapping<dim>              &mapping,
-                                         const DH<dim>           &dof,
-                                         const typename FunctionMap<dim>::type    &function_map,
+VectorTools::interpolate_boundary_values (const Mapping<DH::dimension, DH::space_dimension>              &mapping,
+                                         const DH         &dof,
+                                         const typename FunctionMap<DH::space_dimension>::type    &function_map,
                                          std::map<unsigned int,double> &boundary_values,
                                          const std::vector<bool>       &component_mask)
 {
-  for (typename FunctionMap<dim>::type::const_iterator i=function_map.begin();
+  for (typename FunctionMap<DH::space_dimension>::type::const_iterator i=function_map.begin();
        i!=function_map.end(); ++i)
     interpolate_boundary_values (mapping, dof, i->first, *i->second,
                                 boundary_values, component_mask);
@@ -1292,15 +1322,17 @@ VectorTools::interpolate_boundary_values (const Mapping<dim>              &mappi
 #else
 
 
-template <int dim, template <int> class DH>
+template <class DH>
 void
 VectorTools::
-interpolate_boundary_values (const Mapping<dim>            &mapping,
-                             const DH<dim>                 &dof,
-                             const typename FunctionMap<dim>::type &function_map,
+interpolate_boundary_values (const Mapping<DH::dimension, DH::space_dimension>            &mapping,
+                             const DH                 &dof,
+                             const typename FunctionMap<DH::space_dimension>::type &function_map,
                              std::map<unsigned int,double> &boundary_values,
                              const std::vector<bool>       &component_mask_)
 {
+  const unsigned int dim=DH::dimension;
+
   Assert ((component_mask_.size() == 0) ||
          (component_mask_.size() == dof.get_fe().n_components()),
          ExcMessage ("The number of components in the mask has to be either "
@@ -1320,7 +1352,7 @@ interpolate_boundary_values (const Mapping<dim>            &mapping,
   const unsigned int        n_components = DoFTools::n_components(dof);
   const bool                fe_is_system = (n_components != 1);
 
-  for (typename FunctionMap<dim>::type::const_iterator i=function_map.begin();
+  for (typename FunctionMap<DH::space_dimension>::type::const_iterator i=function_map.begin();
        i!=function_map.end(); ++i)
     Assert (n_components == i->second->n_components,
            ExcDimensionMismatch(n_components, i->second->n_components));
@@ -1338,7 +1370,7 @@ interpolate_boundary_values (const Mapping<dim>            &mapping,
   std::vector<unsigned int> face_dofs;
   face_dofs.reserve (DoFTools::max_dofs_per_face(dof));
 
-  std::vector<Point<dim> >  dof_locations;
+  std::vector<Point<DH::space_dimension> >  dof_locations;
   dof_locations.reserve (DoFTools::max_dofs_per_face(dof));
 
                                   // array to store the values of
@@ -1434,13 +1466,13 @@ interpolate_boundary_values (const Mapping<dim>            &mapping,
   hp::FEFaceValues<dim> x_fe_values (mapping_collection, finite_elements, q_collection,
                                     update_quadrature_points);
   
-  typename DH<dim>::active_cell_iterator cell = dof.begin_active(),
-                                        endc = dof.end();
+  typename DH::active_cell_iterator cell = dof.begin_active(),
+                                   endc = dof.end();
   for (; cell!=endc; ++cell)
     for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
         ++face_no)
       {
-        const FiniteElement<dim> &fe = cell->get_fe();
+        const FiniteElement<dim,DH::space_dimension> &fe = cell->get_fe();
 
                                         // we can presently deal only with
                                         // primitive elements for boundary
@@ -1466,7 +1498,7 @@ interpolate_boundary_values (const Mapping<dim>            &mapping,
                                    "elements"));
          }
        
-       typename DH<dim>::face_iterator face = cell->face(face_no);
+       typename DH::face_iterator face = cell->face(face_no);
        const unsigned char boundary_component = face->boundary_indicator();
        if (function_map.find(boundary_component) != function_map.end()) 
          {
@@ -1632,16 +1664,16 @@ interpolate_boundary_values (const Mapping<dim>            &mapping,
 
 
 
-template <int dim, template <int> class DH>
+template <class DH>
 void
-VectorTools::interpolate_boundary_values (const Mapping<dim>            &mapping,
-                                         const DH<dim>                 &dof,
+VectorTools::interpolate_boundary_values (const Mapping<DH::dimension, DH::space_dimension>            &mapping,
+                                         const DH                 &dof,
                                          const unsigned char            boundary_component,
-                                         const Function<dim>           &boundary_function,
+                                         const Function<DH::space_dimension>           &boundary_function,
                                          std::map<unsigned int,double> &boundary_values,
                                          const std::vector<bool>       &component_mask)
 {
-  typename FunctionMap<dim>::type function_map;
+  typename FunctionMap<DH::space_dimension>::type function_map;
   function_map[boundary_component] = &boundary_function;
   interpolate_boundary_values (mapping, dof, function_map, boundary_values,
                               component_mask);
@@ -1650,30 +1682,32 @@ VectorTools::interpolate_boundary_values (const Mapping<dim>            &mapping
 #endif
   
 
-template <int dim, template <int> class DH>
+template <class DH>
 void
-VectorTools::interpolate_boundary_values (const DH<dim>                 &dof,
+VectorTools::interpolate_boundary_values (const DH                 &dof,
                                          const unsigned char            boundary_component,
-                                         const Function<dim>           &boundary_function,
+                                         const Function<DH::space_dimension>           &boundary_function,
                                          std::map<unsigned int,double> &boundary_values,
                                          const std::vector<bool>       &component_mask)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  interpolate_boundary_values(StaticMappingQ1<dim>::mapping, dof, boundary_component,
+  interpolate_boundary_values(StaticMappingQ1<DH::dimension,DH::space_dimension>::mapping, 
+                             dof, boundary_component,
                              boundary_function, boundary_values, component_mask);
 }
 
 
 
-template <int dim, template <int> class DH>
+template <class DH>
 void
-VectorTools::interpolate_boundary_values (const DH<dim>                 &dof,
-                                         const typename FunctionMap<dim>::type &function_map,
+VectorTools::interpolate_boundary_values (const DH                 &dof,
+                                         const typename FunctionMap<DH::space_dimension>::type &function_map,
                                          std::map<unsigned int,double> &boundary_values,
                                          const std::vector<bool>       &component_mask)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  interpolate_boundary_values(StaticMappingQ1<dim>::mapping, dof, function_map,
+  interpolate_boundary_values(StaticMappingQ1<DH::dimension,DH::space_dimension>::mapping, 
+                             dof, function_map,
                              boundary_values, component_mask);
 }
 
@@ -1681,11 +1715,11 @@ VectorTools::interpolate_boundary_values (const DH<dim>                 &dof,
 #if deal_II_dimension == 1
 
 // Implementation for 1D
-template <int dim>
+template <int dim, int spacedim>
 void
-VectorTools::project_boundary_values (const Mapping<dim>       &mapping,
-                                     const DoFHandler<dim>    &dof,
-                                     const typename FunctionMap<dim>::type &boundary_functions,
+VectorTools::project_boundary_values (const Mapping<dim, spacedim>       &mapping,
+                                     const DoFHandler<dim,spacedim>    &dof,
+                                     const typename FunctionMap<spacedim>::type &boundary_functions,
                                      const Quadrature<dim-1>  &,
                                      std::map<unsigned int,double> &boundary_values,
                                      std::vector<unsigned int> component_mapping)
@@ -1700,11 +1734,11 @@ VectorTools::project_boundary_values (const Mapping<dim>       &mapping,
 #else
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-VectorTools::project_boundary_values (const Mapping<dim>       &mapping,
-                                     const DoFHandler<dim>    &dof,
-                                     const typename FunctionMap<dim>::type &boundary_functions,
+VectorTools::project_boundary_values (const Mapping<dim, spacedim>       &mapping,
+                                     const DoFHandler<dim,spacedim>    &dof,
+                                     const typename FunctionMap<spacedim>::type &boundary_functions,
                                      const Quadrature<dim-1>  &q,
                                      std::map<unsigned int,double> &boundary_values,
                                      std::vector<unsigned int> component_mapping)
@@ -1730,7 +1764,7 @@ VectorTools::project_boundary_values (const Mapping<dim>       &mapping,
   
   std::vector<unsigned int> dof_to_boundary_mapping;
   std::set<unsigned char> selected_boundary_components;
-  for (typename FunctionMap<dim>::type::const_iterator i=boundary_functions.begin();
+  for (typename FunctionMap<spacedim>::type::const_iterator i=boundary_functions.begin();
        i!=boundary_functions.end(); ++i)
     selected_boundary_components.insert (i->first);
   
@@ -1768,7 +1802,7 @@ VectorTools::project_boundary_values (const Mapping<dim>       &mapping,
 #ifdef DEBUG
 // Assert that there are no hanging nodes at the boundary      
       int level = -1;
-      for (typename DoFHandler<dim>::active_cell_iterator cell = dof.begin_active();
+      for (typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof.begin_active();
           cell != dof.end(); ++cell)
        for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
          {
@@ -1794,7 +1828,7 @@ VectorTools::project_boundary_values (const Mapping<dim>       &mapping,
 
   MatrixCreator::create_boundary_mass_matrix (mapping, dof, q, 
                                              mass_matrix, boundary_functions,
-                                             rhs, dof_to_boundary_mapping, (const Function<dim>*) 0,
+                                             rhs, dof_to_boundary_mapping, (const Function<spacedim>*) 0,
                                              component_mapping);
 
                                   // For certain weird elements,
@@ -1845,7 +1879,7 @@ VectorTools::project_boundary_values (const Mapping<dim>       &mapping,
   filtered_precondition.clear();  
                                   // fill in boundary values
   for (unsigned int i=0; i<dof_to_boundary_mapping.size(); ++i)
-    if (dof_to_boundary_mapping[i] != DoFHandler<dim>::invalid_dof_index
+    if (dof_to_boundary_mapping[i] != DoFHandler<dim,spacedim>::invalid_dof_index
     && ! excluded_dofs[dof_to_boundary_mapping[i]])
                                       // this dof is on one of the
                                       // interesting boundary parts
@@ -1859,16 +1893,16 @@ VectorTools::project_boundary_values (const Mapping<dim>       &mapping,
 
 #endif
 
-template <int dim>
+template <int dim, int spacedim>
 void
-VectorTools::project_boundary_values (const DoFHandler<dim>    &dof,
-                                     const typename FunctionMap<dim>::type &boundary_functions,
+VectorTools::project_boundary_values (const DoFHandler<dim,spacedim>    &dof,
+                                     const typename FunctionMap<spacedim>::type &boundary_functions,
                                      const Quadrature<dim-1>  &q,
                                      std::map<unsigned int,double> &boundary_values,
                                      std::vector<unsigned int> component_mapping)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  project_boundary_values(StaticMappingQ1<dim>::mapping, dof, boundary_functions, q,
+  project_boundary_values(StaticMappingQ1<dim,spacedim>::mapping, dof, boundary_functions, q,
                          boundary_values, component_mapping);
 }
 
@@ -2158,13 +2192,13 @@ namespace internal
 
 
 
-template <int dim, template <int> class DH>
+template <int dim, template <int, int> class DH, int spacedim>
 void
-VectorTools::compute_no_normal_flux_constraints (const DH<dim>         &dof_handler,
+VectorTools::compute_no_normal_flux_constraints (const DH<dim,spacedim>         &dof_handler,
                                                 const unsigned int     first_vector_component,
                                                 const std::set<unsigned char> &boundary_ids,
                                                 ConstraintMatrix      &constraints,
-                                                const Mapping<dim>    &mapping)
+                                                const Mapping<dim, spacedim>    &mapping)
 {
   Assert (dim > 1,
          ExcMessage ("This function is not useful in 1d because it amounts "
@@ -2195,13 +2229,13 @@ VectorTools::compute_no_normal_flux_constraints (const DH<dim>         &dof_hand
                                   // was computed on
   typedef 
     std::multimap<internal::VectorTools::VectorDoFTuple<dim>,
-    std::pair<Tensor<1,dim>, typename DH<dim>::active_cell_iterator> >
+    std::pair<Tensor<1,dim>, typename DH<dim,spacedim>::active_cell_iterator> >
     DoFToNormalsMap;
 
   DoFToNormalsMap dof_to_normals_map;
 
                                   // now loop over all cells and all faces
-  typename DH<dim>::active_cell_iterator
+  typename DH<dim,spacedim>::active_cell_iterator
     cell = dof_handler.begin_active(),
     endc = dof_handler.end();
   for (; cell!=endc; ++cell)
@@ -2210,7 +2244,7 @@ VectorTools::compute_no_normal_flux_constraints (const DH<dim>         &dof_hand
       if (boundary_ids.find(cell->face(face_no)->boundary_indicator())
          != boundary_ids.end())
        {
-         typename DH<dim>::face_iterator face = cell->face(face_no);
+         typename DH<dim,spacedim>::face_iterator face = cell->face(face_no);
 
                                           // get the indices of the
                                           // dofs on this cell...
@@ -2308,7 +2342,7 @@ VectorTools::compute_no_normal_flux_constraints (const DH<dim>         &dof_hand
                                       // that have contributed
       typedef
        std::map
-       <typename DH<dim>::active_cell_iterator,
+       <typename DH<dim,spacedim>::active_cell_iterator,
        std::pair<Tensor<1,dim>, unsigned int> >
        CellToNormalsMap;
 
@@ -2505,7 +2539,7 @@ VectorTools::compute_no_normal_flux_constraints (const DH<dim>         &dof_hand
                                             // comparable with
                                             // operator<
            typedef
-             std::map<typename DH<dim>::active_cell_iterator, std::list<Tensor<1,dim> > >
+             std::map<typename DH<dim,spacedim>::active_cell_iterator, std::list<Tensor<1,dim> > >
              CellContributions;
            CellContributions cell_contributions;
 
@@ -2680,10 +2714,10 @@ namespace internal
 {
   namespace VectorTools
   {
-    template <int dim, class InVector, class OutVector, class DH>
+    template <int dim, class InVector, class OutVector, class DH, int spacedim>
     static
     void
-    do_integrate_difference (const dealii::hp::MappingCollection<dim>    &mapping,
+    do_integrate_difference (const dealii::hp::MappingCollection<dim,spacedim>    &mapping,
                              const DH              &dof,
                              const InVector        &fe_function,
                              const Function<dim>   &exact_solution,
@@ -3030,10 +3064,10 @@ namespace internal
 
 
 
-template <int dim, class InVector, class OutVector>
+template <int dim, class InVector, class OutVector, int spacedim>
 void
-VectorTools::integrate_difference (const Mapping<dim>    &mapping,
-                                  const DoFHandler<dim> &dof,
+VectorTools::integrate_difference (const Mapping<dim, spacedim>    &mapping,
+                                  const DoFHandler<dim,spacedim> &dof,
                                   const InVector        &fe_function,
                                   const Function<dim>   &exact_solution,
                                   OutVector             &difference,
@@ -3043,16 +3077,16 @@ VectorTools::integrate_difference (const Mapping<dim>    &mapping,
                                   const double           exponent)
 {
   internal::VectorTools
-    ::do_integrate_difference (hp::MappingCollection<dim>(mapping),
+    ::do_integrate_difference (hp::MappingCollection<dim,spacedim>(mapping),
                                dof, fe_function, exact_solution,
                                difference, hp::QCollection<dim>(q),
                                norm, weight, exponent);
 }
 
 
-template <int dim, class InVector, class OutVector>
+template <int dim, class InVector, class OutVector, int spacedim>
 void
-VectorTools::integrate_difference (const DoFHandler<dim>    &dof,
+VectorTools::integrate_difference (const DoFHandler<dim,spacedim>    &dof,
                                   const InVector           &fe_function,
                                   const Function<dim>      &exact_solution,
                                   OutVector                &difference,
@@ -3071,10 +3105,10 @@ VectorTools::integrate_difference (const DoFHandler<dim>    &dof,
 
 
 
-template <int dim, class InVector, class OutVector>
+template <int dim, class InVector, class OutVector, int spacedim>
 void
-VectorTools::integrate_difference (const dealii::hp::MappingCollection<dim>    &mapping,
-                                  const dealii::hp::DoFHandler<dim> &dof,
+VectorTools::integrate_difference (const dealii::hp::MappingCollection<dim,spacedim>    &mapping,
+                                  const dealii::hp::DoFHandler<dim,spacedim> &dof,
                                   const InVector        &fe_function,
                                   const Function<dim>   &exact_solution,
                                   OutVector             &difference,
@@ -3084,16 +3118,16 @@ VectorTools::integrate_difference (const dealii::hp::MappingCollection<dim>    &
                                   const double           exponent)
 {
   internal::VectorTools
-    ::do_integrate_difference (hp::MappingCollection<dim>(mapping),
+    ::do_integrate_difference (hp::MappingCollection<dim,spacedim>(mapping),
                                dof, fe_function, exact_solution,
                                difference, q,
                                norm, weight, exponent);
 }
 
 
-template <int dim, class InVector, class OutVector>
+template <int dim, class InVector, class OutVector, int spacedim>
 void
-VectorTools::integrate_difference (const dealii::hp::DoFHandler<dim>    &dof,
+VectorTools::integrate_difference (const dealii::hp::DoFHandler<dim,spacedim>    &dof,
                                   const InVector           &fe_function,
                                   const Function<dim>      &exact_solution,
                                   OutVector                &difference,
@@ -3112,9 +3146,9 @@ VectorTools::integrate_difference (const dealii::hp::DoFHandler<dim>    &dof,
 
 
 
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 void
-VectorTools::point_difference (const DoFHandler<dim> &dof,
+VectorTools::point_difference (const DoFHandler<dim,spacedim> &dof,
                               const InVector        &fe_function,
                               const Function<dim>   &exact_function,
                               Vector<double>        &difference,
@@ -3129,10 +3163,10 @@ VectorTools::point_difference (const DoFHandler<dim> &dof,
 }
 
 
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 void
-VectorTools::point_difference (const Mapping<dim>    &mapping,
-                               const DoFHandler<dim> &dof,
+VectorTools::point_difference (const Mapping<dim, spacedim>    &mapping,
+                               const DoFHandler<dim,spacedim> &dof,
                               const InVector        &fe_function,
                               const Function<dim>   &exact_function,
                               Vector<double>        &difference,
@@ -3146,7 +3180,7 @@ VectorTools::point_difference (const Mapping<dim>    &mapping,
                                    // first find the cell in which this point
                                    // is, initialize a quadrature rule with
                                    // it, and then a FEValues object
-  const std::pair<typename DoFHandler<dim>::active_cell_iterator, Point<dim> >
+  const std::pair<typename DoFHandler<dim,spacedim>::active_cell_iterator, Point<dim> >
     cell_point = GridTools::find_active_cell_around_point (mapping, dof, point);
 
   Assert(GeometryInfo<dim>::distance_to_unit_cell(cell_point.second) < 1e-10,
@@ -3172,14 +3206,15 @@ VectorTools::point_difference (const Mapping<dim>    &mapping,
 }
 
 
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 void
-VectorTools::point_value (const DoFHandler<dim> &dof,
+VectorTools::point_value (const DoFHandler<dim,spacedim> &dof,
                          const InVector        &fe_function,
-                         const Point<dim>      &point,
+                         const Point<spacedim>      &point,
                          Vector<double>        &value)
 {
-   point_value(StaticMappingQ1<dim>::mapping,
+
+  point_value(StaticMappingQ1<dim,spacedim>::mapping,
                dof,
                fe_function,
                point,
@@ -3188,24 +3223,24 @@ VectorTools::point_value (const DoFHandler<dim> &dof,
 
 
 
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 double
-VectorTools::point_value (const DoFHandler<dim> &dof,
+VectorTools::point_value (const DoFHandler<dim,spacedim> &dof,
                          const InVector        &fe_function,
-                         const Point<dim>      &point)
+                         const Point<spacedim>      &point)
 {
-   return point_value(StaticMappingQ1<dim>::mapping,
+  return point_value(StaticMappingQ1<dim,spacedim>::mapping,
                       dof,
                       fe_function,
                       point);
 }
 
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 void
-VectorTools::point_value (const Mapping<dim>    &mapping,
-                          const DoFHandler<dim> &dof,
+VectorTools::point_value (const Mapping<dim, spacedim>    &mapping,
+                          const DoFHandler<dim,spacedim> &dof,
                          const InVector        &fe_function,
-                         const Point<dim>      &point,
+                         const Point<spacedim>      &point,
                          Vector<double>        &value)
 {
   const FiniteElement<dim>& fe = dof.get_fe();
@@ -3216,7 +3251,7 @@ VectorTools::point_value (const Mapping<dim>    &mapping,
                                    // first find the cell in which this point
                                    // is, initialize a quadrature rule with
                                    // it, and then a FEValues object
-  const std::pair<typename DoFHandler<dim>::active_cell_iterator, Point<dim> >
+  const std::pair<typename DoFHandler<dim,spacedim>::active_cell_iterator, Point<dim> >
     cell_point
     = GridTools::find_active_cell_around_point (mapping, dof, point);
 
@@ -3239,12 +3274,12 @@ VectorTools::point_value (const Mapping<dim>    &mapping,
 
 
 
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 double
-VectorTools::point_value (const Mapping<dim>    &mapping,
-                          const DoFHandler<dim> &dof,
+VectorTools::point_value (const Mapping<dim, spacedim>    &mapping,
+                          const DoFHandler<dim,spacedim> &dof,
                          const InVector        &fe_function,
-                         const Point<dim>      &point)
+                         const Point<spacedim>      &point)
 {
   const FiniteElement<dim>& fe = dof.get_fe();
 
@@ -3254,7 +3289,7 @@ VectorTools::point_value (const Mapping<dim>    &mapping,
                                    // first find the cell in which this point
                                    // is, initialize a quadrature rule with
                                    // it, and then a FEValues object
-  const std::pair<typename DoFHandler<dim>::active_cell_iterator, Point<dim> >
+  const std::pair<typename DoFHandler<dim,spacedim>::active_cell_iterator, Point<dim> >
     cell_point = GridTools::find_active_cell_around_point (mapping, dof, point);
 
   Assert(GeometryInfo<dim>::distance_to_unit_cell(cell_point.second) < 1e-10,
@@ -3274,10 +3309,10 @@ VectorTools::point_value (const Mapping<dim>    &mapping,
 }
 
 
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 double
-VectorTools::compute_mean_value (const Mapping<dim>    &mapping,
-                                const DoFHandler<dim> &dof,
+VectorTools::compute_mean_value (const Mapping<dim, spacedim>    &mapping,
+                                const DoFHandler<dim,spacedim> &dof,
                                 const Quadrature<dim> &quadrature,
                                 const InVector        &v,
                                 const unsigned int     component)
@@ -3291,7 +3326,7 @@ VectorTools::compute_mean_value (const Mapping<dim>    &mapping,
                   UpdateFlags(update_JxW_values
                               | update_values));
 
-  typename DoFHandler<dim>::active_cell_iterator c;
+  typename DoFHandler<dim,spacedim>::active_cell_iterator c;
   std::vector<Vector<double> > values(quadrature.size(),
                                      Vector<double> (dof.get_fe().n_components()));
   
@@ -3313,9 +3348,9 @@ VectorTools::compute_mean_value (const Mapping<dim>    &mapping,
 }
 
 
-template <int dim, class InVector>
+template <int dim, class InVector, int spacedim>
 double
-VectorTools::compute_mean_value (const DoFHandler<dim> &dof,
+VectorTools::compute_mean_value (const DoFHandler<dim,spacedim> &dof,
                                 const Quadrature<dim> &quadrature,
                                 const InVector        &v,
                                 const unsigned int     component)
index 36ac35d309deda4b5fd17a20c15cbccb143a224a..e7aab2ffd5c35b3e92b7d3aa22e960a84b0bb201 100644 (file)
@@ -37,287 +37,35 @@ DEAL_II_NAMESPACE_OPEN
 /*------------------------- Functions: DoFCellAccessor -----------------------*/
 
 
-#if deal_II_dimension == 1
-
-template <>
-TriaIterator<1, DoFObjectAccessor<0,DoFHandler<1> > >
-DoFCellAccessor<DoFHandler<1> >::face (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return TriaIterator<1, DoFObjectAccessor<0,DoFHandler<1> > >();
-}
-
-
-template <>
-void
-DoFCellAccessor<DoFHandler<1> >::update_cell_dof_indices_cache () const
-{
-  Assert (static_cast<unsigned int>(this->present_level) < this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-  
-  Assert (this->dof_handler != 0, BaseClass::ExcInvalidObject());
-  Assert (&this->get_fe() != 0, BaseClass::ExcInvalidObject());
-
-                                  // check as in documentation that
-                                  // cell is either active, or dofs
-                                  // are only in vertices. otherwise
-                                  // simply don't update the cache at
-                                  // all. the get_dof_indices
-                                  // function will then make sure we
-                                  // don't access the invalid data
-  if (this->has_children()
-      &&
-      (this->get_fe().dofs_per_cell !=
-       this->get_fe().dofs_per_vertex * GeometryInfo<1>::vertices_per_cell))
-    return;
-  
-  const unsigned int dofs_per_vertex = this->get_fe().dofs_per_vertex,
-                    dofs_per_line   = this->get_fe().dofs_per_line,
-                    dofs_per_cell   = this->get_fe().dofs_per_cell;
-
-                                  // make sure the cache is at least
-                                  // as big as we need it when
-                                  // writing to the last element of
-                                  // this cell
-  Assert (this->present_index * dofs_per_cell + dofs_per_cell
-         <=
-         this->dof_handler->levels[this->present_level]
-         ->cell_dof_indices_cache.size(),
-         ExcInternalError());
-
-  std::vector<unsigned int>::iterator next
-    = (this->dof_handler->levels[this->present_level]
-       ->cell_dof_indices_cache.begin() + this->present_index * dofs_per_cell);
-  
-  for (unsigned int vertex=0; vertex<2; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next++ = vertex_dof_index(vertex,d);
-  for (unsigned int d=0; d<dofs_per_line; ++d)
-    *next++ = dof_index(d);
-}
-
-
-
-template <>
-void
-DoFCellAccessor<hp::DoFHandler<1> >::update_cell_dof_indices_cache () const
-{
-//TODO[WB]: should implement a dof indices cache for hp as well
-  
-                                  // not implemented, but should also
-                                  // not be called
-  Assert (false, ExcNotImplemented());
-}
-
-
-
-#endif
-
-
-#if deal_II_dimension == 2
-
-template <>
-TriaIterator<2, DoFObjectAccessor<1,DoFHandler<2> > >
-DoFCellAccessor<DoFHandler<2> >::face (const unsigned int i) const
-{
-  return this->line(i);
-}
-
-
-
-template <>
-void
-DoFCellAccessor<DoFHandler<2> >::update_cell_dof_indices_cache () const
-{
-  Assert (static_cast<unsigned int>(this->present_level) < this->dof_handler->levels.size(),
-          ExcMessage ("DoFHandler not initialized"));
-
-  Assert (this->dof_handler != 0, BaseClass::ExcInvalidObject());
-  Assert (&this->get_fe() != 0, BaseClass::ExcInvalidObject());
-
-                                  // check as in documentation that
-                                  // cell is either active, or dofs
-                                  // are only in vertices. otherwise
-                                  // simply don't update the cache at
-                                  // all. the get_dof_indices
-                                  // function will then make sure we
-                                  // don't access the invalid data
-  if (this->has_children()
-      &&
-      (this->get_fe().dofs_per_cell !=
-       this->get_fe().dofs_per_vertex * GeometryInfo<2>::vertices_per_cell))
-    return;
-  
-  const unsigned int dofs_per_vertex = this->get_fe().dofs_per_vertex,
-                    dofs_per_line   = this->get_fe().dofs_per_line,
-                    dofs_per_quad   = this->get_fe().dofs_per_quad,
-                    dofs_per_cell   = this->get_fe().dofs_per_cell;
-
-                                  // make sure the cache is at least
-                                  // as big as we need it when
-                                  // writing to the last element of
-                                  // this cell
-  Assert (this->present_index * dofs_per_cell + dofs_per_cell
-         <=
-         this->dof_handler->levels[this->present_level]
-         ->cell_dof_indices_cache.size(),
-         ExcInternalError());
-
-  std::vector<unsigned int>::iterator next
-    = (this->dof_handler->levels[this->present_level]
-       ->cell_dof_indices_cache.begin() + this->present_index * dofs_per_cell);
-
-  for (unsigned int vertex=0; vertex<4; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next++ = vertex_dof_index(vertex,d);
-  for (unsigned int line=0; line<4; ++line)
-    for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next++ = this->line(line)->dof_index(d);
-  for (unsigned int d=0; d<dofs_per_quad; ++d)
-    *next++ = dof_index(d);
-}
-
-
-
-template <>
-void
-DoFCellAccessor<hp::DoFHandler<2> >::update_cell_dof_indices_cache () const
-{
-//TODO[WB]: should implement a dof indices cache for hp as well
-  
-                                  // not implemented, but should also
-                                  // not be called
-  Assert (false, ExcNotImplemented());
-}
-
 
-#endif
-
-
-#if deal_II_dimension == 3
-
-template <>
-TriaIterator<3, DoFObjectAccessor<2,DoFHandler<3> > >
-DoFCellAccessor<DoFHandler<3> >::face (const unsigned int i) const
-{
-  return this->quad(i);
-}
 
-
-
-template <>
+template <class DH>
 void
-DoFCellAccessor<DoFHandler<3> >::update_cell_dof_indices_cache () const
+DoFCellAccessor<DH>::update_cell_dof_indices_cache () const
 {
   Assert (static_cast<unsigned int>(this->present_level) < this->dof_handler->levels.size(),
           ExcMessage ("DoFHandler not initialized"));
-
-  Assert (this->dof_handler != 0, BaseClass::ExcInvalidObject());
-  Assert (&this->get_fe() != 0, BaseClass::ExcInvalidObject());
-
-                                  // check as in documentation that
-                                  // cell is either active, or dofs
-                                  // are only in vertices. otherwise
-                                  // simply don't update the cache at
-                                  // all. the get_dof_indices
-                                  // function will then make sure we
-                                  // don't access the invalid data
-  if (this->has_children()
-      &&
-      (this->get_fe().dofs_per_cell !=
-       this->get_fe().dofs_per_vertex * GeometryInfo<3>::vertices_per_cell))
-    return;
   
-  const unsigned int dofs_per_vertex = this->get_fe().dofs_per_vertex,
-                    dofs_per_line   = this->get_fe().dofs_per_line,
-                    dofs_per_quad   = this->get_fe().dofs_per_quad,
-                    dofs_per_hex    = this->get_fe().dofs_per_hex,
-                    dofs_per_cell   = this->get_fe().dofs_per_cell;
-
-                                  // make sure the cache is at least
-                                  // as big as we need it when
-                                  // writing to the last element of
-                                  // this cell
-  Assert (this->present_index * dofs_per_cell + dofs_per_cell
-         <=
-         this->dof_handler->levels[this->present_level]
-         ->cell_dof_indices_cache.size(),
-         ExcInternalError());
-
-  std::vector<unsigned int>::iterator next
-    = (this->dof_handler->levels[this->present_level]
-       ->cell_dof_indices_cache.begin() + this->present_index * dofs_per_cell);
-
-  for (unsigned int vertex=0; vertex<8; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next++ = vertex_dof_index(vertex,d);
-                                  // now copy dof numbers from the line. for
-                                  // lines with the wrong orientation, we have
-                                  // already made sure that we're ok by picking
-                                  // the correct vertices (this happens
-                                  // automatically in the vertex()
-                                  // function). however, if the line is in
-                                  // wrong orientation, we look at it in
-                                  // flipped orientation and we will have to
-                                  // adjust the shape function indices that we
-                                  // see to correspond to the correct
-                                  // (cell-local) ordering.
-  for (unsigned int line=0; line<12; ++line)
-    for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next++ = this->line(line)->dof_index(this->dof_handler->get_fe().
-                                           adjust_line_dof_index_for_line_orientation(d,
-                                                                                      this->line_orientation(line)));
-                                  // now copy dof numbers from the face. for
-                                  // faces with the wrong orientation, we
-                                  // have already made sure that we're ok by
-                                  // picking the correct lines and vertices
-                                  // (this happens automatically in the
-                                  // line() and vertex() functions). however,
-                                  // if the face is in wrong orientation, we
-                                  // look at it in flipped orientation and we
-                                  // will have to adjust the shape function
-                                  // indices that we see to correspond to the
-                                  // correct (cell-local) ordering. The same
-                                  // applies, if the face_rotation or
-                                  // face_orientation is non-standard
-  for (unsigned int quad=0; quad<6; ++quad)
-    for (unsigned int d=0; d<dofs_per_quad; ++d)
-      *next++ = this->quad(quad)->dof_index(this->dof_handler->get_fe().
-                                           adjust_quad_dof_index_for_face_orientation(d,
-                                                                                      this->face_orientation(quad),
-                                                                                      this->face_flip(quad),
-                                                                                      this->face_rotation(quad)));
-  for (unsigned int d=0; d<dofs_per_hex; ++d)
-    *next++ = dof_index(d);
-}
-
+  Assert (this->dof_handler != 0, typename BaseClass::ExcInvalidObject());
+  Assert (&this->get_fe() != 0, typename BaseClass::ExcInvalidObject());
 
-template <>
-void
-DoFCellAccessor<hp::DoFHandler<3> >::update_cell_dof_indices_cache () const
-{
-//TODO[WB]: should implement a dof indices cache for hp as well
-  
-                                  // not implemented, but should also
-                                  // not be called
-  Assert (false, ExcNotImplemented());
+  Implementation::update_cell_dof_indices_cache (*this);
 }
 
 
-#endif
-
 
 template <class DH>
-TriaIterator<DH::dimension,DoFCellAccessor<DH> >
+typename internal::DoFHandler::Iterators<DH>::cell_iterator
 DoFCellAccessor<DH>::neighbor_child_on_subface (const unsigned int face,
                                                const unsigned int subface) const
 {
-  const TriaIterator<dim,CellAccessor<dim> > q
-    = CellAccessor<dim>::neighbor_child_on_subface (face, subface);
-  return TriaIterator<dim,DoFCellAccessor<DH> > (this->tria,
-                                                q->level (),
-                                                q->index (),
-                                                this->dof_handler);
+  const TriaIterator<CellAccessor<dim,spacedim> > q
+    = CellAccessor<dim,spacedim>::neighbor_child_on_subface (face, subface);
+  return
+    typename internal::DoFHandler::Iterators<DH>::cell_iterator (this->tria,
+                                                                q->level (),
+                                                                q->index (),
+                                                                this->dof_handler);
 }
 
 
@@ -368,7 +116,7 @@ DoFCellAccessor<DH>::
 get_interpolated_dof_values (const InputVector &values,
                             Vector<number>    &interpolated_values) const
 {
-  const FiniteElement<dim> &fe            = this->get_fe();
+  const FiniteElement<dim,spacedim> &fe            = this->get_fe();
   const unsigned int        dofs_per_cell = fe.dofs_per_cell;
   
   Assert (this->dof_handler != 0,
@@ -524,19 +272,15 @@ set_dof_values_by_interpolation (const Vector<number> &local_values,
 
 #if deal_II_dimension == 1
 template class DoFAccessor<1, DoFHandler<1> >;
-template class DoFObjectAccessor<1, DoFHandler<1> >;
 #endif
 
 #if deal_II_dimension == 2
 template class DoFAccessor<1, DoFHandler<2> >;
 template class DoFAccessor<2, DoFHandler<2> >;
 
-template class DoFObjectAccessor<1, DoFHandler<2> >;
-template class DoFObjectAccessor<2, DoFHandler<2> >;
-
-template class TriaRawIterator   <2,DoFObjectAccessor<1, DoFHandler<2> > >;
-template class TriaIterator      <2,DoFObjectAccessor<1, DoFHandler<2> > >;
-template class TriaActiveIterator<2,DoFObjectAccessor<1, DoFHandler<2> > >;
+template class TriaRawIterator   <DoFAccessor<1, DoFHandler<2> > >;
+template class TriaIterator      <DoFAccessor<1, DoFHandler<2> > >;
+template class TriaActiveIterator<DoFAccessor<1, DoFHandler<2> > >;
 #endif
 
 #if deal_II_dimension == 3
@@ -544,24 +288,20 @@ template class DoFAccessor<1, DoFHandler<3> >;
 template class DoFAccessor<2, DoFHandler<3> >;
 template class DoFAccessor<3, DoFHandler<3> >;
 
-template class DoFObjectAccessor<1, DoFHandler<3> >;
-template class DoFObjectAccessor<2, DoFHandler<3> >;
-template class DoFObjectAccessor<3, DoFHandler<3> >;
-
-template class TriaRawIterator   <3,DoFObjectAccessor<1, DoFHandler<3> > >;
-template class TriaIterator      <3,DoFObjectAccessor<1, DoFHandler<3> > >;
-template class TriaActiveIterator<3,DoFObjectAccessor<1, DoFHandler<3> > >;
-template class TriaRawIterator   <3,DoFObjectAccessor<2, DoFHandler<3> > >;
-template class TriaIterator      <3,DoFObjectAccessor<2, DoFHandler<3> > >;
-template class TriaActiveIterator<3,DoFObjectAccessor<2, DoFHandler<3> > >;
+template class TriaRawIterator   <DoFAccessor<1, DoFHandler<3> > >;
+template class TriaIterator      <DoFAccessor<1, DoFHandler<3> > >;
+template class TriaActiveIterator<DoFAccessor<1, DoFHandler<3> > >;
+template class TriaRawIterator   <DoFAccessor<2, DoFHandler<3> > >;
+template class TriaIterator      <DoFAccessor<2, DoFHandler<3> > >;
+template class TriaActiveIterator<DoFAccessor<2, DoFHandler<3> > >;
 #endif
 
 
 template class DoFCellAccessor<DoFHandler<deal_II_dimension> >;
 
-template class TriaRawIterator   <deal_II_dimension,DoFCellAccessor<DoFHandler<deal_II_dimension> > >;
-template class TriaIterator      <deal_II_dimension,DoFCellAccessor<DoFHandler<deal_II_dimension> > >;
-template class TriaActiveIterator<deal_II_dimension,DoFCellAccessor<DoFHandler<deal_II_dimension> > >;
+template class TriaRawIterator   <DoFCellAccessor<DoFHandler<deal_II_dimension> > >;
+template class TriaIterator      <DoFCellAccessor<DoFHandler<deal_II_dimension> > >;
+template class TriaActiveIterator<DoFCellAccessor<DoFHandler<deal_II_dimension> > >;
 
 
 // --------------------------------------------------------------------------
@@ -569,19 +309,15 @@ template class TriaActiveIterator<deal_II_dimension,DoFCellAccessor<DoFHandler<d
 
 #if deal_II_dimension == 1
 template class DoFAccessor<1, hp::DoFHandler<1> >;
-template class DoFObjectAccessor<1, hp::DoFHandler<1> >;
 #endif
 
 #if deal_II_dimension == 2
 template class DoFAccessor<1, hp::DoFHandler<2> >;
 template class DoFAccessor<2, hp::DoFHandler<2> >;
 
-template class DoFObjectAccessor<1, hp::DoFHandler<2> >;
-template class DoFObjectAccessor<2, hp::DoFHandler<2> >;
-
-template class TriaRawIterator   <2,DoFObjectAccessor<1, hp::DoFHandler<2> > >;
-template class TriaIterator      <2,DoFObjectAccessor<1, hp::DoFHandler<2> > >;
-template class TriaActiveIterator<2,DoFObjectAccessor<1, hp::DoFHandler<2> > >;
+template class TriaRawIterator   <DoFAccessor<1, hp::DoFHandler<2> > >;
+template class TriaIterator      <DoFAccessor<1, hp::DoFHandler<2> > >;
+template class TriaActiveIterator<DoFAccessor<1, hp::DoFHandler<2> > >;
 #endif
 
 
@@ -590,24 +326,77 @@ template class DoFAccessor<1, hp::DoFHandler<3> >;
 template class DoFAccessor<2, hp::DoFHandler<3> >;
 template class DoFAccessor<3, hp::DoFHandler<3> >;
 
-template class DoFObjectAccessor<1, hp::DoFHandler<3> >;
-template class DoFObjectAccessor<2, hp::DoFHandler<3> >;
-template class DoFObjectAccessor<3, hp::DoFHandler<3> >;
-
-template class TriaRawIterator   <3,DoFObjectAccessor<1, hp::DoFHandler<3> > >;
-template class TriaIterator      <3,DoFObjectAccessor<1, hp::DoFHandler<3> > >;
-template class TriaActiveIterator<3,DoFObjectAccessor<1, hp::DoFHandler<3> > >;
-template class TriaRawIterator   <3,DoFObjectAccessor<2, hp::DoFHandler<3> > >;
-template class TriaIterator      <3,DoFObjectAccessor<2, hp::DoFHandler<3> > >;
-template class TriaActiveIterator<3,DoFObjectAccessor<2, hp::DoFHandler<3> > >;
+template class TriaRawIterator   <DoFAccessor<1, hp::DoFHandler<3> > >;
+template class TriaIterator      <DoFAccessor<1, hp::DoFHandler<3> > >;
+template class TriaActiveIterator<DoFAccessor<1, hp::DoFHandler<3> > >;
+template class TriaRawIterator   <DoFAccessor<2, hp::DoFHandler<3> > >;
+template class TriaIterator      <DoFAccessor<2, hp::DoFHandler<3> > >;
+template class TriaActiveIterator<DoFAccessor<2, hp::DoFHandler<3> > >;
 #endif
 
 
 template class DoFCellAccessor<hp::DoFHandler<deal_II_dimension> >;
 
-template class TriaRawIterator   <deal_II_dimension,DoFCellAccessor<hp::DoFHandler<deal_II_dimension> > >;
-template class TriaIterator      <deal_II_dimension,DoFCellAccessor<hp::DoFHandler<deal_II_dimension> > >;
-template class TriaActiveIterator<deal_II_dimension,DoFCellAccessor<hp::DoFHandler<deal_II_dimension> > >;
+template class TriaRawIterator   <DoFCellAccessor<hp::DoFHandler<deal_II_dimension> > >;
+template class TriaIterator      <DoFCellAccessor<hp::DoFHandler<deal_II_dimension> > >;
+template class TriaActiveIterator<DoFCellAccessor<hp::DoFHandler<deal_II_dimension> > >;
+
+
+
+// // --------------------------------------------------------------------------
+// // explicit instantiations (for DoFHandler)
+
+#if deal_II_dimension == 1
+template class DoFAccessor<1, DoFHandler<1,2> >;
+#endif
+
+#if deal_II_dimension == 2
+template class DoFAccessor<1, DoFHandler<2,3> >;
+template class DoFAccessor<2, DoFHandler<2,3> >;
+
+template class TriaRawIterator   <DoFAccessor<1, DoFHandler<2,3> > >;
+template class TriaIterator      <DoFAccessor<1, DoFHandler<2,3> > >;
+template class TriaActiveIterator<DoFAccessor<1, DoFHandler<2,3> > >;
+#endif
+
+
+#if deal_II_dimension != 3
+template class DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1> >;
+
+template class 
+TriaRawIterator   <DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1> > >;
+template class 
+TriaIterator      <DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1> > >;
+template class 
+TriaActiveIterator<DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1> > >;
+#endif
+
+// --------------------------------------------------------------------------
+// explicit instantiations (for hp::DoFHandler)
+
+#if deal_II_dimension == 1
+template class DoFAccessor<1, hp::DoFHandler<1,2> >;
+#endif
+
+#if deal_II_dimension == 2
+template class DoFAccessor<1, hp::DoFHandler<2,3> >;
+template class DoFAccessor<2, hp::DoFHandler<2,3> >;
+
+template class TriaRawIterator   <DoFAccessor<1, hp::DoFHandler<2,3> > >;
+template class TriaIterator      <DoFAccessor<1, hp::DoFHandler<2,3> > >;
+template class TriaActiveIterator<DoFAccessor<1, hp::DoFHandler<2,3> > >;
+#endif
+
+#if deal_II_dimension != 3
+template class DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> >;
+
+template class 
+TriaRawIterator   <DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> > >;
+template class 
+TriaIterator      <DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> > >;
+template class 
+TriaActiveIterator<DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> > >;
+#endif
 
 
 #include "dof_accessor.inst"
index 7a805ee8fef3f70d4fbcc5acc0594ae5f428cdab..e5904074c04ab24b94e2dcc6a687754c72bac262 100644 (file)
@@ -31,6 +31,29 @@ for (VEC : SERIAL_VECTORS; SCALAR : REAL_SCALARS)
       void
       DoFCellAccessor<DoFHandler<deal_II_dimension> >::set_dof_values_by_interpolation
       (const Vector<SCALAR>&, VEC&) const;
+
+#if deal_II_dimension != 3
+
+    template
+      void
+      DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1> >::get_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+    template
+      void
+      DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1> >::set_dof_values
+      (const Vector<SCALAR>&, VEC&) const;
+
+    template
+      void
+      DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1> >::get_interpolated_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+    template
+      void
+      DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1> >::set_dof_values_by_interpolation
+      (const Vector<SCALAR>&, VEC&) const;
+
+#endif
+
   }
 
 
@@ -53,5 +76,26 @@ for (VEC : SERIAL_VECTORS; SCALAR : REAL_SCALARS)
       void
       DoFCellAccessor<hp::DoFHandler<deal_II_dimension> >::set_dof_values_by_interpolation
       (const Vector<SCALAR>&, VEC&) const;
+
+#if deal_II_dimension != 3
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> >::get_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> >::set_dof_values
+      (const Vector<SCALAR>&, VEC&) const;
+
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> >::get_interpolated_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> >::set_dof_values_by_interpolation
+      (const Vector<SCALAR>&, VEC&) const;
+
+#endif
   }
 
index 5950855b1e3d4bd9b74334cae279d116383d2fab..2da755351a12c45bb433e2b04dbace586cb3ac57 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -34,1571 +34,1976 @@ DEAL_II_NAMESPACE_OPEN
 //auto_ptr or some such thing. alternatively, why not use the DoFFaces object
 //right away?
 
-template <int dim>
-const unsigned int DoFHandler<dim>::dimension;
+template<int dim, int spacedim>
+const unsigned int DoFHandler<dim,spacedim>::dimension;
 
-template <int dim>
-const unsigned int DoFHandler<dim>::invalid_dof_index;
+template<int dim, int spacedim>
+const unsigned int DoFHandler<dim,spacedim>::space_dimension;
 
-template <int dim>
-const unsigned int DoFHandler<dim>::default_fe_index;
+template <int dim, int spacedim>
+const unsigned int DoFHandler<dim,spacedim>::invalid_dof_index;
+
+template <int dim, int spacedim>
+const unsigned int DoFHandler<dim,spacedim>::default_fe_index;
 
 
 // reference the invalid_dof_index variable explicitely to work around
 // a bug in the icc8 compiler
 namespace internal
 {
-  template <int dim>
+  template <int dim, int spacedim>
   const unsigned int * dummy ()
   {
-    return &dealii::DoFHandler<dim>::invalid_dof_index;
+    return &dealii::DoFHandler<dim,spacedim>::invalid_dof_index;
   }
 
-  template const unsigned int * dummy<deal_II_dimension> ();
-}
-
-
-
-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)
-{}
-
-
-template <int dim>
-DoFHandler<dim>::~DoFHandler ()
-{
-                                  // release allocated memory
-  clear ();
-}
-
-
-#if deal_II_dimension == 1
-
-template <>
-DoFHandler<1>::raw_cell_iterator
-DoFHandler<1>::begin_raw (const unsigned int level) const
-{
-  return begin_raw_line (level);
-}
-
-
-template <>
-DoFHandler<1>::cell_iterator
-DoFHandler<1>::begin (const unsigned int level) const
-{
-  return begin_line (level);
-}
-
-
-template <>
-DoFHandler<1>::active_cell_iterator
-DoFHandler<1>::begin_active (const unsigned int level) const
-{
-  return begin_active_line (level);
-}
-
-
-template <>
-DoFHandler<1>::raw_cell_iterator
-DoFHandler<1>::end () const
-{
-  return end_line ();
-}
-
-
-template <>
-DoFHandler<1>::raw_cell_iterator
-DoFHandler<1>::last_raw () const
-{
-  return last_raw_line ();
-}
-
-
-template <>
-DoFHandler<1>::raw_cell_iterator
-DoFHandler<1>::last_raw (const unsigned int level) const
-{
-  return last_raw_line (level);
-}
-
-
-template <>
-DoFHandler<1>::cell_iterator
-DoFHandler<1>::last () const
-{
-  return last_line ();
-}
-
-
-template <>
-DoFHandler<1>::cell_iterator
-DoFHandler<1>::last (const unsigned int level) const
-{
-  return last_line (level);
-}
-
-
-template <>
-DoFHandler<1>::active_cell_iterator
-DoFHandler<1>::last_active () const
-{
-  return last_active_line ();
-}
-
-
-template <>
-DoFHandler<1>::active_cell_iterator
-DoFHandler<1>::last_active (const unsigned int level) const
-{
-  return last_active_line (level);
-}
-
-
-template <>
-DoFHandler<1>::raw_face_iterator
-DoFHandler<1>::begin_raw_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::face_iterator
-DoFHandler<1>::begin_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::active_face_iterator
-DoFHandler<1>::begin_active_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::raw_face_iterator
-DoFHandler<1>::end_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::raw_face_iterator
-DoFHandler<1>::end_raw_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::active_face_iterator
-DoFHandler<1>::end_active_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::raw_face_iterator
-DoFHandler<1>::last_raw_face () const 
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::face_iterator
-DoFHandler<1>::last_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::active_face_iterator
-DoFHandler<1>::last_active_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::raw_quad_iterator
-DoFHandler<1>::begin_raw_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::quad_iterator
-DoFHandler<1>::begin_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::active_quad_iterator
-DoFHandler<1>::begin_active_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::raw_quad_iterator
-DoFHandler<1>::end_quad () const
-{
-  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;
-}
-
-
-template <>
-DoFHandler<1>::raw_quad_iterator
-DoFHandler<1>::last_raw_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::quad_iterator
-DoFHandler<1>::last_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::active_quad_iterator
-DoFHandler<1>::last_active_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::raw_quad_iterator
-DoFHandler<1>::last_raw_quad () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::quad_iterator
-DoFHandler<1>::last_quad () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::active_quad_iterator
-DoFHandler<1>::last_active_quad () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::raw_hex_iterator
-DoFHandler<1>::begin_raw_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::hex_iterator
-DoFHandler<1>::begin_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::active_hex_iterator
-DoFHandler<1>::begin_active_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::raw_hex_iterator
-DoFHandler<1>::end_hex () const
-{
-  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;
-}
-
-
-template <>
-DoFHandler<1>::raw_hex_iterator
-DoFHandler<1>::last_raw_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::raw_hex_iterator
-DoFHandler<1>::last_raw_hex () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::hex_iterator
-DoFHandler<1>::last_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::hex_iterator
-DoFHandler<1>::last_hex () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::active_hex_iterator
-DoFHandler<1>::last_active_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-DoFHandler<1>::active_hex_iterator
-DoFHandler<1>::last_active_hex () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
+  template const unsigned int * dummy<deal_II_dimension,deal_II_dimension> ();
+}
+
+
+
+/**
+ * A class with the same purpose as the similarly named class of the
+ * Triangulation class. See there for more information.
+ */
+template <int x_dim, int x_spacedim>
+struct DoFHandler<x_dim,x_spacedim>::Implementation
+{
+                                    /**
+                                     * Distribute dofs on the given cell,
+                                     * with new dofs starting with index
+                                     * @p next_free_dof. Return the next
+                                     * unused index number. The finite
+                                     * element used is the one given to
+                                     * @p distribute_dofs, which is copied
+                                     * to @p selected_fe.
+                                     *
+                                     * This function is excluded from the
+                                     * @p distribute_dofs function since
+                                     * it can not be implemented dimension
+                                     * independent.
+                                     */
+    template <int spacedim>
+    static
+    unsigned int
+    distribute_dofs_on_cell (const DoFHandler<1,spacedim> &dof_handler,
+                            active_cell_iterator &cell,
+                            unsigned int          next_free_dof)
+      {
 
-#endif
+                                        // distribute dofs of vertices
+       for (unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
+         {
+           cell_iterator neighbor = cell->neighbor(v);
+
+           if (neighbor.state() == IteratorState::valid)
+             {
+                                                // find true neighbor; may be its
+                                                // a child of @p{neighbor}
+               while (neighbor->has_children())
+                 neighbor = neighbor->child(v==0 ? 1 : 0);
+
+                                                // has neighbor already been processed?
+               if (neighbor->user_flag_set())
+                                                  // copy dofs
+                 {
+                   if (v==0) 
+                     for (unsigned int d=0;
+                          d<dof_handler.selected_fe->dofs_per_vertex; ++d)
+                       cell->set_vertex_dof_index (0, d,
+                                                   neighbor->vertex_dof_index (1, d));
+                   else
+                     for (unsigned int d=0;
+                          d<dof_handler.selected_fe->dofs_per_vertex; ++d)
+                       cell->set_vertex_dof_index (1, d,
+                                                   neighbor->vertex_dof_index (0, d));
+
+                                                    // next neighbor
+                   continue;
+                 }
+             }
+            
+                                            // otherwise: create dofs newly
+           for (unsigned int d=0;
+                d<dof_handler.selected_fe->dofs_per_vertex; ++d)
+             cell->set_vertex_dof_index (v, d, next_free_dof++);
+         }
+  
+                                        // dofs of line
+       for (unsigned int d=0;
+            d<dof_handler.selected_fe->dofs_per_line; ++d)
+         cell->set_dof_index (d, next_free_dof++);
+
+                                        // note that this cell has been
+                                        // processed
+       cell->set_user_flag ();
+  
+       return next_free_dof;
+      }
 
 
-#if deal_II_dimension == 2
 
-template <>
-DoFHandler<2>::raw_cell_iterator
-DoFHandler<2>::begin_raw (const unsigned int level) const
-{
-  return begin_raw_quad (level);
-}
+    template <int spacedim>
+    static
+    unsigned int
+    distribute_dofs_on_cell (const DoFHandler<2,spacedim> &dof_handler,
+                            active_cell_iterator &cell,
+                            unsigned int          next_free_dof)
+      {
+       if (dof_handler.selected_fe->dofs_per_vertex > 0)
+                                          // number dofs on vertices
+         for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
+                                            // check whether dofs for this
+                                            // vertex have been distributed
+                                            // (only check the first dof)
+           if (cell->vertex_dof_index(vertex, 0) == invalid_dof_index)
+             for (unsigned int d=0; d<dof_handler.selected_fe->dofs_per_vertex; ++d)
+               cell->set_vertex_dof_index (vertex, d, next_free_dof++);
+    
+                                        // for the four sides
+       if (dof_handler.selected_fe->dofs_per_line > 0)
+         for (unsigned int side=0; side<GeometryInfo<2>::faces_per_cell; ++side)
+           {
+             line_iterator line = cell->line(side);
+       
+                                              // distribute dofs if necessary:
+                                              // check whether line dof is already
+                                              // numbered (check only first dof)
+             if (line->dof_index(0) == invalid_dof_index)
+                                                // if not: distribute dofs
+               for (unsigned int d=0; d<dof_handler.selected_fe->dofs_per_line; ++d)
+                 line->set_dof_index (d, next_free_dof++);         
+           }
 
 
-template <>
-DoFHandler<2>::cell_iterator
-DoFHandler<2>::begin (const unsigned int level) const
-{
-  return begin_quad (level);
-}
+                                        // dofs of quad
+       if (dof_handler.selected_fe->dofs_per_quad > 0)
+         for (unsigned int d=0; d<dof_handler.selected_fe->dofs_per_quad; ++d)
+           cell->set_dof_index (d, next_free_dof++);
 
 
-template <>
-DoFHandler<2>::active_cell_iterator
-DoFHandler<2>::begin_active (const unsigned int level) const
-{
-  return begin_active_quad (level);
-}
+                                        // note that this cell has been processed
+       cell->set_user_flag ();
+  
+       return next_free_dof;
+      }
+    
 
+    template <int spacedim>
+    static
+    unsigned int
+    distribute_dofs_on_cell (const DoFHandler<3,spacedim> &dof_handler,
+                            active_cell_iterator &cell,
+                            unsigned int          next_free_dof)
+      {
+       if (dof_handler.selected_fe->dofs_per_vertex > 0)
+                                          // number dofs on vertices
+         for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
+                                            // check whether dofs for this
+                                            // vertex have been distributed
+                                            // (only check the first dof)
+           if (cell->vertex_dof_index(vertex, 0) == invalid_dof_index)
+             for (unsigned int d=0; d<dof_handler.selected_fe->dofs_per_vertex; ++d)
+               cell->set_vertex_dof_index (vertex, d, next_free_dof++);
+    
+                                        // for the lines
+       if (dof_handler.selected_fe->dofs_per_line > 0)
+         for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
+           {
+             line_iterator line = cell->line(l);
+       
+                                              // distribute dofs if necessary:
+                                              // check whether line dof is already
+                                              // numbered (check only first dof)
+             if (line->dof_index(0) == invalid_dof_index)
+                                                // if not: distribute dofs
+               for (unsigned int d=0; d<dof_handler.selected_fe->dofs_per_line; ++d)
+                 line->set_dof_index (d, next_free_dof++);         
+           }
+
+                                        // for the quads
+       if (dof_handler.selected_fe->dofs_per_quad > 0)
+         for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
+           {
+             quad_iterator quad = cell->quad(q);
+       
+                                              // distribute dofs if necessary:
+                                              // check whether quad dof is already
+                                              // numbered (check only first dof)
+             if (quad->dof_index(0) == invalid_dof_index)
+                                                // if not: distribute dofs
+               for (unsigned int d=0; d<dof_handler.selected_fe->dofs_per_quad; ++d)
+                 quad->set_dof_index (d, next_free_dof++);         
+           }
 
-template <>
-DoFHandler<2>::raw_cell_iterator
-DoFHandler<2>::end () const
-{
-  return end_quad ();
-}
 
+                                        // dofs of hex
+       if (dof_handler.selected_fe->dofs_per_hex > 0)
+         for (unsigned int d=0; d<dof_handler.selected_fe->dofs_per_hex; ++d)
+           cell->set_dof_index (d, next_free_dof++);
 
-template <>
-DoFHandler<2>::raw_cell_iterator
-DoFHandler<2>::last_raw () const
-{
-  return last_raw_quad ();
-}
 
+                                        // note that this cell has been
+                                        // processed
+       cell->set_user_flag ();
+  
+       return next_free_dof;
+      }
+
+
+                                    /**
+                                     * Implementation of the general template
+                                     * of same name.
+                                     */
+    template <int spacedim>
+    static
+    void renumber_dofs (const std::vector<unsigned int> &new_numbers,
+                       DoFHandler<1,spacedim>          &dof_handler)
+      {
+                                        // note that we can not use cell
+                                        // iterators in this function since
+                                        // then we would renumber the dofs on
+                                        // the interface of two cells more
+                                        // than once. Anyway, this way it's
+                                        // not only more correct but also
+                                        // faster; note, however, that dof
+                                        // numbers may be invalid_dof_index,
+                                        // namely when the appropriate
+                                        // vertex/line/etc is unused
+       for (std::vector<unsigned int>::iterator
+              i=dof_handler.vertex_dofs.begin();
+            i!=dof_handler.vertex_dofs.end(); ++i)
+         if (*i != invalid_dof_index)
+           *i = new_numbers[*i];
+         else
+                                            // if index is invalid_dof_index:
+                                            // check if this one really is
+                                            // unused
+           Assert (dof_handler.tria
+                   ->vertex_used((i-dof_handler.vertex_dofs.begin()) /
+                                 dof_handler.selected_fe->dofs_per_vertex)
+                   == false,
+                   ExcInternalError ());
+  
+       for (unsigned int level=0; level<dof_handler.levels.size(); ++level) 
+         for (std::vector<unsigned int>::iterator
+                i=dof_handler.levels[level]->lines.dofs.begin();
+              i!=dof_handler.levels[level]->lines.dofs.end(); ++i)
+           if (*i != invalid_dof_index)
+             *i = new_numbers[*i];
+      }
+    
 
-template <>
-DoFHandler<2>::raw_cell_iterator
-DoFHandler<2>::last_raw (const unsigned int level) const
-{
-  return last_raw_quad (level);
-}
 
+    template <int spacedim>
+    static
+    void renumber_dofs (const std::vector<unsigned int> &new_numbers,
+                       DoFHandler<2,spacedim>          &dof_handler)
+      {
+                                        // note that we can not use cell
+                                        // iterators in this function since
+                                        // then we would renumber the dofs on
+                                        // the interface of two cells more
+                                        // than once. Anyway, this way it's
+                                        // not only more correct but also
+                                        // faster; note, however, that dof
+                                        // numbers may be invalid_dof_index,
+                                        // namely when the appropriate
+                                        // vertex/line/etc is unused
+       for (std::vector<unsigned int>::iterator
+              i=dof_handler.vertex_dofs.begin();
+            i!=dof_handler.vertex_dofs.end(); ++i)
+         if (*i != invalid_dof_index)
+           *i = new_numbers[*i];
+         else
+                                            // if index is invalid_dof_index:
+                                            // check if this one really is
+                                            // unused
+           Assert (dof_handler.tria
+                   ->vertex_used((i-dof_handler.vertex_dofs.begin()) /
+                                 dof_handler.selected_fe->dofs_per_vertex)
+                   == false,
+                   ExcInternalError ());
+  
+       for (std::vector<unsigned int>::iterator
+              i=dof_handler.faces->lines.dofs.begin();
+            i!=dof_handler.faces->lines.dofs.end(); ++i)
+         if (*i != invalid_dof_index)
+           *i = new_numbers[*i];
+
+       for (unsigned int level=0; level<dof_handler.levels.size(); ++level) 
+         {
+           for (std::vector<unsigned int>::iterator
+                  i=dof_handler.levels[level]->quads.dofs.begin();
+                i!=dof_handler.levels[level]->quads.dofs.end(); ++i)
+             if (*i != invalid_dof_index)
+               *i = new_numbers[*i];
+         }
+      }
+
+
+    template <int spacedim>
+    static
+    void renumber_dofs (const std::vector<unsigned int> &new_numbers,
+                       DoFHandler<3,spacedim>          &dof_handler)
+      {
+                                        // note that we can not use cell
+                                        // iterators in this function since
+                                        // then we would renumber the dofs on
+                                        // the interface of two cells more
+                                        // than once. Anyway, this way it's
+                                        // not only more correct but also
+                                        // faster; note, however, that dof
+                                        // numbers may be invalid_dof_index,
+                                        // namely when the appropriate
+                                        // vertex/line/etc is unused
+       for (std::vector<unsigned int>::iterator
+              i=dof_handler.vertex_dofs.begin();
+            i!=dof_handler.vertex_dofs.end(); ++i)
+         if (*i != invalid_dof_index)
+           *i = new_numbers[*i];
+         else
+                                            // if index is invalid_dof_index:
+                                            // check if this one really is
+                                            // unused
+           Assert (dof_handler.tria
+                   ->vertex_used((i-dof_handler.vertex_dofs.begin()) /
+                                 dof_handler.selected_fe->dofs_per_vertex)
+                   == false,
+                   ExcInternalError ());
+  
+       for (std::vector<unsigned int>::iterator
+              i=dof_handler.faces->lines.dofs.begin();
+            i!=dof_handler.faces->lines.dofs.end(); ++i)
+         if (*i != invalid_dof_index)
+           *i = new_numbers[*i];
+       for (std::vector<unsigned int>::iterator
+              i=dof_handler.faces->quads.dofs.begin();
+            i!=dof_handler.faces->quads.dofs.end(); ++i)
+         if (*i != invalid_dof_index)
+           *i = new_numbers[*i];
+  
+       for (unsigned int level=0; level<dof_handler.levels.size(); ++level) 
+         {
+           for (std::vector<unsigned int>::iterator
+                  i=dof_handler.levels[level]->hexes.dofs.begin();
+                i!=dof_handler.levels[level]->hexes.dofs.end(); ++i)
+             if (*i != invalid_dof_index)
+               *i = new_numbers[*i];
+         }
+      }
+
+
+
+                                    /**
+                                     * Implement the function of same name in
+                                     * the mother class.
+                                     */
+    template <int spacedim>
+    static
+    unsigned int
+    max_couplings_between_dofs (const DoFHandler<1,spacedim> &dof_handler)
+      {
+       return std::min(3*dof_handler.selected_fe->dofs_per_vertex +
+                       2*dof_handler.selected_fe->dofs_per_line,
+                       dof_handler.n_dofs());
+      }
 
-template <>
-DoFHandler<2>::cell_iterator
-DoFHandler<2>::last () const
-{
-  return last_quad ();
-}
 
 
-template <>
-DoFHandler<2>::cell_iterator
-DoFHandler<2>::last (const unsigned int level) const
-{
-  return last_quad (level);
-}
+    template <int spacedim>
+    static
+    unsigned int
+    max_couplings_between_dofs (const DoFHandler<2,spacedim> &dof_handler)
+      {
 
+                                        // get these numbers by drawing pictures
+                                        // and counting...
+                                        // example:
+                                        //   |     |     |
+                                        // --x-----x--x--X--
+                                        //   |     |  |  |
+                                        //   |     x--x--x
+                                        //   |     |  |  |
+                                        // --x--x--*--x--x--
+                                        //   |  |  |     |
+                                        //   x--x--x     |
+                                        //   |  |  |     |
+                                        // --X--x--x-----x--
+                                        //   |     |     |
+                                        // x = vertices connected with center vertex *;
+                                        //   = total of 19
+                                        // (the X vertices are connected with * if
+                                        // the vertices adjacent to X are hanging
+                                        // nodes)
+                                        // count lines -> 28 (don't forget to count
+                                        // mother and children separately!)
+       unsigned int max_couplings;
+       switch (dof_handler.tria->max_adjacent_cells())
+         {
+           case 4:
+                 max_couplings=19*dof_handler.selected_fe->dofs_per_vertex +
+                               28*dof_handler.selected_fe->dofs_per_line +
+                               8*dof_handler.selected_fe->dofs_per_quad;
+                 break;
+           case 5:
+                 max_couplings=21*dof_handler.selected_fe->dofs_per_vertex +
+                               31*dof_handler.selected_fe->dofs_per_line +
+                               9*dof_handler.selected_fe->dofs_per_quad;
+                 break;
+           case 6:
+                 max_couplings=28*dof_handler.selected_fe->dofs_per_vertex +
+                               42*dof_handler.selected_fe->dofs_per_line +
+                               12*dof_handler.selected_fe->dofs_per_quad;
+                 break;
+           case 7:
+                 max_couplings=30*dof_handler.selected_fe->dofs_per_vertex +
+                               45*dof_handler.selected_fe->dofs_per_line +
+                               13*dof_handler.selected_fe->dofs_per_quad;
+                 break;
+           case 8:
+                 max_couplings=37*dof_handler.selected_fe->dofs_per_vertex +
+                               56*dof_handler.selected_fe->dofs_per_line +
+                               16*dof_handler.selected_fe->dofs_per_quad;
+                 break;
+           default:
+                 Assert (false, ExcNotImplemented());
+                 max_couplings=0;
+         }
+       return std::min(max_couplings,dof_handler.n_dofs());
+      }
+
+
+    template <int spacedim>
+    static
+    unsigned int
+    max_couplings_between_dofs (const DoFHandler<3,spacedim> &dof_handler)
+      {
+//TODO:[?] Invent significantly better estimates than the ones in this function  
 
-template <>
-DoFHandler<2>::active_cell_iterator
-DoFHandler<2>::last_active () const
-{
-  return last_active_quad ();
-}
+                                        // doing the same thing here is a
+                                        // rather complicated thing, compared
+                                        // to the 2d case, since it is hard
+                                        // to draw pictures with several
+                                        // refined hexahedra :-) so I
+                                        // presently only give a coarse
+                                        // estimate for the case that at most
+                                        // 8 hexes meet at each vertex
+                                        //
+                                        // can anyone give better estimate
+                                        // here?
+       const unsigned int max_adjacent_cells
+         = dof_handler.tria->max_adjacent_cells();
+
+       unsigned int max_couplings;
+       if (max_adjacent_cells <= 8)
+         max_couplings=7*7*7*dof_handler.selected_fe->dofs_per_vertex +
+                       7*6*7*3*dof_handler.selected_fe->dofs_per_line +
+                       9*4*7*3*dof_handler.selected_fe->dofs_per_quad +
+                       27*dof_handler.selected_fe->dofs_per_hex;
+       else
+         {
+           Assert (false, ExcNotImplemented());
+           max_couplings=0;
+         }
+  
+       return std::min(max_couplings,dof_handler.n_dofs());
+      }
+
+
+                                    /**
+                                     * Reserve enough space in the 
+                                     * <tt>levels[]</tt> objects to store the
+                                     * numbers of the degrees of freedom
+                                     * needed for the given element. The
+                                     * given element is that one which
+                                     * was selected when calling
+                                     * @p distribute_dofs the last time.
+                                     */
+    template <int spacedim>
+    static
+    void reserve_space (DoFHandler<1,spacedim> &dof_handler)
+      {  
+       dof_handler.vertex_dofs
+         .resize(dof_handler.tria->n_vertices() *
+                 dof_handler.selected_fe->dofs_per_vertex,
+                 invalid_dof_index);
+    
+       for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i) 
+         {
+           dof_handler.levels
+             .push_back (new internal::DoFHandler::DoFLevel<1>);
+
+           dof_handler.levels.back()->lines.dofs
+             .resize (dof_handler.tria->n_raw_lines(i) *
+                      dof_handler.selected_fe->dofs_per_line,
+                      invalid_dof_index);
+
+           dof_handler.levels.back()->cell_dof_indices_cache
+             .resize (dof_handler.tria->n_raw_lines(i) *
+                      dof_handler.selected_fe->dofs_per_cell,
+                      invalid_dof_index);
+         }
+      }
 
+    
+    template <int spacedim>
+    static
+    void reserve_space (DoFHandler<2,spacedim> &dof_handler)
+      {
+       dof_handler.vertex_dofs
+         .resize(dof_handler.tria->n_vertices() *
+                 dof_handler.selected_fe->dofs_per_vertex,
+                 invalid_dof_index);
+
+       for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i) 
+         {
+           dof_handler.levels.push_back (new internal::DoFHandler::DoFLevel<2>);
+
+           dof_handler.levels.back()->quads.dofs
+             .resize (dof_handler.tria->n_raw_quads(i) *
+                      dof_handler.selected_fe->dofs_per_quad,
+                      invalid_dof_index);
+
+           dof_handler.levels.back()->cell_dof_indices_cache
+             .resize (dof_handler.tria->n_raw_quads(i) *
+                      dof_handler.selected_fe->dofs_per_cell,
+                      invalid_dof_index);
+         }
+
+       dof_handler.faces = new internal::DoFHandler::DoFFaces<2>;
+       dof_handler.faces->lines.dofs
+         .resize (dof_handler.tria->n_raw_lines() *
+                  dof_handler.selected_fe->dofs_per_line,
+                  invalid_dof_index);
+      }
 
-template <>
-DoFHandler<2>::active_cell_iterator
-DoFHandler<2>::last_active (const unsigned int level) const
-{
-  return last_active_quad (level);
-}
+    
+    template <int spacedim>
+    static
+    void reserve_space (DoFHandler<3,spacedim> &dof_handler)
+      {
+       dof_handler.vertex_dofs
+         .resize(dof_handler.tria->n_vertices() *
+                 dof_handler.selected_fe->dofs_per_vertex,
+                 invalid_dof_index);
+
+       for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i) 
+         {
+           dof_handler.levels.push_back (new internal::DoFHandler::DoFLevel<3>);
+
+           dof_handler.levels.back()->hexes.dofs
+             .resize (dof_handler.tria->n_raw_hexs(i) *
+                      dof_handler.selected_fe->dofs_per_hex,
+                      invalid_dof_index);
+
+           dof_handler.levels.back()->cell_dof_indices_cache
+             .resize (dof_handler.tria->n_raw_hexs(i) *
+                      dof_handler.selected_fe->dofs_per_cell,
+                      invalid_dof_index);
+         }
+       dof_handler.faces = new internal::DoFHandler::DoFFaces<3>;
+  
+       dof_handler.faces->lines.dofs
+         .resize (dof_handler.tria->n_raw_lines() *
+                  dof_handler.selected_fe->dofs_per_line,
+                  invalid_dof_index);
+       dof_handler.faces->quads.dofs
+         .resize (dof_handler.tria->n_raw_quads() *
+                  dof_handler.selected_fe->dofs_per_quad,
+                  invalid_dof_index);
+      }
+
+                                    /**
+                                     * Implementations of the
+                                     * get_dof_index/set_dof_index functions.
+                                     */
+    template <int spacedim>
+    static
+    unsigned int
+    get_dof_index (const DoFHandler<1,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<1>)
+      {
+       return dof_handler.levels[obj_level]->lines.
+         get_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index);
+      }
+
+
+    template <int spacedim>
+    static
+    void
+    set_dof_index (const DoFHandler<1,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<1>,
+                  const unsigned int              global_index)
+      {
+       dof_handler.levels[obj_level]->lines.
+         set_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index,
+                        global_index);
+      }
+    
 
+    template <int spacedim>
+    static
+    unsigned int
+    get_dof_index (const DoFHandler<2,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<1>)
+      {
+                                        // faces have no levels
+       Assert (obj_level == 0, ExcInternalError());
+       return dof_handler.faces->lines.
+         get_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index);
+      }
+
+
+    template <int spacedim>
+    static
+    void
+    set_dof_index (const DoFHandler<2,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<1>,
+                  const unsigned int              global_index)
+      {
+                                        // faces have no levels
+       Assert (obj_level == 0, ExcInternalError());
+       dof_handler.faces->lines.
+         set_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index,
+                        global_index);
+      }
+    
+    
+    template <int spacedim>
+    static
+    unsigned int
+    get_dof_index (const DoFHandler<2,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<2>)
+      {
+       return dof_handler.levels[obj_level]->quads.
+         get_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index);
+      }
+
+
+    template <int spacedim>
+    static
+    void
+    set_dof_index (const DoFHandler<2,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<2>,
+                  const unsigned int              global_index)
+      {
+       dof_handler.levels[obj_level]->quads.
+         set_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index,
+                        global_index);
+      }
+
+
+    template <int spacedim>
+    static
+    unsigned int
+    get_dof_index (const DoFHandler<3,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<1>)
+      {
+                                        // faces have no levels
+       Assert (obj_level == 0, ExcInternalError());
+       return dof_handler.faces->lines.
+         get_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index);
+      }
+
+
+    template <int spacedim>
+    static
+    void
+    set_dof_index (const DoFHandler<3,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<1>,
+                  const unsigned int              global_index)
+      {
+                                        // faces have no levels
+       Assert (obj_level == 0, ExcInternalError());
+       dof_handler.faces->lines.
+         set_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index,
+                        global_index);
+      }
+
+
+
+    template <int spacedim>
+    static
+    unsigned int
+    get_dof_index (const DoFHandler<3,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<2>)
+      {
+                                        // faces have no levels
+       Assert (obj_level == 0, ExcInternalError());
+       return dof_handler.faces->quads.
+         get_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index);
+      }
+
+
+    template <int spacedim>
+    static
+    void
+    set_dof_index (const DoFHandler<3,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<2>,
+                  const unsigned int              global_index)
+      {
+                                        // faces have no levels
+       Assert (obj_level == 0, ExcInternalError());
+       dof_handler.faces->quads.
+         set_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index,
+                        global_index);
+      }
+
+
+
+    template <int spacedim>
+    static
+    unsigned int
+    get_dof_index (const DoFHandler<3,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<3>)
+      {
+       return dof_handler.levels[obj_level]->hexes.
+         get_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index);  
+      }
+
+
+    template <int spacedim>
+    static
+    void
+    set_dof_index (const DoFHandler<3,spacedim>   &dof_handler,
+                  const unsigned int              obj_level,
+                  const unsigned int              obj_index,
+                  const unsigned int              fe_index,
+                  const unsigned int              local_index,
+                  internal::int2type<3>,
+                  const unsigned int              global_index)
+      {
+       dof_handler.levels[obj_level]->hexes.
+         set_dof_index (dof_handler,
+                        obj_index,
+                        fe_index,
+                        local_index,
+                        global_index);
+      }
+};
 
-template <>
-DoFHandler<2>::raw_face_iterator
-DoFHandler<2>::begin_raw_face () const
-{
-  return begin_raw_line ();
-}
 
 
-template <>
-DoFHandler<2>::face_iterator
-DoFHandler<2>::begin_face () const
-{
-  return begin_line ();
-}
+template<int dim, int spacedim>
+DoFHandler<dim,spacedim>::DoFHandler (const Triangulation<dim,spacedim> &tria)
+               :
+               tria(&tria, typeid(*this).name()),
+               selected_fe(0, typeid(*this).name()),
+               faces(NULL),
+               used_dofs (0)
+{}
 
 
-template <>
-DoFHandler<2>::active_face_iterator
-DoFHandler<2>::begin_active_face () const
+template <int dim, int spacedim>
+DoFHandler<dim,spacedim>::~DoFHandler ()
 {
-  return begin_active_line ();
+                                  // release allocated memory
+  clear ();
 }
 
 
-template <>
-DoFHandler<2>::raw_face_iterator
-DoFHandler<2>::end_face () const
-{
-  return end_line ();
-}
+/*------------------------ Cell iterator functions ------------------------*/
 
 
-template <>
-DoFHandler<2>::raw_face_iterator
-DoFHandler<2>::end_raw_face () const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_cell_iterator
+DoFHandler<dim,spacedim>::begin_raw (const unsigned int level) const
 {
-  return end_line ();
+  switch (dim)
+    {
+      case 1:
+           return begin_raw_line (level);
+      case 2:
+           return begin_raw_quad (level);
+      case 3:
+           return begin_raw_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_cell_iterator();
+    }
 }
 
 
-template <>
-DoFHandler<2>::active_face_iterator
-DoFHandler<2>::end_active_face () const
-{
-  return end_line ();
-}
 
-
-template <>
-DoFHandler<2>::raw_face_iterator
-DoFHandler<2>::last_raw_face () const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::cell_iterator
+DoFHandler<dim,spacedim>::begin (const unsigned int level) const
 {
-  return last_raw_line ();
+  switch (dim)
+    {
+      case 1:
+           return begin_line (level);
+      case 2:
+           return begin_quad (level);
+      case 3:
+           return begin_hex (level);
+      default:
+           Assert (false, ExcImpossibleInDim(dim));
+           return cell_iterator();
+    }
 }
 
 
-template <>
-DoFHandler<2>::face_iterator
-DoFHandler<2>::last_face () const
-{
-  return last_line ();
-}
-
 
-template <>
-DoFHandler<2>::active_face_iterator
-DoFHandler<2>::last_active_face () const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::active_cell_iterator
+DoFHandler<dim,spacedim>::begin_active (const unsigned int level) const
 {
-  return last_active_line ();
+  switch (dim)
+    {
+      case 1:
+           return begin_active_line (level);
+      case 2:
+           return begin_active_quad (level);
+      case 3:
+           return begin_active_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_cell_iterator();
+    }
 }
 
 
-template <>
-DoFHandler<2>::raw_hex_iterator
-DoFHandler<2>::begin_raw_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
 
-
-template <>
-DoFHandler<2>::hex_iterator
-DoFHandler<2>::begin_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_cell_iterator
+DoFHandler<dim,spacedim>::last_raw () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_raw_line ();
+      case 2:
+           return last_raw_quad ();
+      case 3:
+           return last_raw_hex ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_cell_iterator();
+    }
 }
 
 
-template <>
-DoFHandler<2>::active_hex_iterator
-DoFHandler<2>::begin_active_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
-
 
-template <>
-DoFHandler<2>::raw_hex_iterator
-DoFHandler<2>::end_hex () const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_cell_iterator
+DoFHandler<dim,spacedim>::last_raw (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_raw_line (level);
+      case 2:
+           return last_raw_quad (level);
+      case 3:
+           return last_raw_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_cell_iterator();
+    }
 }
 
 
-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
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::cell_iterator
+DoFHandler<dim,spacedim>::last () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_line ();
+      case 2:
+           return last_quad ();
+      case 3:
+           return last_hex ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return cell_iterator();
+    }
 }
 
 
-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
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::cell_iterator
+DoFHandler<dim,spacedim>::last (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_line (level);
+      case 2:
+           return last_quad (level);
+      case 3:
+           return last_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return cell_iterator();
+    }
 }
 
 
-template <>
-DoFHandler<2>::raw_hex_iterator
-DoFHandler<2>::last_raw_hex () const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
-
 
-template <>
-DoFHandler<2>::hex_iterator
-DoFHandler<2>::last_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::active_cell_iterator
+DoFHandler<dim,spacedim>::last_active () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_active_line ();
+      case 2:
+           return last_active_quad ();
+      case 3:
+           return last_active_hex ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_cell_iterator();
+    }
 }
 
 
-template <>
-DoFHandler<2>::hex_iterator
-DoFHandler<2>::last_hex () const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
-
 
-template <>
-DoFHandler<2>::active_hex_iterator
-DoFHandler<2>::last_active_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::active_cell_iterator
+DoFHandler<dim,spacedim>::last_active (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_active_line (level);
+      case 2:
+           return last_active_quad (level);
+      case 3:
+           return last_active_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_cell_iterator();
+    }
 }
 
 
-template <>
-DoFHandler<2>::active_hex_iterator
-DoFHandler<2>::last_active_hex () const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_cell_iterator
+DoFHandler<dim,spacedim>::end () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
-
-
-#endif
+  switch (dim)
+    {
+      case 1:
+           return end_line();
+      case 2:
+           return end_quad();
+      case 3:
+           return end_hex();
+      default:
+           Assert (false, ExcImpossibleInDim(dim));
+           return raw_cell_iterator();
+    }
+}
 
 
-#if deal_II_dimension == 3
 
-template <>
-DoFHandler<3>::raw_cell_iterator
-DoFHandler<3>::begin_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_cell_iterator
+DoFHandler<dim, spacedim>::end_raw (const unsigned int level) const
 {
-  return begin_raw_hex (level);
+  return (level == tria->n_levels()-1 ?
+         end() :
+         begin_raw (level+1));
 }
 
 
-template <>
-DoFHandler<3>::cell_iterator
-DoFHandler<3>::begin (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::cell_iterator
+DoFHandler<dim, spacedim>::end (const unsigned int level) const
 {
-  return begin_hex (level);
+  return (level == tria->n_levels()-1 ?
+         cell_iterator(end()) :
+         begin (level+1));
 }
 
 
-template <>
-DoFHandler<3>::active_cell_iterator
-DoFHandler<3>::begin_active (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_cell_iterator
+DoFHandler<dim, spacedim>::end_active (const unsigned int level) const
 {
-  return begin_active_hex (level);
+  return (level == tria->n_levels()-1 ?
+         active_cell_iterator(end()) :
+         begin_active (level+1));
 }
 
 
-template <>
-DoFHandler<3>::raw_cell_iterator
-DoFHandler<3>::end () const
-{
-  return end_hex ();
-}
+/*------------------------ Face iterator functions ------------------------*/
 
 
-template <>
-DoFHandler<3>::raw_cell_iterator
-DoFHandler<3>::last_raw () const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_face_iterator
+DoFHandler<dim,spacedim>::begin_raw_face () const
 {
-  return last_raw_hex ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return begin_raw_line ();
+      case 3:
+           return begin_raw_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-DoFHandler<3>::raw_cell_iterator
-DoFHandler<3>::last_raw (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::face_iterator
+DoFHandler<dim,spacedim>::begin_face () const
 {
-  return last_raw_hex (level);
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return begin_line ();
+      case 3:
+           return begin_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return face_iterator ();
+    }
 }
 
 
-template <>
-DoFHandler<3>::cell_iterator
-DoFHandler<3>::last () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::active_face_iterator
+DoFHandler<dim,spacedim>::begin_active_face () const
 {
-  return last_hex ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return begin_active_line ();
+      case 3:
+           return begin_active_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_face_iterator ();
+    }
 }
 
 
-template <>
-DoFHandler<3>::cell_iterator
-DoFHandler<3>::last (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_face_iterator
+DoFHandler<dim, spacedim>::end_raw_face () const
 {
-  return last_hex (level);
+  return end_face();
 }
 
 
-template <>
-DoFHandler<3>::active_cell_iterator
-DoFHandler<3>::last_active () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_face_iterator
+DoFHandler<dim,spacedim>::end_face () const
 {
-  return last_active_hex ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return end_line ();
+      case 3:
+           return end_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-DoFHandler<3>::active_cell_iterator
-DoFHandler<3>::last_active (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_face_iterator
+DoFHandler<dim, spacedim>::end_active_face () const
 {
-  return last_active_hex (level);
+  return active_face_iterator(end_face());
 }
 
 
-template <>
-DoFHandler<3>::raw_face_iterator
-DoFHandler<3>::begin_raw_face () const
-{
-  return begin_raw_quad ();
-}
 
 
-template <>
-DoFHandler<3>::face_iterator
-DoFHandler<3>::begin_face () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_face_iterator
+DoFHandler<dim,spacedim>::last_raw_face () const
 {
-  return begin_quad ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return last_raw_line ();
+      case 3:
+           return last_raw_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-DoFHandler<3>::active_face_iterator
-DoFHandler<3>::begin_active_face () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::face_iterator
+DoFHandler<dim,spacedim>::last_face () const
 {
-  return begin_active_quad ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return last_line ();
+      case 3:
+           return last_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-DoFHandler<3>::raw_face_iterator
-DoFHandler<3>::end_face () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::active_face_iterator
+DoFHandler<dim,spacedim>::last_active_face () const
 {
-  return end_quad ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return last_active_line ();
+      case 3:
+           return last_active_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-DoFHandler<3>::raw_face_iterator
-DoFHandler<3>::end_raw_face () const
-{
-  return end_quad ();
-}
+/*------------------------ Line iterator functions ------------------------*/
 
 
-template <>
-DoFHandler<3>::active_face_iterator
-DoFHandler<3>::end_active_face () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_line_iterator
+DoFHandler<dim, spacedim>::begin_raw_line (const unsigned int level) const
 {
-  return end_quad ();
-}
+  switch (dim)
+    {
+      case 1:
+           Assert (level<tria->n_levels(), ExcInvalidLevel(level));
 
+           if (tria->n_raw_lines(level) == 0)
+             return end_line ();
 
-template <>
-DoFHandler<3>::raw_face_iterator
-DoFHandler<3>::last_raw_face () const
-{
-  return last_raw_quad ();
+           return raw_line_iterator (tria,
+                                     level,
+                                     0,
+                                     this);
+
+      default:
+           Assert (level == 0, ExcFacesHaveNoLevel());
+           return raw_line_iterator (tria,
+                                     0,
+                                     0,
+                                     this);
+    }
 }
 
 
-template <>
-DoFHandler<3>::face_iterator
-DoFHandler<3>::last_face () const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::line_iterator
+DoFHandler<dim, spacedim>::begin_line (const unsigned int level) const
 {
-  return last_quad ();
+                                  // level is checked in begin_raw
+  raw_line_iterator ri = begin_raw_line (level);
+  if (ri.state() != IteratorState::valid)
+    return ri;
+  while (ri->used() == false)
+    if ((++ri).state() != IteratorState::valid)
+      return ri;
+  return ri;
 }
 
 
-template <>
-DoFHandler<3>::active_face_iterator
-DoFHandler<3>::last_active_face () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_line_iterator
+DoFHandler<dim, spacedim>::begin_active_line (const unsigned int level) const
 {
-  return last_active_quad ();
+                                  // level is checked in begin_raw
+  line_iterator i = begin_line (level);
+  if (i.state() != IteratorState::valid)
+    return i;
+  while (i->has_children())
+    if ((++i).state() != IteratorState::valid)
+      return i;
+  return i;
 }
 
 
-#endif
-
 
-template <int dim>
-typename DoFHandler<dim>::raw_line_iterator
-DoFHandler<dim>::begin_raw_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_line_iterator
+DoFHandler<dim, spacedim>::end_line () const
 {
-  Assert (dim==1 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());
   return raw_line_iterator (tria,
-                           dim==1 ? tria->begin_raw_line(level)->level() : 0,
-                           tria->begin_raw_line(level)->index(),
+                           -1,
+                           -1,
                            this);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::line_iterator
-DoFHandler<dim>::begin_line (const unsigned int level) const
-{
-  Assert (dim==1 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());
-  return line_iterator (tria,
-                       dim==1 ? tria->begin_line(level)->level() : 0,
-                       tria->begin_line(level)->index(),
-                       this);
-}
-
 
-template <int dim>
-typename DoFHandler<dim>::active_line_iterator
-DoFHandler<dim>::begin_active_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_line_iterator
+DoFHandler<dim, spacedim>::last_raw_line (const unsigned int level) const
 {
-  Assert (dim==1 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());
-  return active_line_iterator (tria,
-                              dim==1 ? tria->begin_active_line(level)->level() : 0,
-                              tria->begin_active_line(level)->index(),
-                              this);
-}
+  switch (dim)
+    {
+      case 1:
+           Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+           Assert (tria->n_raw_lines(level) != 0,
+                   ExcEmptyLevel (level));
 
+           return raw_line_iterator (tria,
+                                     level,
+                                     tria->n_raw_lines(level)-1,
+                                     this);
 
-template <int dim>
-typename DoFHandler<dim>::raw_quad_iterator
-DoFHandler<dim>::begin_raw_quad (const unsigned int level) const
-{
-  Assert (dim==2 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());  
-  return raw_quad_iterator (tria,
-                           dim==2 ? tria->begin_raw_quad(level)->level() : 0,
-                           tria->begin_raw_quad(level)->index(),
-                           this);
+      default:
+           Assert (level == 0, ExcFacesHaveNoLevel());
+           return raw_line_iterator (tria,
+                                     0,
+                                     tria->n_raw_lines()-1,
+                                     this);
+    }
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::quad_iterator
-DoFHandler<dim>::begin_quad (const unsigned int level) const
-{
-  Assert (dim==2 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());  
-  return quad_iterator (tria,
-                       dim==2 ? tria->begin_quad(level)->level() : 0,
-                       tria->begin_quad(level)->index(),
-                       this);
-}
 
-
-template <int dim>
-typename DoFHandler<dim>::active_quad_iterator
-DoFHandler<dim>::begin_active_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_line_iterator
+DoFHandler<dim, spacedim>::last_raw_line () const
 {
-  Assert (dim==2 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());  
-  return active_quad_iterator (tria,
-                              dim==2 ? tria->begin_active_quad(level)->level() : 0,
-                              tria->begin_active_quad(level)->index(),
-                              this);
+  if (dim == 1)
+    return last_raw_line (tria->n_levels()-1);
+  else
+    return last_raw_line (0);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_hex_iterator
-DoFHandler<dim>::begin_raw_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::line_iterator
+DoFHandler<dim, spacedim>::last_line (const unsigned int level) const
 {
-  return raw_hex_iterator (tria,
-                          tria->begin_raw_hex(level)->level(),
-                          tria->begin_raw_hex(level)->index(),
-                          this);
+                                  // level is checked in last_raw
+  raw_line_iterator ri = last_raw_line(level);
+  if (ri->used()==true)
+    return ri;
+  while ((--ri).state() == IteratorState::valid)
+    if (ri->used()==true)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::hex_iterator
-DoFHandler<dim>::begin_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::line_iterator
+DoFHandler<dim, spacedim>::last_line () const
 {
-  return hex_iterator (tria,
-                      tria->begin_hex(level)->level(),
-                      tria->begin_hex(level)->index(),
-                      this);
+  if (dim == 1)
+    return last_line (tria->n_levels()-1);
+  else
+    return last_line (0);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::active_hex_iterator
-DoFHandler<dim>::begin_active_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_line_iterator
+DoFHandler<dim, spacedim>::last_active_line (const unsigned int level) const
 {
-  return active_hex_iterator (tria,
-                             tria->begin_active_hex(level)->level(),
-                             tria->begin_active_hex(level)->index(),
-                             this);
+                                  // level is checked in last_raw
+  line_iterator i = last_line(level);
+  if (i->has_children()==false)
+    return i;
+  while ((--i).state() == IteratorState::valid)
+    if (i->has_children()==false)
+      return i;
+  return i;
 }
 
-                                // 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
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_line_iterator
+DoFHandler<dim, spacedim>::last_active_line () const
 {
-  return raw_line_iterator (tria, -1, -1, this);
+  if (dim == 1)
+    return last_active_line (tria->n_levels()-1);
+  else
+    return last_active_line (0);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_quad_iterator
-DoFHandler<dim>::end_quad () const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_line_iterator
+DoFHandler<dim, spacedim>::end_raw_line (const unsigned int level) const
 {
-  return raw_quad_iterator (tria, -1, -1, this);
+  Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 1)
+    return (level == tria->n_levels()-1 ?
+           end_line() :
+           begin_raw_line (level+1));
+  else
+    return end_line();
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_hex_iterator
-DoFHandler<dim>::end_hex () const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::line_iterator
+DoFHandler<dim, spacedim>::end_line (const unsigned int level) const
 {
-  return raw_hex_iterator (tria, -1, -1, this);
+  Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 1)
+    return (level == tria->n_levels()-1 ?
+           line_iterator(end_line()) :
+           begin_line (level+1));
+  else
+    return line_iterator(end_line());
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_cell_iterator
-DoFHandler<dim>::end_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_line_iterator
+DoFHandler<dim, spacedim>::end_active_line (const unsigned int level) const
 {
-  return (level == levels.size()-1 ?
-         end() :
-         begin_raw (level+1));
+  Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 1)
+    return (level == tria->n_levels()-1 ?
+           active_line_iterator(end_line()) :
+           begin_active_line (level+1));
+  else
+    return active_line_iterator(end_line());
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::cell_iterator
-DoFHandler<dim>::end (const unsigned int level) const
-{
-  return (level == levels.size()-1 ?
-         cell_iterator(end()) :
-         begin (level+1));
-}
 
+/*------------------------ Quad iterator functions ------------------------*/
 
-template <int dim>
-typename DoFHandler<dim>::active_cell_iterator
-DoFHandler<dim>::end_active (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_quad_iterator
+DoFHandler<dim,spacedim>::begin_raw_quad (const unsigned int level) const
 {
-  return (level == levels.size()-1 ?
-         active_cell_iterator(end()) :
-         begin_active (level+1));
-}
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_hex_iterator();
+      case 2:
+      {
+       Assert (level<tria->n_levels(), ExcInvalidLevel(level));
 
+       if (tria->n_raw_quads(level) == 0)
+         return end_quad();
+  
+       return raw_quad_iterator (tria,
+                                 level,
+                                 0,
+                                 this);
+      }
 
-template <int dim>
-typename DoFHandler<dim>::raw_line_iterator
-DoFHandler<dim>::end_raw_line (const unsigned int level) const
-{
-  return raw_line_iterator(tria,
-                          tria->end_raw_line(level)->level(),
-                          tria->end_raw_line(level)->index(),
-                          this);
+      case 3:
+      {
+       Assert (level == 0, ExcFacesHaveNoLevel());
+
+       return raw_quad_iterator (tria,
+                                 0,
+                                 0,
+                                 this);
+      }
+      
+      
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_hex_iterator();      
+    }
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::line_iterator
-DoFHandler<dim>::end_line (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::quad_iterator
+DoFHandler<dim,spacedim>::begin_quad (const unsigned int level) const
 {
-  return line_iterator(tria,
-                      tria->end_line(level)->level(),
-                      tria->end_line(level)->index(),
-                      this);
+                                  // level is checked in begin_raw
+  raw_quad_iterator ri = begin_raw_quad (level);
+  if (ri.state() != IteratorState::valid)
+    return ri;
+  while (ri->used() == false)
+    if ((++ri).state() != IteratorState::valid)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::active_line_iterator
-DoFHandler<dim>::end_active_line (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::active_quad_iterator
+DoFHandler<dim,spacedim>::begin_active_quad (const unsigned int level) const
 {
-  return active_line_iterator(tria,
-                             tria->end_active_line(level)->level(),
-                             tria->end_active_line(level)->index(),
-                             this);
+                                  // level is checked in begin_raw
+  quad_iterator i = begin_quad (level);
+  if (i.state() != IteratorState::valid)
+    return i;
+  while (i->has_children())
+    if ((++i).state() != IteratorState::valid)
+      return i;
+  return i;
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_quad_iterator
-DoFHandler<dim>::end_raw_quad (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_quad_iterator
+DoFHandler<dim, spacedim>::end_raw_quad (const unsigned int level) const
 {
-  return raw_quad_iterator(tria,
-                          tria->end_raw_quad(level)->level(),
-                          tria->end_raw_quad(level)->index(),
-                          this);
+  Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 2)
+    return (level == tria->n_levels()-1 ?
+           end_quad() :
+           begin_raw_quad (level+1));
+  else
+    return end_quad();
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::quad_iterator
-DoFHandler<dim>::end_quad (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::quad_iterator
+DoFHandler<dim, spacedim>::end_quad (const unsigned int level) const
 {
-  return quad_iterator(tria,
-                      tria->end_quad(level)->level(),
-                      tria->end_quad(level)->index(),
-                      this);
+  Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 2)
+    return (level == tria->n_levels()-1 ?
+           quad_iterator(end_quad()) :
+           begin_quad (level+1));
+  else
+    return quad_iterator(end_quad());  
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::active_quad_iterator
-DoFHandler<dim>::end_active_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_quad_iterator
+DoFHandler<dim, spacedim>::end_active_quad (const unsigned int level) const
 {
-  return active_quad_iterator(tria,
-                             tria->end_active_quad(level)->level(),
-                             tria->end_active_quad(level)->index(),
-                             this);
+  Assert(dim == 2 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 2)
+    return (level == tria->n_levels()-1 ?
+           active_quad_iterator(end_quad()) :
+           begin_active_quad (level+1));
+  else
+    return active_quad_iterator(end_quad());
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_hex_iterator
-DoFHandler<dim>::end_raw_hex (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_quad_iterator
+DoFHandler<dim,spacedim>::end_quad () const
 {
-  return raw_hex_iterator(tria,
-                         tria->end_raw_hex(level)->level(),
-                         tria->end_raw_hex(level)->index(),
-                         this);
+  return raw_quad_iterator (tria,
+                           -1,
+                           -1,
+                           this);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::hex_iterator
-DoFHandler<dim>::end_hex (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_quad_iterator
+DoFHandler<dim,spacedim>::last_raw_quad (const unsigned int level) const
 {
-  return hex_iterator(tria,
-                     tria->end_hex(level)->level(),
-                     tria->end_hex(level)->index(),
-                     this);
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_quad_iterator();
+      case 2:
+           Assert (level<tria->n_levels(),
+                   ExcInvalidLevel(level));
+           Assert (tria->n_raw_quads(level) != 0,
+                   ExcEmptyLevel (level));
+           return raw_quad_iterator (tria,
+                                     level,
+                                     tria->n_raw_quads(level)-1,
+                                     this);
+      case 3:
+           Assert (level == 0, ExcFacesHaveNoLevel());
+           return raw_quad_iterator (tria,
+                                     0,
+                                     tria->n_raw_quads()-1,
+                                     this);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_quad_iterator();
+    }      
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::active_hex_iterator
-DoFHandler<dim>::end_active_hex (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_quad_iterator
+DoFHandler<dim,spacedim>::last_raw_quad () const
 {
-  return active_hex_iterator(tria,
-                            tria->end_active_hex(level)->level(),
-                            tria->end_active_hex(level)->index(),
-                            this);
+  if (dim == 2)
+    return last_raw_quad (tria->n_levels()-1);
+  else
+    return last_raw_quad (0);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_line_iterator
-DoFHandler<dim>::last_raw_line (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::quad_iterator
+DoFHandler<dim,spacedim>::last_quad (const unsigned int level) const
 {
-  return raw_line_iterator (tria,
-                           tria->last_raw_line(level)->level(),
-                           tria->last_raw_line(level)->index(),
-                           this);
+                                  // level is checked in last_raw
+  raw_quad_iterator ri = last_raw_quad(level);
+  if (ri->used()==true)
+    return ri;
+  while ((--ri).state() == IteratorState::valid)
+    if (ri->used()==true)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::line_iterator
-DoFHandler<dim>::last_line (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::quad_iterator
+DoFHandler<dim,spacedim>::last_quad () const
 {
-  return line_iterator (tria,
-                       tria->last_line(level)->level(),
-                       tria->last_line(level)->index(),
-                       this);
+  if (dim == 2)
+    return last_quad (tria->n_levels()-1);
+  else
+    return last_quad (0);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::active_line_iterator
-DoFHandler<dim>::last_active_line (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::active_quad_iterator
+DoFHandler<dim,spacedim>::last_active_quad (const unsigned int level) const
 {
-  return active_line_iterator (tria,
-                              tria->last_active_line(level)->level(),
-                              tria->last_active_line(level)->index(),
-                              this);
+                                  // level is checked in last_raw
+  quad_iterator i = last_quad(level);
+  if (i->has_children()==false)
+    return i;
+  while ((--i).state() == IteratorState::valid)
+    if (i->has_children()==false)
+      return i;
+  return i;
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_quad_iterator
-DoFHandler<dim>::last_raw_quad (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::active_quad_iterator
+DoFHandler<dim,spacedim>::last_active_quad () const
 {
-  return raw_quad_iterator (tria,
-                           tria->last_raw_quad(level)->level(),
-                           tria->last_raw_quad(level)->index(),
-                           this);
+  if (dim == 2)
+    return last_active_quad (tria->n_levels()-1);
+  else
+    return last_active_quad (0);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::quad_iterator
-DoFHandler<dim>::last_quad (const unsigned int level) const
-{
-  return quad_iterator (tria,
-                       tria->last_quad(level)->level(),
-                       tria->last_quad(level)->index(),
-                       this);
-}
+/*------------------------ Hex iterator functions ------------------------*/
 
 
-template <int dim>
-typename DoFHandler<dim>::active_quad_iterator
-DoFHandler<dim>::last_active_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::raw_hex_iterator
+DoFHandler<dim,spacedim>::begin_raw_hex (const unsigned int level) const
 {
-  return active_quad_iterator (tria,
-                              tria->last_active_quad(level)->level(),
-                              tria->last_active_quad(level)->index(),
-                              this);
+  switch (dim)
+    {
+      case 1:
+      case 2:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_hex_iterator();
+      case 3:
+      {
+       Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+
+       if (tria->n_raw_hexs(level) == 0)
+         return end_hex();
+  
+       return raw_hex_iterator (tria,
+                                level,
+                                0,
+                                this);
+      }
+      
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_hex_iterator();      
+    }
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_hex_iterator
-DoFHandler<dim>::last_raw_hex (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim,spacedim>::hex_iterator
+DoFHandler<dim,spacedim>::begin_hex (const unsigned int level) const
 {
-  return raw_hex_iterator (tria,
-                          tria->last_raw_hex(level)->level(),
-                          tria->last_raw_hex(level)->index(),
-                          this);
+                                  // level is checked in begin_raw
+  raw_hex_iterator ri = begin_raw_hex (level);
+  if (ri.state() != IteratorState::valid)
+    return ri;
+  while (ri->used() == false)
+    if ((++ri).state() != IteratorState::valid)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::hex_iterator
-DoFHandler<dim>::last_hex (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_hex_iterator
+DoFHandler<dim, spacedim>::begin_active_hex (const unsigned int level) const
 {
-  return hex_iterator (tria,
-                      tria->last_hex(level)->level(),
-                      tria->last_hex(level)->index(),
-                      this);
+                                  // level is checked in begin_raw
+  hex_iterator i = begin_hex (level);
+  if (i.state() != IteratorState::valid)
+    return i;
+  while (i->has_children())
+    if ((++i).state() != IteratorState::valid)
+      return i;
+  return i;
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::active_hex_iterator
-DoFHandler<dim>::last_active_hex (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_hex_iterator
+DoFHandler<dim, spacedim>::end_raw_hex (const unsigned int level) const
 {
-  return active_hex_iterator (tria,
-                             tria->last_active_hex(level)->level(),
-                             tria->last_active_hex(level)->index(),
-                             this);
+  return (level == tria->n_levels()-1 ?
+         end_hex() :
+         begin_raw_hex (level+1));
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_line_iterator
-DoFHandler<dim>::last_raw_line () const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::hex_iterator
+DoFHandler<dim, spacedim>::end_hex (const unsigned int level) const
 {
-  return raw_line_iterator (tria,
-                           tria->last_raw_line()->level(),
-                           tria->last_raw_line()->index(),
-                           this);
+  return (level == tria->n_levels()-1 ?
+         hex_iterator(end_hex()) :
+         begin_hex (level+1));
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_quad_iterator
-DoFHandler<dim>::last_raw_quad () const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_hex_iterator
+DoFHandler<dim, spacedim>::end_active_hex (const unsigned int level) const
 {
-  return raw_quad_iterator (tria,
-                           tria->last_raw_quad()->level(),
-                           tria->last_raw_quad()->index(),
-                           this);
+  return (level == tria->n_levels()-1 ?
+         active_hex_iterator(end_hex()) :
+         begin_active_hex (level+1));
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::raw_hex_iterator
-DoFHandler<dim>::last_raw_hex () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_hex_iterator
+DoFHandler<dim, spacedim>::end_hex () const
 {
   return raw_hex_iterator (tria,
-                          tria->last_raw_hex()->level(),
-                          tria->last_raw_hex()->index(),
+                          -1,
+                          -1,
                           this);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::line_iterator
-DoFHandler<dim>::last_line () const
-{
-  return line_iterator (tria,
-                       tria->last_line()->level(),
-                       tria->last_line()->index(),
-                       this);
-}
-
 
-template <int dim>
-typename DoFHandler<dim>::quad_iterator
-DoFHandler<dim>::last_quad () const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_hex_iterator
+DoFHandler<dim, spacedim>::last_raw_hex (const unsigned int level) const
 {
-  return quad_iterator (tria,
-                       tria->last_quad()->level(),
-                       tria->last_quad()->index(),
-                       this);
+  switch (dim)
+    {
+      case 1:
+      case 2:
+           Assert (false, ExcImpossibleInDim(dim));
+           return raw_hex_iterator();
+
+      case 3:
+           Assert (level<tria->n_levels(),
+                   ExcInvalidLevel(level));
+           Assert (tria->n_raw_hexs(level) != 0,
+                   ExcEmptyLevel (level));
+
+           return raw_hex_iterator (tria,
+                                    level,
+                                    tria->n_raw_hexs(level)-1,
+                                    this);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_hex_iterator();
+    }
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::hex_iterator
-DoFHandler<dim>::last_hex () const
-{
-  return hex_iterator (tria,
-                      tria->last_hex()->level(),
-                      tria->last_hex()->index(),
-                      this);
-}
 
-
-template <int dim>
-typename DoFHandler<dim>::active_line_iterator
-DoFHandler<dim>::last_active_line () const
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::raw_hex_iterator
+DoFHandler<dim, spacedim>::last_raw_hex () const
 {
-  return active_line_iterator (tria,
-                              tria->last_active_line()->level(),
-                              tria->last_active_line()->index(),
-                              this);
+  return last_raw_hex (tria->n_levels()-1);
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::active_quad_iterator
-DoFHandler<dim>::last_active_quad () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::hex_iterator
+DoFHandler<dim, spacedim>::last_hex (const unsigned int level) const
 {
-  return active_quad_iterator (tria,
-                              tria->last_active_quad()->level(),
-                              tria->last_active_quad()->index(),
-                              this);
+                                  // level is checked in last_raw
+  raw_hex_iterator ri = last_raw_hex(level);
+  if (ri->used()==true)
+    return ri;
+  while ((--ri).state() == IteratorState::valid)
+    if (ri->used()==true)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename DoFHandler<dim>::active_hex_iterator
-DoFHandler<dim>::last_active_hex () const
+
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::hex_iterator
+DoFHandler<dim, spacedim>::last_hex () const
 {
-  return active_hex_iterator (tria,
-                             tria->last_active_hex()->level(),
-                             tria->last_active_hex()->index(),
-                             this);
+  return last_hex (tria->n_levels()-1);
 }
 
 
-//---------------------------------------------------------------------------
-
-#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
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_hex_iterator
+DoFHandler<dim, spacedim>::last_active_hex (const unsigned int level) const
 {
-  return this->levels[obj_level]->lines.
-    get_dof_index (*this,
-                  obj_index,
-                  fe_index,
-                  local_index);
+                                  // level is checked in last_raw
+  hex_iterator i = last_hex(level);
+  if (i->has_children()==false)
+    return i;
+  while ((--i).state() == IteratorState::valid)
+    if (i->has_children()==false)
+      return i;
+  return i;
 }
 
 
-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);
-  
-}
-#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
+template <int dim, int spacedim>
+typename DoFHandler<dim, spacedim>::active_hex_iterator
+DoFHandler<dim, spacedim>::last_active_hex () const
 {
-  return this->faces->lines.
-    get_dof_index (*this,
-                  obj_index,
-                  fe_index,
-                  local_index);
+  return last_active_hex (tria->n_levels()-1);
 }
 
 
-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 <>
+
+template <int dim, int spacedim>
+template <int structdim>
 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
+DoFHandler<dim,spacedim>::get_dof_index (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);
+  return 
+    Implementation::get_dof_index (*this,
+                                  obj_level, obj_index,
+                                  fe_index, local_index,
+                                  internal::int2type<structdim>());
 }
 
 
-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);
-  
-}
-#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
+template <int dim, int spacedim>
+template <int structdim>
+void
+DoFHandler<dim,spacedim>::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
 {
-  return this->faces->lines.
-    get_dof_index (*this,
-                  obj_index,
-                  fe_index,
-                  local_index);
+  Implementation::set_dof_index (*this,
+                                obj_level, obj_index,
+                                fe_index, local_index,
+                                internal::int2type<structdim>(),
+                                global_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);
-  
-}
-
 
+#if deal_II_dimension == 1
 
 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
+unsigned int DoFHandler<1>::n_boundary_dofs () const
 {
-  return this->faces->quads.
-    get_dof_index (*this,
-                  obj_index,
-                  fe_index,
-                  local_index);
+  Assert (selected_fe != 0, ExcNoFESelected());
+  return 2*selected_fe->dofs_per_vertex;
 }
 
 
 
 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
+unsigned int DoFHandler<1>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
 {
-  return this->levels[obj_level]->hexes.
-    get_dof_index (*this,
-                  obj_index,
-                  fe_index,
-                  local_index);
-}
-
+  Assert (selected_fe != 0, ExcNoFESelected());
 
+                                  // check that only boundary
+                                  // indicators 0 and 1 are allowed
+                                  // in 1d
+  for (FunctionMap::const_iterator i=boundary_indicators.begin();
+       i!=boundary_indicators.end(); ++i)
+    Assert ((i->first == 0) || (i->first == 1),
+           ExcInvalidBoundaryIndicator());
 
-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);
-  
+  return boundary_indicators.size()*selected_fe->dofs_per_vertex;
 }
 
 
 
 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);
-  
-}
-#endif
+unsigned int DoFHandler<1>::n_boundary_dofs (const std::set<unsigned char> &boundary_indicators) const
+{
+  Assert (selected_fe != 0, ExcNoFESelected());
+
+                                  // check that only boundary
+                                  // indicators 0 and 1 are allowed
+                                  // in 1d
+  for (std::set<unsigned char>::const_iterator i=boundary_indicators.begin();
+       i!=boundary_indicators.end(); ++i)
+    Assert ((*i == 0) || (*i == 1),
+           ExcInvalidBoundaryIndicator());
 
+  return boundary_indicators.size()*selected_fe->dofs_per_vertex;
+}
 
-#if deal_II_dimension == 1
 
 template <>
-unsigned int DoFHandler<1>::n_boundary_dofs () const
+unsigned int DoFHandler<1,2>::n_boundary_dofs () const
 {
   Assert (selected_fe != 0, ExcNoFESelected());
   return 2*selected_fe->dofs_per_vertex;
@@ -1607,7 +2012,7 @@ unsigned int DoFHandler<1>::n_boundary_dofs () const
 
 
 template <>
-unsigned int DoFHandler<1>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
+unsigned int DoFHandler<1,2>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
 {
   Assert (selected_fe != 0, ExcNoFESelected());
 
@@ -1625,7 +2030,7 @@ unsigned int DoFHandler<1>::n_boundary_dofs (const FunctionMap &boundary_indicat
 
 
 template <>
-unsigned int DoFHandler<1>::n_boundary_dofs (const std::set<unsigned char> &boundary_indicators) const
+unsigned int DoFHandler<1,2>::n_boundary_dofs (const std::set<unsigned char> &boundary_indicators) const
 {
   Assert (selected_fe != 0, ExcNoFESelected());
 
@@ -1643,8 +2048,8 @@ unsigned int DoFHandler<1>::n_boundary_dofs (const std::set<unsigned char> &boun
 #endif
 
 
-template <int dim>
-unsigned int DoFHandler<dim>::n_boundary_dofs () const
+template<int dim, int spacedim>
+unsigned int DoFHandler<dim,spacedim>::n_boundary_dofs () const
 {
   Assert (selected_fe != 0, ExcNoFESelected());
   
@@ -1671,15 +2076,15 @@ unsigned int DoFHandler<dim>::n_boundary_dofs () const
        face->get_dof_indices (dofs_on_face);
        for (unsigned int i=0; i<dofs_per_face; ++i)
          boundary_dofs.insert(dofs_on_face[i]);
-      };
+      }
   return boundary_dofs.size();
 }
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 unsigned int
-DoFHandler<dim>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
+DoFHandler<dim,spacedim>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
 {
   Assert (selected_fe != 0, ExcNoFESelected());
   Assert (boundary_indicators.find(255) == boundary_indicators.end(),
@@ -1698,15 +2103,15 @@ DoFHandler<dim>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
        face->get_dof_indices (dofs_on_face);
        for (unsigned int i=0; i<dofs_per_face; ++i)
          boundary_dofs.insert(dofs_on_face[i]);
-      };
+      }
   return boundary_dofs.size();
 }
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 unsigned int
-DoFHandler<dim>::n_boundary_dofs (const std::set<unsigned char> &boundary_indicators) const
+DoFHandler<dim,spacedim>::n_boundary_dofs (const std::set<unsigned char> &boundary_indicators) const
 {
   Assert (selected_fe != 0, ExcNoFESelected());
   Assert (boundary_indicators.find (255) == boundary_indicators.end(),
@@ -1727,14 +2132,14 @@ DoFHandler<dim>::n_boundary_dofs (const std::set<unsigned char> &boundary_indica
        face->get_dof_indices (dofs_on_face);
        for (unsigned int i=0; i<dofs_per_face; ++i)
          boundary_dofs.insert(dofs_on_face[i]);
-      };
+      }
   return boundary_dofs.size();
 }
 
 
-template <int dim>
+template<int dim, int spacedim>
 unsigned int
-DoFHandler<dim>::memory_consumption () const
+DoFHandler<dim,spacedim>::memory_consumption () const
 {
   unsigned int mem = (MemoryConsumption::memory_consumption (tria) +
                      MemoryConsumption::memory_consumption (selected_fe) +
@@ -1752,15 +2157,20 @@ DoFHandler<dim>::memory_consumption () const
 
 
 
-template <int dim>
-void DoFHandler<dim>::distribute_dofs (const FiniteElement<dim> &ff,
+template<int dim, int spacedim>
+void DoFHandler<dim,spacedim>::distribute_dofs (const FiniteElement<dim,spacedim> &ff,
                                       const unsigned int        offset)
 {
   Assert (tria->n_levels() > 0, ExcInvalidTriangulation());
   
   selected_fe = &ff;
-  
-  reserve_space ();
+
+                                   // delete all levels and set them up
+                                   // newly, since vectors are
+                                   // troublesome if you want to change
+                                   // their size
+  clear_space ();
+  Implementation::reserve_space (*this);
 
                                   // Clear user flags because we will
                                   // need them. But first we save
@@ -1772,14 +2182,15 @@ void DoFHandler<dim>::distribute_dofs (const FiniteElement<dim> &ff,
                                   // beginning of this function.
   std::vector<bool> user_flags;
   tria->save_user_flags(user_flags);
-  const_cast<Triangulation<dim> &>(*tria).clear_user_flags ();
+  const_cast<Triangulation<dim,spacedim> &>(*tria).clear_user_flags ();
   
   unsigned int next_free_dof = offset;   
   active_cell_iterator cell = begin_active(),
                       endc = end();
 
   for (; cell != endc; ++cell) 
-    next_free_dof = distribute_dofs_on_cell (cell, next_free_dof);
+    next_free_dof
+      = Implementation::distribute_dofs_on_cell (*this, cell, next_free_dof);
 
   used_dofs = next_free_dof;
 
@@ -1789,13 +2200,13 @@ void DoFHandler<dim>::distribute_dofs (const FiniteElement<dim> &ff,
     cell->update_cell_dof_indices_cache ();
   
                                   // finally restore the user flags
-  const_cast<Triangulation<dim> &>(*tria).load_user_flags(user_flags);
+  const_cast<Triangulation<dim,spacedim> &>(*tria).load_user_flags(user_flags);
 }
 
 
 
-template <int dim>
-void DoFHandler<dim>::clear ()
+template<int dim, int spacedim>
+void DoFHandler<dim,spacedim>::clear ()
 {
                                   // release lock to old fe
   selected_fe = 0;
@@ -1805,232 +2216,14 @@ void DoFHandler<dim>::clear ()
 }
 
 
-#if deal_II_dimension == 1
-
-template <>
-unsigned int
-DoFHandler<1>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                       unsigned int          next_free_dof)
-{
-
-                                  // distribute dofs of vertices
-  for (unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
-    {
-      cell_iterator neighbor = cell->neighbor(v);
-
-      if (neighbor.state() == IteratorState::valid)
-       {
-                                          // find true neighbor; may be its
-                                          // a child of @p{neighbor}
-         while (neighbor->has_children())
-           neighbor = neighbor->child(v==0 ? 1 : 0);
-
-                                          // has neighbor already been processed?
-         if (neighbor->user_flag_set())
-                                            // copy dofs
-           {
-             if (v==0) 
-               for (unsigned int d=0; d<selected_fe->dofs_per_vertex; ++d)
-                 cell->set_vertex_dof_index (0, d,
-                                             neighbor->vertex_dof_index (1, d));
-             else
-               for (unsigned int d=0; d<selected_fe->dofs_per_vertex; ++d)
-                 cell->set_vertex_dof_index (1, d,
-                                             neighbor->vertex_dof_index (0, d));
-
-                                              // next neighbor
-             continue;
-           };
-       };
-            
-                                      // otherwise: create dofs newly
-      for (unsigned int d=0; d<selected_fe->dofs_per_vertex; ++d)
-       cell->set_vertex_dof_index (v, d, next_free_dof++);
-    };
-  
-                                  // dofs of line
-  for (unsigned int d=0; d<selected_fe->dofs_per_line; ++d)
-    cell->set_dof_index (d, next_free_dof++);
-
-                                  // note that this cell has been processed
-  cell->set_user_flag ();
-  
-  return next_free_dof;
-}
-
-#endif
-
-
-#if deal_II_dimension == 2
-
-template <>
-unsigned int
-DoFHandler<2>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                       unsigned int          next_free_dof)
-{
-  if (selected_fe->dofs_per_vertex > 0)
-                                    // number dofs on vertices
-    for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
-                                      // check whether dofs for this
-                                      // vertex have been distributed
-                                      // (only check the first dof)
-      if (cell->vertex_dof_index(vertex, 0) == invalid_dof_index)
-       for (unsigned int d=0; d<selected_fe->dofs_per_vertex; ++d)
-         cell->set_vertex_dof_index (vertex, d, next_free_dof++);
-    
-                                  // for the four sides
-  if (selected_fe->dofs_per_line > 0)
-    for (unsigned int side=0; side<GeometryInfo<2>::faces_per_cell; ++side)
-      {
-       line_iterator line = cell->line(side);
-       
-                                        // distribute dofs if necessary:
-                                        // check whether line dof is already
-                                        // numbered (check only first dof)
-       if (line->dof_index(0) == invalid_dof_index)
-                                          // if not: distribute dofs
-         for (unsigned int d=0; d<selected_fe->dofs_per_line; ++d)
-           line->set_dof_index (d, next_free_dof++);       
-      };
-
-
-                                  // dofs of quad
-  if (selected_fe->dofs_per_quad > 0)
-    for (unsigned int d=0; d<selected_fe->dofs_per_quad; ++d)
-      cell->set_dof_index (d, next_free_dof++);
-
-
-                                  // note that this cell has been processed
-  cell->set_user_flag ();
-  
-  return next_free_dof;
-}
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-template <>
-unsigned int
-DoFHandler<3>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                       unsigned int          next_free_dof)
-{
-  if (selected_fe->dofs_per_vertex > 0)
-                                    // number dofs on vertices
-    for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
-                                      // check whether dofs for this
-                                      // vertex have been distributed
-                                      // (only check the first dof)
-      if (cell->vertex_dof_index(vertex, 0) == invalid_dof_index)
-       for (unsigned int d=0; d<selected_fe->dofs_per_vertex; ++d)
-         cell->set_vertex_dof_index (vertex, d, next_free_dof++);
-    
-                                  // for the lines
-  if (selected_fe->dofs_per_line > 0)
-    for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
-      {
-       line_iterator line = cell->line(l);
-       
-                                        // distribute dofs if necessary:
-                                        // check whether line dof is already
-                                        // numbered (check only first dof)
-       if (line->dof_index(0) == invalid_dof_index)
-                                          // if not: distribute dofs
-         for (unsigned int d=0; d<selected_fe->dofs_per_line; ++d)
-           line->set_dof_index (d, next_free_dof++);       
-      };
-
-                                  // for the quads
-  if (selected_fe->dofs_per_quad > 0)
-    for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
-      {
-       quad_iterator quad = cell->quad(q);
-       
-                                        // distribute dofs if necessary:
-                                        // check whether quad dof is already
-                                        // numbered (check only first dof)
-       if (quad->dof_index(0) == invalid_dof_index)
-                                          // if not: distribute dofs
-         for (unsigned int d=0; d<selected_fe->dofs_per_quad; ++d)
-           quad->set_dof_index (d, next_free_dof++);       
-      };
-
-
-                                  // dofs of hex
-  if (selected_fe->dofs_per_hex > 0)
-    for (unsigned int d=0; d<selected_fe->dofs_per_hex; ++d)
-      cell->set_dof_index (d, next_free_dof++);
-
-
-                                  // note that this cell has been processed
-  cell->set_user_flag ();
-  
-  return next_free_dof;
-}
-
-#endif
-
-
-#if deal_II_dimension == 1
 
-template <>
-void DoFHandler<1>::renumber_dofs (const std::vector<unsigned int> &new_numbers)
+template <int dim, int spacedim>
+void
+DoFHandler<dim,spacedim>::
+renumber_dofs (const std::vector<unsigned int> &new_numbers)
 {
   Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
-#ifdef DEBUG
-                                  // assert that the new indices are
-                                  // consecutively numbered
-  if (true)
-    {
-      std::vector<unsigned int> tmp(new_numbers);
-      std::sort (tmp.begin(), tmp.end());
-      std::vector<unsigned int>::const_iterator p = tmp.begin();
-      unsigned int                         i = 0;
-      for (; p!=tmp.end(); ++p, ++i)
-       Assert (*p == i, ExcNewNumbersNotConsecutive(i));
-    };
-#endif
-
-                                  // note that we can not use cell iterators
-                                  // in this function since then we would
-                                  // renumber the dofs on the interface of
-                                  // two cells more than once. Anyway, this
-                                  // way it's not only more correct but also
-                                  // faster; note, however, that dof numbers
-                                  // may be invalid_dof_index, namely when the appropriate
-                                  // vertex/line/etc is unused
-  for (std::vector<unsigned int>::iterator i=vertex_dofs.begin(); i!=vertex_dofs.end(); ++i)
-    if (*i != invalid_dof_index)
-      *i = new_numbers[*i];
-    else
-                                      // if index is invalid_dof_index: check if this one
-                                      // really is unused
-      Assert (tria->vertex_used((i-vertex_dofs.begin()) /
-                               selected_fe->dofs_per_vertex) == false,
-             ExcInternalError ());
-  
-  for (unsigned int level=0; level<levels.size(); ++level) 
-    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];
-
-                                  // finally update the cache used
-                                  // for cell dof indices
-  for (cell_iterator cell = begin(); cell != end(); ++cell)
-    cell->update_cell_dof_indices_cache ();
-}
-
-#endif
 
-
-#if deal_II_dimension == 2
-
-template <>
-void DoFHandler<2>::renumber_dofs (const std::vector<unsigned int> &new_numbers)
-{
-  Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
 #ifdef DEBUG
                                   // assert that the new indices are
                                   // consecutively numbered
@@ -2042,404 +2235,81 @@ void DoFHandler<2>::renumber_dofs (const std::vector<unsigned int> &new_numbers)
       unsigned int                         i = 0;
       for (; p!=tmp.end(); ++p, ++i)
        Assert (*p == i, ExcNewNumbersNotConsecutive(i));
-    };
-#endif
-
-                                  // note that we can not use cell iterators
-                                  // in this function since then we would
-                                  // renumber the dofs on the interface of
-                                  // two cells more than once. Anyway, this
-                                  // way it's not only more correct but also
-                                  // faster; note, however, that dof numbers
-                                  // may be invalid_dof_index, namely when the appropriate
-                                  // vertex/line/etc is unused
-  for (std::vector<unsigned int>::iterator i=vertex_dofs.begin(); i!=vertex_dofs.end(); ++i)
-    if (*i != invalid_dof_index)
-      *i = new_numbers[*i];
-    else
-                                      // if index is invalid_dof_index: check if this one
-                                      // really is unused
-      Assert (tria->vertex_used((i-vertex_dofs.begin()) /
-                               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]->quads.dofs.begin();
-          i!=levels[level]->quads.dofs.end(); ++i)
-       if (*i != invalid_dof_index)
-         *i = new_numbers[*i];
     }
-
-                                  // finally update the cache used
-                                  // for cell dof indices
-  for (cell_iterator cell = begin(); cell != end(); ++cell)
-    cell->update_cell_dof_indices_cache ();
-}
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-template <>
-void DoFHandler<3>::renumber_dofs (const std::vector<unsigned int> &new_numbers)
-{
-  Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
-#ifdef DEBUG
-                                  // assert that the new indices are
-                                  // consecutively numbered
-  if (true)
-    {
-      std::vector<unsigned int> tmp(new_numbers);
-      std::sort (tmp.begin(), tmp.end());
-      std::vector<unsigned int>::const_iterator p = tmp.begin();
-      unsigned int                              i = 0;
-      for (; p!=tmp.end(); ++p, ++i)
-       Assert (*p == i, ExcNewNumbersNotConsecutive(i));
-    };
 #endif
 
-                                  // note that we can not use cell iterators
-                                  // in this function since then we would
-                                  // renumber the dofs on the interface of
-                                  // two cells more than once. Anyway, this
-                                  // way it's not only more correct but also
-                                  // faster; note, however, that dof numbers
-                                  // may be invalid_dof_index, namely when the appropriate
-                                  // vertex/line/etc is unused
-  for (std::vector<unsigned int>::iterator i=vertex_dofs.begin(); i!=vertex_dofs.end(); ++i)
-    if (*i != invalid_dof_index)
-      *i = new_numbers[*i];
-    else
-                                      // if index is invalid_dof_index: check if this one
-                                      // really is unused
-      Assert (tria->vertex_used((i-vertex_dofs.begin()) /
-                               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]->hexes.dofs.begin();
-          i!=levels[level]->hexes.dofs.end(); ++i)
-       if (*i != invalid_dof_index)
-         *i = new_numbers[*i];
-    }
+  Implementation::renumber_dofs (new_numbers, *this);
 
-                                  // finally update the cache used
-                                  // for cell dof indices
+                                  // update the cache used for cell dof
+                                  // indices
   for (cell_iterator cell = begin(); cell != end(); ++cell)
     cell->update_cell_dof_indices_cache ();
+  
 }
 
-#endif
-
 
-#if deal_II_dimension == 1
 
-template <>
+template <int dim, int spacedim>
 unsigned int
-DoFHandler<1>::max_couplings_between_dofs () const
+DoFHandler<dim,spacedim>::max_couplings_between_dofs () const
 {
   Assert (selected_fe != 0, ExcNoFESelected());
-  return std::min(3*selected_fe->dofs_per_vertex +
-                 2*selected_fe->dofs_per_line, n_dofs());
-}
-
 
-
-template <>
-unsigned int
-DoFHandler<1>::max_couplings_between_boundary_dofs () const
-{
-  Assert (selected_fe != 0, ExcNoFESelected());
-  return selected_fe->dofs_per_vertex;
+  return Implementation::max_couplings_between_dofs (*this);
 }
 
-#endif
-
 
-#if deal_II_dimension == 2
 
-template <>
+template <int dim, int spacedim>
 unsigned int
-DoFHandler<2>::max_couplings_between_dofs () const
+DoFHandler<dim,spacedim>::max_couplings_between_boundary_dofs () const
 {
   Assert (selected_fe != 0, ExcNoFESelected());
 
-                                  // get these numbers by drawing pictures
-                                  // and counting...
-                                  // example:
-                                  //   |     |     |
-                                  // --x-----x--x--X--
-                                  //   |     |  |  |
-                                  //   |     x--x--x
-                                  //   |     |  |  |
-                                  // --x--x--*--x--x--
-                                  //   |  |  |     |
-                                  //   x--x--x     |
-                                  //   |  |  |     |
-                                  // --X--x--x-----x--
-                                  //   |     |     |
-                                  // x = vertices connected with center vertex *;
-                                  //   = total of 19
-                                  // (the X vertices are connected with * if
-                                  // the vertices adjacent to X are hanging
-                                  // nodes)
-                                  // count lines -> 28 (don't forget to count
-                                  // mother and children separately!)
-  unsigned int max_couplings;
-  switch (tria->max_adjacent_cells())
+  switch (dim)
     {
-      case 4:
-           max_couplings=19*selected_fe->dofs_per_vertex +
-                         28*selected_fe->dofs_per_line +
-                         8*selected_fe->dofs_per_quad;
-           break;
-      case 5:
-           max_couplings=21*selected_fe->dofs_per_vertex +
-                         31*selected_fe->dofs_per_line +
-                         9*selected_fe->dofs_per_quad;
-           break;
-      case 6:
-           max_couplings=28*selected_fe->dofs_per_vertex +
-                         42*selected_fe->dofs_per_line +
-                         12*selected_fe->dofs_per_quad;
-           break;
-      case 7:
-           max_couplings=30*selected_fe->dofs_per_vertex +
-                         45*selected_fe->dofs_per_line +
-                         13*selected_fe->dofs_per_quad;
-           break;
-      case 8:
-           max_couplings=37*selected_fe->dofs_per_vertex +
-                         56*selected_fe->dofs_per_line +
-                         16*selected_fe->dofs_per_quad;
-           break;
+      case 1:
+           return selected_fe->dofs_per_vertex;
+      case 2:
+           return (3*selected_fe->dofs_per_vertex +
+                   2*selected_fe->dofs_per_line);
+      case 3:
+                                            // we need to take refinement of
+                                            // one boundary face into
+                                            // consideration here; in fact,
+                                            // this function returns what
+                                            // #max_coupling_between_dofs<2>
+                                            // returns
+                                            //
+                                            // we assume here, that only four
+                                            // faces meet at the boundary;
+                                            // this assumption is not
+                                            // justified and needs to be
+                                            // fixed some time. fortunately,
+                                            // ommitting it for now does no
+                                            // harm since the matrix will cry
+                                            // foul if its requirements are
+                                            // not satisfied
+           return (19*selected_fe->dofs_per_vertex +
+                   28*selected_fe->dofs_per_line +
+                   8*selected_fe->dofs_per_quad);
       default:
            Assert (false, ExcNotImplemented());
-           max_couplings=0;
-    };
-  return std::min(max_couplings,n_dofs());
-}
-
-
-
-template <>
-unsigned int
-DoFHandler<2>::max_couplings_between_boundary_dofs () const
-{
-  Assert (selected_fe != 0, ExcNoFESelected());
-  return 3*selected_fe->dofs_per_vertex + 2*selected_fe->dofs_per_line;
-}
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-template <>
-unsigned int
-DoFHandler<3>::max_couplings_between_dofs () const
-{
-//TODO:[?] Invent significantly better estimates than the ones in this function  
-  Assert (selected_fe != 0, ExcNoFESelected());
-
-                                  // doing the same thing here is a rather
-                                  // complicated thing, compared to the 2d
-                                  // case, since it is hard to draw pictures
-                                  // with several refined hexahedra :-) so I
-                                  // presently only give a coarse estimate
-                                  // for the case that at most 8 hexes meet
-                                  // at each vertex
-                                  //
-                                  // can anyone give better estimate here?
-  const unsigned int max_adjacent_cells = tria->max_adjacent_cells();
-
-  unsigned int max_couplings;
-  if (max_adjacent_cells <= 8)
-    max_couplings=7*7*7*selected_fe->dofs_per_vertex +
-                 7*6*7*3*selected_fe->dofs_per_line +
-                 9*4*7*3*selected_fe->dofs_per_quad +
-                 27*selected_fe->dofs_per_hex;
-  else
-    {
-      Assert (false, ExcNotImplemented());
-      max_couplings=0;
-    }
-  
-  return std::min(max_couplings,n_dofs());
-}
-
-
-template <>
-unsigned int
-DoFHandler<3>::max_couplings_between_boundary_dofs () const
-{
-  Assert (selected_fe != 0, ExcNoFESelected());
-                                  // we need to take refinement of
-                                  // one boundary face into consideration
-                                  // here; in fact, this function returns
-                                  // what #max_coupling_between_dofs<2>
-                                  // returns
-                                  //
-                                  // we assume here, that only four faces
-                                  // meet at the boundary; this assumption
-                                  // is not justified and needs to be
-                                  // fixed some time. fortunately, ommitting
-                                  // it for now does no harm since the
-                                  // matrix will cry foul if its requirements
-                                  // are not satisfied
-  return (19*selected_fe->dofs_per_vertex +
-         28*selected_fe->dofs_per_line +
-         8*selected_fe->dofs_per_quad);
-}
-
-
-#endif
-
-
-
-#if deal_II_dimension == 1
-
-template <>
-void DoFHandler<1>::reserve_space ()
-{
-  Assert (selected_fe != 0, ExcNoFESelected());
-  Assert (tria->n_levels() > 0, ExcInvalidTriangulation());
-
-                                   // delete all levels and set them up
-                                   // newly, since vectors are
-                                   // troublesome if you want to change
-                                   // their size
-  clear_space ();
-  
-  vertex_dofs.resize(tria->n_vertices()*selected_fe->dofs_per_vertex,
-                    invalid_dof_index);
-    
-  for (unsigned int i=0; i<tria->n_levels(); ++i) 
-    {
-      levels.push_back (new internal::DoFHandler::DoFLevel<1>);
-
-      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,
-                                                   invalid_dof_index);
-    }
-}
-
-
-#endif
-
-
-#if deal_II_dimension == 2
-
-template <>
-void DoFHandler<2>::reserve_space ()
-{
-  Assert (selected_fe != 0, ExcNoFESelected());
-  Assert (tria->n_levels() > 0, ExcInvalidTriangulation());
-  
-                                   // delete all levels and set them up
-                                   // newly, since vectors are
-                                   // troublesome if you want to change
-                                   // their size
-  clear_space ();
-
-  vertex_dofs.resize(tria->n_vertices()*selected_fe->dofs_per_vertex,
-                    invalid_dof_index);
-
-  for (unsigned int i=0; i<tria->n_levels(); ++i) 
-    {
-      levels.push_back (new internal::DoFHandler::DoFLevel<2>);
-
-      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
-
-
-#if deal_II_dimension == 3
-
-template <>
-void DoFHandler<3>::reserve_space ()
-{
-  Assert (selected_fe != 0, ExcNoFESelected());
-  Assert (tria->n_levels() > 0, ExcInvalidTriangulation());
-  
-                                   // delete all levels and set them up
-                                   // newly, since vectors are
-                                   // troublesome if you want to change
-                                   // their size
-  clear_space ();
-  
-  vertex_dofs.resize(tria->n_vertices()*selected_fe->dofs_per_vertex,
-                    invalid_dof_index);
-
-  for (unsigned int i=0; i<tria->n_levels(); ++i) 
-    {
-      levels.push_back (new internal::DoFHandler::DoFLevel<3>);
-
-      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 ()
+template<int dim, int spacedim>
+void DoFHandler<dim,spacedim>::clear_space ()
 {
   for (unsigned int i=0; i<levels.size(); ++i)
     delete levels[i];
   levels.resize (0);
     
   delete faces;
-  faces = NULL;
+  faces = 0;
   
   std::vector<unsigned int> tmp;
   std::swap (vertex_dofs, tmp);
@@ -2449,4 +2319,36 @@ void DoFHandler<dim>::clear_space ()
 /*-------------- Explicit Instantiations -------------------------------*/
 template class DoFHandler<deal_II_dimension>;
 
+#if deal_II_dimension==1 || deal_II_dimension==2
+template class DoFHandler<deal_II_dimension,deal_II_dimension+1>;
+#endif
+
+
+template
+unsigned int
+DoFHandler<deal_II_dimension,deal_II_dimension>::
+get_dof_index<deal_II_dimension> (const unsigned int, const unsigned int,
+                                 const unsigned int, const unsigned int) const;
+template
+void
+DoFHandler<deal_II_dimension,deal_II_dimension>::
+set_dof_index<deal_II_dimension> (const unsigned int, const unsigned int,
+                                 const unsigned int, const unsigned int,
+                                 const unsigned int) const;
+
+#if deal_II_dimension != 3
+
+template
+unsigned int
+DoFHandler<deal_II_dimension,deal_II_dimension+1>::
+get_dof_index<deal_II_dimension> (const unsigned int, const unsigned int,
+                                 const unsigned int, const unsigned int) const;
+template
+void
+DoFHandler<deal_II_dimension,deal_II_dimension+1>::
+set_dof_index<deal_II_dimension> (const unsigned int, const unsigned int,
+                                 const unsigned int, const unsigned int,
+                                 const unsigned int) const;
+#endif
+
 DEAL_II_NAMESPACE_CLOSE
index ea78a5430a1be29186d72afb5b216095f614c9ed..104b2a6d853b55e18805465611dd75a2d811785a 100644 (file)
@@ -25,16 +25,16 @@ namespace internal
   namespace DoFHandler
   {
     template <int dim>
-    template <int spacedim>
+    template <int dh_dim, int spacedim>
     void
     DoFObjects<dim>::
-    set_dof_index (const dealii::DoFHandler<spacedim> &dof_handler,
+    set_dof_index (const dealii::DoFHandler<dh_dim, spacedim> &dof_handler,
                   const unsigned int       obj_index,
                   const unsigned int       fe_index,
                   const unsigned int       local_index,
                   const unsigned int       global_index)
     {
-      Assert (fe_index == dealii::DoFHandler<spacedim>::default_fe_index,
+      Assert ((fe_index == dealii::DoFHandler<dh_dim, spacedim>::default_fe_index),
              ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
       Assert (local_index<dof_handler.get_fe().template n_dofs_per_object<dim>(),
              ExcIndexRange (local_index, 0, dof_handler.get_fe().template n_dofs_per_object<dim>()));
@@ -107,6 +107,48 @@ namespace internal
                   const unsigned int       local_index,
                   const unsigned int       global_index);
 
+
+#if deal_II_dimension!=3
+
+    template
+    unsigned int
+    DoFObjects<1>::
+    get_dof_index (const dealii::DoFHandler<deal_II_dimension,deal_II_dimension+1> &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 dealii::DoFHandler<deal_II_dimension,deal_II_dimension+1> &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>::
+    get_dof_index (const dealii::DoFHandler<deal_II_dimension,deal_II_dimension+1> &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 dealii::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_handler,
+                  const unsigned int       obj_index,
+                  const unsigned int       fe_index,
+                  const unsigned int       local_index,
+                  const unsigned int       global_index);
+
+
+#endif
+
+
   }
 }
 
index 014275230f8afa77750f087e3d3005338738eda0..9bba2f39f0ffa7df5ae705c17cfe7de57c113a9b 100644 (file)
@@ -104,7 +104,7 @@ DoFTools::make_sparsity_pattern (
   Assert (couplings.n_cols() == dof.get_fe().n_components(),
          ExcDimensionMismatch(couplings.n_cols(), dof.get_fe().n_components()));
 
-  const hp::FECollection<DH::dimension> fe_collection (dof.get_fe());
+  const hp::FECollection<DH::dimension,DH::space_dimension> fe_collection (dof.get_fe());
   
                                   // first, for each finite element, build a
                                   // mask for each dof, not like the one
@@ -289,7 +289,7 @@ template <class DH, class SparsityPattern>
 void
 DoFTools::make_boundary_sparsity_pattern (
   const DH                               &dof_handler,
-  const typename FunctionMap<DH::dimension>::type &function_map,
+  const typename FunctionMap<DH::space_dimension>::type &function_map,
   const std::vector<unsigned int>        &dof_to_boundary_mapping,
   SparsityPattern                        &sparsity)
 {
@@ -418,7 +418,7 @@ DoFTools::make_boundary_sparsity_pattern (
 template <class DH, class SparsityPattern>
 void DoFTools::make_boundary_sparsity_pattern (
   const DH                                        &dof,
-  const typename FunctionMap<DH::dimension>::type &boundary_indicators,
+  const typename FunctionMap<DH::space_dimension>::type &boundary_indicators,
   const std::vector<unsigned int>                 &dof_to_boundary_mapping,
   SparsityPattern                                 &sparsity)
 {
@@ -1064,10 +1064,10 @@ namespace internal
                                        * this isn't the case, go back
                                        * and select dofs differently
                                        */
-      template <int dim>
+      template <int dim, int spacedim>  
       void
-      select_master_dofs_for_face_restriction (const FiniteElement<dim> &fe1,
-                                              const FiniteElement<dim> &fe2,
+      select_master_dofs_for_face_restriction (const FiniteElement<dim,spacedim> &fe1,
+                                              const FiniteElement<dim,spacedim> &fe2,
                                               const FullMatrix<double> &face_interpolation_matrix,
                                               std::vector<bool>        &master_dof_mask)
       {
@@ -1238,10 +1238,10 @@ namespace internal
                                        * masters on refined faces where an
                                        * fe1 and a fe2 meet.
                                        */
-      template <int dim>
+      template <int dim, int spacedim>  
       void
-      ensure_existence_of_master_dof_mask (const FiniteElement<dim> &fe1,
-                                          const FiniteElement<dim> &fe2,
+      ensure_existence_of_master_dof_mask (const FiniteElement<dim,spacedim> &fe1,
+                                          const FiniteElement<dim,spacedim> &fe2,
                                           const FullMatrix<double> &face_interpolation_matrix,
                                           boost::shared_ptr<std::vector<bool> > &master_dof_mask)
       {
@@ -1266,10 +1266,10 @@ namespace internal
                                         * with the correct data. If it
                                         * is nonzero, don't touch it.
                                         */
-      template <int dim>
+      template <int dim, int spacedim>  
       void
-      ensure_existence_of_face_matrix (const FiniteElement<dim> &fe1,
-                                       const FiniteElement<dim> &fe2,
+      ensure_existence_of_face_matrix (const FiniteElement<dim,spacedim> &fe1,
+                                       const FiniteElement<dim,spacedim> &fe2,
                                        boost::shared_ptr<FullMatrix<double> > &matrix)
       {
         if (matrix == 0)
@@ -1288,10 +1288,10 @@ namespace internal
                                        * Same, but for subface
                                        * interpolation matrices.
                                        */
-      template <int dim>
+      template <int dim, int spacedim>  
       void
-      ensure_existence_of_subface_matrix (const FiniteElement<dim> &fe1,
-                                          const FiniteElement<dim> &fe2,
+      ensure_existence_of_subface_matrix (const FiniteElement<dim,spacedim> &fe1,
+                                          const FiniteElement<dim,spacedim> &fe2,
                                           const unsigned int        subface,
                                           boost::shared_ptr<FullMatrix<double> > &matrix)
       {
@@ -1379,19 +1379,22 @@ namespace internal
                                        // a given DoFHandler class
                                        // supports different finite
                                        // element elements
-      template <typename> struct DoFHandlerSupportsDifferentP
+      template <typename>
+      struct DoFHandlerSupportsDifferentFEs
       {
           static const bool value = true;
       };
 
 
-      template <int dim> struct DoFHandlerSupportsDifferentP< dealii::DoFHandler<dim> >
+      template <int dim, int spacedim>
+      struct DoFHandlerSupportsDifferentFEs< dealii::DoFHandler<dim,spacedim> >
       {
           static const bool value = false;
       };
 
 
-      template <int dim> struct DoFHandlerSupportsDifferentP< dealii::MGDoFHandler<dim> >
+      template <int dim, int spacedim>
+      struct DoFHandlerSupportsDifferentFEs< dealii::MGDoFHandler<dim,spacedim> >
       {
           static const bool value = false;
       };
@@ -1406,9 +1409,9 @@ namespace internal
                                         * dof_handler.get_fe().size()
                                         * for the hp-versions.
                                         */
-      template <int dim>
+      template <int dim, int spacedim>
       unsigned int
-      n_finite_elements (const dealii::hp::DoFHandler<dim> &dof_handler)
+      n_finite_elements (const dealii::hp::DoFHandler<dim,spacedim> &dof_handler)
       {
         return dof_handler.get_fe().size();
       }
@@ -1435,6 +1438,9 @@ namespace internal
       unsigned int
       get_most_dominating_subface_fe_index (const face_iterator &face)
       {
+
+       const unsigned int spacedim=dim;
         unsigned int dominating_subface_no = 0;
         for (; dominating_subface_no<face->n_children();
              ++dominating_subface_no)
@@ -1450,7 +1456,7 @@ namespace internal
                     == 1,
                     ExcInternalError());
                        
-            const FiniteElement<dim> &
+            const FiniteElement<dim,spacedim> &
               this_subface_fe = (face->child(dominating_subface_no)
                                  ->get_fe (face->child(dominating_subface_no)
                                            ->nth_active_fe_index(0)));
@@ -1460,7 +1466,7 @@ namespace internal
             for (unsigned int sf=0; sf<face->n_children(); ++sf)
               if (sf != dominating_subface_no)
                 {
-                  const FiniteElement<dim> &
+                  const FiniteElement<dim,spacedim> &
                     that_subface_fe = (face->child(sf)
                                        ->get_fe (face->child(sf)
                                                  ->nth_active_fe_index(0)));
@@ -1681,6 +1687,8 @@ namespace internal
                                            dealii::internal::int2type<2>)
     {
       const unsigned int dim = 2;
+
+      const unsigned int spacedim = DH::space_dimension;
   
       std::vector<unsigned int> dofs_on_mother;
       std::vector<unsigned int> dofs_on_children;
@@ -1746,7 +1754,7 @@ namespace internal
                        ExcNotImplemented());
 
                                               // ok, start up the work
-             const FiniteElement<dim> &fe       = cell->get_fe();
+             const FiniteElement<dim,spacedim> &fe       = cell->get_fe();
              const unsigned int        fe_index = cell->active_fe_index();
                
              const unsigned int
@@ -2071,6 +2079,8 @@ namespace internal
                                       // what is going on here
       const unsigned int dim = DH::dimension;
 
+      const unsigned int spacedim = DH::space_dimension;
+
       
                                        // a matrix to be used for
                                        // constraints below. declared
@@ -2194,7 +2204,7 @@ namespace internal
              FiniteElementDomination::Domination
                mother_face_dominates = FiniteElementDomination::either_element_can_dominate;
 
-              if (DoFHandlerSupportsDifferentP<DH>::value == true)
+              if (DoFHandlerSupportsDifferentFEs<DH>::value == true)
                 for (unsigned int c=0; c<cell->face(face)->number_of_children(); ++c)
                   mother_face_dominates = mother_face_dominates &
                                           (cell->get_fe().compare_for_face_domination
@@ -2345,7 +2355,7 @@ namespace internal
                                                      // dof handlers,
                                                      // add a check
                                                      // here...
-                    Assert (DoFHandlerSupportsDifferentP<DH>::value == true,
+                    Assert (DoFHandlerSupportsDifferentFEs<DH>::value == true,
                             ExcInternalError());
 
                                                     // we first have
@@ -2360,7 +2370,7 @@ namespace internal
                     const unsigned int dominating_fe_index
                       = get_most_dominating_subface_fe_index<dim> (cell->face(face));
                     
-                   const FiniteElement<dim> &dominating_fe
+                   const FiniteElement<dim,spacedim> &dominating_fe
                      = dof_handler.get_fe()[dominating_fe_index];
                    
                                                     // check also
@@ -2499,7 +2509,7 @@ namespace internal
 
                        const unsigned int subface_fe_index
                          = cell->face(face)->child(sf)->nth_active_fe_index(0);
-                       const FiniteElement<dim> &subface_fe
+                       const FiniteElement<dim,spacedim> &subface_fe
                          = dof_handler.get_fe()[subface_fe_index];
                            
                                                         // first get the
@@ -2572,7 +2582,7 @@ namespace internal
                                               // and the same h-level,
                                               // some action has
                                               // to be taken.
-             if ((DoFHandlerSupportsDifferentP<DH>::value == true)
+             if ((DoFHandlerSupportsDifferentFEs<DH>::value == true)
                   &&
                   !cell->face(face)->at_boundary ()
                   &&
@@ -2867,15 +2877,15 @@ void DoFTools::distribute_cell_to_dof_vector (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::extract_dofs (
-  const DoFHandler<dim>   &dof,
+  const DoFHandler<dim,spacedim>   &dof,
   const std::vector<bool> &component_select,
   std::vector<bool>       &selected_dofs,
   const bool               count_by_blocks)
 {
-  const FiniteElement<dim> &fe = dof.get_fe();
+  const FiniteElement<dim,spacedim> &fe = dof.get_fe();
   
   if (count_by_blocks == true)
     {
@@ -2970,7 +2980,7 @@ DoFTools::extract_dofs (
                                    // then loop over all cells and do
                                    // the work
   std::vector<unsigned int> indices(fe.dofs_per_cell);
-  typename DoFHandler<dim>::active_cell_iterator c;
+  typename DoFHandler<dim,spacedim>::active_cell_iterator c;
   for (c=dof.begin_active(); c!=dof.end(); ++ c)
     {
       c->get_dof_indices(indices);
@@ -2981,10 +2991,10 @@ DoFTools::extract_dofs (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::extract_dofs (
-  const hp::DoFHandler<dim>   &/*dof*/,
+  const hp::DoFHandler<dim,spacedim>   &/*dof*/,
   const std::vector<bool> &/*component_select*/,
   std::vector<bool>       &/*selected_dofs*/,
   const bool               /*count_by_blocks*/)
@@ -2992,7 +3002,7 @@ DoFTools::extract_dofs (
 //TODO[WB]: implement this function  
   Assert (false, ExcNotImplemented());
 /*  
-  const FiniteElement<dim> &fe = dof.get_fe();
+  const FiniteElement<dim,spacedim> &fe = dof.get_fe();
   
   if (count_by_blocks == true)
     {
@@ -3087,7 +3097,7 @@ DoFTools::extract_dofs (
                                    // then loop over all cells and do
                                    // the work
   std::vector<unsigned int> indices(fe.dofs_per_cell);
-  typename DoFHandler<dim>::active_cell_iterator c;
+  typename DoFHandler<dim,spacedim>::active_cell_iterator c;
   for (c=dof.begin_active(); c!=dof.end(); ++ c)
     {
       c->get_dof_indices(indices);
@@ -3099,16 +3109,16 @@ DoFTools::extract_dofs (
 
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
 DoFTools::extract_level_dofs(
   const unsigned int       level,
-  const MGDoFHandler<dim> &dof,
+  const MGDoFHandler<dim,spacedim> &dof,
   const std::vector<bool> &component_select,
   std::vector<bool>       &selected_dofs,
   const bool               count_by_blocks)
 {
-  const FiniteElement<dim>& fe = dof.get_fe();
+  const FiniteElement<dim,spacedim>& fe = dof.get_fe();
   
   if (count_by_blocks == true)
     {
@@ -3202,7 +3212,7 @@ DoFTools::extract_level_dofs(
                                    // then loop over all cells and do
                                    // work
   std::vector<unsigned int> indices(fe.dofs_per_cell);  
-  typename MGDoFHandler<dim>::cell_iterator c;
+  typename MGDoFHandler<dim,spacedim>::cell_iterator c;
   for (c = dof.begin(level) ; c != dof.end(level) ; ++ c)
     {
       c->get_mg_dof_indices(indices);
@@ -3464,127 +3474,135 @@ DoFTools::extract_boundary_dofs (const DH                 &dof_handler,
 #endif
 
 
-
-#if deal_II_dimension == 1
-
-void
-DoFTools::extract_hanging_node_dofs (const DoFHandler<1> &dof_handler,
-                                    std::vector<bool>   &selected_dofs)
+namespace internal
 {
-  Assert(selected_dofs.size() == dof_handler.n_dofs(),
-        ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
-                                  // preset all values by false
-  std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
-
-                                  // there are no hanging nodes in 1d
-}
-
-#endif
-
+  namespace DoFTools
+  {
+    template <int spacedim>
+    void extract_hanging_node_dofs (const dealii::DoFHandler<1,spacedim> &dof_handler,
+                                    std::vector<bool>           &selected_dofs)
+    {
+      Assert(selected_dofs.size() == dof_handler.n_dofs(),
+            ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
+                                      // preset all values by false
+      std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
+      
+                                      // there are no hanging nodes in 1d
+    }
 
-#if deal_II_dimension == 2
 
-void
-DoFTools::extract_hanging_node_dofs (const DoFHandler<2> &dof_handler,
-                                    std::vector<bool>   &selected_dofs)
-{
-  const unsigned int dim = 2;
+    template <int spacedim>
+    void extract_hanging_node_dofs (const dealii::DoFHandler<2,spacedim> &dof_handler,
+                                    std::vector<bool>           &selected_dofs)
+    {
+      const unsigned int dim = 2;
   
-  Assert(selected_dofs.size() == dof_handler.n_dofs(),
-        ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
-                                  // preset all values by false
-  std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
-
-  const FiniteElement<dim> &fe   = dof_handler.get_fe();
-
-                                  // this function is similar to the
-                                  // make_sparsity_pattern function,
-                                  // see there for more information
-  DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
-                                       endc = dof_handler.end();
-  for (; cell!=endc; ++cell)
-    for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-      if (cell->face(face)->has_children()) 
-       {
-         const DoFHandler<dim>::line_iterator line = cell->face(face);
+      Assert(selected_dofs.size() == dof_handler.n_dofs(),
+            ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
+                                      // preset all values by false
+      std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
+
+      const FiniteElement<dim,spacedim> &fe = dof_handler.get_fe();
+
+                                      // this function is similar to the
+                                      // make_sparsity_pattern function,
+                                      // see there for more information
+      typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+       cell = dof_handler.begin_active(),
+       endc = dof_handler.end();
+      for (; cell!=endc; ++cell)
+       for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+         if (cell->face(face)->has_children()) 
+           {
+             const typename dealii::DoFHandler<dim,spacedim>::line_iterator
+               line = cell->face(face);
 
-         for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
-           selected_dofs[line->child(0)->vertex_dof_index(1,dof)] = true;
+             for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+               selected_dofs[line->child(0)->vertex_dof_index(1,dof)] = true;
          
-         for (unsigned int child=0; child<2; ++child)
-           for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
-             selected_dofs[line->child(child)->dof_index(dof)] = true;
-       };
-}
-
-#endif
-
-
+             for (unsigned int child=0; child<2; ++child)
+               for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+                 selected_dofs[line->child(child)->dof_index(dof)] = true;
+           }
+    }
 
-#if deal_II_dimension == 3
 
-void
-DoFTools::extract_hanging_node_dofs (const DoFHandler<3> &dof_handler,
-                                    std::vector<bool>   &selected_dofs)
-{
-  const unsigned int dim = 3;
+    template <int spacedim>
+    void extract_hanging_node_dofs (const dealii::DoFHandler<3,spacedim> &dof_handler,
+                                    std::vector<bool>           &selected_dofs)
+    {
+      const unsigned int dim = 3;
 
-  Assert(selected_dofs.size() == dof_handler.n_dofs(),
-        ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
-                                  // preset all values by false
-  std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
+      Assert(selected_dofs.size() == dof_handler.n_dofs(),
+            ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
+                                      // preset all values by false
+      std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
 
-  const FiniteElement<dim> &fe   = dof_handler.get_fe();
+      const FiniteElement<dim,spacedim> &fe = dof_handler.get_fe();
   
-                                  // this function is similar to the
-                                  // make_sparsity_pattern function,
-                                  // see there for more information
+                                      // this function is similar to the
+                                      // make_sparsity_pattern function,
+                                      // see there for more information
 
-  DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
-                                       endc = dof_handler.end();
-  for (; cell!=endc; ++cell)
-    for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-      if (cell->face(f)->has_children()) 
-       {
-         const DoFHandler<dim>::face_iterator face = cell->face(f);
+      typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+       cell = dof_handler.begin_active(),
+       endc = dof_handler.end();
+      for (; cell!=endc; ++cell)
+       for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+         if (cell->face(f)->has_children()) 
+           {
+             const typename dealii::DoFHandler<dim,spacedim>::face_iterator
+               face = cell->face(f);
          
-         for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
-           selected_dofs[face->child(0)->vertex_dof_index(2,dof)] = true;
+             for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+               selected_dofs[face->child(0)->vertex_dof_index(2,dof)] = true;
          
-                                          // dof numbers on the centers of
-                                          // the lines bounding this face
-         for (unsigned int line=0; line<4; ++line)
-           for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
-             selected_dofs[face->line(line)->child(0)->vertex_dof_index(1,dof)] = true;
+                                              // dof numbers on the centers of
+                                              // the lines bounding this face
+             for (unsigned int line=0; line<4; ++line)
+               for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+                 selected_dofs[face->line(line)->child(0)->vertex_dof_index(1,dof)] = true;
          
-                                          // next the dofs on the lines interior
-                                          // to the face; the order of these
-                                          // lines is laid down in the
-                                          // FiniteElement class documentation
-         for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
-           selected_dofs[face->child(0)->line(1)->dof_index(dof)] = true;
-         for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
-           selected_dofs[face->child(1)->line(2)->dof_index(dof)] = true;
-         for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
-           selected_dofs[face->child(2)->line(3)->dof_index(dof)] = true;
-         for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
-           selected_dofs[face->child(3)->line(0)->dof_index(dof)] = true;
+                                              // next the dofs on the lines interior
+                                              // to the face; the order of these
+                                              // lines is laid down in the
+                                              // FiniteElement class documentation
+             for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+               selected_dofs[face->child(0)->line(1)->dof_index(dof)] = true;
+             for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+               selected_dofs[face->child(1)->line(2)->dof_index(dof)] = true;
+             for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+               selected_dofs[face->child(2)->line(3)->dof_index(dof)] = true;
+             for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+               selected_dofs[face->child(3)->line(0)->dof_index(dof)] = true;
          
-                                          // dofs on the bordering lines
-         for (unsigned int line=0; line<4; ++line)
-           for (unsigned int child=0; child<2; ++child)
-             for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
-               selected_dofs[face->line(line)->child(child)->dof_index(dof)] = true;
+                                              // dofs on the bordering lines
+             for (unsigned int line=0; line<4; ++line)
+               for (unsigned int child=0; child<2; ++child)
+                 for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+                   selected_dofs[face->line(line)->child(child)->dof_index(dof)] = true;
        
-                                          // finally, for the dofs interior
-                                          // to the four child faces
-         for (unsigned int child=0; child<4; ++child)
-           for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
-             selected_dofs[face->child(child)->dof_index(dof)] = true;
-       };
+                                              // finally, for the dofs interior
+                                              // to the four child faces
+             for (unsigned int child=0; child<4; ++child)
+               for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
+                 selected_dofs[face->child(child)->dof_index(dof)] = true;
+           }
+    }
+  }
 }
 
-#endif
+    
+
+template <int dim, int spacedim>
+void
+DoFTools::
+extract_hanging_node_dofs (const DoFHandler<dim,spacedim> &dof_handler,
+                          std::vector<bool>              &selected_dofs)
+{
+  internal::DoFTools::extract_hanging_node_dofs (dof_handler,
+                                                selected_dofs);
+}
 
 
 
@@ -3775,7 +3793,7 @@ DoFTools::count_dofs_with_subdomain_association (const DH           &dof_handler
 #ifdef DEBUG
   {
     bool found = false;
-    for (typename Triangulation<DH::dimension>::active_cell_iterator
+    for (typename Triangulation<DH::dimension, DH::space_dimension>::active_cell_iterator
            cell=dof_handler.get_tria().begin_active();
          cell!=dof_handler.get_tria().end(); ++cell)
       if (cell->subdomain_id() == subdomain)
@@ -3815,7 +3833,7 @@ DoFTools::count_dofs_with_subdomain_association (const DH           &dof_handler
 #ifdef DEBUG
   {
     bool found = false;
-    for (typename Triangulation<DH::dimension>::active_cell_iterator
+    for (typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator
            cell=dof_handler.get_tria().begin_active();
          cell!=dof_handler.get_tria().end(); ++cell)
       if (cell->subdomain_id() == subdomain)
@@ -3847,15 +3865,15 @@ DoFTools::count_dofs_with_subdomain_association (const DH           &dof_handler
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::count_dofs_per_component (
-  const DoFHandler<dim>&     dof_handler,
+  const DoFHandler<dim,spacedim>&     dof_handler,
   std::vector<unsigned int>& dofs_per_component,
   bool only_once,
   std::vector<unsigned int>  target_component)
 {
-  const FiniteElement<dim>& fe = dof_handler.get_fe();
+  const FiniteElement<dim,spacedim>& fe = dof_handler.get_fe();
   const unsigned int n_components = fe.n_components();
   dofs_per_component.resize (n_components);
   std::fill (dofs_per_component.begin(), dofs_per_component.end(), 0U);
@@ -3896,7 +3914,7 @@ DoFTools::count_dofs_per_component (
   Threads::ThreadGroup<> threads;
   for (unsigned int i=0; i<n_components; ++i)
     {
-      void (*fun_ptr) (const DoFHandler<dim>   &,
+      void (*fun_ptr) (const DoFHandler<dim,spacedim>   &,
                       const std::vector<bool> &,
                       std::vector<bool>       &,
                       bool)
@@ -3911,7 +3929,7 @@ DoFTools::count_dofs_per_component (
   unsigned int component = 0;
   for (unsigned int b=0;b<fe.n_base_elements();++b)
     {
-      const FiniteElement<dim>& base = fe.base_element(b);
+      const FiniteElement<dim,spacedim>& base = fe.base_element(b);
                                       // Dimension of base element
       unsigned int d = base.n_components();
       
@@ -3942,14 +3960,14 @@ DoFTools::count_dofs_per_component (
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::count_dofs_per_block (
-  const DoFHandler<dim>&     dof_handler,
+  const DoFHandler<dim,spacedim>&     dof_handler,
   std::vector<unsigned int>& dofs_per_block,
   std::vector<unsigned int>  target_block)
 {
-  const FiniteElement<dim>& fe = dof_handler.get_fe();
+  const FiniteElement<dim,spacedim>& fe = dof_handler.get_fe();
   const unsigned int n_blocks = fe.n_blocks();
   dofs_per_block.resize (n_blocks);
   std::fill (dofs_per_block.begin(), dofs_per_block.end(), 0U);
@@ -3986,7 +4004,7 @@ DoFTools::count_dofs_per_block (
   Threads::ThreadGroup<> threads;
   for (unsigned int i=0; i<n_blocks; ++i)
     {
-      void (*fun_ptr) (const DoFHandler<dim>   &,
+      void (*fun_ptr) (const DoFHandler<dim,spacedim>   &,
                       const std::vector<bool> &,
                       std::vector<bool>       &,
                       bool)
@@ -4006,10 +4024,10 @@ DoFTools::count_dofs_per_block (
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::count_dofs_per_component (
-  const DoFHandler<dim>&     dof_handler,
+  const DoFHandler<dim,spacedim>&     dof_handler,
   std::vector<unsigned int>& dofs_per_component,
   std::vector<unsigned int>  target_component)
 {
@@ -4017,14 +4035,14 @@ DoFTools::count_dofs_per_component (
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::compute_intergrid_constraints (
-  const DoFHandler<dim>              &coarse_grid,
+  const DoFHandler<dim,spacedim>              &coarse_grid,
   const unsigned int                  coarse_component,
-  const DoFHandler<dim>              &fine_grid,
+  const DoFHandler<dim,spacedim>              &fine_grid,
   const unsigned int                  fine_component,
-  const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+  const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
   ConstraintMatrix                   &constraints)
 {
                                   // store the weights with which a dof
@@ -4240,15 +4258,15 @@ DoFTools::compute_intergrid_constraints (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::
 compute_intergrid_transfer_representation (
-  const DoFHandler<dim>              &coarse_grid,
+  const DoFHandler<dim,spacedim>              &coarse_grid,
   const unsigned int                  coarse_component,
-  const DoFHandler<dim>              &fine_grid,
+  const DoFHandler<dim,spacedim>              &fine_grid,
   const unsigned int                  fine_component,
-  const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+  const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
   std::vector<std::map<unsigned int, float> > &transfer_representation)
 {
                                   // store the weights with which a dof
@@ -4311,7 +4329,7 @@ compute_intergrid_transfer_representation (
                                   // first construct the inverse
                                   // mapping of weight_mapping
   std::vector<unsigned int> inverse_weight_mapping (n_global_parm_dofs,
-                                                   DoFHandler<dim>::invalid_dof_index);
+                                                   DoFHandler<dim,spacedim>::invalid_dof_index);
   for (unsigned int i=0; i<weight_mapping.size(); ++i)
     {
       const unsigned int parameter_dof = weight_mapping[i];
@@ -4320,7 +4338,7 @@ compute_intergrid_transfer_representation (
       if (parameter_dof != numbers::invalid_unsigned_int)
        {
          Assert (parameter_dof < n_global_parm_dofs, ExcInternalError());
-         Assert (inverse_weight_mapping[parameter_dof] == DoFHandler<dim>::invalid_dof_index,
+         Assert ((inverse_weight_mapping[parameter_dof] == DoFHandler<dim,spacedim>::invalid_dof_index),
                  ExcInternalError());
          
          inverse_weight_mapping[parameter_dof] = i;
@@ -4351,20 +4369,20 @@ compute_intergrid_transfer_representation (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
 DoFTools::compute_intergrid_weights_1 (
-  const DoFHandler<dim>              &coarse_grid,
+  const DoFHandler<dim,spacedim>              &coarse_grid,
   const unsigned int                  coarse_component,
-  const DoFHandler<dim>              &fine_grid,
+  const DoFHandler<dim,spacedim>              &fine_grid,
   const unsigned int                  fine_component,
-  const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+  const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
   std::vector<std::map<unsigned int, float> > &weights,
   std::vector<int>                   &weight_mapping)
 {
                                   // aliases to the finite elements
                                   // used by the dof handlers:
-  const FiniteElement<dim> &coarse_fe = coarse_grid.get_fe(),
+  const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe(),
                           &fine_fe   = fine_grid.get_fe();
 
                                   // global numbers of dofs
@@ -4416,7 +4434,7 @@ DoFTools::compute_intergrid_weights_1 (
                                   // the coarse grid is indeed
                                   // coarser everywhere than the fine
                                   // grid
-  for (typename DoFHandler<dim>::active_cell_iterator cell=coarse_grid.begin_active();
+  for (typename DoFHandler<dim,spacedim>::active_cell_iterator cell=coarse_grid.begin_active();
        cell != coarse_grid.end(); ++cell)
     Assert (cell->level() <= coarse_to_fine_grid_map[cell]->level(),
            ExcGridNotCoarser());
@@ -4482,7 +4500,7 @@ DoFTools::compute_intergrid_weights_1 (
       std::vector<bool> dof_is_interesting (fine_grid.n_dofs(), false);
       std::vector<unsigned int>  local_dof_indices (fine_fe.dofs_per_cell);
       
-      for (typename DoFHandler<dim>::active_cell_iterator
+      for (typename DoFHandler<dim,spacedim>::active_cell_iterator
             cell=fine_grid.begin_active();
           cell!=fine_grid.end(); ++cell)
        {
@@ -4509,7 +4527,7 @@ DoFTools::compute_intergrid_weights_1 (
     {
       std::vector<unsigned int> local_dof_indices(fine_fe.dofs_per_cell);
       unsigned int next_free_index=0;
-      for (typename DoFHandler<dim>::active_cell_iterator cell=fine_grid.begin_active();
+      for (typename DoFHandler<dim,spacedim>::active_cell_iterator cell=fine_grid.begin_active();
           cell != fine_grid.end(); ++cell)
        {
          cell->get_dof_indices (local_dof_indices);
@@ -4588,33 +4606,33 @@ DoFTools::compute_intergrid_weights_1 (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::compute_intergrid_weights_2 (
-  const DoFHandler<dim>              &coarse_grid,
+  const DoFHandler<dim,spacedim>              &coarse_grid,
   const unsigned int                  coarse_component,
-  const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+  const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
   const std::vector<Vector<double> > &parameter_dofs,
   const std::vector<int>             &weight_mapping,
   std::vector<std::map<unsigned int,float> > &weights)
 {
                                   // simply distribute the range of
                                   // cells to different threads
-  typedef typename DoFHandler<dim>::active_cell_iterator active_cell_iterator;
+  typedef typename DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
     cell_intervals = Threads::split_range<active_cell_iterator> (coarse_grid.begin_active(),
                                                                 coarse_grid.end(),
                                                                 multithread_info.n_default_threads);
 
   Threads::ThreadGroup<> threads;
-  void (*fun_ptr) (const DoFHandler<dim>              &,
+  void (*fun_ptr) (const DoFHandler<dim,spacedim>              &,
                   const unsigned int                  ,
-                  const InterGridMap<DoFHandler<dim> > &,
+                  const InterGridMap<DoFHandler<dim,spacedim> > &,
                   const std::vector<Vector<double> > &,
                   const std::vector<int>             &,
                   std::vector<std::map<unsigned int, float> > &,
-                  const typename DoFHandler<dim>::active_cell_iterator &,
-                  const typename DoFHandler<dim>::active_cell_iterator &)
+                  const typename DoFHandler<dim,spacedim>::active_cell_iterator &,
+                  const typename DoFHandler<dim,spacedim>::active_cell_iterator &)
     = &DoFTools::template compute_intergrid_weights_3<dim>;
   for (unsigned int i=0; i<multithread_info.n_default_threads; ++i)
     threads += Threads::spawn (fun_ptr)(coarse_grid, coarse_component,
@@ -4629,21 +4647,21 @@ DoFTools::compute_intergrid_weights_2 (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::compute_intergrid_weights_3 (
-  const DoFHandler<dim>              &coarse_grid,
+  const DoFHandler<dim,spacedim>              &coarse_grid,
   const unsigned int                  coarse_component,
-  const InterGridMap<DoFHandler<dim> > &coarse_to_fine_grid_map,
+  const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
   const std::vector<Vector<double> > &parameter_dofs,
   const std::vector<int>             &weight_mapping,
   std::vector<std::map<unsigned int, float> > &weights,
-  const typename DoFHandler<dim>::active_cell_iterator &begin,
-  const typename DoFHandler<dim>::active_cell_iterator &end)
+  const typename DoFHandler<dim,spacedim>::active_cell_iterator &begin,
+  const typename DoFHandler<dim,spacedim>::active_cell_iterator &end)
 {
                                   // aliases to the finite elements
                                   // used by the dof handlers:
-  const FiniteElement<dim> &coarse_fe = coarse_grid.get_fe();    
+  const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe();    
 
                                   // for each cell on the parameter grid:
                                   // find out which degrees of freedom on the
@@ -4717,7 +4735,7 @@ DoFTools::compute_intergrid_weights_3 (
   const unsigned int n_fine_dofs = weight_mapping.size();
   Vector<double> global_parameter_representation (n_fine_dofs);
   
-  typename DoFHandler<dim>::active_cell_iterator cell;
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell;
   std::vector<unsigned int> parameter_dof_indices (coarse_fe.dofs_per_cell);
   
   for (cell=begin; cell!=end; ++cell)
@@ -4975,10 +4993,10 @@ void DoFTools::map_dof_to_boundary_indices (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-DoFTools::map_dofs_to_support_points (const Mapping<dim>       &mapping,
-                                     const DoFHandler<dim>    &dof_handler,
+DoFTools::map_dofs_to_support_points (const Mapping<dim,spacedim>       &mapping,
+                                     const DoFHandler<dim,spacedim>    &dof_handler,
                                      std::vector<Point<dim> > &support_points)
 {
   const unsigned int dofs_per_cell = dof_handler.get_fe().dofs_per_cell;
@@ -5005,7 +5023,7 @@ DoFTools::map_dofs_to_support_points (const Mapping<dim>       &mapping,
   Quadrature<dim> q_dummy(dof_handler.get_fe().get_unit_support_points());
   FEValues<dim> fe_values (mapping, dof_handler.get_fe(),
                           q_dummy, update_quadrature_points);
-  typename DoFHandler<dim>::active_cell_iterator
+  typename DoFHandler<dim,spacedim>::active_cell_iterator
     cell = dof_handler.begin_active(),
     endc = dof_handler.end();
 
@@ -5022,12 +5040,12 @@ DoFTools::map_dofs_to_support_points (const Mapping<dim>       &mapping,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 DoFTools::compute_dof_couplings(
   Table<2,Coupling>&        dof_couplings,
   const Table<2,Coupling>&  component_couplings,
-  const FiniteElement<dim>& fe)
+  const FiniteElement<dim,spacedim>& fe)
 {
   Assert(component_couplings.n_rows() == fe.n_components(),
         ExcDimensionMismatch(component_couplings.n_rows(),
@@ -5079,14 +5097,14 @@ DoFTools::compute_dof_couplings(
 }
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
 DoFTools::convert_couplings_to_blocks (
-  const DoFHandler<dim>& dof_handler,
+  const DoFHandler<dim,spacedim>& dof_handler,
   const Table<2, Coupling>& table,
   std::vector<Table<2,Coupling> >& tables_by_block)
 {
-  const FiniteElement<dim>& fe = dof_handler.get_fe();
+  const FiniteElement<dim,spacedim>& fe = dof_handler.get_fe();
   const unsigned int nb = fe.n_blocks();
   
   tables_by_block.resize(1);
@@ -5105,10 +5123,10 @@ DoFTools::convert_couplings_to_blocks (
 }
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
 DoFTools::convert_couplings_to_blocks (
-  const hp::DoFHandler<dim>& dof_handler,
+  const hp::DoFHandler<dim,spacedim>& dof_handler,
   const Table<2, Coupling>& table,
   std::vector<Table<2,Coupling> >& tables_by_block)
 {
@@ -5117,7 +5135,7 @@ DoFTools::convert_couplings_to_blocks (
 
   for (unsigned int f=0;f<fe_collection.size();++f)
     {
-      const FiniteElement<dim>& fe = fe_collection[f];
+      const FiniteElement<dim,spacedim>& fe = fe_collection[f];
       
       const unsigned int nb = fe.n_blocks();
       tables_by_block[f].reinit(nb, nb);
@@ -5136,9 +5154,9 @@ DoFTools::convert_couplings_to_blocks (
 
 #if deal_II_dimension == 1
 
-template <int dim, template <int> class DH> 
+template <int dim, int spacedim, template <int,int> class DH> 
 void 
-DoFTools::make_zero_boundary_constraints (const DH<dim>           &dof,  
+DoFTools::make_zero_boundary_constraints (const DH<dim, spacedim> &dof,  
                                          ConstraintMatrix        &zero_boundary_constraints,
                                          const std::vector<bool> &component_mask_) 
 {
@@ -5160,7 +5178,7 @@ DoFTools::make_zero_boundary_constraints (const DH<dim>           &dof,
                                    // cell by traversing the coarse
                                    // grid to its end and then looking
                                    // for the children
-      typename DH<dim>::cell_iterator outermost_cell = dof.begin(0);
+      typename DH<dim,spacedim>::cell_iterator outermost_cell = dof.begin(0);
       while (outermost_cell->neighbor(direction).state() == IteratorState::valid)
        outermost_cell = outermost_cell->neighbor(direction);
       
@@ -5169,7 +5187,7 @@ DoFTools::make_zero_boundary_constraints (const DH<dim>           &dof,
 
                                    // then get the FE corresponding to
                                    // this cell
-      const FiniteElement<dim> &fe = outermost_cell->get_fe();
+      const FiniteElement<dim,spacedim> &fe = outermost_cell->get_fe();
 
                                   // set the component mask to either
                                   // the original value or a vector
@@ -5192,9 +5210,9 @@ DoFTools::make_zero_boundary_constraints (const DH<dim>           &dof,
 
 #else
 
-template <int dim, template <int> class DH> 
+template <int dim, int spacedim, template <int,int> class DH> 
 void 
-DoFTools::make_zero_boundary_constraints (const DH<dim>           &dof,  
+DoFTools::make_zero_boundary_constraints (const DH<dim, spacedim> &dof,  
                                          ConstraintMatrix        &zero_boundary_constraints,
                                          const std::vector<bool> &component_mask_) 
 {
@@ -5220,13 +5238,14 @@ DoFTools::make_zero_boundary_constraints (const DH<dim>           &dof,
   std::vector<unsigned int> face_dofs;
   face_dofs.reserve (DoFTools::max_dofs_per_face(dof));
 
-  typename DH<dim>::active_cell_iterator cell = dof.begin_active(),
-                                        endc = dof.end();
+  typename DH<dim,spacedim>::active_cell_iterator
+    cell = dof.begin_active(),
+    endc = dof.end();
   for (; cell!=endc; ++cell)
     for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
         ++face_no)
       {
-        const FiniteElement<dim> &fe = cell->get_fe();
+        const FiniteElement<dim,spacedim> &fe = cell->get_fe();
 
                                   // we can presently deal only with
                                   // primitive elements for boundary
@@ -5248,7 +5267,7 @@ DoFTools::make_zero_boundary_constraints (const DH<dim>           &dof,
                                    "elements"));
          }
 
-       typename DH<dim>::face_iterator face = cell->face(face_no);
+       typename DH<dim,spacedim>::face_iterator face = cell->face(face_no);
        if (face->boundary_indicator () == 0)
                                   // face is of the right component
          {
@@ -6073,6 +6092,12 @@ DoFTools::extract_boundary_dofs<hp::DoFHandler<deal_II_dimension> >
  std::vector<bool>                        &,
  const std::set<unsigned char> &);
 
+template
+void
+DoFTools::extract_hanging_node_dofs
+(const DoFHandler<deal_II_dimension> &dof_handler,
+ std::vector<bool>     &selected_dofs);
+
 template
 void
 DoFTools::extract_subdomain_dofs<DoFHandler<deal_II_dimension> >
@@ -6229,7 +6254,7 @@ DoFTools::map_dof_to_boundary_indices<hp::DoFHandler<deal_II_dimension> >
 template
 void
 DoFTools::map_dofs_to_support_points<deal_II_dimension>
-(const Mapping<deal_II_dimension>&,
+(const Mapping<deal_II_dimension,deal_II_dimension>&,
  const DoFHandler<deal_II_dimension>&,
  std::vector<Point<deal_II_dimension> >&);
 
@@ -6253,9 +6278,448 @@ DoFTools::convert_couplings_to_blocks (
 
 template 
 void 
-DoFTools::make_zero_boundary_constraints<deal_II_dimension>
+DoFTools::make_zero_boundary_constraints
 (const DoFHandler<deal_II_dimension> &, 
  ConstraintMatrix                    &,
  const std::vector<bool>             &);
 
+#if deal_II_dimension !=3
+
+// explicit instantiations
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               SparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+ SparsityPattern    &sparsity,
+ const ConstraintMatrix &,
+ const bool);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               CompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+ CompressedSparsityPattern    &sparsity,
+ const ConstraintMatrix &,
+ const bool);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               CompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+ CompressedSetSparsityPattern    &sparsity,
+ const ConstraintMatrix &,
+ const bool);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               BlockSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+ BlockSparsityPattern                &sparsity,
+ const ConstraintMatrix &,
+ const bool);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               BlockCompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+ BlockCompressedSparsityPattern      &sparsity,
+ const ConstraintMatrix &,
+ const bool);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               BlockCompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+ BlockCompressedSetSparsityPattern      &sparsity,
+ const ConstraintMatrix &,
+ const bool);
+
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             SparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+//  SparsityPattern    &sparsity,
+//  const ConstraintMatrix &);
+
+
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             CompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+//  CompressedSparsityPattern    &sparsity,
+//  const ConstraintMatrix &);
+
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             CompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+//  CompressedSetSparsityPattern    &sparsity,
+//  const ConstraintMatrix &);
+
+
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             BlockSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+//  BlockSparsityPattern                &sparsity,
+//  const ConstraintMatrix &);
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             BlockCompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+//  BlockCompressedSparsityPattern      &sparsity,
+//  const ConstraintMatrix &);
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             BlockCompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+//  BlockCompressedSetSparsityPattern      &sparsity,
+//  const ConstraintMatrix &);
+
+
+template void 
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               SparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+ const Table<2,Coupling>&,
+ SparsityPattern&,
+ const ConstraintMatrix&,
+ const bool);
+template void 
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               CompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+ const Table<2,Coupling>&,
+ CompressedSparsityPattern&,
+ const ConstraintMatrix&,
+ const bool);
+template void 
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               CompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+ const Table<2,Coupling>&,
+ CompressedSetSparsityPattern&,
+ const ConstraintMatrix&,
+ const bool);
+template void 
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               BlockSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+ const Table<2,Coupling>&,
+ BlockSparsityPattern&,
+ const ConstraintMatrix&,
+ const bool);
+template void 
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               BlockCompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+ const Table<2,Coupling>&,
+ BlockCompressedSparsityPattern&,
+ const ConstraintMatrix&,
+ const bool);
+template void 
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               BlockCompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+ const Table<2,Coupling>&,
+ BlockCompressedSetSparsityPattern&,
+ const ConstraintMatrix&,
+ const bool);
+
+
+// template void 
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             SparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+//  const Table<2,Coupling>&,
+//  SparsityPattern&);
+// template void 
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             CompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+//  const Table<2,Coupling>&,
+//  CompressedSparsityPattern&);
+// template void 
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             CompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+//  const Table<2,Coupling>&,
+//  CompressedSetSparsityPattern&);
+// template void 
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             BlockSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+//  const Table<2,Coupling>&,
+//  BlockSparsityPattern&);
+// template void 
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             BlockCompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+//  const Table<2,Coupling>&,
+//  BlockCompressedSparsityPattern&);
+// template void 
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             BlockCompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+//  const Table<2,Coupling>&,
+//  BlockCompressedSetSparsityPattern&);
+
+
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               SparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+ SparsityPattern    &sparsity);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               CompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+ CompressedSparsityPattern    &sparsity);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               CompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+ CompressedSetSparsityPattern    &sparsity);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               BlockSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+ BlockSparsityPattern                &sparsity);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               BlockCompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+ BlockCompressedSparsityPattern      &sparsity);
+template void
+DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+                               BlockCompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+ BlockCompressedSetSparsityPattern      &sparsity);
+
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             SparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+//  const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+//  SparsityPattern    &sparsity);
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             CompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+//  const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+//  CompressedSparsityPattern    &sparsity);
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             CompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+//  const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+//  CompressedSetSparsityPattern    &sparsity);
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             BlockSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+//  const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+//  BlockSparsityPattern                &sparsity);
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             BlockCompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+//  const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+//  BlockCompressedSparsityPattern      &sparsity);
+// template void
+// DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,
+//                             BlockCompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+//  const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+//  BlockCompressedSetSparsityPattern      &sparsity);
+
+
+// #if deal_II_dimension > 1
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,SparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const std::vector<unsigned int>  &,
+ SparsityPattern    &);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,CompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const std::vector<unsigned int>  &,
+ CompressedSparsityPattern    &);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,CompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const std::vector<unsigned int>  &,
+ CompressedSetSparsityPattern    &);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const std::vector<unsigned int>  &,
+ BlockSparsityPattern    &);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockCompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const std::vector<unsigned int>  &,
+ BlockCompressedSparsityPattern    &);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockCompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const std::vector<unsigned int>  &,
+ BlockCompressedSetSparsityPattern    &);
+
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,SparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const std::vector<unsigned int>  &,
+//  SparsityPattern    &);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,CompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const std::vector<unsigned int>  &,
+//  CompressedSparsityPattern    &);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,CompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const std::vector<unsigned int>  &,
+//  CompressedSetSparsityPattern    &);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const std::vector<unsigned int>  &,
+//  BlockSparsityPattern    &);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockCompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const std::vector<unsigned int>  &,
+//  BlockCompressedSparsityPattern    &);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockCompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const std::vector<unsigned int>  &,
+//  BlockCompressedSetSparsityPattern    &);
+
+
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,SparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+ const std::vector<unsigned int>  &dof_to_boundary_mapping,
+ SparsityPattern    &sparsity);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,CompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+ const std::vector<unsigned int>  &dof_to_boundary_mapping,
+ CompressedSparsityPattern    &sparsity);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,CompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+ const std::vector<unsigned int>  &dof_to_boundary_mapping,
+ CompressedSetSparsityPattern    &sparsity);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+ const std::vector<unsigned int>  &dof_to_boundary_mapping,
+ BlockSparsityPattern    &sparsity);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockCompressedSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+ const std::vector<unsigned int>  &dof_to_boundary_mapping,
+ BlockCompressedSparsityPattern    &sparsity);
+template void
+DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockCompressedSetSparsityPattern>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+ const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+ const std::vector<unsigned int>  &dof_to_boundary_mapping,
+ BlockCompressedSetSparsityPattern    &sparsity);
+
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,SparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+//  const std::vector<unsigned int>  &dof_to_boundary_mapping,
+//  SparsityPattern    &sparsity);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,CompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+//  const std::vector<unsigned int>  &dof_to_boundary_mapping,
+//  CompressedSparsityPattern    &sparsity);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,CompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+//  const std::vector<unsigned int>  &dof_to_boundary_mapping,
+//  CompressedSetSparsityPattern    &sparsity);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+//  const std::vector<unsigned int>  &dof_to_boundary_mapping,
+//  BlockSparsityPattern    &sparsity);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockCompressedSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+//  const std::vector<unsigned int>  &dof_to_boundary_mapping,
+//  BlockCompressedSparsityPattern    &sparsity);
+// template void
+// DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,BlockCompressedSetSparsityPattern>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+//  const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+//  const std::vector<unsigned int>  &dof_to_boundary_mapping,
+//  BlockCompressedSetSparsityPattern    &sparsity);
+
+
+template
+void
+DoFTools::map_dof_to_boundary_indices<DoFHandler<deal_II_dimension,deal_II_dimension+1> >
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &,
+ const std::set<unsigned char> &,
+ std::vector<unsigned int> &);
+
+#if deal_II_dimension != 1
+
+template
+void
+DoFTools::map_dof_to_boundary_indices<DoFHandler<deal_II_dimension,deal_II_dimension+1> >
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &,
+ std::vector<unsigned int> &);
+
+#endif
+
+
+template
+void
+DoFTools::extract_hanging_node_dofs
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_handler,
+ std::vector<bool>     &selected_dofs);
+
+// template
+// void
+// DoFTools::map_dof_to_boundary_indices<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> >
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &,
+//  const std::set<unsigned char> &,
+//  std::vector<unsigned int> &);
+
+// #if deal_II_dimension != 1
+
+// template
+// void
+// DoFTools::map_dof_to_boundary_indices<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> >
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &,
+//  std::vector<unsigned int> &);
+
+// #endif
+
+
+
+#endif
+
+
+
+
 DEAL_II_NAMESPACE_CLOSE
index 6ee95da79914be225718435a9fd1563e8a3c5135..87d25560d66d124efe9533c84703819aa2603790 100644 (file)
@@ -33,15 +33,15 @@ DEAL_II_NAMESPACE_OPEN
 /*------------------------------- FiniteElement ----------------------*/
 
 
-template <int dim>
-const double FiniteElement<dim>::fd_step_length = 1.0e-6;
+template <int dim, int spacedim>  
+const double FiniteElement<dim,spacedim>::fd_step_length = 1.0e-6;
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FiniteElement<dim>::
-InternalDataBase::initialize_2nd (const FiniteElement<dim> *element,
-                                 const Mapping<dim>       &mapping,
+FiniteElement<dim,spacedim>::
+InternalDataBase::initialize_2nd (const FiniteElement<dim,spacedim> *element,
+                                 const Mapping<dim,spacedim>       &mapping,
                                  const Quadrature<dim>    &quadrature)
 {
                                   // if we shall compute second
@@ -74,14 +74,14 @@ InternalDataBase::initialize_2nd (const FiniteElement<dim> *element,
       for (unsigned int i=0; i<diff_points.size(); ++i)
        diff_points[i] = quadrature.point(i) + shift;
       const Quadrature<dim> plus_quad (diff_points, quadrature.get_weights());
-      differences[d] = new FEValues<dim> (mapping, *element,
+      differences[d] = new FEValues<dim,spacedim> (mapping, *element,
                                          plus_quad, update_gradients);
 
                                       // now same in minus-direction
       for (unsigned int i=0; i<diff_points.size(); ++i)
        diff_points[i] = quadrature.point(i) - shift;
       const Quadrature<dim> minus_quad (diff_points, quadrature.get_weights());
-      differences[d+dim] = new FEValues<dim> (mapping, *element,
+      differences[d+dim] = new FEValues<dim,spacedim> (mapping, *element,
                                              minus_quad, update_gradients); 
     }
 }
@@ -89,8 +89,8 @@ InternalDataBase::initialize_2nd (const FiniteElement<dim> *element,
 
 
 
-template <int dim>
-FiniteElement<dim>::InternalDataBase::~InternalDataBase ()
+template <int dim, int spacedim>  
+FiniteElement<dim,spacedim>::InternalDataBase::~InternalDataBase ()
 {
   for (unsigned int i=0; i<differences.size (); ++i)
     if (differences[i] != 0)
@@ -106,8 +106,8 @@ FiniteElement<dim>::InternalDataBase::~InternalDataBase ()
 
 
 
-template <int dim>
-FiniteElement<dim>::FiniteElement (
+template <int dim, int spacedim>  
+FiniteElement<dim,spacedim>::FiniteElement (
   const FiniteElementData<dim> &fe_data,
   const std::vector<bool> &r_i_a_f,
   const std::vector<std::vector<bool> > &nonzero_c)
@@ -231,16 +231,16 @@ FiniteElement<dim>::FiniteElement (
 
 
 
-template <int dim>
-FiniteElement<dim>::~FiniteElement ()
+template <int dim, int spacedim>  
+FiniteElement<dim,spacedim>::~FiniteElement ()
 {}
 
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 double
-FiniteElement<dim>::shape_value (const unsigned int,
+FiniteElement<dim,spacedim>::shape_value (const unsigned int,
                                     const Point<dim> &) const
 {
   AssertThrow(false, ExcUnitShapeValuesDoNotExist());
@@ -249,9 +249,9 @@ FiniteElement<dim>::shape_value (const unsigned int,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 double
-FiniteElement<dim>::shape_value_component (const unsigned int,
+FiniteElement<dim,spacedim>::shape_value_component (const unsigned int,
                                               const Point<dim> &,
                                               const unsigned int) const
 {
@@ -261,9 +261,9 @@ FiniteElement<dim>::shape_value_component (const unsigned int,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Tensor<1,dim>
-FiniteElement<dim>::shape_grad (const unsigned int,
+FiniteElement<dim,spacedim>::shape_grad (const unsigned int,
                                    const Point<dim> &) const
 {
   AssertThrow(false, ExcUnitShapeValuesDoNotExist());
@@ -272,9 +272,9 @@ FiniteElement<dim>::shape_grad (const unsigned int,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Tensor<1,dim>
-FiniteElement<dim>::shape_grad_component (const unsigned int,
+FiniteElement<dim,spacedim>::shape_grad_component (const unsigned int,
                                              const Point<dim> &,
                                              const unsigned int) const
 {
@@ -284,9 +284,9 @@ FiniteElement<dim>::shape_grad_component (const unsigned int,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Tensor<2,dim>
-FiniteElement<dim>::shape_grad_grad (const unsigned int,
+FiniteElement<dim,spacedim>::shape_grad_grad (const unsigned int,
                                         const Point<dim> &) const
 {
   AssertThrow(false, ExcUnitShapeValuesDoNotExist());
@@ -295,9 +295,9 @@ FiniteElement<dim>::shape_grad_grad (const unsigned int,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Tensor<2,dim>
-FiniteElement<dim>::shape_grad_grad_component (const unsigned int,
+FiniteElement<dim,spacedim>::shape_grad_grad_component (const unsigned int,
                                                   const Point<dim> &,
                                                   const unsigned int) const
 {
@@ -306,10 +306,9 @@ FiniteElement<dim>::shape_grad_grad_component (const unsigned int,
 }
 
 
-
-template <int dim>
+template <int dim, int spacedim>  
 void
-FiniteElement<dim>::reinit_restriction_and_prolongation_matrices (
+FiniteElement<dim,spacedim>::reinit_restriction_and_prolongation_matrices (
   const bool isotropic_restriction_only,
   const bool isotropic_prolongation_only)
 {
@@ -331,10 +330,10 @@ FiniteElement<dim>::reinit_restriction_and_prolongation_matrices (
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 const FullMatrix<double> &
-FiniteElement<dim>::get_restriction_matrix (const unsigned int child,
-                                           const RefinementCase<dim> &refinement_case) const
+FiniteElement<dim,spacedim>::get_restriction_matrix (const unsigned int child,
+                                                    const RefinementCase<dim> &refinement_case) const
 {
   Assert (refinement_case<RefinementCase<dim>::isotropic_refinement+1,
          ExcIndexRange(refinement_case,0,RefinementCase<dim>::isotropic_refinement+1));
@@ -353,10 +352,10 @@ FiniteElement<dim>::get_restriction_matrix (const unsigned int child,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 const FullMatrix<double> &
-FiniteElement<dim>::get_prolongation_matrix (const unsigned int child,
-                                            const RefinementCase<dim> &refinement_case) const
+FiniteElement<dim,spacedim>::get_prolongation_matrix (const unsigned int child,
+                                                     const RefinementCase<dim> &refinement_case) const
 {
   Assert (refinement_case<RefinementCase<dim>::isotropic_refinement+1,
          ExcIndexRange(refinement_case,0,RefinementCase<dim>::isotropic_refinement+1));
@@ -375,9 +374,9 @@ FiniteElement<dim>::get_prolongation_matrix (const unsigned int child,
 
 
 //TODO:[GK] This is probably not the most efficient way of doing this.
-template <int dim>  
+template <int dim, int spacedim>    
 unsigned int
-FiniteElement<dim>::component_to_block_index (const unsigned int index) const
+FiniteElement<dim,spacedim>::component_to_block_index (const unsigned int index) const
 {
   Assert (index < this->n_components(),
          ExcIndexRange(index, 0, this->n_components()));
@@ -387,9 +386,9 @@ FiniteElement<dim>::component_to_block_index (const unsigned int index) const
 }
 
 
-template <int dim>
+template <int dim, int spacedim>  
 unsigned int
-FiniteElement<dim>::adjust_quad_dof_index_for_face_orientation (const unsigned int index,
+FiniteElement<dim,spacedim>::adjust_quad_dof_index_for_face_orientation (const unsigned int index,
                                                                const bool,
                                                                const bool,
                                                                const bool) const
@@ -430,9 +429,9 @@ FiniteElement<3>::adjust_quad_dof_index_for_face_orientation (const unsigned int
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 unsigned int
-FiniteElement<dim>::adjust_line_dof_index_for_line_orientation (const unsigned int index,
+FiniteElement<dim,spacedim>::adjust_line_dof_index_for_line_orientation (const unsigned int index,
                                                                const bool) const
 {
                                   // general template for 1D and 2D: do
@@ -462,9 +461,9 @@ FiniteElement<3>::adjust_line_dof_index_for_line_orientation (const unsigned int
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::prolongation_is_implemented () const
+FiniteElement<dim,spacedim>::prolongation_is_implemented () const
 {
   for (unsigned int ref_case=RefinementCase<dim>::cut_x;
        ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
@@ -486,9 +485,9 @@ FiniteElement<dim>::prolongation_is_implemented () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FiniteElement<dim>::restriction_is_implemented () const
+FiniteElement<dim,spacedim>::restriction_is_implemented () const
 {
   for (unsigned int ref_case=RefinementCase<dim>::cut_x;
        ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
@@ -510,9 +509,9 @@ FiniteElement<dim>::restriction_is_implemented () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FiniteElement<dim>::isotropic_prolongation_is_implemented () const
+FiniteElement<dim,spacedim>::isotropic_prolongation_is_implemented () const
 {
   const RefinementCase<dim> ref_case=RefinementCase<dim>::isotropic_refinement;
   
@@ -534,9 +533,9 @@ FiniteElement<dim>::isotropic_prolongation_is_implemented () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::isotropic_restriction_is_implemented () const
+FiniteElement<dim,spacedim>::isotropic_restriction_is_implemented () const
 {
   const RefinementCase<dim> ref_case = RefinementCase<dim>::isotropic_refinement;
 
@@ -558,9 +557,9 @@ FiniteElement<dim>::isotropic_restriction_is_implemented () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::constraints_are_implemented (const internal::SubfaceCase<dim> &subface_case) const
+FiniteElement<dim,spacedim>::constraints_are_implemented (const internal::SubfaceCase<dim> &subface_case) const
 {
   if (subface_case==internal::SubfaceCase<dim>::case_isotropic)
     return (this->dofs_per_face  == 0) || (interface_constraints.m() != 0);
@@ -570,18 +569,18 @@ FiniteElement<dim>::constraints_are_implemented (const internal::SubfaceCase<dim
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::hp_constraints_are_implemented () const
+FiniteElement<dim,spacedim>::hp_constraints_are_implemented () const
 {
   return false;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 const FullMatrix<double> &
-FiniteElement<dim>::constraints (const internal::SubfaceCase<dim> &subface_case) const
+FiniteElement<dim,spacedim>::constraints (const internal::SubfaceCase<dim> &subface_case) const
 {
   Assert (subface_case==internal::SubfaceCase<dim>::case_isotropic, ExcConstraintsVoid());
   Assert ((this->dofs_per_face  == 0) || (interface_constraints.m() != 0),
@@ -597,9 +596,9 @@ FiniteElement<dim>::constraints (const internal::SubfaceCase<dim> &subface_case)
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 TableIndices<2>
-FiniteElement<dim>::interface_constraints_size () const 
+FiniteElement<dim,spacedim>::interface_constraints_size () const 
 {
   switch (dim)
     {
@@ -623,59 +622,61 @@ FiniteElement<dim>::interface_constraints_size () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FiniteElement<dim>::
-get_interpolation_matrix (const FiniteElement<dim> &,
+FiniteElement<dim,spacedim>::
+get_interpolation_matrix (const FiniteElement<dim,spacedim> &,
                          FullMatrix<double>           &) const
 {
                                   // by default, no interpolation
                                   // implemented. so throw exception,
                                   // as documentation says
+  typedef FiniteElement<dim,spacedim> FEE;
   AssertThrow (false,
-               typename FiniteElement<dim>::
-               ExcInterpolationNotImplemented());
+               typename FEE::
+               ExcInterpolationNotImplemented());
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FiniteElement<dim>::
-get_face_interpolation_matrix (const FiniteElement<dim> &,
+FiniteElement<dim,spacedim>::
+get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &,
                               FullMatrix<double>           &) const
 {
                                   // by default, no interpolation
                                   // implemented. so throw exception,
                                   // as documentation says
+  typedef    FiniteElement<dim,spacedim> FEE;
   AssertThrow (false,
-               typename FiniteElement<dim>::
+               typename FEE::
                ExcInterpolationNotImplemented());
 }
                                    
 
                                    
-template <int dim>
+template <int dim, int spacedim>  
 void
-FiniteElement<dim>::
-get_subface_interpolation_matrix (const FiniteElement<dim> &,
+FiniteElement<dim,spacedim>::
+get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &,
                                  const unsigned int,
                                  FullMatrix<double>           &) const
 {
                                   // by default, no interpolation
                                   // implemented. so throw exception,
                                   // as documentation says
+  typedef    FiniteElement<dim,spacedim> FEE;
   AssertThrow (false,
-               typename FiniteElement<dim>::
-               ExcInterpolationNotImplemented());
+               typename FEE::ExcInterpolationNotImplemented());
 }
                                    
 
 
-template <int dim>
+template <int dim, int spacedim>  
 std::vector<std::pair<unsigned int, unsigned int> >
-FiniteElement<dim>::
-hp_vertex_dof_identities (const FiniteElement<dim> &) const
+FiniteElement<dim,spacedim>::
+hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &) const
 {
   Assert (false, ExcNotImplemented());
   return std::vector<std::pair<unsigned int, unsigned int> > ();
@@ -683,10 +684,10 @@ hp_vertex_dof_identities (const FiniteElement<dim> &) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 std::vector<std::pair<unsigned int, unsigned int> >
-FiniteElement<dim>::
-hp_line_dof_identities (const FiniteElement<dim> &) const
+FiniteElement<dim,spacedim>::
+hp_line_dof_identities (const FiniteElement<dim,spacedim> &) const
 {
   Assert (false, ExcNotImplemented());
   return std::vector<std::pair<unsigned int, unsigned int> > ();
@@ -694,10 +695,10 @@ hp_line_dof_identities (const FiniteElement<dim> &) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 std::vector<std::pair<unsigned int, unsigned int> >
-FiniteElement<dim>::
-hp_quad_dof_identities (const FiniteElement<dim> &) const
+FiniteElement<dim,spacedim>::
+hp_quad_dof_identities (const FiniteElement<dim,spacedim> &) const
 {
   Assert (false, ExcNotImplemented());
   return std::vector<std::pair<unsigned int, unsigned int> > ();
@@ -705,10 +706,10 @@ hp_quad_dof_identities (const FiniteElement<dim> &) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 FiniteElementDomination::Domination
-FiniteElement<dim>::
-compare_for_face_domination (const FiniteElement<dim> &) const
+FiniteElement<dim,spacedim>::
+compare_for_face_domination (const FiniteElement<dim,spacedim> &) const
 {
   Assert (false, ExcNotImplemented());
   return FiniteElementDomination::neither_element_dominates;
@@ -716,9 +717,9 @@ compare_for_face_domination (const FiniteElement<dim> &) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::operator == (const FiniteElement<dim> &f) const
+FiniteElement<dim,spacedim>::operator == (const FiniteElement<dim,spacedim> &f) const
 {
   return ((static_cast<const FiniteElementData<dim>&>(*this) ==
           static_cast<const FiniteElementData<dim>&>(f)) &&
@@ -727,9 +728,9 @@ FiniteElement<dim>::operator == (const FiniteElement<dim> &f) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 const std::vector<Point<dim> > &
-FiniteElement<dim>::get_unit_support_points () const
+FiniteElement<dim,spacedim>::get_unit_support_points () const
 {
                                   // a finite element may define
                                   // support points, but only if
@@ -743,18 +744,18 @@ FiniteElement<dim>::get_unit_support_points () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::has_support_points () const
+FiniteElement<dim,spacedim>::has_support_points () const
 {
   return (unit_support_points.size() != 0);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 const std::vector<Point<dim> > &
-FiniteElement<dim>::get_generalized_support_points () const
+FiniteElement<dim,spacedim>::get_generalized_support_points () const
 {
                                   // a finite element may define
                                   // support points, but only if
@@ -767,18 +768,18 @@ FiniteElement<dim>::get_generalized_support_points () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::has_generalized_support_points () const
+FiniteElement<dim,spacedim>::has_generalized_support_points () const
 {
   return (get_generalized_support_points().size() != 0);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Point<dim>
-FiniteElement<dim>::unit_support_point (const unsigned index) const
+FiniteElement<dim,spacedim>::unit_support_point (const unsigned index) const
 {
   Assert (index < this->dofs_per_cell,
           ExcIndexRange (index, 0, this->dofs_per_cell));
@@ -789,9 +790,9 @@ FiniteElement<dim>::unit_support_point (const unsigned index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 const std::vector<Point<dim-1> > &
-FiniteElement<dim>::get_unit_face_support_points () const
+FiniteElement<dim,spacedim>::get_unit_face_support_points () const
 {
                                   // a finite element may define
                                   // support points, but only if
@@ -805,18 +806,18 @@ FiniteElement<dim>::get_unit_face_support_points () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::has_face_support_points () const
+FiniteElement<dim,spacedim>::has_face_support_points () const
 {
   return (unit_face_support_points.size() != 0);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 const std::vector<Point<dim-1> > &
-FiniteElement<dim>::get_generalized_face_support_points () const
+FiniteElement<dim,spacedim>::get_generalized_face_support_points () const
 {
                                   // a finite element may define
                                   // support points, but only if
@@ -829,18 +830,18 @@ FiniteElement<dim>::get_generalized_face_support_points () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::has_generalized_face_support_points () const
+FiniteElement<dim,spacedim>::has_generalized_face_support_points () const
 {
   return (generalized_face_support_points.size() != 0);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Point<dim-1>
-FiniteElement<dim>::unit_face_support_point (const unsigned index) const
+FiniteElement<dim,spacedim>::unit_face_support_point (const unsigned index) const
 {
   Assert (index < this->dofs_per_face,
           ExcIndexRange (index, 0, this->dofs_per_face));
@@ -850,9 +851,9 @@ FiniteElement<dim>::unit_face_support_point (const unsigned index) const
 }
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FiniteElement<dim>::has_support_on_face (
+FiniteElement<dim,spacedim>::has_support_on_face (
   const unsigned int,
   const unsigned int) const
 {
@@ -860,9 +861,9 @@ FiniteElement<dim>::has_support_on_face (
 }
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FiniteElement<dim>::interpolate(
+FiniteElement<dim,spacedim>::interpolate(
   std::vector<double>&       local_dofs,
   const std::vector<double>& values) const
 {
@@ -880,9 +881,9 @@ FiniteElement<dim>::interpolate(
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FiniteElement<dim>::interpolate(
+FiniteElement<dim,spacedim>::interpolate(
   std::vector<double>&    local_dofs,
   const std::vector<Vector<double> >& values,
   unsigned int offset) const
@@ -906,9 +907,9 @@ FiniteElement<dim>::interpolate(
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FiniteElement<dim>::interpolate(
+FiniteElement<dim,spacedim>::interpolate(
   std::vector<double>& local_dofs,
   const VectorSlice<const std::vector<std::vector<double> > >& values) const
 {
@@ -931,9 +932,9 @@ FiniteElement<dim>::interpolate(
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 unsigned int
-FiniteElement<dim>::memory_consumption () const
+FiniteElement<dim,spacedim>::memory_consumption () const
 {
   return (sizeof(FiniteElementData<dim>) +
          MemoryConsumption::memory_consumption (restriction)+
@@ -949,17 +950,44 @@ FiniteElement<dim>::memory_consumption () const
          MemoryConsumption::memory_consumption (n_nonzero_components_table));
 }
 
+template<>
+void
+FiniteElement<1,2>::compute_2nd (
+  const Mapping<1,2>                   &,
+  const Triangulation<1,2>::cell_iterator &,
+  const unsigned int,
+  Mapping<1,2>::InternalDataBase &,
+  InternalDataBase                     &,
+  FEValuesData<1,2>                    &) const
+{
+
+       Assert(false, ExcNotImplemented());
+}
+
+template<>
+void
+FiniteElement<2,3>::compute_2nd (
+  const Mapping<2,3>                   &,
+  const Triangulation<2,3>::cell_iterator &,
+  const unsigned int,
+  Mapping<2,3>::InternalDataBase &,
+  InternalDataBase                     &,
+  FEValuesData<2,3>                    &) const
+{
+
+       Assert(false, ExcNotImplemented());
+}
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FiniteElement<dim>::compute_2nd (
-  const Mapping<dim>                   &mapping,
-  const typename Triangulation<dim>::cell_iterator &cell,
+FiniteElement<dim,spacedim>::compute_2nd (
+  const Mapping<dim,spacedim>                   &mapping,
+  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
   const unsigned int offset,
-  typename Mapping<dim>::InternalDataBase &mapping_internal,
+  typename Mapping<dim,spacedim>::InternalDataBase &mapping_internal,
   InternalDataBase                     &fe_internal,
-  FEValuesData<dim>                    &data) const
+  FEValuesData<dim,spacedim>                    &data) const
 {
   Assert ((fe_internal.update_each | fe_internal.update_once)
          & update_hessians,
@@ -1096,9 +1124,9 @@ FiniteElement<dim>::compute_2nd (
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 std::vector<unsigned int>
-FiniteElement<dim>::compute_n_nonzero_components (
+FiniteElement<dim,spacedim>::compute_n_nonzero_components (
   const std::vector<std::vector<bool> > &nonzero_components)
 {
   std::vector<unsigned int> retval (nonzero_components.size());
@@ -1113,10 +1141,10 @@ FiniteElement<dim>::compute_n_nonzero_components (
 
 /*------------------------------- FiniteElement ----------------------*/
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-FiniteElement<dim>::get_face_data (const UpdateFlags       flags,
-                                  const Mapping<dim>      &mapping,
+template <int dim, int spacedim>  
+typename Mapping<dim,spacedim>::InternalDataBase *
+FiniteElement<dim,spacedim>::get_face_data (const UpdateFlags       flags,
+                                  const Mapping<dim,spacedim>      &mapping,
                                   const Quadrature<dim-1> &quadrature) const
 {
   return get_data (flags, mapping,
@@ -1125,10 +1153,10 @@ FiniteElement<dim>::get_face_data (const UpdateFlags       flags,
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-FiniteElement<dim>::get_subface_data (const UpdateFlags        flags,
-                                     const Mapping<dim>      &mapping,
+template <int dim, int spacedim>  
+typename Mapping<dim,spacedim>::InternalDataBase *
+FiniteElement<dim,spacedim>::get_subface_data (const UpdateFlags        flags,
+                                     const Mapping<dim,spacedim>      &mapping,
                                      const Quadrature<dim-1> &quadrature) const
 {
   return get_data (flags, mapping,
@@ -1137,9 +1165,9 @@ FiniteElement<dim>::get_subface_data (const UpdateFlags        flags,
 
 
 
-template <int dim>
-const FiniteElement<dim>&
-FiniteElement<dim>::base_element(const unsigned index) const
+template <int dim, int spacedim>  
+const FiniteElement<dim,spacedim>&
+FiniteElement<dim,spacedim>::base_element(const unsigned index) const
 {
   Assert (index==0, ExcIndexRange(index,0,1));
   return *this;
@@ -1149,4 +1177,12 @@ FiniteElement<dim>::base_element(const unsigned index) const
 
 template class FiniteElement<deal_II_dimension>;
 
+
+#if deal_II_dimension != 3
+template class FiniteElement<deal_II_dimension,deal_II_dimension+1>;
+#endif
+
+
+
+
 DEAL_II_NAMESPACE_CLOSE
index ed3e0b7802f1a91373bc578892d062d3fd7a7ed5..9470a0bb6547a45863f777ca51128753d4cb97ef 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim>
-FE_DGP<dim>::FE_DGP (const unsigned int degree)
+template <int dim, int spacedim>
+FE_DGP<dim,spacedim>::FE_DGP (const unsigned int degree)
                :
-               FE_Poly<PolynomialSpace<dim>, dim> (
+                FE_Poly<PolynomialSpace<dim>, dim, spacedim> (
                  PolynomialSpace<dim>(Polynomials::Legendre::generate_complete_basis(degree)),
                  FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
                  std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
@@ -33,16 +33,18 @@ FE_DGP<dim>::FE_DGP (const unsigned int degree)
                                   // matrices to the right sizes
   this->reinit_restriction_and_prolongation_matrices();
                                   // Fill prolongation matrices with embedding operators
-  FETools::compute_embedding_matrices (*this, this->prolongation);
+  if (dim == spacedim)
+  {
+      FETools::compute_embedding_matrices (*this, this->prolongation);
                                   // Fill restriction matrices with L2-projection
-  FETools::compute_projection_matrices (*this, this->restriction);
+      FETools::compute_projection_matrices (*this, this->restriction);
+  }
 }
 
 
-
-template <int dim>
+template <int dim, int spacedim>
 std::string
-FE_DGP<dim>::get_name () const
+FE_DGP<dim,spacedim>::get_name () const
 {
                                   // note that the
                                   // FETools::get_fe_from_name
@@ -59,11 +61,11 @@ FE_DGP<dim>::get_name () const
 
 
 
-template <int dim>
-FiniteElement<dim> *
-FE_DGP<dim>::clone() const
+template <int dim, int spacedim>
+FiniteElement<dim,spacedim> *
+FE_DGP<dim,spacedim>::clone() const
 {
-  return new FE_DGP<dim>(*this);
+  return new FE_DGP<dim,spacedim>(*this);
 }
 
 
@@ -73,9 +75,9 @@ FE_DGP<dim>::clone() const
 //---------------------------------------------------------------------------
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<unsigned int>
-FE_DGP<dim>::get_dpo_vector (const unsigned int deg)
+FE_DGP<dim,spacedim>::get_dpo_vector (const unsigned int deg)
 {
   std::vector<unsigned int> dpo(dim+1, 0U);
   dpo[dim] = deg+1;
@@ -89,10 +91,10 @@ FE_DGP<dim>::get_dpo_vector (const unsigned int deg)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_DGP<dim>::
-get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_DGP<dim,spacedim>::
+get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                               FullMatrix<double>       &interpolation_matrix) const
 {
                                   // this is only implemented, if the source
@@ -101,10 +103,12 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                   // faces and the face interpolation matrix
                                   // is necessarily empty -- i.e. there isn't
                                   // much we need to do here.
+  typedef FiniteElement<dim,spacedim> FE;
+  typedef FE_DGP<dim,spacedim> FEDGP;
   AssertThrow ((x_source_fe.get_name().find ("FE_DGP<") == 0)
                ||
-               (dynamic_cast<const FE_DGP<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
+               (dynamic_cast<const FEDGP*>(&x_source_fe) != 0),
+               typename FE::
                ExcInterpolationNotImplemented());
   
   Assert (interpolation_matrix.m() == 0,
@@ -117,10 +121,10 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_DGP<dim>::
-get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_DGP<dim,spacedim>::
+get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                                  const unsigned int ,
                                  FullMatrix<double>           &interpolation_matrix) const
 {
@@ -130,10 +134,12 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                   // faces and the face interpolation matrix
                                   // is necessarily empty -- i.e. there isn't
                                   // much we need to do here.
+  typedef FiniteElement<dim,spacedim> FE;
+  typedef FE_DGP<dim,spacedim> FEDGP;
   AssertThrow ((x_source_fe.get_name().find ("FE_DGP<") == 0)
                ||
-               (dynamic_cast<const FE_DGP<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
+               (dynamic_cast<const FEDGP*>(&x_source_fe) != 0),
+               typename FE::
                ExcInterpolationNotImplemented());
   
   Assert (interpolation_matrix.m() == 0,
@@ -146,23 +152,23 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FE_DGP<dim>::hp_constraints_are_implemented () const
+FE_DGP<dim,spacedim>::hp_constraints_are_implemented () const
 {
   return true;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_DGP<dim>::
-hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
+FE_DGP<dim,spacedim>::
+hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // there are no such constraints for DGP
                                   // elements at all
-  if (dynamic_cast<const FE_DGP<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGP<dim,spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > ();
   else
@@ -174,14 +180,14 @@ hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_DGP<dim>::
-hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
+FE_DGP<dim,spacedim>::
+hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // there are no such constraints for DGP
                                   // elements at all
-  if (dynamic_cast<const FE_DGP<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGP<dim,spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > ();
   else
@@ -193,14 +199,14 @@ hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_DGP<dim>::
-hp_quad_dof_identities (const FiniteElement<dim>        &fe_other) const
+FE_DGP<dim,spacedim>::
+hp_quad_dof_identities (const FiniteElement<dim,spacedim>        &fe_other) const
 {
                                   // there are no such constraints for DGP
                                   // elements at all
-  if (dynamic_cast<const FE_DGP<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGP<dim,spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > ();
   else
@@ -212,15 +218,15 @@ hp_quad_dof_identities (const FiniteElement<dim>        &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 FiniteElementDomination::Domination
-FE_DGP<dim>::compare_for_face_domination (const FiniteElement<dim> &fe_other) const
+FE_DGP<dim,spacedim>::compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // check whether both are discontinuous
                                   // elements and both could dominate, see
                                   // the description of
                                   // FiniteElementDomination::Domination
-  if (dynamic_cast<const FE_DGP<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGP<dim,spacedim>*>(&fe_other) != 0)
     return FiniteElementDomination::either_element_can_dominate;
 
   Assert (false, ExcNotImplemented());
@@ -229,9 +235,9 @@ FE_DGP<dim>::compare_for_face_domination (const FiniteElement<dim> &fe_other) co
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FE_DGP<dim>::has_support_on_face (const unsigned int,
+FE_DGP<dim,spacedim>::has_support_on_face (const unsigned int,
                                  const unsigned int) const
 {
                                    // all shape functions have support on all
@@ -241,9 +247,9 @@ FE_DGP<dim>::has_support_on_face (const unsigned int,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FE_DGP<dim>::memory_consumption () const
+FE_DGP<dim,spacedim>::memory_consumption () const
 {
   Assert (false, ExcNotImplemented ());
   return 0;
@@ -253,4 +259,8 @@ FE_DGP<dim>::memory_consumption () const
 
 template class FE_DGP<deal_II_dimension>;
 
+#if deal_II_dimension != 3
+template class FE_DGP<deal_II_dimension, deal_II_dimension+1>;
+#endif
+
 DEAL_II_NAMESPACE_CLOSE
index 5c27e698a21402d62be8a74b0ff4614b277a1373..5cf951458a17b1cc4380223a6d0f46a9abbc36ba 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim>
-FE_DGPNonparametric<dim>::FE_DGPNonparametric (const unsigned int degree)
+template <int dim, int spacedim>  
+FE_DGPNonparametric<dim,spacedim>::FE_DGPNonparametric (const unsigned int degree)
                :
-               FiniteElement<dim> (
+               FiniteElement<dim,spacedim> (
                  FiniteElementData<dim>(get_dpo_vector(degree), 1, degree,
                                         FiniteElementData<dim>::L2),
                  std::vector<bool>(
@@ -90,9 +90,9 @@ FE_DGPNonparametric<dim>::FE_DGPNonparametric (const unsigned int degree)
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 std::string
-FE_DGPNonparametric<dim>::get_name () const
+FE_DGPNonparametric<dim,spacedim>::get_name () const
 {
                                   // note that the
                                   // FETools::get_fe_from_name
@@ -109,18 +109,18 @@ FE_DGPNonparametric<dim>::get_name () const
 
 
 
-template <int dim>
-FiniteElement<dim> *
-FE_DGPNonparametric<dim>::clone() const
+template <int dim, int spacedim>  
+FiniteElement<dim,spacedim> *
+FE_DGPNonparametric<dim,spacedim>::clone() const
 {
-  return new FE_DGPNonparametric<dim>(*this);
+  return new FE_DGPNonparametric<dim,spacedim>(*this);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 double
-FE_DGPNonparametric<dim>::shape_value (const unsigned int i,
+FE_DGPNonparametric<dim,spacedim>::shape_value (const unsigned int i,
                          const Point<dim> &p) const
 {
   Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
@@ -129,9 +129,9 @@ FE_DGPNonparametric<dim>::shape_value (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 double
-FE_DGPNonparametric<dim>::shape_value_component (const unsigned int i,
+FE_DGPNonparametric<dim,spacedim>::shape_value_component (const unsigned int i,
                                    const Point<dim> &p,
                                    const unsigned int component) const
 {
@@ -142,9 +142,9 @@ FE_DGPNonparametric<dim>::shape_value_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Tensor<1,dim>
-FE_DGPNonparametric<dim>::shape_grad (const unsigned int i,
+FE_DGPNonparametric<dim,spacedim>::shape_grad (const unsigned int i,
                         const Point<dim> &p) const
 {
   Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
@@ -152,9 +152,9 @@ FE_DGPNonparametric<dim>::shape_grad (const unsigned int i,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Tensor<1,dim>
-FE_DGPNonparametric<dim>::shape_grad_component (const unsigned int i,
+FE_DGPNonparametric<dim,spacedim>::shape_grad_component (const unsigned int i,
                                   const Point<dim> &p,
                                   const unsigned int component) const
 {
@@ -165,9 +165,9 @@ FE_DGPNonparametric<dim>::shape_grad_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Tensor<2,dim>
-FE_DGPNonparametric<dim>::shape_grad_grad (const unsigned int i,
+FE_DGPNonparametric<dim,spacedim>::shape_grad_grad (const unsigned int i,
                              const Point<dim> &p) const
 {
   Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
@@ -176,9 +176,9 @@ FE_DGPNonparametric<dim>::shape_grad_grad (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 Tensor<2,dim>
-FE_DGPNonparametric<dim>::shape_grad_grad_component (const unsigned int i,
+FE_DGPNonparametric<dim,spacedim>::shape_grad_grad_component (const unsigned int i,
                                        const Point<dim> &p,
                                        const unsigned int component) const
 {
@@ -193,9 +193,9 @@ FE_DGPNonparametric<dim>::shape_grad_grad_component (const unsigned int i,
 //---------------------------------------------------------------------------
 
 
-template <int dim>
+template <int dim, int spacedim>  
 std::vector<unsigned int>
-FE_DGPNonparametric<dim>::get_dpo_vector (const unsigned int deg)
+FE_DGPNonparametric<dim,spacedim>::get_dpo_vector (const unsigned int deg)
 {
   std::vector<unsigned int> dpo(dim+1, static_cast<unsigned int>(0));
   dpo[dim] = deg+1;
@@ -208,9 +208,9 @@ FE_DGPNonparametric<dim>::get_dpo_vector (const unsigned int deg)
 }
 
 
-template <int dim>
+template <int dim, int spacedim>  
 UpdateFlags
-FE_DGPNonparametric<dim>::update_once (const UpdateFlags) const
+FE_DGPNonparametric<dim,spacedim>::update_once (const UpdateFlags) const
 {
                                   // for this kind of elements, only
                                   // the values can be precomputed
@@ -221,9 +221,9 @@ FE_DGPNonparametric<dim>::update_once (const UpdateFlags) const
 }
 
 
-template <int dim>
+template <int dim, int spacedim>  
 UpdateFlags
-FE_DGPNonparametric<dim>::update_each (const UpdateFlags flags) const
+FE_DGPNonparametric<dim,spacedim>::update_each (const UpdateFlags flags) const
 {
   UpdateFlags out = flags;
 
@@ -238,11 +238,11 @@ FE_DGPNonparametric<dim>::update_each (const UpdateFlags flags) const
 // Data field initialization
 //---------------------------------------------------------------------------
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-FE_DGPNonparametric<dim>::get_data (
+template <int dim, int spacedim>  
+typename Mapping<dim,spacedim>::InternalDataBase *
+FE_DGPNonparametric<dim,spacedim>::get_data (
   const UpdateFlags      update_flags,
-  const Mapping<dim>&,
+  const Mapping<dim,spacedim>&,
   const Quadrature<dim>&) const
 {
                                   // generate a new data object
@@ -283,15 +283,15 @@ FE_DGPNonparametric<dim>::get_data (
 // Fill data of FEValues
 //---------------------------------------------------------------------------
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FE_DGPNonparametric<dim>::fill_fe_values (
-  const Mapping<dim>&,
-  const typename Triangulation<dim>::cell_iterator&,
+FE_DGPNonparametric<dim,spacedim>::fill_fe_values (
+  const Mapping<dim,spacedim>&,
+  const typename Triangulation<dim,spacedim>::cell_iterator&,
   const Quadrature<dim>&,
-  typename Mapping<dim>::InternalDataBase&,
-  typename Mapping<dim>::InternalDataBase& fedata,
-  FEValuesData<dim>& data) const
+  typename Mapping<dim,spacedim>::InternalDataBase&,
+  typename Mapping<dim,spacedim>::InternalDataBase& fedata,
+  FEValuesData<dim,spacedim>& data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -323,16 +323,16 @@ FE_DGPNonparametric<dim>::fill_fe_values (
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FE_DGPNonparametric<dim>::fill_fe_face_values (
-  const Mapping<dim>&,
-  const typename Triangulation<dim>::cell_iterator&,
+FE_DGPNonparametric<dim,spacedim>::fill_fe_face_values (
+  const Mapping<dim,spacedim>&,
+  const typename Triangulation<dim,spacedim>::cell_iterator&,
   const unsigned int,
   const Quadrature<dim-1>&,
-  typename Mapping<dim>::InternalDataBase&,
-  typename Mapping<dim>::InternalDataBase&       fedata,
-  FEValuesData<dim>&                             data) const
+  typename Mapping<dim,spacedim>::InternalDataBase&,
+  typename Mapping<dim,spacedim>::InternalDataBase&       fedata,
+  FEValuesData<dim,spacedim>&                             data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -364,17 +364,17 @@ FE_DGPNonparametric<dim>::fill_fe_face_values (
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FE_DGPNonparametric<dim>::fill_fe_subface_values (
-  const Mapping<dim>&,
-  const typename Triangulation<dim>::cell_iterator&,
+FE_DGPNonparametric<dim,spacedim>::fill_fe_subface_values (
+  const Mapping<dim,spacedim>&,
+  const typename Triangulation<dim,spacedim>::cell_iterator&,
   const unsigned int,
   const unsigned int,
   const Quadrature<dim-1>&,
-  typename Mapping<dim>::InternalDataBase&,
-  typename Mapping<dim>::InternalDataBase&       fedata,
-  FEValuesData<dim>&                             data) const
+  typename Mapping<dim,spacedim>::InternalDataBase&,
+  typename Mapping<dim,spacedim>::InternalDataBase&       fedata,
+  FEValuesData<dim,spacedim>&                             data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -406,18 +406,18 @@ FE_DGPNonparametric<dim>::fill_fe_subface_values (
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 unsigned int
-FE_DGPNonparametric<dim>::n_base_elements () const
+FE_DGPNonparametric<dim,spacedim>::n_base_elements () const
 {
   return 1;
 }
 
 
 
-template <int dim>
-const FiniteElement<dim> &
-FE_DGPNonparametric<dim>::base_element (const unsigned int index) const
+template <int dim, int spacedim>  
+const FiniteElement<dim,spacedim> &
+FE_DGPNonparametric<dim,spacedim>::base_element (const unsigned int index) const
 {
   Assert (index==0, ExcIndexRange(index, 0, 1));
   return *this;
@@ -425,9 +425,9 @@ FE_DGPNonparametric<dim>::base_element (const unsigned int index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 unsigned int
-FE_DGPNonparametric<dim>::element_multiplicity (const unsigned int index) const
+FE_DGPNonparametric<dim,spacedim>::element_multiplicity (const unsigned int index) const
 {
   Assert (index==0, ExcIndexRange(index, 0, 1));
   return 1;
@@ -435,10 +435,10 @@ FE_DGPNonparametric<dim>::element_multiplicity (const unsigned int index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FE_DGPNonparametric<dim>::
-get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_DGPNonparametric<dim,spacedim>::
+get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                               FullMatrix<double>       &interpolation_matrix) const
 {
                                   // this is only implemented, if the source
@@ -447,10 +447,11 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                   // faces and the face interpolation matrix
                                   // is necessarily empty -- i.e. there isn't
                                   // much we need to do here.
+  typedef             FiniteElement<dim,spacedim> FEE;
   AssertThrow ((x_source_fe.get_name().find ("FE_DGPNonparametric<") == 0)
                ||
-               (dynamic_cast<const FE_DGPNonparametric<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
+               (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&x_source_fe) != 0),
+               typename FEE::
                ExcInterpolationNotImplemented());
   
   Assert (interpolation_matrix.m() == 0,
@@ -463,10 +464,10 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 void
-FE_DGPNonparametric<dim>::
-get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_DGPNonparametric<dim,spacedim>::
+get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                                  const unsigned int ,
                                  FullMatrix<double>           &interpolation_matrix) const
 {
@@ -476,11 +477,12 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                   // faces and the face interpolation matrix
                                   // is necessarily empty -- i.e. there isn't
                                   // much we need to do here.
+  typedef             FiniteElement<dim,spacedim> FEE;
   AssertThrow ((x_source_fe.get_name().find ("FE_DGPNonparametric<") == 0)
                ||
-               (dynamic_cast<const FE_DGPNonparametric<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
-               ExcInterpolationNotImplemented());
+               (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&x_source_fe) != 0),
+               typename FEE::
+              ExcInterpolationNotImplemented());
   
   Assert (interpolation_matrix.m() == 0,
          ExcDimensionMismatch (interpolation_matrix.m(),
@@ -492,23 +494,23 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FE_DGPNonparametric<dim>::hp_constraints_are_implemented () const
+FE_DGPNonparametric<dim,spacedim>::hp_constraints_are_implemented () const
 {
   return true;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_DGPNonparametric<dim>::
-hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
+FE_DGPNonparametric<dim,spacedim>::
+hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // there are no such constraints for DGPNonparametric
                                   // elements at all
-  if (dynamic_cast<const FE_DGPNonparametric<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > ();
   else
@@ -520,14 +522,14 @@ hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_DGPNonparametric<dim>::
-hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
+FE_DGPNonparametric<dim,spacedim>::
+hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // there are no such constraints for DGPNonparametric
                                   // elements at all
-  if (dynamic_cast<const FE_DGPNonparametric<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > ();
   else
@@ -539,14 +541,14 @@ hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_DGPNonparametric<dim>::
-hp_quad_dof_identities (const FiniteElement<dim>        &fe_other) const
+FE_DGPNonparametric<dim,spacedim>::
+hp_quad_dof_identities (const FiniteElement<dim,spacedim>        &fe_other) const
 {
                                   // there are no such constraints for DGPNonparametric
                                   // elements at all
-  if (dynamic_cast<const FE_DGPNonparametric<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > ();
   else
@@ -558,16 +560,16 @@ hp_quad_dof_identities (const FiniteElement<dim>        &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 FiniteElementDomination::Domination
-FE_DGPNonparametric<dim>::
-compare_for_face_domination (const FiniteElement<dim> &fe_other) const
+FE_DGPNonparametric<dim,spacedim>::
+compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // check whether both are discontinuous
                                   // elements and both could dominate, see
                                   // the description of
                                   // FiniteElementDomination::Domination
-  if (dynamic_cast<const FE_DGPNonparametric<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
     return FiniteElementDomination::either_element_can_dominate;
 
   Assert (false, ExcNotImplemented());
@@ -576,9 +578,9 @@ compare_for_face_domination (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 bool
-FE_DGPNonparametric<dim>::has_support_on_face (const unsigned int,
+FE_DGPNonparametric<dim,spacedim>::has_support_on_face (const unsigned int,
                                  const unsigned int) const
 {
   return true;
@@ -586,9 +588,9 @@ FE_DGPNonparametric<dim>::has_support_on_face (const unsigned int,
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 unsigned int
-FE_DGPNonparametric<dim>::memory_consumption () const
+FE_DGPNonparametric<dim,spacedim>::memory_consumption () const
 {
   Assert (false, ExcNotImplemented ());
   return 0;
@@ -596,9 +598,9 @@ FE_DGPNonparametric<dim>::memory_consumption () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>  
 unsigned int
-FE_DGPNonparametric<dim>::get_degree () const
+FE_DGPNonparametric<dim,spacedim>::get_degree () const
 {
   return degree;
 }
index e0f9bfc95115385f2316fa3873ee67b52855dadb..9befa2fc91ac5c954ce8bc38db2a287513a9ef71 100644 (file)
@@ -128,10 +128,10 @@ namespace
 
 
 
-template <int dim>
-FE_DGQ<dim>::FE_DGQ (const unsigned int degree)
+template <int dim, int spacedim>
+FE_DGQ<dim, spacedim>::FE_DGQ (const unsigned int degree)
                :
-               FE_Poly<TensorProductPolynomials<dim>, dim> (
+               FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
                  TensorProductPolynomials<dim>(Polynomials::LagrangeEquidistant::generate_complete_basis(degree)),
                  FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
                  std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell, true),
@@ -143,8 +143,10 @@ FE_DGQ<dim>::FE_DGQ (const unsigned int degree)
                                   // matrices to the right sizes
   this->reinit_restriction_and_prolongation_matrices();
                                   // Fill prolongation matrices with embedding operators
+  if (dim ==spacedim)
   FETools::compute_embedding_matrices (*this, this->prolongation);
                                   // Fill restriction matrices with L2-projection
+  if (dim ==spacedim)
   FETools::compute_projection_matrices (*this, this->restriction);
                              
   
@@ -190,10 +192,10 @@ FE_DGQ<dim>::FE_DGQ (const unsigned int degree)
 
 
 
-template <int dim>
-FE_DGQ<dim>::FE_DGQ (const Quadrature<1>& points)
+template <int dim, int spacedim>
+FE_DGQ<dim, spacedim>::FE_DGQ (const Quadrature<1>& points)
                :
-               FE_Poly<TensorProductPolynomials<dim>, dim> (
+               FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
                  TensorProductPolynomials<dim>(Polynomials::Lagrange::generate_complete_basis(points.get_points())),
                  FiniteElementData<dim>(get_dpo_vector(points.size()-1), 1, points.size()-1, FiniteElementData<dim>::L2),
                  std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(points.size()-1),1, points.size()-1).dofs_per_cell, true),
@@ -219,9 +221,9 @@ FE_DGQ<dim>::FE_DGQ (const Quadrature<1>& points)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::string
-FE_DGQ<dim>::get_name () const
+FE_DGQ<dim, spacedim>::get_name () const
 {
                                   // note that the
                                   // FETools::get_fe_from_name
@@ -237,11 +239,11 @@ FE_DGQ<dim>::get_name () const
 
 
 
-template <int dim>
-FiniteElement<dim> *
-FE_DGQ<dim>::clone() const
+template <int dim, int spacedim>
+FiniteElement<dim,spacedim> *
+FE_DGQ<dim, spacedim>::clone() const
 {
-  return new FE_DGQ<dim>(*this);
+  return new FE_DGQ<dim, spacedim>(*this);
 }
 
 
@@ -250,9 +252,9 @@ FE_DGQ<dim>::clone() const
 //---------------------------------------------------------------------------
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<unsigned int>
-FE_DGQ<dim>::get_dpo_vector (const unsigned int deg)
+FE_DGQ<dim, spacedim>::get_dpo_vector (const unsigned int deg)
 {
   std::vector<unsigned int> dpo(dim+1, 0U);
   dpo[dim] = deg+1;
@@ -263,9 +265,9 @@ FE_DGQ<dim>::get_dpo_vector (const unsigned int deg)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_DGQ<dim>::rotate_indices (std::vector<unsigned int> &numbers,
+FE_DGQ<dim, spacedim>::rotate_indices (std::vector<unsigned int> &numbers,
                             const char                 direction) const
 {
   const unsigned int n = this->degree+1;
@@ -340,25 +342,25 @@ FE_DGQ<dim>::rotate_indices (std::vector<unsigned int> &numbers,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_DGQ<dim>::
-get_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_DGQ<dim, spacedim>::
+get_interpolation_matrix (const FiniteElement<dim, spacedim> &x_source_fe,
                          FullMatrix<double>           &interpolation_matrix) const
 {
                                   // this is only implemented, if the
                                   // source FE is also a
                                   // DGQ element
+  typedef FiniteElement<dim, spacedim> FE;
   AssertThrow ((x_source_fe.get_name().find ("FE_DGQ<") == 0)
                ||
-               (dynamic_cast<const FE_DGQ<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
-               ExcInterpolationNotImplemented());
+               (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&x_source_fe) != 0),
+                typename FE::ExcInterpolationNotImplemented() );
   
                                   // ok, source is a Q element, so
                                   // we will be able to do the work
-  const FE_DGQ<dim> &source_fe
-    = dynamic_cast<const FE_DGQ<dim>&>(x_source_fe);
+  const FE_DGQ<dim, spacedim> &source_fe
+    = dynamic_cast<const FE_DGQ<dim, spacedim>&>(x_source_fe);
 
   Assert (interpolation_matrix.m() == this->dofs_per_cell,
          ExcDimensionMismatch (interpolation_matrix.m(),
@@ -426,10 +428,10 @@ get_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_DGQ<dim>::
-get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_DGQ<dim, spacedim>::
+get_face_interpolation_matrix (const FiniteElement<dim, spacedim> &x_source_fe,
                               FullMatrix<double>       &interpolation_matrix) const
 {
                                   // this is only implemented, if the source
@@ -438,11 +440,11 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                   // faces and the face interpolation matrix
                                   // is necessarily empty -- i.e. there isn't
                                   // much we need to do here.
+  typedef FiniteElement<dim,spacedim> FE;
   AssertThrow ((x_source_fe.get_name().find ("FE_DGQ<") == 0)
                ||
-               (dynamic_cast<const FE_DGQ<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
-               ExcInterpolationNotImplemented());
+               (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&x_source_fe) != 0),
+               typename FE::ExcInterpolationNotImplemented());
   
   Assert (interpolation_matrix.m() == 0,
          ExcDimensionMismatch (interpolation_matrix.m(),
@@ -454,10 +456,10 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_DGQ<dim>::
-get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_DGQ<dim, spacedim>::
+get_subface_interpolation_matrix (const FiniteElement<dim, spacedim> &x_source_fe,
                                  const unsigned int ,
                                  FullMatrix<double>           &interpolation_matrix) const
 {
@@ -467,11 +469,11 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                   // faces and the face interpolation matrix
                                   // is necessarily empty -- i.e. there isn't
                                   // much we need to do here.
+  typedef FiniteElement<dim, spacedim> FE;
   AssertThrow ((x_source_fe.get_name().find ("FE_DGQ<") == 0)
                ||
-               (dynamic_cast<const FE_DGQ<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
-               ExcInterpolationNotImplemented());
+               (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&x_source_fe) != 0),
+               typename FE::ExcInterpolationNotImplemented());
   
   Assert (interpolation_matrix.m() == 0,
          ExcDimensionMismatch (interpolation_matrix.m(),
@@ -483,23 +485,23 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FE_DGQ<dim>::hp_constraints_are_implemented () const
+FE_DGQ<dim, spacedim>::hp_constraints_are_implemented () const
 {
   return true;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_DGQ<dim>::
-hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
+FE_DGQ<dim, spacedim>::
+hp_vertex_dof_identities (const FiniteElement<dim, spacedim> &fe_other) const
 {
                                   // there are no such constraints for DGQ
                                   // elements at all
-  if (dynamic_cast<const FE_DGQ<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > ();
   else
@@ -511,14 +513,14 @@ hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_DGQ<dim>::
-hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
+FE_DGQ<dim, spacedim>::
+hp_line_dof_identities (const FiniteElement<dim, spacedim> &fe_other) const
 {
                                   // there are no such constraints for DGQ
                                   // elements at all
-  if (dynamic_cast<const FE_DGQ<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > ();
   else
@@ -530,14 +532,14 @@ hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_DGQ<dim>::
-hp_quad_dof_identities (const FiniteElement<dim>        &fe_other) const
+FE_DGQ<dim, spacedim>::
+hp_quad_dof_identities (const FiniteElement<dim, spacedim>        &fe_other) const
 {
                                   // there are no such constraints for DGQ
                                   // elements at all
-  if (dynamic_cast<const FE_DGQ<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > ();
   else
@@ -549,15 +551,15 @@ hp_quad_dof_identities (const FiniteElement<dim>        &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 FiniteElementDomination::Domination
-FE_DGQ<dim>::compare_for_face_domination (const FiniteElement<dim> &fe_other) const
+FE_DGQ<dim, spacedim>::compare_for_face_domination (const FiniteElement<dim, spacedim> &fe_other) const
 {
                                   // check whether both are discontinuous
                                   // elements and both could dominate, see
                                   // the description of
                                   // FiniteElementDomination::Domination
-  if (dynamic_cast<const FE_DGQ<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&fe_other) != 0)
     return FiniteElementDomination::either_element_can_dominate;
 
   Assert (false, ExcNotImplemented());
@@ -566,9 +568,9 @@ FE_DGQ<dim>::compare_for_face_domination (const FiniteElement<dim> &fe_other) co
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FE_DGQ<dim>::has_support_on_face (const unsigned int shape_index,
+FE_DGQ<dim, spacedim>::has_support_on_face (const unsigned int shape_index,
                                  const unsigned int face_index) const
 {
   Assert (shape_index < this->dofs_per_cell,
@@ -639,9 +641,9 @@ FE_DGQ<dim>::has_support_on_face (const unsigned int shape_index,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FE_DGQ<dim>::memory_consumption () const
+FE_DGQ<dim, spacedim>::memory_consumption () const
 {
   Assert (false, ExcNotImplemented ());
   return 0;
@@ -744,6 +746,13 @@ FE_DGQArbitraryNodes<dim>::clone() const
 
 
 template class FE_DGQ<deal_II_dimension>;
+
+//codimension 1
+
+#if deal_II_dimension != 3
+template class FE_DGQ<deal_II_dimension, deal_II_dimension+1>;
+#endif
+
 template class FE_DGQArbitraryNodes<deal_II_dimension>;
 
 DEAL_II_NAMESPACE_CLOSE
index 122a0d42ef2e7e3e33430ac5794559c40d8f1baf..9f6373f773d9d337de8293ebfd2cdcc1888d4549 100644 (file)
@@ -31,10 +31,10 @@ DEAL_II_NAMESPACE_OPEN
 
 
 //TODO: Remove doubled member variable 'degree'
-template <int dim>
-FE_Nedelec<dim>::FE_Nedelec (const unsigned int degree)
+template <int dim, int spacedim>
+FE_Nedelec<dim,spacedim>::FE_Nedelec (const unsigned int degree)
                :
-               FiniteElement<dim> (
+               FiniteElement<dim,spacedim> (
                  FiniteElementData<dim>(get_dpo_vector(degree), dim,
                                         degree+1, FiniteElementData<dim>::Hcurl, 1),
                                    std::vector<bool> (
@@ -80,9 +80,9 @@ FE_Nedelec<dim>::FE_Nedelec (const unsigned int degree)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::string
-FE_Nedelec<dim>::get_name () const
+FE_Nedelec<dim,spacedim>::get_name () const
 {
                                   // note that the
                                   // FETools::get_fe_from_name
@@ -99,11 +99,11 @@ FE_Nedelec<dim>::get_name () const
 
 
 
-template <int dim>
-FiniteElement<dim> *
-FE_Nedelec<dim>::clone() const
+template <int dim, int spacedim>
+FiniteElement<dim,spacedim> *
+FE_Nedelec<dim,spacedim>::clone() const
 {
-  return new FE_Nedelec<dim>(*this);
+  return new FE_Nedelec<dim,spacedim>(*this);
 }
 
 
@@ -545,9 +545,9 @@ FE_Nedelec<3>::shape_grad_grad_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Nedelec<dim>::initialize_constraints ()
+FE_Nedelec<dim,spacedim>::initialize_constraints ()
 {
                                   // copy constraint matrices if they
                                   // are defined. otherwise leave
@@ -562,9 +562,9 @@ FE_Nedelec<dim>::initialize_constraints ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Nedelec<dim>::initialize_embedding ()
+FE_Nedelec<dim,spacedim>::initialize_embedding ()
 {
   unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
   if ((degree < Matrices::n_embedding_matrices+1) &&
@@ -597,9 +597,9 @@ FE_Nedelec<dim>::initialize_embedding ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Nedelec<dim>::initialize_restriction ()
+FE_Nedelec<dim,spacedim>::initialize_restriction ()
 {
   unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
   switch (dim)
@@ -777,8 +777,8 @@ FE_Nedelec<dim>::initialize_restriction ()
 
 
 
-template <int dim>
-void FE_Nedelec<dim>::initialize_unit_support_points ()
+template <int dim, int spacedim>
+void FE_Nedelec<dim,spacedim>::initialize_unit_support_points ()
 {
   switch (degree)
     {
@@ -828,8 +828,8 @@ void FE_Nedelec<1>::initialize_unit_face_support_points ()
 #endif
 
 
-template <int dim>
-void FE_Nedelec<dim>::initialize_unit_face_support_points ()
+template <int dim, int spacedim>
+void FE_Nedelec<dim,spacedim>::initialize_unit_face_support_points ()
 {
   switch (degree)
     {
@@ -866,9 +866,9 @@ void FE_Nedelec<dim>::initialize_unit_face_support_points ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<unsigned int>
-FE_Nedelec<dim>::get_dpo_vector(const unsigned int degree)
+FE_Nedelec<dim,spacedim>::get_dpo_vector(const unsigned int degree)
 {
   Assert (degree == 1, ExcNotImplemented());
 
@@ -884,9 +884,9 @@ FE_Nedelec<dim>::get_dpo_vector(const unsigned int degree)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 UpdateFlags
-FE_Nedelec<dim>::update_once (const UpdateFlags) const
+FE_Nedelec<dim,spacedim>::update_once (const UpdateFlags) const
 {
                                   // even the values have to be
                                   // computed on the real cell, so
@@ -896,9 +896,9 @@ FE_Nedelec<dim>::update_once (const UpdateFlags) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 UpdateFlags
-FE_Nedelec<dim>::update_each (const UpdateFlags flags) const
+FE_Nedelec<dim,spacedim>::update_each (const UpdateFlags flags) const
 {
   UpdateFlags out = update_default;
 
@@ -918,10 +918,10 @@ FE_Nedelec<dim>::update_each (const UpdateFlags flags) const
 // Data field initialization
 //---------------------------------------------------------------------------
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-FE_Nedelec<dim>::get_data (const UpdateFlags      update_flags,
-                          const Mapping<dim>    &mapping,
+template <int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+FE_Nedelec<dim,spacedim>::get_data (const UpdateFlags      update_flags,
+                          const Mapping<dim,spacedim>    &mapping,
                           const Quadrature<dim> &quadrature) const
 {
                                   // generate a new data object and
@@ -988,14 +988,14 @@ FE_Nedelec<dim>::get_data (const UpdateFlags      update_flags,
 // Fill data of FEValues
 //---------------------------------------------------------------------------
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Nedelec<dim>::fill_fe_values (const Mapping<dim>                   &mapping,
-                                const typename Triangulation<dim>::cell_iterator &cell,
+FE_Nedelec<dim,spacedim>::fill_fe_values (const Mapping<dim,spacedim>                   &mapping,
+                                const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                 const Quadrature<dim>                &quadrature,
-                                typename Mapping<dim>::InternalDataBase &mapping_data,
-                                typename Mapping<dim>::InternalDataBase &fedata,
-                                FEValuesData<dim>                    &data) const
+                                typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+                                typename Mapping<dim,spacedim>::InternalDataBase &fedata,
+                                FEValuesData<dim,spacedim>                    &data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -1113,15 +1113,15 @@ FE_Nedelec<dim>::fill_fe_values (const Mapping<dim>                   &mapping,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Nedelec<dim>::fill_fe_face_values (const Mapping<dim>                   &mapping,
-                                     const typename Triangulation<dim>::cell_iterator &cell,
+FE_Nedelec<dim,spacedim>::fill_fe_face_values (const Mapping<dim,spacedim>                   &mapping,
+                                     const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                      const unsigned int                    face,
                                      const Quadrature<dim-1>              &quadrature,
-                                     typename Mapping<dim>::InternalDataBase       &mapping_data,
-                                     typename Mapping<dim>::InternalDataBase       &fedata,
-                                     FEValuesData<dim>                    &data) const
+                                     typename Mapping<dim,spacedim>::InternalDataBase       &mapping_data,
+                                     typename Mapping<dim,spacedim>::InternalDataBase       &fedata,
+                                     FEValuesData<dim,spacedim>                    &data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -1261,16 +1261,16 @@ FE_Nedelec<dim>::fill_fe_face_values (const Mapping<dim>                   &mapp
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Nedelec<dim>::fill_fe_subface_values (const Mapping<dim>                   &mapping,
-                                        const typename Triangulation<dim>::cell_iterator &cell,
+FE_Nedelec<dim,spacedim>::fill_fe_subface_values (const Mapping<dim,spacedim>                   &mapping,
+                                        const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                         const unsigned int                    face,
                                         const unsigned int                    subface,
                                         const Quadrature<dim-1>              &quadrature,
-                                        typename Mapping<dim>::InternalDataBase       &mapping_data,
-                                        typename Mapping<dim>::InternalDataBase       &fedata,
-                                        FEValuesData<dim>                    &data) const
+                                        typename Mapping<dim,spacedim>::InternalDataBase       &mapping_data,
+                                        typename Mapping<dim,spacedim>::InternalDataBase       &fedata,
+                                        FEValuesData<dim,spacedim>                    &data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -1407,18 +1407,18 @@ FE_Nedelec<dim>::fill_fe_subface_values (const Mapping<dim>                   &m
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FE_Nedelec<dim>::n_base_elements () const
+FE_Nedelec<dim,spacedim>::n_base_elements () const
 {
   return 1;
 }
 
 
 
-template <int dim>
-const FiniteElement<dim> &
-FE_Nedelec<dim>::base_element (const unsigned int index) const
+template <int dim, int spacedim>
+const FiniteElement<dim,spacedim> &
+FE_Nedelec<dim,spacedim>::base_element (const unsigned int index) const
 {
   Assert (index==0, ExcIndexRange(index, 0, 1));
   return *this;
@@ -1426,9 +1426,9 @@ FE_Nedelec<dim>::base_element (const unsigned int index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FE_Nedelec<dim>::element_multiplicity (const unsigned int index) const
+FE_Nedelec<dim,spacedim>::element_multiplicity (const unsigned int index) const
 {
   Assert (index==0, ExcIndexRange(index, 0, 1));
   return 1;
@@ -1436,9 +1436,9 @@ FE_Nedelec<dim>::element_multiplicity (const unsigned int index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FE_Nedelec<dim>::has_support_on_face (const unsigned int shape_index,
+FE_Nedelec<dim,spacedim>::has_support_on_face (const unsigned int shape_index,
                                      const unsigned int face_index) const
 {
   Assert (shape_index < this->dofs_per_cell,
@@ -1499,9 +1499,9 @@ FE_Nedelec<dim>::has_support_on_face (const unsigned int shape_index,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FE_Nedelec<dim>::memory_consumption () const
+FE_Nedelec<dim,spacedim>::memory_consumption () const
 {
   Assert (false, ExcNotImplemented ());
   return 0;
@@ -1509,9 +1509,9 @@ FE_Nedelec<dim>::memory_consumption () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FE_Nedelec<dim>::get_degree () const
+FE_Nedelec<dim,spacedim>::get_degree () const
 {
   return degree;
 }
index ee3e6496b2d47f28de6681f4096db302b77af93f..d74db073ef98fee52e674a8a2fb3436783215282 100644 (file)
@@ -25,4 +25,11 @@ template class FE_Poly<TensorProductPolynomials<deal_II_dimension>, deal_II_dime
 template class FE_Poly<PolynomialSpace<deal_II_dimension>, deal_II_dimension>;
 template class FE_Poly<PolynomialsP<deal_II_dimension>, deal_II_dimension>;
 
+#if deal_II_dimension != 3
+
+template class FE_Poly<TensorProductPolynomials<deal_II_dimension>, deal_II_dimension, deal_II_dimension+1>;
+template class FE_Poly<PolynomialSpace<deal_II_dimension>, deal_II_dimension, deal_II_dimension+1>;
+//template class FE_Poly<PolynomialsP<deal_II_dimension>, deal_II_dimension, deal_II_dimension+1>;
+
+#endif
 DEAL_II_NAMESPACE_CLOSE
index 34cb8648c44c13572b71ae8f8d4fc2f51d85e79e..6c60bba24ae9c763066458e9aa9044c0dfaf2948 100644 (file)
@@ -52,6 +52,7 @@ namespace
                        std::vector<double>                   &face_sign)
   {
     const unsigned int dim = 2;
+    const unsigned int spacedim = 2;
     
                                     // Default is no sign
                                     // change. I.e. multiply by one.
@@ -60,7 +61,7 @@ namespace
     for (unsigned int f = GeometryInfo<dim>::faces_per_cell / 2; 
         f < GeometryInfo<dim>::faces_per_cell; ++f)
       {
-       Triangulation<dim>::face_iterator face = cell->face (f);
+       Triangulation<dim,spacedim>::face_iterator face = cell->face (f);
        if (!face->at_boundary ())
          {
            const unsigned int neighbor_level = cell->neighbor (f)->level ();
@@ -107,13 +108,13 @@ namespace
 
 
 
-template <class POLY, int dim>
-FE_PolyTensor<POLY,dim>::FE_PolyTensor (const unsigned int degree,
+template <class POLY, int dim, int spacedim>
+FE_PolyTensor<POLY,dim,spacedim>::FE_PolyTensor (const unsigned int degree,
                                        const FiniteElementData<dim> &fe_data,
                                        const std::vector<bool> &restriction_is_additive_flags,
                                        const std::vector<std::vector<bool> > &nonzero_components)
                :
-               FiniteElement<dim> (fe_data,
+               FiniteElement<dim,spacedim> (fe_data,
                                    restriction_is_additive_flags,
                                    nonzero_components),
                 poly_space(POLY(degree))
@@ -132,19 +133,21 @@ FE_PolyTensor<POLY,dim>::FE_PolyTensor (const unsigned int degree,
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 double
-FE_PolyTensor<POLY,dim>::shape_value (const unsigned int, const Point<dim> &) const
+FE_PolyTensor<POLY,dim,spacedim>::shape_value (const unsigned int, const Point<dim> &) const
+
 {
-  Assert(false, typename FiniteElement<dim>::ExcFENotPrimitive());
+  typedef    FiniteElement<dim,spacedim> FEE;
+  Assert(false, typename FEE::ExcFENotPrimitive());
   return 0.;
 }
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 double
-FE_PolyTensor<POLY,dim>::shape_value_component (const unsigned int i,
+FE_PolyTensor<POLY,dim,spacedim>::shape_value_component (const unsigned int i,
                                                const Point<dim> &p,
                                                const unsigned int component) const
 {
@@ -169,20 +172,21 @@ FE_PolyTensor<POLY,dim>::shape_value_component (const unsigned int i,
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 Tensor<1,dim>
-FE_PolyTensor<POLY,dim>::shape_grad (const unsigned int,
+FE_PolyTensor<POLY,dim,spacedim>::shape_grad (const unsigned int,
                                     const Point<dim> &) const
 {
-  Assert(false, typename FiniteElement<dim>::ExcFENotPrimitive());
+  typedef    FiniteElement<dim,spacedim> FEE;
+  Assert(false, typename FEE::ExcFENotPrimitive());
   return Tensor<1,dim>();
 }
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 Tensor<1,dim>
-FE_PolyTensor<POLY,dim>::shape_grad_component (const unsigned int i,
+FE_PolyTensor<POLY,dim,spacedim>::shape_grad_component (const unsigned int i,
                                               const Point<dim> &p,
                                               const unsigned int component) const
 {
@@ -208,19 +212,20 @@ FE_PolyTensor<POLY,dim>::shape_grad_component (const unsigned int i,
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 Tensor<2,dim>
-FE_PolyTensor<POLY,dim>::shape_grad_grad (const unsigned int, const Point<dim> &) const
+FE_PolyTensor<POLY,dim,spacedim>::shape_grad_grad (const unsigned int, const Point<dim> &) const
 {
-  Assert(false, typename FiniteElement<dim>::ExcFENotPrimitive());
+  typedef    FiniteElement<dim,spacedim> FEE;
+  Assert(false, typename FEE::ExcFENotPrimitive());
   return Tensor<2,dim>();
 }
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 Tensor<2,dim>
-FE_PolyTensor<POLY,dim>::shape_grad_grad_component (const unsigned int i,
+FE_PolyTensor<POLY,dim,spacedim>::shape_grad_grad_component (const unsigned int i,
                                                    const Point<dim> &p,
                                                    const unsigned int component) const
 {
@@ -250,10 +255,10 @@ FE_PolyTensor<POLY,dim>::shape_grad_grad_component (const unsigned int i,
 // Data field initialization
 //---------------------------------------------------------------------------
 
-template <class POLY, int dim>
-typename Mapping<dim>::InternalDataBase *
-FE_PolyTensor<POLY,dim>::get_data (const UpdateFlags      update_flags,
-                            const Mapping<dim>    &mapping,
+template <class POLY, int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+FE_PolyTensor<POLY,dim,spacedim>::get_data (const UpdateFlags      update_flags,
+                            const Mapping<dim,spacedim>    &mapping,
                             const Quadrature<dim> &quadrature) const
 {
                                   // generate a new data object and
@@ -350,15 +355,15 @@ FE_PolyTensor<POLY,dim>::get_data (const UpdateFlags      update_flags,
 // Fill data of FEValues
 //---------------------------------------------------------------------------
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 void
-FE_PolyTensor<POLY,dim>::fill_fe_values (
-  const Mapping<dim>                   &mapping,
-  const typename Triangulation<dim>::cell_iterator &cell,
+FE_PolyTensor<POLY,dim,spacedim>::fill_fe_values (
+  const Mapping<dim,spacedim>                   &mapping,
+  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
   const Quadrature<dim>                &quadrature,
-  typename Mapping<dim>::InternalDataBase &mapping_data,
-  typename Mapping<dim>::InternalDataBase &fedata,
-  FEValuesData<dim>                    &data) const
+  typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+  typename Mapping<dim,spacedim>::InternalDataBase &fedata,
+  FEValuesData<dim,spacedim>                    &data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -519,16 +524,16 @@ FE_PolyTensor<POLY,dim>::fill_fe_values (
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 void
-FE_PolyTensor<POLY,dim>::fill_fe_face_values (
-  const Mapping<dim>                   &mapping,
-  const typename Triangulation<dim>::cell_iterator &cell,
+FE_PolyTensor<POLY,dim,spacedim>::fill_fe_face_values (
+  const Mapping<dim,spacedim>                   &mapping,
+  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
   const unsigned int                    face,
   const Quadrature<dim-1>              &quadrature,
-  typename Mapping<dim>::InternalDataBase       &mapping_data,
-  typename Mapping<dim>::InternalDataBase       &fedata,
-  FEValuesData<dim>                    &data) const
+  typename Mapping<dim,spacedim>::InternalDataBase       &mapping_data,
+  typename Mapping<dim,spacedim>::InternalDataBase       &fedata,
+  FEValuesData<dim,spacedim>                    &data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -702,17 +707,17 @@ FE_PolyTensor<POLY,dim>::fill_fe_face_values (
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 void
-FE_PolyTensor<POLY,dim>::fill_fe_subface_values (
-  const Mapping<dim>                   &mapping,
-  const typename Triangulation<dim>::cell_iterator &cell,
+FE_PolyTensor<POLY,dim,spacedim>::fill_fe_subface_values (
+  const Mapping<dim,spacedim>                   &mapping,
+  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
   const unsigned int                    face,
   const unsigned int                    subface,
   const Quadrature<dim-1>              &quadrature,
-  typename Mapping<dim>::InternalDataBase       &mapping_data,
-  typename Mapping<dim>::InternalDataBase       &fedata,
-  FEValuesData<dim>                    &data) const
+  typename Mapping<dim,spacedim>::InternalDataBase       &mapping_data,
+  typename Mapping<dim,spacedim>::InternalDataBase       &fedata,
+  FEValuesData<dim,spacedim>                    &data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -886,18 +891,18 @@ FE_PolyTensor<POLY,dim>::fill_fe_subface_values (
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 unsigned int
-FE_PolyTensor<POLY,dim>::n_base_elements () const
+FE_PolyTensor<POLY,dim,spacedim>::n_base_elements () const
 {
   return 1;
 }
 
 
 
-template <class POLY, int dim>
-const FiniteElement<dim> &
-FE_PolyTensor<POLY,dim>::base_element (const unsigned int index) const
+template <class POLY, int dim, int spacedim>
+const FiniteElement<dim,spacedim> &
+FE_PolyTensor<POLY,dim,spacedim>::base_element (const unsigned int index) const
 {
   Assert (index==0, ExcIndexRange(index, 0, 1));
   return *this;
@@ -905,18 +910,18 @@ FE_PolyTensor<POLY,dim>::base_element (const unsigned int index) const
 
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 unsigned int
-FE_PolyTensor<POLY,dim>::element_multiplicity (const unsigned int index) const
+FE_PolyTensor<POLY,dim,spacedim>::element_multiplicity (const unsigned int index) const
 {
   Assert (index==0, ExcIndexRange(index, 0, 1));
   return 1;
 }
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 UpdateFlags
-FE_PolyTensor<POLY,dim>::update_once (const UpdateFlags flags) const
+FE_PolyTensor<POLY,dim,spacedim>::update_once (const UpdateFlags flags) const
 {
   Assert (mapping_type != no_mapping, ExcNotInitialized());
   const bool values_once = (mapping_type == independent);
@@ -930,9 +935,9 @@ FE_PolyTensor<POLY,dim>::update_once (const UpdateFlags flags) const
 }
 
 
-template <class POLY, int dim>
+template <class POLY, int dim, int spacedim>
 UpdateFlags
-FE_PolyTensor<POLY,dim>::update_each (const UpdateFlags flags) const
+FE_PolyTensor<POLY,dim,spacedim>::update_each (const UpdateFlags flags) const
 {
   Assert (mapping_type != no_mapping, ExcNotInitialized());
   const bool values_once = (mapping_type == independent);
@@ -945,13 +950,18 @@ FE_PolyTensor<POLY,dim>::update_each (const UpdateFlags flags) const
     out |= update_gradients          | update_covariant_transformation;
   if (flags & update_hessians)
     out |= update_hessians | update_covariant_transformation;
+  if (flags & update_cell_normal_vectors)
+    out |= update_cell_normal_vectors | update_JxW_values;
 
   return out;
 }
 
 
+
 template class FE_PolyTensor<PolynomialsRaviartThomas<deal_II_dimension>,deal_II_dimension>;
 template class FE_PolyTensor<PolynomialsABF<deal_II_dimension>,deal_II_dimension>;
 template class FE_PolyTensor<PolynomialsBDM<deal_II_dimension>,deal_II_dimension>;
 
+
+
 DEAL_II_NAMESPACE_CLOSE
index 5377a8fb474045f469d9df285b904c080abf9dd2..6c1790dd48add5e269c603cf0ef866f73b2a07f6 100644 (file)
@@ -38,7 +38,7 @@ DEAL_II_NAMESPACE_OPEN
 //   static void SYMBOL (const int2type<1> & ) {}
 // }
 // 
-// template <int dim> void g() {
+// template <int dim, int spacedim> void g() {
 //   SYMBOL(int2type<dim>());
 // }
 //
@@ -174,10 +174,379 @@ namespace FE_Q_Helper
 
 
 
-template <int dim>
-FE_Q<dim>::FE_Q (const unsigned int degree)
+/**
+ * A class with the same purpose as the similarly named class of the
+ * Triangulation class. See there for more information.
+ */
+template <int xdim, int xspacedim>
+struct FE_Q<xdim,xspacedim>::Implementation
+{
+                                    /**
+                                     * Initialize the hanging node
+                                     * constraints matrices. Called from the
+                                     * constructor in case the finite element
+                                     * is based on quadrature points.
+                                     */
+    template <int spacedim>
+    static
+    void initialize_constraints (const Quadrature<1> &,
+                                FE_Q<1,spacedim>    &)
+      {
+                                        // no constraints in 1d
+      }
+
+
+    template <int spacedim>
+    static
+    void initialize_constraints (const Quadrature<1> &points,
+                                FE_Q<2,spacedim>    &fe)
+      {
+       const unsigned int dim = 2;
+
+                                        // restricted to each face, the
+                                        // traces of the shape functions is
+                                        // an element of P_{k} (in 2d), or
+                                        // Q_{k} (in 3d), where k is the
+                                        // degree of the element.  from
+                                        // this, we interpolate between
+                                        // mother and cell face.
+
+                                        // the interpolation process works
+                                        // as followings: on each subface,
+                                        // we want that finite element
+                                        // solutions from both sides
+                                        // coincide. i.e. if a and b are
+                                        // expansion coefficients for the
+                                        // shape functions from both sides,
+                                        // we seek a relation between x and
+                                        // y such that
+                                        //   sum_j a_j phi^c_j(x)
+                                        //   == sum_j b_j phi_j(x)  
+                                        // for all points x on the
+                                        // interface. here, phi^c_j are the
+                                        // shape functions on the small
+                                        // cell on one side of the face,
+                                        // and phi_j those on the big cell
+                                        // on the other side. To get this
+                                        // relation, it suffices to look at
+                                        // a sufficient number of points
+                                        // for which this has to hold. if
+                                        // there are n functions, then we
+                                        // need n evaluation points, and we
+                                        // choose them equidistantly.
+                                        //
+                                        // we obtain the matrix system
+                                        //    A a  ==  B b
+                                        // where
+                                        //    A_ij = phi^c_j(x_i)
+                                        //    B_ij = phi_j(x_i)
+                                        // and the relation we are looking
+                                        // for is
+                                        //    a = A^-1 B b
+                                        //
+                                        // for the special case of Lagrange
+                                        // interpolation polynomials, A_ij
+                                        // reduces to delta_ij, and
+                                        //    a_i = B_ij b_j
+                                        // Hence,
+                                        // interface_constraints(i,j)=B_ij.
+                                        //
+                                        // for the general case, where we
+                                        // don't have Lagrange
+                                        // interpolation polynomials, this
+                                        // is a little more
+                                        // complicated. Then we would
+                                        // evaluate at a number of points
+                                        // and invert the interpolation
+                                        // matrix A.
+                                        //
+                                        // Note, that we build up these
+                                        // matrices for all subfaces at
+                                        // once, rather than considering
+                                        // them separately. the reason is
+                                        // that we finally will want to
+                                        // have them in this order anyway,
+                                        // as this is the format we need
+                                        // inside deal.II
+
+                                        // In the following the points x_i
+                                        // are constructed in following
+                                        // order (n=degree-1)
+                                        // *----------*---------*
+                                        //     1..n   0  n+1..2n
+                                        // i.e. first the midpoint of the
+                                        // line, then the support points on
+                                        // subface 0 and on subface 1
+       std::vector<Point<dim-1> > constraint_points;
+                                        // Add midpoint
+       constraint_points.push_back (Point<dim-1> (0.5));
+
+       if (fe.degree>1)
+         {
+           const unsigned int n=fe.degree-1;
+           const double step=1./fe.degree;
+                                            // subface 0
+           for (unsigned int i=1; i<=n; ++i)
+             constraint_points.push_back (
+               GeometryInfo<dim-1>::child_to_cell_coordinates(Point<dim-1>(i*step),0));
+                                            // subface 1
+           for (unsigned int i=1; i<=n; ++i)
+             constraint_points.push_back (
+               GeometryInfo<dim-1>::child_to_cell_coordinates(Point<dim-1>(i*step),1));
+         }
+
+                                        // Now construct relation between
+                                        // destination (child) and source (mother)
+                                        // dofs.
+       const std::vector<Polynomials::Polynomial<double> > polynomials=
+         Polynomials::Lagrange::generate_complete_basis(points.get_points());
+
+       fe.interface_constraints
+         .TableBase<2,double>::reinit (fe.interface_constraints_size());
+
+       for (unsigned int i=0; i<constraint_points.size(); ++i)
+         for (unsigned j=0; j<fe.degree+1; ++j)
+           {
+             fe.interface_constraints(i,j) = 
+               polynomials[fe.face_index_map[j]].value (constraint_points[i](0));
+                   
+                                              // if the value is small up
+                                              // to round-off, then
+                                              // simply set it to zero to
+                                              // avoid unwanted fill-in
+                                              // of the constraint
+                                              // matrices (which would
+                                              // then increase the number
+                                              // of other DoFs a
+                                              // constrained DoF would
+                                              // couple to)
+             if (std::fabs(fe.interface_constraints(i,j)) < 1e-14)
+               fe.interface_constraints(i,j) = 0;
+           }
+      }
+
+
+    template <int spacedim>
+    static
+    void initialize_constraints (const Quadrature<1> &points,
+                                FE_Q<3,spacedim>    &fe)
+      {
+       const unsigned int dim = 3;
+
+                                        // For a detailed documentation of
+                                        // the interpolation see the
+                                        // FE_Q<2>::initialize_constraints
+                                        // function.
+
+                                        // In the following the points x_i
+                                        // are constructed in the order as
+                                        // described in the documentation
+                                        // of the FiniteElement class
+                                        // (fe_base.h), i.e.
+                                        //   *--15--4--16--*
+                                        //   |      |      |
+                                        //   10 19  6  20  12
+                                        //   |      |      |
+                                        //   1--7---0--8---2
+                                        //   |      |      |
+                                        //   9  17  5  18  11
+                                        //   |      |      |
+                                        //   *--13--3--14--*
+       std::vector<Point<dim-1> > constraint_points;
+
+                                        // Add midpoint
+       constraint_points.push_back (Point<dim-1> (0.5, 0.5));
+
+                                        // Add midpoints of lines of
+                                        // "mother-face"
+       constraint_points.push_back (Point<dim-1> (0, 0.5));
+       constraint_points.push_back (Point<dim-1> (1, 0.5));
+       constraint_points.push_back (Point<dim-1> (0.5, 0));
+       constraint_points.push_back (Point<dim-1> (0.5, 1));
+
+       if (fe.degree>1)
+         {
+           const unsigned int n=fe.degree-1;
+           const double step=1./fe.degree;
+           std::vector<Point<dim-2> > line_support_points(n);
+           for (unsigned int i=0; i<n; ++i)
+             line_support_points[i](0)=(i+1)*step;
+           Quadrature<dim-2> qline(line_support_points);
+
+                                            // auxiliary points in 2d
+           std::vector<Point<dim-1> > p_line(n);
+  
+                                            // Add nodes of lines interior
+                                            // in the "mother-face"
+
+                                            // line 5: use line 9
+           QProjector<dim-1>::project_to_subface(qline, 0, 0, p_line);
+           for (unsigned int i=0; i<n; ++i)
+             constraint_points.push_back (p_line[i] + Point<dim-1> (0.5, 0));
+                                            // line 6: use line 10
+           QProjector<dim-1>::project_to_subface(qline, 0, 1, p_line);
+           for (unsigned int i=0; i<n; ++i)
+             constraint_points.push_back (p_line[i] + Point<dim-1> (0.5, 0));
+                                            // line 7: use line 13
+           QProjector<dim-1>::project_to_subface(qline, 2, 0, p_line);
+           for (unsigned int i=0; i<n; ++i)
+             constraint_points.push_back (p_line[i] + Point<dim-1> (0, 0.5));
+                                            // line 8: use line 14
+           QProjector<dim-1>::project_to_subface(qline, 2, 1, p_line);
+           for (unsigned int i=0; i<n; ++i)
+             constraint_points.push_back (p_line[i] + Point<dim-1> (0, 0.5));
+      
+                                            // DoFs on bordering lines
+                                            // lines 9-16
+           for (unsigned int face=0; face<GeometryInfo<dim-1>::faces_per_cell; ++face)
+             for (unsigned int subface=0;
+                  subface<GeometryInfo<dim-1>::max_children_per_face; ++subface)
+               {
+                 QProjector<dim-1>::project_to_subface(qline, face, subface, p_line);
+                 constraint_points.insert(constraint_points.end(),
+                                          p_line.begin(), p_line.end());
+               }
+      
+                                            // Create constraints for
+                                            // interior nodes
+           std::vector<Point<dim-1> > inner_points(n*n);
+           for (unsigned int i=0, iy=1; iy<=n; ++iy)
+             for (unsigned int ix=1; ix<=n; ++ix)
+               inner_points[i++] = Point<dim-1> (ix*step, iy*step);
+      
+           for (unsigned int child=0; 
+                child<GeometryInfo<dim-1>::max_children_per_cell; ++child)
+             for (unsigned int i=0; i<inner_points.size(); ++i)
+               constraint_points.push_back (
+                 GeometryInfo<dim-1>::child_to_cell_coordinates(inner_points[i], child));
+         }
+
+                                        // Now construct relation between
+                                        // destination (child) and source (mother)
+                                        // dofs.
+       const unsigned int pnts=(fe.degree+1)*(fe.degree+1); 
+       const std::vector<Polynomials::Polynomial<double> > polynomial_basis=
+         Polynomials::Lagrange::generate_complete_basis(points.get_points()); 
+
+       const TensorProductPolynomials<dim-1> face_polynomials(polynomial_basis);
+
+       fe.interface_constraints
+         .TableBase<2,double>::reinit (fe.interface_constraints_size());
+
+       for (unsigned int i=0; i<constraint_points.size(); ++i)
+         {
+           const double interval = (double) (fe.degree * 2);
+           bool mirror[dim - 1];
+           Point<dim-1> constraint_point;
+
+                                            // Eliminate FP errors in constraint
+                                            // points. Due to their origin, they
+                                            // must all be fractions of the unit
+                                            // interval. If we have polynomial
+                                            // degree 4, the refined element has 8
+                                            // intervals.  Hence the coordinates
+                                            // must be 0, 0.125, 0.25, 0.375 etc.
+                                            // Now the coordinates of the
+                                            // constraint points will be multiplied
+                                            // by the inverse of the interval size
+                                            // (in the example by 8).  After that
+                                            // the coordinates must be integral
+                                            // numbers. Hence a normal truncation
+                                            // is performed and the coordinates
+                                            // will be scaled back. The equal
+                                            // treatment of all coordinates should
+                                            // eliminate any FP errors.
+           for (unsigned int k=0; k<dim-1; ++k)
+             {
+               const int coord_int =
+                 static_cast<int> (constraint_points[i](k) * interval + 0.25);
+               constraint_point(k) = 1.*coord_int / interval;
+
+                                                // The following lines of code
+                                                // should eliminate the problems
+                                                // with the Constraint-Matrix,
+                                                // which appeared for P>=4. The
+                                                // Constraint-Matrix class
+                                                // complained about different
+                                                // constraints for the same entry
+                                                // of the Constraint-Matrix.
+                                                // Actually this difference could
+                                                // be attributed to FP errors, as
+                                                // it was in the range of
+                                                // 1.0e-16. These errors originate
+                                                // in the loss of symmetry in the
+                                                // FP approximation of the
+                                                // shape-functions.  Considering a
+                                                // 3rd order shape function in 1D,
+                                                // we have N0(x)=N3(1-x) and
+                                                // N1(x)=N2(1-x).  For higher order
+                                                // polynomials the FP
+                                                // approximations of the shape
+                                                // functions do not satisfy these
+                                                // equations any more!  Thus in the
+                                                // following code everything is
+                                                // computed in the interval x \in
+                                                // [0..0.5], which is sufficient to
+                                                // express all values that could
+                                                // come out from a computation of
+                                                // any shape function in the full
+                                                // interval [0..1]. If x > 0.5 the
+                                                // computation is done for 1-x with
+                                                // the shape function N_{p-n}
+                                                // instead of N_n.  Hence symmetry
+                                                // is preserved and everything
+                                                // works fine...
+                                                //
+                                                // For a different explanation of
+                                                // the problem, see the discussion
+                                                // in the FiniteElement class
+                                                // for constraint matrices in 3d.
+               mirror[k] = (constraint_point(k) > 0.5);
+               if (mirror[k])
+                 constraint_point(k) = 1.0 - constraint_point(k);
+             }
+
+           for (unsigned j=0; j<pnts; ++j)
+             {
+               unsigned int indices[2]
+                 = { fe.face_index_map[j] % (fe.degree + 1),
+                     fe.face_index_map[j] / (fe.degree + 1) };
+          
+               for (unsigned int k = 0; k<2; ++k)
+                 if (mirror[k])
+                   indices[k] = fe.degree - indices[k];
+          
+               const unsigned int
+                 new_index = indices[1] * (fe.degree + 1) + indices[0];
+
+               fe.interface_constraints(i,j) = 
+                 face_polynomials.compute_value (new_index, constraint_point);
+           
+                                                // if the value is small up
+                                                // to round-off, then
+                                                // simply set it to zero to
+                                                // avoid unwanted fill-in
+                                                // of the constraint
+                                                // matrices (which would
+                                                // then increase the number
+                                                // of other DoFs a
+                                                // constrained DoF would
+                                                // couple to)
+               if (std::fabs(fe.interface_constraints(i,j)) < 1e-14)
+                 fe.interface_constraints(i,j) = 0;
+             }
+         }
+      }
+};
+
+
+    
+
+
+template <int dim, int spacedim>
+FE_Q<dim,spacedim>::FE_Q (const unsigned int degree)
                :
-               FE_Poly<TensorProductPolynomials<dim>, dim> (
+               FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
                  TensorProductPolynomials<dim>(Polynomials::LagrangeEquidistant::generate_complete_basis(degree)),
                  FiniteElementData<dim>(get_dpo_vector(degree),
                                         1, degree,
@@ -210,10 +579,10 @@ FE_Q<dim>::FE_Q (const unsigned int degree)
 
 
 
-template <int dim>
-FE_Q<dim>::FE_Q (const Quadrature<1> &points)
+template <int dim, int spacedim>
+FE_Q<dim,spacedim>::FE_Q (const Quadrature<1> &points)
                :
-               FE_Poly<TensorProductPolynomials<dim>, dim> (
+               FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
                  TensorProductPolynomials<dim>(Polynomials::Lagrange::generate_complete_basis(points.get_points())),
                  FiniteElementData<dim>(get_dpo_vector(points.n_quadrature_points-1),
                                         1, points.n_quadrature_points-1,
@@ -243,7 +612,7 @@ FE_Q<dim>::FE_Q (const Quadrature<1> &points)
 
                                   // compute constraint, embedding
                                   // and restriction matrices
-  initialize_constraints (points);
+  Implementation::initialize_constraints (points, *this);
 
                                   // Reinit the vectors of
                                   // restriction and prolongation
@@ -262,9 +631,9 @@ FE_Q<dim>::FE_Q (const Quadrature<1> &points)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::string
-FE_Q<dim>::get_name () const
+FE_Q<dim,spacedim>::get_name () const
 {
                                   // note that the
                                   // FETools::get_fe_from_name
@@ -335,28 +704,31 @@ FE_Q<dim>::get_name () const
 
 
 
-template <int dim>
-FiniteElement<dim> *
-FE_Q<dim>::clone() const
+template <int dim, int spacedim>
+FiniteElement<dim,spacedim> *
+FE_Q<dim,spacedim>::clone() const
 {
-  return new FE_Q<dim>(*this);
+  return new FE_Q<dim,spacedim>(*this);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Q<dim>::
-get_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_Q<dim,spacedim>::
+get_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                          FullMatrix<double>       &interpolation_matrix) const
 {
                                   // this is only implemented, if the
                                   // source FE is also a
                                   // Q element
+  typedef FE_Q<dim,spacedim> FEQ;
+  typedef FiniteElement<dim,spacedim> FEL;
+
   AssertThrow ((x_source_fe.get_name().find ("FE_Q<") == 0)
                ||
-               (dynamic_cast<const FE_Q<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
+               (dynamic_cast<const FEQ*>(&x_source_fe) != 0),
+               typename FEL::
                ExcInterpolationNotImplemented());
   
   Assert (interpolation_matrix.m() == this->dofs_per_cell,
@@ -368,8 +740,8 @@ get_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
                                   // ok, source is a Q element, so
                                   // we will be able to do the work
-  const FE_Q<dim> &source_fe
-    = dynamic_cast<const FE_Q<dim>&>(x_source_fe);
+  const FE_Q<dim,spacedim> &source_fe
+    = dynamic_cast<const FE_Q<dim,spacedim>&>(x_source_fe);
 
                                   // compute the interpolation
                                   // matrices in much the same way as
@@ -452,24 +824,53 @@ get_subface_interpolation_matrix (const FiniteElement<1> &/*x_source_fe*/,
          ExcInterpolationNotImplemented ());
 }
 
+
+template <>
+void
+FE_Q<1,2>::
+get_face_interpolation_matrix (const FiniteElement<1,2> &/*x_source_fe*/,
+                              FullMatrix<double>     &/*interpolation_matrix*/) const
+{
+  typedef FiniteElement<1,2> FEL;
+  Assert (false,
+         FEL::
+          ExcInterpolationNotImplemented ());
+}
+
+
+template <>
+void
+FE_Q<1,2>::
+get_subface_interpolation_matrix (const FiniteElement<1,2> &/*x_source_fe*/,
+                                 const unsigned int      /*subface*/,
+                                 FullMatrix<double>     &/*interpolation_matrix*/) const
+{
+  typedef FiniteElement<1,2> FEL;
+  Assert (false,
+         FEL::
+         ExcInterpolationNotImplemented ());
+}
+
 #endif
 
 
 #if deal_II_dimension > 1
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Q<dim>::
-get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_Q<dim,spacedim>::
+get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                               FullMatrix<double>       &interpolation_matrix) const
 {
                                   // this is only implemented, if the
                                   // source FE is also a
                                   // Q element
+  typedef FE_Q<dim,spacedim> FEQ;
+  typedef FiniteElement<dim,spacedim> FEL;
   AssertThrow ((x_source_fe.get_name().find ("FE_Q<") == 0)
                ||
-               (dynamic_cast<const FE_Q<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
+               (dynamic_cast<const FEQ*>(&x_source_fe) != 0),
+               typename FEL::
                ExcInterpolationNotImplemented());
   
   Assert (interpolation_matrix.n() == this->dofs_per_face,
@@ -481,8 +882,8 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
                                   // ok, source is a Q element, so
                                   // we will be able to do the work
-  const FE_Q<dim> &source_fe
-    = dynamic_cast<const FE_Q<dim>&>(x_source_fe);
+  const FE_Q<dim,spacedim> &source_fe
+    = dynamic_cast<const FE_Q<dim,spacedim>&>(x_source_fe);
 
                                   // Make sure, that the element,
                                    // for which the DoFs should be
@@ -496,7 +897,7 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                    // hp procedures, which use this
                                   // method.
   Assert (this->dofs_per_face <= source_fe.dofs_per_face,
-         typename FiniteElement<dim>::
+         typename FEL::
          ExcInterpolationNotImplemented ());
   
                                    // generate a quadrature
@@ -512,7 +913,7 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                   // given polynomial degree.
                                   // This value is used to cut
                                   // off values close to zero.
-  double eps = 2e-13*this->degree*(dim-1);
+  const double eps = 2e-13*this->degree*(dim-1);
   
                                   // compute the interpolation
                                   // matrix by simply taking the
@@ -564,20 +965,22 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Q<dim>::
-get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FE_Q<dim,spacedim>::
+get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                                  const unsigned int        subface,
                                  FullMatrix<double>       &interpolation_matrix) const
 {
                                   // this is only implemented, if the
                                   // source FE is also a
                                   // Q element
+  typedef FE_Q<dim,spacedim> FEQ;
+  typedef FiniteElement<dim,spacedim> FEL;
   AssertThrow ((x_source_fe.get_name().find ("FE_Q<") == 0)
                ||
-               (dynamic_cast<const FE_Q<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
+               (dynamic_cast<const FEQ*>(&x_source_fe) != 0),
+               typename FEL::
                ExcInterpolationNotImplemented());
   
   Assert (interpolation_matrix.n() == this->dofs_per_face,
@@ -589,8 +992,8 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
                                   // ok, source is a Q element, so
                                   // we will be able to do the work
-  const FE_Q<dim> &source_fe
-    = dynamic_cast<const FE_Q<dim>&>(x_source_fe);
+  const FE_Q<dim,spacedim> &source_fe
+    = dynamic_cast<const FE_Q<dim,spacedim>&>(x_source_fe);
 
                                   // Make sure, that the element,
                                    // for which the DoFs should be
@@ -604,7 +1007,7 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                    // hp procedures, which use this
                                   // method.
   Assert (this->dofs_per_face <= source_fe.dofs_per_face,
-         typename FiniteElement<dim>::
+         typename FEL::
          ExcInterpolationNotImplemented ());
   
                                    // generate a point on this
@@ -671,9 +1074,9 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 #endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FE_Q<dim>::hp_constraints_are_implemented () const
+FE_Q<dim,spacedim>::hp_constraints_are_implemented () const
 {
   return true;
 }
@@ -681,10 +1084,10 @@ FE_Q<dim>::hp_constraints_are_implemented () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_Q<dim>::
-hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
+FE_Q<dim,spacedim>::
+hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // we can presently only compute
                                   // these identities if both FEs are
@@ -692,7 +1095,7 @@ hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
                                   // should be exactly one single DoF
                                   // of each FE at a vertex, and they
                                   // should have identical value
-  if (dynamic_cast<const FE_Q<dim>*>(&fe_other) != 0)
+  if (dynamic_cast<const FE_Q<dim,spacedim>*>(&fe_other) != 0)
     return
       std::vector<std::pair<unsigned int, unsigned int> > (1, std::make_pair (0U, 0U));
   else
@@ -704,15 +1107,15 @@ hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_Q<dim>::
-hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
+FE_Q<dim,spacedim>::
+hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // we can presently only compute
                                   // these identities if both FEs are
                                   // FE_Qs
-  if (const FE_Q<dim> *fe_q_other = dynamic_cast<const FE_Q<dim>*>(&fe_other))
+  if (const FE_Q<dim,spacedim> *fe_q_other = dynamic_cast<const FE_Q<dim,spacedim>*>(&fe_other))
     {
                                       // dofs are located along
                                       // lines, so two dofs are
@@ -747,15 +1150,15 @@ hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FE_Q<dim>::
-hp_quad_dof_identities (const FiniteElement<dim>        &fe_other) const
+FE_Q<dim,spacedim>::
+hp_quad_dof_identities (const FiniteElement<dim,spacedim>        &fe_other) const
 {
                                   // we can presently only compute
                                   // these identities if both FEs are
                                   // FE_Qs
-  if (const FE_Q<dim> *fe_q_other = dynamic_cast<const FE_Q<dim>*>(&fe_other))
+  if (const FE_Q<dim,spacedim> *fe_q_other = dynamic_cast<const FE_Q<dim,spacedim>*>(&fe_other))
     {
                                       // this works exactly like the line
                                       // case above, except that now we
@@ -792,13 +1195,13 @@ hp_quad_dof_identities (const FiniteElement<dim>        &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 FiniteElementDomination::Domination
-FE_Q<dim>::
-compare_for_face_domination (const FiniteElement<dim> &fe_other) const
+FE_Q<dim,spacedim>::
+compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const
 {
-  if (const FE_Q<dim> *fe_q_other
-      = dynamic_cast<const FE_Q<dim>*>(&fe_other))
+  if (const FE_Q<dim,spacedim> *fe_q_other
+      = dynamic_cast<const FE_Q<dim,spacedim>*>(&fe_other))
     {
       if (this->degree < fe_q_other->degree)
        return FiniteElementDomination::this_element_dominates;
@@ -819,8 +1222,8 @@ compare_for_face_domination (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
-void FE_Q<dim>::initialize_unit_support_points ()
+template <int dim, int spacedim>
+void FE_Q<dim,spacedim>::initialize_unit_support_points ()
 {
                                   // number of points: (degree+1)^dim
   unsigned int n = this->degree+1;
@@ -852,8 +1255,8 @@ void FE_Q<dim>::initialize_unit_support_points ()
 
 
 
-template <int dim>
-void FE_Q<dim>::initialize_unit_support_points (const Quadrature<1> &points)
+template <int dim, int spacedim>
+void FE_Q<dim,spacedim>::initialize_unit_support_points (const Quadrature<1> &points)
 {
                                   // number of points: (degree+1)^dim
   unsigned int n = this->degree+1;
@@ -890,11 +1293,23 @@ void FE_Q<1>::initialize_unit_face_support_points (const Quadrature<1> &/*points
                                   // no faces in 1d, so nothing to do
 }
 
+template <>
+void FE_Q<1,2>::initialize_unit_face_support_points ()
+{
+                                  // no faces in 1d, so nothing to do
+}
+
+template <>
+void FE_Q<1,2>::initialize_unit_face_support_points (const Quadrature<1> &/*points*/)
+{
+                                  // no faces in 1d, so nothing to do
+}
+
 #endif
 
 
-template <int dim>
-void FE_Q<dim>::initialize_unit_face_support_points ()
+template <int dim, int spacedim>
+void FE_Q<dim,spacedim>::initialize_unit_face_support_points ()
 {
   const unsigned int codim = dim-1;
   
@@ -928,8 +1343,8 @@ void FE_Q<dim>::initialize_unit_face_support_points ()
 
 
 
-template <int dim>
-void FE_Q<dim>::initialize_unit_face_support_points (const Quadrature<1> &points)
+template <int dim, int spacedim>
+void FE_Q<dim,spacedim>::initialize_unit_face_support_points (const Quadrature<1> &points)
 {
   const unsigned int codim = dim-1;
   
@@ -964,9 +1379,9 @@ void FE_Q<dim>::initialize_unit_face_support_points (const Quadrature<1> &points
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Q<dim>::initialize_quad_dof_index_permutation ()
+FE_Q<dim,spacedim>::initialize_quad_dof_index_permutation ()
 {
                                   // general template for 1D and 2D, do nothing
 }
@@ -1044,9 +1459,9 @@ FE_Q<3>::initialize_quad_dof_index_permutation ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<unsigned int>
-FE_Q<dim>::get_dpo_vector(const unsigned int deg)
+FE_Q<dim,spacedim>::get_dpo_vector(const unsigned int deg)
 {
   std::vector<unsigned int> dpo(dim+1, 1U);
   for (unsigned int i=1; i<dpo.size(); ++i)
@@ -1055,10 +1470,9 @@ FE_Q<dim>::get_dpo_vector(const unsigned int deg)
 }
 
 
-
-template <int dim>
+template <int dim, int spacedim>
 std::vector<unsigned int>
-FE_Q<dim>::face_lexicographic_to_hierarchic_numbering (const unsigned int degree)
+FE_Q<dim,spacedim>::face_lexicographic_to_hierarchic_numbering (const unsigned int degree)
 {
   const FiniteElementData<dim-1> face_data(FE_Q<dim-1>::get_dpo_vector(degree),1,degree);
   std::vector<unsigned int> face_renumber (face_data.dofs_per_cell);  
@@ -1076,385 +1490,29 @@ FE_Q<1>::face_lexicographic_to_hierarchic_numbering (const unsigned int)
   return std::vector<unsigned int>();
 }
 
-#endif
-
-
-
-template <int dim>
-void
-FE_Q<dim>::initialize_constraints ()
-{
-  QTrapez<1> trapez;
-  QIterated<1> points (trapez,this->degree);
-  initialize_constraints (points);
-}
-
-
-#if deal_II_dimension == 1
-
 template <>
-void
-FE_Q<1>::initialize_constraints (const Quadrature<1> &/*points*/)
-{
-                                  // no constraints in 1d
-}
-
-#endif
-
-
-#if deal_II_dimension == 2
-
-template <>
-void
-FE_Q<2>::initialize_constraints (const Quadrature<1> &points)
+std::vector<unsigned int>
+FE_Q<1,2>::face_lexicographic_to_hierarchic_numbering (const unsigned int)
 {
-  const unsigned int dim = 2;
-
-                                  // restricted to each face, the
-                                  // traces of the shape functions is
-                                  // an element of P_{k} (in 2d), or
-                                  // Q_{k} (in 3d), where k is the
-                                  // degree of the element.  from
-                                  // this, we interpolate between
-                                  // mother and cell face.
-
-                                  // the interpolation process works
-                                  // as followings: on each subface,
-                                  // we want that finite element
-                                  // solutions from both sides
-                                  // coincide. i.e. if a and b are
-                                  // expansion coefficients for the
-                                  // shape functions from both sides,
-                                  // we seek a relation between x and
-                                  // y such that
-                                  //   sum_j a_j phi^c_j(x)
-                                  //   == sum_j b_j phi_j(x)  
-                                  // for all points x on the
-                                  // interface. here, phi^c_j are the
-                                  // shape functions on the small
-                                  // cell on one side of the face,
-                                  // and phi_j those on the big cell
-                                  // on the other side. To get this
-                                  // relation, it suffices to look at
-                                  // a sufficient number of points
-                                  // for which this has to hold. if
-                                  // there are n functions, then we
-                                  // need n evaluation points, and we
-                                  // choose them equidistantly.
-                                  //
-                                  // we obtain the matrix system
-                                  //    A a  ==  B b
-                                  // where
-                                  //    A_ij = phi^c_j(x_i)
-                                  //    B_ij = phi_j(x_i)
-                                  // and the relation we are looking
-                                  // for is
-                                  //    a = A^-1 B b
-                                  //
-                                  // for the special case of Lagrange
-                                  // interpolation polynomials, A_ij
-                                  // reduces to delta_ij, and
-                                  //    a_i = B_ij b_j
-                                  // Hence,
-                                  // interface_constraints(i,j)=B_ij.
-                                  //
-                                  // for the general case, where we
-                                  // don't have Lagrange
-                                  // interpolation polynomials, this
-                                  // is a little more
-                                  // complicated. Then we would
-                                  // evaluate at a number of points
-                                  // and invert the interpolation
-                                  // matrix A.
-                                  //
-                                  // Note, that we build up these
-                                  // matrices for all subfaces at
-                                  // once, rather than considering
-                                  // them separately. the reason is
-                                  // that we finally will want to
-                                  // have them in this order anyway,
-                                  // as this is the format we need
-                                  // inside deal.II
-
-                                  // In the following the points x_i
-                                  // are constructed in following
-                                  // order (n=degree-1)
-                                  // *----------*---------*
-                                  //     1..n   0  n+1..2n
-                                  // i.e. first the midpoint of the
-                                  // line, then the support points on
-                                  // subface 0 and on subface 1
-  std::vector<Point<dim-1> > constraint_points;
-                                   // Add midpoint
-  constraint_points.push_back (Point<dim-1> (0.5));
-
-  if (this->degree>1)
-    {
-      const unsigned int n=this->degree-1;
-      const double step=1./this->degree;
-                                      // subface 0
-      for (unsigned int i=1; i<=n; ++i)
-       constraint_points.push_back (
-         GeometryInfo<dim-1>::child_to_cell_coordinates(Point<dim-1>(i*step),0));
-                                      // subface 1
-      for (unsigned int i=1; i<=n; ++i)
-       constraint_points.push_back (
-         GeometryInfo<dim-1>::child_to_cell_coordinates(Point<dim-1>(i*step),1));
-    }
-
-                                   // Now construct relation between
-                                   // destination (child) and source (mother)
-                                   // dofs.
-  const std::vector<Polynomials::Polynomial<double> > polynomials=
-    Polynomials::Lagrange::generate_complete_basis(points.get_points());
-
-  this->interface_constraints
-    .TableBase<2,double>::reinit (this->interface_constraints_size());
-
-  for (unsigned int i=0; i<constraint_points.size(); ++i)
-    for (unsigned j=0; j<this->degree+1; ++j)
-      {
-       this->interface_constraints(i,j) = 
-         polynomials[face_index_map[j]].value (constraint_points[i](0));
-                   
-                                   // if the value is small up
-                                   // to round-off, then
-                                  // simply set it to zero to
-                                   // avoid unwanted fill-in
-                                   // of the constraint
-                                   // matrices (which would
-                                   // then increase the number
-                                   // of other DoFs a
-                                   // constrained DoF would
-                                   // couple to)
-          if (std::fabs(this->interface_constraints(i,j)) < 1e-14)
-            this->interface_constraints(i,j) = 0;
-      }
+  return std::vector<unsigned int>();
 }
 
 #endif
 
-#if deal_II_dimension == 3
-
-template <>
+template <int dim, int spacedim>
 void
-FE_Q<3>::initialize_constraints (const Quadrature<1> &points)
+FE_Q<dim,spacedim>::initialize_constraints ()
 {
-  const unsigned int dim = 3;
-
-                                  // For a detailed documentation of
-                                  // the interpolation see the
-                                  // FE_Q<2>::initialize_constraints
-                                  // function.
-
-                                  // In the following the points x_i
-                                  // are constructed in the order as
-                                  // described in the documentation
-                                  // of the FiniteElement class
-                                  // (fe_base.h), i.e.
-                                  //   *--15--4--16--*
-                                  //   |      |      |
-                                  //   10 19  6  20  12
-                                  //   |      |      |
-                                  //   1--7---0--8---2
-                                  //   |      |      |
-                                  //   9  17  5  18  11
-                                  //   |      |      |
-                                  //   *--13--3--14--*
-  std::vector<Point<dim-1> > constraint_points;
-
-                                   // Add midpoint
-  constraint_points.push_back (Point<dim-1> (0.5, 0.5));
-
-                                   // Add midpoints of lines of
-                                   // "mother-face"
-  constraint_points.push_back (Point<dim-1> (0, 0.5));
-  constraint_points.push_back (Point<dim-1> (1, 0.5));
-  constraint_points.push_back (Point<dim-1> (0.5, 0));
-  constraint_points.push_back (Point<dim-1> (0.5, 1));
-
-  if (this->degree>1)
-    {
-      const unsigned int n=this->degree-1;
-      const double step=1./this->degree;
-      std::vector<Point<dim-2> > line_support_points(n);
-      for (unsigned int i=0; i<n; ++i)
-       line_support_points[i](0)=(i+1)*step;
-      Quadrature<dim-2> qline(line_support_points);
-
-                                      // auxiliary points in 2d
-      std::vector<Point<dim-1> > p_line(n);
-  
-                                      // Add nodes of lines interior
-                                      // in the "mother-face"
-
-                                      // line 5: use line 9
-      QProjector<dim-1>::project_to_subface(qline, 0, 0, p_line);
-      for (unsigned int i=0; i<n; ++i)
-       constraint_points.push_back (p_line[i] + Point<dim-1> (0.5, 0));
-                                      // line 6: use line 10
-      QProjector<dim-1>::project_to_subface(qline, 0, 1, p_line);
-      for (unsigned int i=0; i<n; ++i)
-       constraint_points.push_back (p_line[i] + Point<dim-1> (0.5, 0));
-                                      // line 7: use line 13
-      QProjector<dim-1>::project_to_subface(qline, 2, 0, p_line);
-      for (unsigned int i=0; i<n; ++i)
-       constraint_points.push_back (p_line[i] + Point<dim-1> (0, 0.5));
-                                      // line 8: use line 14
-      QProjector<dim-1>::project_to_subface(qline, 2, 1, p_line);
-      for (unsigned int i=0; i<n; ++i)
-       constraint_points.push_back (p_line[i] + Point<dim-1> (0, 0.5));
-      
-                                      // DoFs on bordering lines
-                                      // lines 9-16
-      for (unsigned int face=0; face<GeometryInfo<dim-1>::faces_per_cell; ++face)
-       for (unsigned int subface=0;
-            subface<GeometryInfo<dim-1>::max_children_per_face; ++subface)
-         {
-           QProjector<dim-1>::project_to_subface(qline, face, subface, p_line);
-           constraint_points.insert(constraint_points.end(),
-                                    p_line.begin(), p_line.end());
-         }
-      
-                                      // Create constraints for
-                                      // interior nodes
-      std::vector<Point<dim-1> > inner_points(n*n);
-      for (unsigned int i=0, iy=1; iy<=n; ++iy)
-       for (unsigned int ix=1; ix<=n; ++ix)
-         inner_points[i++] = Point<dim-1> (ix*step, iy*step);
-      
-      for (unsigned int child=0; 
-          child<GeometryInfo<dim-1>::max_children_per_cell; ++child)
-       for (unsigned int i=0; i<inner_points.size(); ++i)
-         constraint_points.push_back (
-           GeometryInfo<dim-1>::child_to_cell_coordinates(inner_points[i], child));
-    }
-
-                                   // Now construct relation between
-                                   // destination (child) and source (mother)
-                                   // dofs.
-  const unsigned int pnts=(this->degree+1)*(this->degree+1); 
-  const std::vector<Polynomials::Polynomial<double> > polynomial_basis=
-    Polynomials::Lagrange::generate_complete_basis(points.get_points()); 
-    //const std::vector<Polynomials::Polynomial<double> > polynomial_basis=
-    //Polynomials::LagrangeEquidistant::generate_complete_basis(this->degree);
-  const TensorProductPolynomials<dim-1> face_polynomials(polynomial_basis);
-
-  this->interface_constraints
-    .TableBase<2,double>::reinit (this->interface_constraints_size());
-
-  for (unsigned int i=0; i<constraint_points.size(); ++i)
-    {
-      const double interval = (double) (this->degree * 2);
-      bool mirror[dim - 1];
-      Point<dim-1> constraint_point;
-
-                                       // Eliminate FP errors in constraint
-                                       // points. Due to their origin, they
-                                       // must all be fractions of the unit
-                                       // interval. If we have polynomial
-                                       // degree 4, the refined element has 8
-                                       // intervals.  Hence the coordinates
-                                       // must be 0, 0.125, 0.25, 0.375 etc.
-                                       // Now the coordinates of the
-                                       // constraint points will be multiplied
-                                       // by the inverse of the interval size
-                                       // (in the example by 8).  After that
-                                       // the coordinates must be integral
-                                       // numbers. Hence a normal truncation
-                                       // is performed and the coordinates
-                                       // will be scaled back. The equal
-                                       // treatment of all coordinates should
-                                       // eliminate any FP errors.
-      for (unsigned int k=0; k<dim-1; ++k)
-        {
-          const int coord_int =
-            static_cast<int> (constraint_points[i](k) * interval + 0.25);
-          constraint_point(k) = 1.*coord_int / interval;
-
-                                           // The following lines of code
-                                           // should eliminate the problems
-                                           // with the Constraint-Matrix,
-                                           // which appeared for P>=4. The
-                                           // Constraint-Matrix class
-                                           // complained about different
-                                           // constraints for the same entry
-                                           // of the Constraint-Matrix.
-                                           // Actually this difference could
-                                           // be attributed to FP errors, as
-                                           // it was in the range of
-                                           // 1.0e-16. These errors originate
-                                           // in the loss of symmetry in the
-                                           // FP approximation of the
-                                           // shape-functions.  Considering a
-                                           // 3rd order shape function in 1D,
-                                           // we have N0(x)=N3(1-x) and
-                                           // N1(x)=N2(1-x).  For higher order
-                                           // polynomials the FP
-                                           // approximations of the shape
-                                           // functions do not satisfy these
-                                           // equations any more!  Thus in the
-                                           // following code everything is
-                                           // computed in the interval x \in
-                                           // [0..0.5], which is sufficient to
-                                           // express all values that could
-                                           // come out from a computation of
-                                           // any shape function in the full
-                                           // interval [0..1]. If x > 0.5 the
-                                           // computation is done for 1-x with
-                                           // the shape function N_{p-n}
-                                           // instead of N_n.  Hence symmetry
-                                           // is preserved and everything
-                                           // works fine...
-                                           //
-                                           // For a different explanation of
-                                           // the problem, see the discussion
-                                           // in the FiniteElement class
-                                           // for constraint matrices in 3d.
-          mirror[k] = (constraint_point(k) > 0.5);
-          if (mirror[k])
-            constraint_point(k) = 1.0 - constraint_point(k);
-        }
-
-      for (unsigned j=0; j<pnts; ++j)
-        {
-          unsigned int indices[2]
-            = { face_index_map[j] % (this->degree + 1),
-                face_index_map[j] / (this->degree + 1) };
-          
-          for (unsigned int k = 0; k<2; ++k)
-            if (mirror[k])
-              indices[k] = this->degree - indices[k];
-          
-          const unsigned int
-            new_index = indices[1] * (this->degree + 1) + indices[0];
-
-          this->interface_constraints(i,j) = 
-            face_polynomials.compute_value (new_index, constraint_point);
-           
-                                           // if the value is small up
-                                           // to round-off, then
-                                           // simply set it to zero to
-                                           // avoid unwanted fill-in
-                                           // of the constraint
-                                           // matrices (which would
-                                           // then increase the number
-                                           // of other DoFs a
-                                           // constrained DoF would
-                                           // couple to)
-          if (std::fabs(this->interface_constraints(i,j)) < 1e-14)
-            this->interface_constraints(i,j) = 0;
-        }
-    }
+  QTrapez<1> trapez;
+  QIterated<1> points (trapez,this->degree);
+  Implementation::initialize_constraints (points, *this);
 }
 
-#endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Q<dim>::initialize_embedding ()
+FE_Q<dim,spacedim>::initialize_embedding ()
 {
   unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
 
@@ -1594,9 +1652,9 @@ FE_Q<dim>::initialize_embedding ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FE_Q<dim>::initialize_restriction ()
+FE_Q<dim,spacedim>::initialize_restriction ()
 {
   unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
 
@@ -1754,12 +1812,36 @@ FE_Q<1>::has_support_on_face (const unsigned int shape_index,
 }
 
 
+template <>
+bool
+FE_Q<1,2>::has_support_on_face (const unsigned int shape_index,
+                              const unsigned int face_index) const
+{
+  Assert (shape_index < this->dofs_per_cell,
+         ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+  Assert (face_index < GeometryInfo<1>::faces_per_cell,
+         ExcIndexRange (face_index, 0, GeometryInfo<1>::faces_per_cell));
+
+
+                                  // in 1d, things are simple. since
+                                  // there is only one degree of
+                                  // freedom per vertex in this
+                                  // class, the first is on vertex 0
+                                  // (==face 0 in some sense), the
+                                  // second on face 1:
+  return (((shape_index == 0) && (face_index == 0)) ||
+          ((shape_index == 1) && (face_index == 1)));
+}
+
+
+
+
 #else
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FE_Q<dim>::has_support_on_face (const unsigned int shape_index,
+FE_Q<dim,spacedim>::has_support_on_face (const unsigned int shape_index,
                                const unsigned int face_index) const
 {
   Assert (shape_index < this->dofs_per_cell,
@@ -1866,9 +1948,9 @@ FE_Q<dim>::has_support_on_face (const unsigned int shape_index,
 #endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FE_Q<dim>::memory_consumption () const
+FE_Q<dim,spacedim>::memory_consumption () const
 {
   Assert (false, ExcNotImplemented ());
   return 0;
@@ -1878,4 +1960,10 @@ FE_Q<dim>::memory_consumption () const
 
 template class FE_Q<deal_II_dimension>;
 
+#if deal_II_dimension !=3
+template class FE_Q<deal_II_dimension,deal_II_dimension+1>;
+#endif
+
+
+
 DEAL_II_NAMESPACE_CLOSE
index 2135be8d36b4cafd3e8c38fd7de8fcc1309b71ac..f5365dad0407cdf0db7a910c4026978a57a139d0 100644 (file)
@@ -28,16 +28,16 @@ DEAL_II_NAMESPACE_OPEN
 /* ----------------------- FESystem::InternalData ------------------- */
 
 
-template <int dim>
-FESystem<dim>::InternalData::InternalData(const unsigned int n_base_elements):
+template <int dim, int spacedim>
+FESystem<dim,spacedim>::InternalData::InternalData(const unsigned int n_base_elements):
                base_fe_datas(n_base_elements),
                base_fe_values_datas(n_base_elements)
 {}
 
 
 
-template <int dim>
-FESystem<dim>::InternalData::~InternalData()
+template <int dim, int spacedim>
+FESystem<dim,spacedim>::InternalData::~InternalData()
 {
                                   // delete pointers and set them to
                                   // zero to avoid inadvertant use
@@ -58,9 +58,9 @@ FESystem<dim>::InternalData::~InternalData()
 
 
 
-template <int dim>
-typename FiniteElement<dim>::InternalDataBase &
-FESystem<dim>::
+template <int dim, int spacedim>
+typename FiniteElement<dim,spacedim>::InternalDataBase &
+FESystem<dim,spacedim>::
 InternalData::get_fe_data (const unsigned int base_no) const
 {
   Assert(base_no<base_fe_datas.size(),
@@ -70,11 +70,11 @@ InternalData::get_fe_data (const unsigned int base_no) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
+FESystem<dim,spacedim>::
 InternalData::set_fe_data (const unsigned int base_no,
-                          typename FiniteElement<dim>::InternalDataBase *ptr)
+                          typename FiniteElement<dim,spacedim>::InternalDataBase *ptr)
 {
   Assert(base_no<base_fe_datas.size(),
         ExcIndexRange(base_no,0,base_fe_datas.size()));
@@ -83,9 +83,9 @@ InternalData::set_fe_data (const unsigned int base_no,
 
 
 
-template <int dim>
-FEValuesData<dim> &
-FESystem<dim>::
+template <int dim, int spacedim>
+FEValuesData<dim,spacedim> &
+FESystem<dim,spacedim>::
 InternalData::get_fe_values_data (const unsigned int base_no) const
 {
   Assert(base_no<base_fe_values_datas.size(),
@@ -96,11 +96,11 @@ InternalData::get_fe_values_data (const unsigned int base_no) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
+FESystem<dim,spacedim>::
 InternalData::set_fe_values_data (const unsigned int base_no,
-                                 FEValuesData<dim> *ptr)
+                                 FEValuesData<dim,spacedim> *ptr)
 {
   Assert(base_no<base_fe_values_datas.size(),
         ExcIndexRange(base_no,0,base_fe_values_datas.size()));
@@ -109,9 +109,9 @@ InternalData::set_fe_values_data (const unsigned int base_no,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
+FESystem<dim,spacedim>::
 InternalData::delete_fe_values_data (const unsigned int base_no)
 {
   Assert(base_no<base_fe_values_datas.size(),
@@ -123,13 +123,13 @@ InternalData::delete_fe_values_data (const unsigned int base_no)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::InternalData::clear_first_cell ()
+FESystem<dim,spacedim>::InternalData::clear_first_cell ()
 {
                                    // call respective function of base
                                    // class
-  FiniteElement<dim>::InternalDataBase::clear_first_cell ();
+  FiniteElement<dim,spacedim>::InternalDataBase::clear_first_cell ();
                                    // then the functions of all the
                                    // sub-objects
   for (unsigned int i=0; i<base_fe_datas.size(); ++i)
@@ -140,14 +140,14 @@ FESystem<dim>::InternalData::clear_first_cell ()
 /* ---------------------------------- FESystem ------------------- */
 
 
-template <int dim>
-const unsigned int FESystem<dim>::invalid_face_number;
+template <int dim, int spacedim>
+const unsigned int FESystem<dim,spacedim>::invalid_face_number;
 
 
-template <int dim>
-FESystem<dim>::FESystem (const FiniteElement<dim> &fe,
+template <int dim, int spacedim>
+FESystem<dim,spacedim>::FESystem (const FiniteElement<dim,spacedim> &fe,
                         const unsigned int n_elements) :
-               FiniteElement<dim> (multiply_dof_numbers(fe, n_elements),
+               FiniteElement<dim,spacedim> (multiply_dof_numbers(fe, n_elements),
                                    compute_restriction_is_additive_flags (fe, n_elements),
                                    compute_nonzero_components(fe, n_elements)),
                 base_elements(1)
@@ -159,12 +159,12 @@ FESystem<dim>::FESystem (const FiniteElement<dim> &fe,
 
 
 
-template <int dim>
-FESystem<dim>::FESystem (const FiniteElement<dim> &fe1,
+template <int dim, int spacedim>
+FESystem<dim,spacedim>::FESystem (const FiniteElement<dim,spacedim> &fe1,
                         const unsigned int        n1,
-                        const FiniteElement<dim> &fe2,
+                        const FiniteElement<dim,spacedim> &fe2,
                         const unsigned int        n2) :
-               FiniteElement<dim> (multiply_dof_numbers(fe1, n1, fe2, n2),
+               FiniteElement<dim,spacedim> (multiply_dof_numbers(fe1, n1, fe2, n2),
                                    compute_restriction_is_additive_flags (fe1, n1,
                                                                           fe2, n2),
                                    compute_nonzero_components(fe1, n1,
@@ -181,14 +181,14 @@ FESystem<dim>::FESystem (const FiniteElement<dim> &fe1,
 
 
 
-template <int dim>
-FESystem<dim>::FESystem (const FiniteElement<dim> &fe1,
+template <int dim, int spacedim>
+FESystem<dim,spacedim>::FESystem (const FiniteElement<dim,spacedim> &fe1,
                         const unsigned int        n1,
-                        const FiniteElement<dim> &fe2,
+                        const FiniteElement<dim,spacedim> &fe2,
                         const unsigned int        n2,
-                        const FiniteElement<dim> &fe3,
+                        const FiniteElement<dim,spacedim> &fe3,
                         const unsigned int        n3) :
-               FiniteElement<dim> (multiply_dof_numbers(fe1, n1,
+               FiniteElement<dim,spacedim> (multiply_dof_numbers(fe1, n1,
                                                         fe2, n2,
                                                         fe3, n3),
                                    compute_restriction_is_additive_flags (fe1, n1,
@@ -212,8 +212,8 @@ FESystem<dim>::FESystem (const FiniteElement<dim> &fe1,
 
 
 
-template <int dim>
-FESystem<dim>::~FESystem ()
+template <int dim, int spacedim>
+FESystem<dim,spacedim>::~FESystem ()
 {
                                   // delete base elements created in
                                   // the constructor
@@ -227,9 +227,9 @@ FESystem<dim>::~FESystem ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::string
-FESystem<dim>::get_name () const
+FESystem<dim,spacedim>::get_name () const
 {
                                   // note that the
                                   // FETools::get_fe_from_name
@@ -256,9 +256,9 @@ FESystem<dim>::get_name () const
 
 
 
-template <int dim>
-FiniteElement<dim>*
-FESystem<dim>::clone() const
+template <int dim, int spacedim>
+FiniteElement<dim,spacedim>*
+FESystem<dim,spacedim>::clone() const
 {
   switch (n_base_elements())
     {
@@ -285,14 +285,14 @@ FESystem<dim>::clone() const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 double
-FESystem<dim>::shape_value (const unsigned int i,
+FESystem<dim,spacedim>::shape_value (const unsigned int i,
                            const Point<dim> &p) const
 {
   Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
   Assert (this->is_primitive(i), 
-         typename FiniteElement<dim>::ExcShapeFunctionNotPrimitive(i));
+         (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(i)));
 
   return (base_element(this->system_to_base_table[i].first.first)
          .shape_value(this->system_to_base_table[i].second, p));
@@ -300,9 +300,9 @@ FESystem<dim>::shape_value (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 double
-FESystem<dim>::shape_value_component (const unsigned int i,
+FESystem<dim,spacedim>::shape_value_component (const unsigned int i,
                                      const Point<dim>  &p,
                                      const unsigned int component) const
 {
@@ -337,14 +337,14 @@ FESystem<dim>::shape_value_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 Tensor<1,dim>
-FESystem<dim>::shape_grad (const unsigned int i,
+FESystem<dim,spacedim>::shape_grad (const unsigned int i,
                           const Point<dim> &p) const
 {
   Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
   Assert (this->is_primitive(i),
-         typename FiniteElement<dim>::ExcShapeFunctionNotPrimitive(i));
+         (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(i)));
 
   return (base_element(this->system_to_base_table[i].first.first)
          .shape_grad(this->system_to_base_table[i].second, p));
@@ -352,9 +352,9 @@ FESystem<dim>::shape_grad (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 Tensor<1,dim>
-FESystem<dim>::shape_grad_component (const unsigned int i,
+FESystem<dim,spacedim>::shape_grad_component (const unsigned int i,
                                     const Point<dim>  &p,
                                     const unsigned int component) const
 {
@@ -389,14 +389,14 @@ FESystem<dim>::shape_grad_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 Tensor<2,dim>
-FESystem<dim>::shape_grad_grad (const unsigned int i,
+FESystem<dim,spacedim>::shape_grad_grad (const unsigned int i,
                                const Point<dim> &p) const
 {
   Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
   Assert (this->is_primitive(i), 
-         typename FiniteElement<dim>::ExcShapeFunctionNotPrimitive(i));
+         (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(i)));
 
   return (base_element(this->system_to_base_table[i].first.first)
          .shape_grad_grad(this->system_to_base_table[i].second, p));
@@ -404,9 +404,9 @@ FESystem<dim>::shape_grad_grad (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 Tensor<2,dim>
-FESystem<dim>::shape_grad_grad_component (const unsigned int i,
+FESystem<dim,spacedim>::shape_grad_grad_component (const unsigned int i,
                                          const Point<dim>  &p,
                                          const unsigned int component) const
 {
@@ -441,10 +441,10 @@ FESystem<dim>::shape_grad_grad_component (const unsigned int i,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
-get_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FESystem<dim,spacedim>::
+get_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                          FullMatrix<double>           &interpolation_matrix) const
 {
   Assert (interpolation_matrix.m() == this->dofs_per_cell,
@@ -460,21 +460,23 @@ get_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                    // 
                                    // condition 1: the other element
                                    // must also be a system element
+
+  typedef FiniteElement<dim,spacedim> FEL;
   AssertThrow ((x_source_fe.get_name().find ("FESystem<") == 0)
                ||
-               (dynamic_cast<const FESystem<dim>*>(&x_source_fe) != 0),
-               typename FiniteElement<dim>::
+               (dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe) != 0),
+               typename FEL::
                ExcInterpolationNotImplemented());
   
                                   // ok, source is a system element,
                                   // so we may be able to do the work
-  const FESystem<dim> &source_fe
-    = dynamic_cast<const FESystem<dim>&>(x_source_fe);
+  const FESystem<dim,spacedim> &source_fe
+    = dynamic_cast<const FESystem<dim,spacedim>&>(x_source_fe);
 
                                    // condition 2: same number of
                                    // basis elements
   AssertThrow (n_base_elements() == source_fe.n_base_elements(),
-               typename FiniteElement<dim>::
+               typename FEL::
                ExcInterpolationNotImplemented());
 
                                    // condition 3: same number of
@@ -482,7 +484,7 @@ get_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
   for (unsigned int i=0; i<n_base_elements(); ++i)
     AssertThrow (element_multiplicity(i) ==
                  source_fe.element_multiplicity(i),
-                 typename FiniteElement<dim>::
+                 typename FEL::
                  ExcInterpolationNotImplemented());
 
                                    // ok, so let's try whether it
@@ -531,9 +533,9 @@ get_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 UpdateFlags
-FESystem<dim>::update_once (const UpdateFlags flags) const
+FESystem<dim,spacedim>::update_once (const UpdateFlags flags) const
 {
   UpdateFlags out = update_default;
                                   // generate maximal set of flags
@@ -545,9 +547,9 @@ FESystem<dim>::update_once (const UpdateFlags flags) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 UpdateFlags
-FESystem<dim>::update_each (const UpdateFlags flags) const
+FESystem<dim,spacedim>::update_each (const UpdateFlags flags) const
 {
   UpdateFlags out = update_default;
                                   // generate maximal set of flags
@@ -572,10 +574,10 @@ FESystem<dim>::update_each (const UpdateFlags flags) const
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-FESystem<dim>::get_data (const UpdateFlags      flags_,
-                        const Mapping<dim>    &mapping,
+template <int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+FESystem<dim,spacedim>::get_data (const UpdateFlags      flags_,
+                        const Mapping<dim,spacedim>    &mapping,
                         const Quadrature<dim> &quadrature) const
 {
   UpdateFlags flags = flags_;
@@ -607,11 +609,11 @@ FESystem<dim>::get_data (const UpdateFlags      flags_,
                                   // the base elements and store them
   for (unsigned int base_no=0; base_no<n_base_elements(); ++base_no)
     {
-      typename Mapping<dim>::InternalDataBase *base_fe_data_base =
+      typename Mapping<dim,spacedim>::InternalDataBase *base_fe_data_base =
        base_element(base_no).get_data(sub_flags, mapping, quadrature);
 
-      typename FiniteElement<dim>::InternalDataBase *base_fe_data =
-       dynamic_cast<typename FiniteElement<dim>::InternalDataBase *>
+      typename FiniteElement<dim,spacedim>::InternalDataBase *base_fe_data =
+       dynamic_cast<typename FiniteElement<dim,spacedim>::InternalDataBase *>
        (base_fe_data_base);
       
       data->set_fe_data(base_no, base_fe_data);
@@ -649,7 +651,7 @@ FESystem<dim>::get_data (const UpdateFlags      flags_,
                                       // @p{data}, similar to the
                                       // storing of the
                                       // @p{base_fe_data}s.
-      FEValuesData<dim> *base_data = new FEValuesData<dim>();
+      FEValuesData<dim,spacedim> *base_data = new FEValuesData<dim,spacedim>();
       data->set_fe_values_data(base_no, base_data);
     }
   data->update_flags = data->update_once |
@@ -659,15 +661,15 @@ FESystem<dim>::get_data (const UpdateFlags      flags_,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
-fill_fe_values (const Mapping<dim>                   &mapping,
-                const typename Triangulation<dim>::cell_iterator &cell,
+FESystem<dim,spacedim>::
+fill_fe_values (const Mapping<dim,spacedim>                   &mapping,
+                const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                 const Quadrature<dim>                &quadrature,
-                typename Mapping<dim>::InternalDataBase &mapping_data,
-                typename Mapping<dim>::InternalDataBase &fe_data,
-                FEValuesData<dim>                    &data) const
+                typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+                typename Mapping<dim,spacedim>::InternalDataBase &fe_data,
+                FEValuesData<dim,spacedim>                    &data) const
 {
   compute_fill(mapping, cell, invalid_face_number, invalid_face_number,
               quadrature, mapping_data, fe_data, data);
@@ -675,16 +677,16 @@ fill_fe_values (const Mapping<dim>                   &mapping,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
-fill_fe_face_values (const Mapping<dim>                   &mapping,
-                     const typename Triangulation<dim>::cell_iterator &cell,
+FESystem<dim,spacedim>::
+fill_fe_face_values (const Mapping<dim,spacedim>                   &mapping,
+                     const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                      const unsigned int                    face_no,
                      const Quadrature<dim-1>              &quadrature,
-                     typename Mapping<dim>::InternalDataBase &mapping_data,
-                     typename Mapping<dim>::InternalDataBase &fe_data,
-                     FEValuesData<dim>                    &data) const
+                     typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+                     typename Mapping<dim,spacedim>::InternalDataBase &fe_data,
+                     FEValuesData<dim,spacedim>                    &data) const
 {
   compute_fill (mapping, cell, face_no, invalid_face_number,
                 quadrature, mapping_data, fe_data, data);
@@ -693,17 +695,17 @@ fill_fe_face_values (const Mapping<dim>                   &mapping,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
-fill_fe_subface_values (const Mapping<dim>                   &mapping,
-                        const typename Triangulation<dim>::cell_iterator &cell,
+FESystem<dim,spacedim>::
+fill_fe_subface_values (const Mapping<dim,spacedim>                   &mapping,
+                        const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                         const unsigned int                    face_no,
                         const unsigned int                    sub_no,
                         const Quadrature<dim-1>              &quadrature,
-                        typename Mapping<dim>::InternalDataBase &mapping_data,
-                        typename Mapping<dim>::InternalDataBase &fe_data,
-                        FEValuesData<dim>                    &data) const
+                        typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+                        typename Mapping<dim,spacedim>::InternalDataBase &fe_data,
+                        FEValuesData<dim,spacedim>                    &data) const
 {
   compute_fill (mapping, cell, face_no, sub_no,
                 quadrature, mapping_data, fe_data, data);
@@ -711,18 +713,18 @@ fill_fe_subface_values (const Mapping<dim>                   &mapping,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <int dim_1>
 void
-FESystem<dim>::
-compute_fill (const Mapping<dim>                   &mapping,
-              const typename Triangulation<dim>::cell_iterator &cell,
+FESystem<dim,spacedim>::
+compute_fill (const Mapping<dim,spacedim>                   &mapping,
+              const typename Triangulation<dim,spacedim>::cell_iterator &cell,
               const unsigned int                    face_no,
               const unsigned int                    sub_no,
               const Quadrature<dim_1>              &quadrature,
-              typename Mapping<dim>::InternalDataBase &mapping_data,
-              typename Mapping<dim>::InternalDataBase &fedata,
-              FEValuesData<dim>                    &data) const
+              typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+              typename Mapping<dim,spacedim>::InternalDataBase &fedata,
+              FEValuesData<dim,spacedim>                    &data) const
 {       
   const unsigned int n_q_points = quadrature.size();
   
@@ -764,7 +766,7 @@ compute_fill (const Mapping<dim>                   &mapping,
                                               // Pointer needed to get
                                               // the update flags of the
                                               // base element
-             typename Mapping<dim>::InternalDataBase &
+             typename Mapping<dim,spacedim>::InternalDataBase &
                base_fe_data = fe_data.get_fe_data(base_no);
              
                                               // compute update flags ...
@@ -773,8 +775,8 @@ compute_fill (const Mapping<dim>                   &mapping,
              
                                               // Initialize the FEValuesDatas
                                               // for the base elements.
-             FEValuesData<dim> &base_data=fe_data.get_fe_values_data(base_no);
-             const FiniteElement<dim> &base_fe=base_element(base_no);
+             FEValuesData<dim,spacedim> &base_data=fe_data.get_fe_values_data(base_no);
+             const FiniteElement<dim,spacedim> &base_fe=base_element(base_no);
              base_data.initialize (n_q_points, base_fe, base_update_flags);
            }
        }
@@ -814,11 +816,11 @@ compute_fill (const Mapping<dim>                   &mapping,
                                        // necessary data
       for (unsigned int base_no=0; base_no<n_base_elements(); ++base_no)
        {
-         const FiniteElement<dim> &
+         const FiniteElement<dim,spacedim> &
             base_fe      = base_element(base_no);
-         typename FiniteElement<dim>::InternalDataBase &
+         typename FiniteElement<dim,spacedim>::InternalDataBase &
            base_fe_data = fe_data.get_fe_data(base_no);
-         FEValuesData<dim> &
+         FEValuesData<dim,spacedim> &
             base_data    = fe_data.get_fe_values_data(base_no);
 
                                           //TODO: Think about a smarter alternative
@@ -965,7 +967,7 @@ compute_fill (const Mapping<dim>                   &mapping,
                                               // Pointer needed to get
                                               // the update flags of the
                                               // base element
-             typename Mapping<dim>::InternalDataBase &base_fe_data=
+             typename Mapping<dim,spacedim>::InternalDataBase &base_fe_data=
                fe_data.get_fe_data(base_no);
              
                                               // compute update flags ...
@@ -1008,9 +1010,9 @@ compute_fill (const Mapping<dim>                   &mapping,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::build_cell_tables()
+FESystem<dim,spacedim>::build_cell_tables()
 {
                                   // If the system is not primitive,
                                   // these have not been initialized
@@ -1194,9 +1196,9 @@ FESystem<dim>::build_cell_tables()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::build_face_tables()
+FESystem<dim,spacedim>::build_face_tables()
 {
                                   // Initialize index tables. do this
                                   // in the same way as done for the
@@ -1376,8 +1378,8 @@ FESystem<dim>::build_face_tables()
 
 
 
-template <int dim>
-void FESystem<dim>::build_interface_constraints () 
+template <int dim, int spacedim>
+void FESystem<dim,spacedim>::build_interface_constraints () 
 {
                                    // check whether all base elements
                                    // implement their interface
@@ -1642,8 +1644,8 @@ void FESystem<dim>::build_interface_constraints ()
 
 
 
-template <int dim>
-void FESystem<dim>::initialize ()
+template <int dim, int spacedim>
+void FESystem<dim,spacedim>::initialize ()
 {
   build_cell_tables();
   build_face_tables();
@@ -1756,9 +1758,9 @@ void FESystem<dim>::initialize ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 FiniteElementData<dim>
-FESystem<dim>::multiply_dof_numbers (const FiniteElementData<dim> &fe_data,
+FESystem<dim,spacedim>::multiply_dof_numbers (const FiniteElementData<dim> &fe_data,
                                     const unsigned int            N)
 {
   std::vector<unsigned int> dpo;
@@ -1777,9 +1779,9 @@ FESystem<dim>::multiply_dof_numbers (const FiniteElementData<dim> &fe_data,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
+FESystem<dim,spacedim>::
 initialize_unit_support_points ()
 {
                                   // if one of the base elements
@@ -1828,9 +1830,9 @@ initialize_unit_face_support_points ()
 #endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
+FESystem<dim,spacedim>::
 initialize_unit_face_support_points ()
 {
                                   // if one of the base elements has
@@ -1870,9 +1872,9 @@ initialize_unit_face_support_points ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::initialize_quad_dof_index_permutation ()
+FESystem<dim,spacedim>::initialize_quad_dof_index_permutation ()
 {
                                   // general template for 1D and 2D, do nothing
 }
@@ -1932,9 +1934,9 @@ FESystem<3>::initialize_quad_dof_index_permutation ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FESystem<dim>::
+FESystem<dim,spacedim>::
 hp_constraints_are_implemented () const
 {
   for (unsigned int b=0; b<n_base_elements(); ++b)
@@ -1946,16 +1948,17 @@ hp_constraints_are_implemented () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
-get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FESystem<dim,spacedim>::
+get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                               FullMatrix<double>       &interpolation_matrix) const
 {
+  typedef FiniteElement<dim,spacedim> FEL;
   AssertThrow ((x_source_fe.get_name().find ("FE_System<") == 0)
               ||
-              (dynamic_cast<const FESystem<dim>*>(&x_source_fe) != 0),
-              typename FiniteElement<dim>::
+              (dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe) != 0),
+              typename FEL::
               ExcInterpolationNotImplemented());
 
   Assert (interpolation_matrix.n() == this->dofs_per_face,
@@ -1981,8 +1984,8 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                   // FESystem(FE_Q(r),2,FE_Q(s),1), but not
                                   // FESystem(FE_Q(p),1,FE_Q(q),2) vs
                                   // FESystem(FESystem(FE_Q(r),2),1,FE_Q(s),1)
-  const FESystem<dim> *fe_other_system
-    = dynamic_cast<const FESystem<dim>*>(&x_source_fe);
+  const FESystem<dim,spacedim> *fe_other_system
+    = dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe);
 
                                   // clear matrix, since we will not get to
                                   // set all elements
@@ -2000,7 +2003,7 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
   
   while (true)
     {
-      const FiniteElement<dim>
+      const FiniteElement<dim,spacedim>
        &base       = base_element(base_index),
        &base_other = fe_other_system->base_element(base_index_other);
 
@@ -2072,17 +2075,18 @@ get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESystem<dim>::
-get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
+FESystem<dim,spacedim>::
+get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                                  const unsigned int        subface,
                                  FullMatrix<double>       &interpolation_matrix) const
 {
+  typedef FiniteElement<dim,spacedim> FEL;
   AssertThrow ((x_source_fe.get_name().find ("FE_System<") == 0)
               ||
-              (dynamic_cast<const FESystem<dim>*>(&x_source_fe) != 0),
-              typename FiniteElement<dim>::
+              (dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe) != 0),
+              typename FEL::
               ExcInterpolationNotImplemented());
 
   Assert (interpolation_matrix.n() == this->dofs_per_face,
@@ -2108,8 +2112,8 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
                                   // FESystem(FE_Q(r),2,FE_Q(s),1), but not
                                   // FESystem(FE_Q(p),1,FE_Q(q),2) vs
                                   // FESystem(FESystem(FE_Q(r),2),1,FE_Q(s),1)
-  const FESystem<dim> *fe_other_system
-    = dynamic_cast<const FESystem<dim>*>(&x_source_fe);
+  const FESystem<dim,spacedim> *fe_other_system
+    = dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe);
 
                                   // clear matrix, since we will not get to
                                   // set all elements
@@ -2127,7 +2131,7 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
   
   while (true)
     {
-      const FiniteElement<dim>
+      const FiniteElement<dim,spacedim>
        &base       = base_element(base_index),
        &base_other = fe_other_system->base_element(base_index_other);
 
@@ -2200,10 +2204,10 @@ get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <int structdim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FESystem<dim>::hp_object_dof_identities (const FiniteElement<dim> &fe_other) const
+FESystem<dim,spacedim>::hp_object_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // since dofs on each subobject (vertex,
                                   // line, ...) are ordered such that first
@@ -2224,8 +2228,8 @@ FESystem<dim>::hp_object_dof_identities (const FiniteElement<dim> &fe_other) con
                                   // FESystem(FE_Q(r),2,FE_Q(s),1), but not
                                   // FESystem(FE_Q(p),1,FE_Q(q),2) vs
                                   // FESystem(FESystem(FE_Q(r),2),1,FE_Q(s),1)
-  if (const FESystem<dim> *fe_other_system
-      = dynamic_cast<const FESystem<dim>*>(&fe_other))
+  if (const FESystem<dim,spacedim> *fe_other_system
+      = dynamic_cast<const FESystem<dim,spacedim>*>(&fe_other))
     {
                                       // loop over all the base elements of
                                       // this and the other element, counting
@@ -2245,7 +2249,7 @@ FESystem<dim>::hp_object_dof_identities (const FiniteElement<dim> &fe_other) con
       
       while (true)
        {
-         const FiniteElement<dim>
+         const FiniteElement<dim,spacedim>
            &base       = base_element(base_index),
            &base_other = fe_other_system->base_element(base_index_other);
 
@@ -2332,41 +2336,41 @@ FESystem<dim>::hp_object_dof_identities (const FiniteElement<dim> &fe_other) con
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FESystem<dim>::hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
+FESystem<dim,spacedim>::hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
   return hp_object_dof_identities<0> (fe_other);
 }
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FESystem<dim>::hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
+FESystem<dim,spacedim>::hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
   return hp_object_dof_identities<1> (fe_other);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::pair<unsigned int, unsigned int> >
-FESystem<dim>::hp_quad_dof_identities (const FiniteElement<dim> &fe_other) const
+FESystem<dim,spacedim>::hp_quad_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
 {
   return hp_object_dof_identities<2> (fe_other);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 FiniteElementDomination::Domination
-FESystem<dim>::
-compare_for_face_domination (const FiniteElement<dim> &fe_other) const
+FESystem<dim,spacedim>::
+compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const
 {
                                   // at present all we can do is to compare
                                   // with other FESystems that have the same
                                   // number of components and bases
-  if (const FESystem<dim> *fe_sys_other
-      = dynamic_cast<const FESystem<dim>*>(&fe_other))
+  if (const FESystem<dim,spacedim> *fe_sys_other
+      = dynamic_cast<const FESystem<dim,spacedim>*>(&fe_other))
     {
       Assert (this->n_components() == fe_sys_other->n_components(),
              ExcNotImplemented());
@@ -2410,9 +2414,9 @@ compare_for_face_domination (const FiniteElement<dim> &fe_other) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 FiniteElementData<dim>
-FESystem<dim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
+FESystem<dim,spacedim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
                                     const unsigned int            N1,
                                     const FiniteElementData<dim> &fe2,
                                     const unsigned int            N2)
@@ -2440,9 +2444,9 @@ FESystem<dim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 FiniteElementData<dim>
-FESystem<dim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
+FESystem<dim,spacedim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
                                     const unsigned int            N1,
                                     const FiniteElementData<dim> &fe2,
                                     const unsigned int            N2,
@@ -2479,12 +2483,12 @@ FESystem<dim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<bool>
-FESystem<dim>::compute_restriction_is_additive_flags (const FiniteElement<dim> &fe,
+FESystem<dim,spacedim>::compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe,
                                                      const unsigned int n_elements) 
 {
-  std::vector<const FiniteElement<dim>*> fe_list;
+  std::vector<const FiniteElement<dim,spacedim>*> fe_list;
   std::vector<unsigned int>              multiplicities;
 
   fe_list.push_back (&fe);
@@ -2495,14 +2499,14 @@ FESystem<dim>::compute_restriction_is_additive_flags (const FiniteElement<dim> &
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<bool>
-FESystem<dim>::compute_restriction_is_additive_flags (const FiniteElement<dim> &fe1,
+FESystem<dim,spacedim>::compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe1,
                                                      const unsigned int        N1,
-                                                     const FiniteElement<dim> &fe2,
+                                                     const FiniteElement<dim,spacedim> &fe2,
                                                      const unsigned int        N2) 
 {
-  std::vector<const FiniteElement<dim>*> fe_list;
+  std::vector<const FiniteElement<dim,spacedim>*> fe_list;
   std::vector<unsigned int>              multiplicities;
 
   fe_list.push_back (&fe1);
@@ -2516,16 +2520,16 @@ FESystem<dim>::compute_restriction_is_additive_flags (const FiniteElement<dim> &
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<bool>
-FESystem<dim>::compute_restriction_is_additive_flags (const FiniteElement<dim> &fe1,
+FESystem<dim,spacedim>::compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe1,
                                                      const unsigned int        N1,
-                                                     const FiniteElement<dim> &fe2,
+                                                     const FiniteElement<dim,spacedim> &fe2,
                                                      const unsigned int        N2,
-                                                     const FiniteElement<dim> &fe3,
+                                                     const FiniteElement<dim,spacedim> &fe3,
                                                      const unsigned int        N3) 
 {
-  std::vector<const FiniteElement<dim>*> fe_list;
+  std::vector<const FiniteElement<dim,spacedim>*> fe_list;
   std::vector<unsigned int>              multiplicities;
 
   fe_list.push_back (&fe1);
@@ -2542,10 +2546,10 @@ FESystem<dim>::compute_restriction_is_additive_flags (const FiniteElement<dim> &
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<bool>
-FESystem<dim>::
-compute_restriction_is_additive_flags (const std::vector<const FiniteElement<dim>*> &fes,
+FESystem<dim,spacedim>::
+compute_restriction_is_additive_flags (const std::vector<const FiniteElement<dim,spacedim>*> &fes,
                                        const std::vector<unsigned int>              &multiplicities)
 {
   Assert (fes.size() == multiplicities.size(), ExcInternalError());
@@ -2674,12 +2678,12 @@ compute_restriction_is_additive_flags (const std::vector<const FiniteElement<dim
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::vector<bool> >
-FESystem<dim>::compute_nonzero_components (const FiniteElement<dim> &fe1,
+FESystem<dim,spacedim>::compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
                                           const unsigned int        N1)
 {
-  std::vector<const FiniteElement<dim>*> fe_list;
+  std::vector<const FiniteElement<dim,spacedim>*> fe_list;
   std::vector<unsigned int>              multiplicities;
 
   fe_list.push_back (&fe1);
@@ -2690,14 +2694,14 @@ FESystem<dim>::compute_nonzero_components (const FiniteElement<dim> &fe1,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::vector<bool> >
-FESystem<dim>::compute_nonzero_components (const FiniteElement<dim> &fe1,
+FESystem<dim,spacedim>::compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
                                           const unsigned int        N1,
-                                          const FiniteElement<dim> &fe2,
+                                          const FiniteElement<dim,spacedim> &fe2,
                                           const unsigned int        N2)
 {
-  std::vector<const FiniteElement<dim>*> fe_list;
+  std::vector<const FiniteElement<dim,spacedim>*> fe_list;
   std::vector<unsigned int>              multiplicities;
 
   fe_list.push_back (&fe1);
@@ -2711,16 +2715,16 @@ FESystem<dim>::compute_nonzero_components (const FiniteElement<dim> &fe1,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::vector<bool> >
-FESystem<dim>::compute_nonzero_components (const FiniteElement<dim> &fe1,
+FESystem<dim,spacedim>::compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
                                           const unsigned int        N1,
-                                          const FiniteElement<dim> &fe2,
+                                          const FiniteElement<dim,spacedim> &fe2,
                                           const unsigned int        N2,
-                                          const FiniteElement<dim> &fe3,
+                                          const FiniteElement<dim,spacedim> &fe3,
                                           const unsigned int        N3)
 {
-  std::vector<const FiniteElement<dim>*> fe_list;
+  std::vector<const FiniteElement<dim,spacedim>*> fe_list;
   std::vector<unsigned int>              multiplicities;
 
   fe_list.push_back (&fe1);
@@ -2737,10 +2741,10 @@ FESystem<dim>::compute_nonzero_components (const FiniteElement<dim> &fe1,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::vector<std::vector<bool> >
-FESystem<dim>::
-compute_nonzero_components (const std::vector<const FiniteElement<dim>*> &fes,
+FESystem<dim,spacedim>::
+compute_nonzero_components (const std::vector<const FiniteElement<dim,spacedim>*> &fes,
                            const std::vector<unsigned int>              &multiplicities)
 {
   Assert (fes.size() == multiplicities.size(), ExcInternalError());
@@ -2920,9 +2924,9 @@ compute_nonzero_components (const std::vector<const FiniteElement<dim>*> &fes,
 
 
 
-template <int dim>
-const FiniteElement<dim> &
-FESystem<dim>::base_element (const unsigned int index) const
+template <int dim, int spacedim>
+const FiniteElement<dim,spacedim> &
+FESystem<dim,spacedim>::base_element (const unsigned int index) const
 {
   Assert (index < base_elements.size(), 
          ExcIndexRange(index, 0, base_elements.size()));
@@ -2931,18 +2935,18 @@ FESystem<dim>::base_element (const unsigned int index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FESystem<dim>::n_base_elements () const
+FESystem<dim,spacedim>::n_base_elements () const
 {
   return base_elements.size();
 }
 
 
 
-template<int dim>
+template <int dim, int spacedim>
 unsigned int
-FESystem<dim>::element_multiplicity (const unsigned int index) const
+FESystem<dim,spacedim>::element_multiplicity (const unsigned int index) const
 {
   Assert (index < base_elements.size(), 
          ExcIndexRange(index, 0, base_elements.size()));
@@ -2951,9 +2955,9 @@ FESystem<dim>::element_multiplicity (const unsigned int index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-FESystem<dim>::has_support_on_face (const unsigned int shape_index,
+FESystem<dim,spacedim>::has_support_on_face (const unsigned int shape_index,
                                    const unsigned int face_index) const
 {
   return (base_element(this->system_to_base_index(shape_index).first.first)
@@ -2963,15 +2967,16 @@ FESystem<dim>::has_support_on_face (const unsigned int shape_index,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 Point<dim>
-FESystem<dim>::unit_support_point (const unsigned index) const
+FESystem<dim,spacedim>::unit_support_point (const unsigned index) const
 {
   Assert (index < this->dofs_per_cell,
           ExcIndexRange (index, 0, this->dofs_per_cell));
+  typedef FiniteElement<dim,spacedim> FEL;
   Assert ((this->unit_support_points.size() == this->dofs_per_cell) ||
           (this->unit_support_points.size() == 0),
-          typename FiniteElement<dim>::ExcFEHasNoSupportPoints ());
+          typename FEL::ExcFEHasNoSupportPoints ());
 
                                    // let's see whether we have the
                                    // information pre-computed
@@ -2987,15 +2992,16 @@ FESystem<dim>::unit_support_point (const unsigned index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 Point<dim-1>
-FESystem<dim>::unit_face_support_point (const unsigned index) const
+FESystem<dim,spacedim>::unit_face_support_point (const unsigned index) const
 {
   Assert (index < this->dofs_per_face,
           ExcIndexRange (index, 0, this->dofs_per_face));
+  typedef  FiniteElement<dim,spacedim> FEL;
   Assert ((this->unit_face_support_points.size() == this->dofs_per_face) ||
           (this->unit_face_support_points.size() == 0),
-          typename FiniteElement<dim>::ExcFEHasNoSupportPoints ());
+          typename FEL::ExcFEHasNoSupportPoints ());
 
                                    // let's see whether we have the
                                    // information pre-computed
@@ -3011,9 +3017,9 @@ FESystem<dim>::unit_face_support_point (const unsigned index) const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FESystem<dim>::memory_consumption () const 
+FESystem<dim,spacedim>::memory_consumption () const 
 {
                                   // neglect size of data stored in
                                   // @p{base_elements} due to some
@@ -3021,7 +3027,7 @@ FESystem<dim>::memory_consumption () const
                                   // compiler. should be neglectable
                                   // after all, considering the size
                                   // of the data of the subelements
-  unsigned int mem = (FiniteElement<dim>::memory_consumption () +
+  unsigned int mem = (FiniteElement<dim,spacedim>::memory_consumption () +
                      sizeof (base_elements));
   for (unsigned int i=0; i<base_elements.size(); ++i)
     mem += MemoryConsumption::memory_consumption (*base_elements[i].first);
@@ -3033,5 +3039,8 @@ FESystem<dim>::memory_consumption () const
 
 // explicit instantiations
 template class FESystem<deal_II_dimension>;
+#if deal_II_dimension != 3
+template class FESystem<deal_II_dimension, deal_II_dimension+1>;
+#endif
 
 DEAL_II_NAMESPACE_CLOSE
index a61bbd06777204112f6561d6d19bf49c60c62b41..214f8d993a8e3d8cdc5e4aebeb1436b9d0bf71ac 100644 (file)
@@ -167,20 +167,20 @@ namespace
                                    // that function directly if
                                    // T==double, and otherwise uses a
                                    // temporary
-  template <int dim>
+  template <int dim, int spacedim>
   inline
-  void gim_forwarder (const FiniteElement<dim> &fe1,
-                      const FiniteElement<dim> &fe2,
+  void gim_forwarder (const FiniteElement<dim,spacedim> &fe1,
+                      const FiniteElement<dim,spacedim> &fe2,
                       FullMatrix<double> &interpolation_matrix)
   {
     fe2.get_interpolation_matrix (fe1, interpolation_matrix);
   }
 
   
-  template <int dim, typename number>
+  template <int dim, typename number, int spacedim>
   inline
-  void gim_forwarder (const FiniteElement<dim> &fe1,
-                      const FiniteElement<dim> &fe2,
+  void gim_forwarder (const FiniteElement<dim,spacedim> &fe1,
+                      const FiniteElement<dim,spacedim> &fe2,
                       FullMatrix<number> &interpolation_matrix)
   {
     FullMatrix<double> tmp (interpolation_matrix.m(),
@@ -198,7 +198,7 @@ namespace
                                   // specialized string with "dim"
                                   // replaced with the numeric value
                                   // of the template argument
-  template <int dim>
+  template <int dim, int spacedim>
   inline
   unsigned int match_dimension (const std::string &name,
                                const unsigned int position)
@@ -238,14 +238,14 @@ namespace
 }
 
 
-template <int dim>
-FETools::FEFactoryBase<dim>::~FEFactoryBase()
+template <int dim, int spacedim>
+FETools::FEFactoryBase<dim,spacedim>::~FEFactoryBase()
 {}
 
 
-template<int dim>
+template<int dim, int spacedim>
 void FETools::compute_component_wise(
-  const FiniteElement<dim>& element,
+  const FiniteElement<dim,spacedim>& element,
   std::vector<unsigned int>& renumbering,
   std::vector<std::vector<unsigned int> >& comp_start)
 {
@@ -285,9 +285,9 @@ void FETools::compute_component_wise(
 
 
 
-template<int dim>
+template<int dim, int spacedim>
 void FETools::compute_block_renumbering (
-  const FiniteElement<dim>& element,
+  const FiniteElement<dim,spacedim>& element,
   std::vector<unsigned int>& renumbering,
   std::vector<unsigned int>& start_indices)
 {
@@ -319,9 +319,9 @@ void FETools::compute_block_renumbering (
 
 
 
-template <int dim, typename number>
-void FETools::get_interpolation_matrix (const FiniteElement<dim> &fe1,
-                                        const FiniteElement<dim> &fe2,
+template <int dim, typename number, int spacedim>
+void FETools::get_interpolation_matrix (const FiniteElement<dim,spacedim> &fe1,
+                                        const FiniteElement<dim,spacedim> &fe2,
                                         FullMatrix<number> &interpolation_matrix)
 {
   Assert (fe1.n_components() == fe2.n_components(),
@@ -341,7 +341,7 @@ void FETools::get_interpolation_matrix (const FiniteElement<dim> &fe1,
     {
       gim_forwarder (fe1, fe2, interpolation_matrix);
     }
-  catch (typename FiniteElement<dim>::ExcInterpolationNotImplemented &)
+  catch (typename FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented &)
     {
                                        // too bad....
       fe_implements_interpolation = false;
@@ -363,8 +363,9 @@ void FETools::get_interpolation_matrix (const FiniteElement<dim> &fe1,
   const std::vector<Point<dim> > &
     fe2_support_points = fe2.get_unit_support_points ();
 
+  typedef FiniteElement<dim,spacedim> FEL;
   Assert(fe2_support_points.size()==fe2.dofs_per_cell,
-        typename FiniteElement<dim>::ExcFEHasNoSupportPoints());
+        typename FEL::ExcFEHasNoSupportPoints());
 
   for (unsigned int i=0; i<fe2.dofs_per_cell; ++i)     
     {
@@ -382,9 +383,9 @@ void FETools::get_interpolation_matrix (const FiniteElement<dim> &fe1,
 
 
 
-template <int dim, typename number>
-void FETools::get_back_interpolation_matrix(const FiniteElement<dim> &fe1,
-                                           const FiniteElement<dim> &fe2,
+template <int dim, typename number, int spacedim>
+void FETools::get_back_interpolation_matrix(const FiniteElement<dim,spacedim> &fe1,
+                                           const FiniteElement<dim,spacedim> &fe2,
                                            FullMatrix<number> &interpolation_matrix)
 {
   Assert (fe1.n_components() == fe2.n_components(),
@@ -408,9 +409,9 @@ void FETools::get_back_interpolation_matrix(const FiniteElement<dim> &fe1,
 
 
 
-template <int dim, typename number>
-void FETools::get_interpolation_difference_matrix (const FiniteElement<dim> &fe1,
-                                                  const FiniteElement<dim> &fe2,
+template <int dim, typename number, int spacedim>
+void FETools::get_interpolation_difference_matrix (const FiniteElement<dim,spacedim> &fe1,
+                                                  const FiniteElement<dim,spacedim> &fe2,
                                                   FullMatrix<number> &difference_matrix)
 {
   Assert (fe1.n_components() == fe2.n_components(),
@@ -434,9 +435,9 @@ void FETools::get_interpolation_difference_matrix (const FiniteElement<dim> &fe1
 
 
 
-template <int dim, typename number>
-void FETools::get_projection_matrix (const FiniteElement<dim> &fe1,
-                                    const FiniteElement<dim> &fe2,
+template <int dim, typename number, int spacedim>
+void FETools::get_projection_matrix (const FiniteElement<dim,spacedim> &fe1,
+                                    const FiniteElement<dim,spacedim> &fe2,
                                     FullMatrix<number> &matrix)
 {
   Assert (fe1.n_components() == 1, ExcNotImplemented());
@@ -453,7 +454,7 @@ void FETools::get_projection_matrix (const FiniteElement<dim> &fe1,
 
                                   // First, create a local mass matrix for
                                   // the unit cell
-  Triangulation<dim> tr;
+  Triangulation<dim,spacedim> tr;
   GridGenerator::hyper_cube(tr);
   
                                   // Choose a quadrature rule
@@ -517,11 +518,11 @@ void FETools::get_projection_matrix (const FiniteElement<dim> &fe1,
 }
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
 FETools::compute_node_matrix(
   FullMatrix<double>& N,
-  const FiniteElement<dim>& fe)
+  const FiniteElement<dim,spacedim>& fe)
 {
   const unsigned int n_dofs = fe.dofs_per_cell;
   Assert (fe.has_generalized_support_points(), ExcNotInitialized());
@@ -559,13 +560,32 @@ FETools::compute_node_matrix(
     }
 }
 
+#if deal_II_dimension != 3
+template<>
+void
+FETools::compute_embedding_matrices(const FiniteElement<1,2> &,
+                                   std::vector<std::vector<FullMatrix<double> > > & )
+{
+  Assert(false, ExcNotImplemented());
+}
+
+template<>
+void
+FETools::compute_embedding_matrices(const FiniteElement<2,3>&,
+                                   std::vector<std::vector<FullMatrix<double> > >& )
+{
+  Assert(false, ExcNotImplemented());
+}
+
+#endif
 
 // This function is tested by tests/fe/internals, since it produces the matrices printed there
-template<int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
-FETools::compute_embedding_matrices(const FiniteElement<dim>& fe,
+FETools::compute_embedding_matrices(const FiniteElement<dim,spacedim>& fe,
                                    std::vector<std::vector<FullMatrix<number> > >& matrices)
 {
+
   const unsigned int n  = fe.dofs_per_cell;
   const unsigned int nd = fe.n_components();
   const unsigned int degree = fe.degree;
@@ -581,9 +601,9 @@ FETools::compute_embedding_matrices(const FiniteElement<dim>& fe,
          Assert(matrices[ref_case-1][i].m() == n, ExcDimensionMismatch(matrices[ref_case-1][i].m(),n));
        }
   
-                                      // Set up meshes, one with a single
-                                      // reference cell and refine it once
-      Triangulation<dim> tria;
+                                   // Set up meshes, one with a single
+                                   // reference cell and refine it once
+      Triangulation<dim,spacedim> tria;
       GridGenerator::hyper_cube (tria, 0, 1);
       tria.begin_active()->set_refine_flag(RefinementCase<dim>(ref_case));
       tria.execute_coarsening_and_refinement();
@@ -682,9 +702,9 @@ FETools::compute_embedding_matrices(const FiniteElement<dim>& fe,
 // This function is tested by tests/fe/internals, since it produces the matrices printed there
 
 //TODO:[GK] Is this correct for vector valued?
-template<int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
-FETools::compute_face_embedding_matrices(const FiniteElement<dim>& fe,
+FETools::compute_face_embedding_matrices(const FiniteElement<dim,spacedim>& fe,
                                         FullMatrix<number> (&matrices)[GeometryInfo<dim>::max_children_per_face],
                                         const unsigned int face_coarse,
                                         const unsigned int face_fine)
@@ -702,7 +722,7 @@ FETools::compute_face_embedding_matrices(const FiniteElement<dim>& fe,
   
                                    // Set up meshes, one with a single
                                    // reference cell and refine it once
-  Triangulation<dim> tria;
+  Triangulation<dim,spacedim> tria;
   GridGenerator::hyper_cube (tria, 0, 1);
   tria.refine_global(1);
 
@@ -802,7 +822,7 @@ FETools::compute_face_embedding_matrices(const FiniteElement<dim>& fe,
        = QProjector<dim>::project_to_subface(q_gauss, face_coarse, cell_number);
       FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
       
-      typename Triangulation<dim>::active_cell_iterator fine_cell
+      typename Triangulation<dim,spacedim>::active_cell_iterator fine_cell
        = tria.begin(0)->child(GeometryInfo<dim>::child_cell_on_face(
          tria.begin(0)->refinement_case(), face_coarse, cell_number));
       fine.reinit(fine_cell);
@@ -847,10 +867,29 @@ FETools::compute_face_embedding_matrices(const FiniteElement<dim>& fe,
     }
 }
 
+#if deal_II_dimension != 3
+template <>
+void
+FETools::compute_projection_matrices(const FiniteElement<1,2>&,
+                                    std::vector<std::vector<FullMatrix<double> > >& )
+{
+  Assert(false, ExcNotImplemented());
+}
+
+template <>
+void
+FETools::compute_projection_matrices(const FiniteElement<2,3>&,
+                                    std::vector<std::vector<FullMatrix<double> > >& )
+{
+  Assert(false, ExcNotImplemented());
+}
+
+#endif
+
 
-template<int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
-FETools::compute_projection_matrices(const FiniteElement<dim>& fe,
+FETools::compute_projection_matrices(const FiniteElement<dim,spacedim>& fe,
                                     std::vector<std::vector<FullMatrix<number> > >& matrices)
 {
   const unsigned int n  = fe.dofs_per_cell;
@@ -872,7 +911,7 @@ FETools::compute_projection_matrices(const FiniteElement<dim>& fe,
                 ExcDimensionMismatch(matrices[ref_case-1][i].m(),n));
        }
   
-      Triangulation<dim> tr;
+      Triangulation<dim,spacedim> tr;
       GridGenerator::hyper_cube (tr, 0, 1);
       tr.begin_active()->set_refine_flag(RefinementCase<dim>(ref_case));
       tr.execute_coarsening_and_refinement();
@@ -890,7 +929,7 @@ FETools::compute_projection_matrices(const FiniteElement<dim>& fe,
                          update_JxW_values |
                          update_values);
   
-      typename Triangulation<dim>::cell_iterator coarse_cell
+      typename Triangulation<dim,spacedim>::cell_iterator coarse_cell
        = tr.begin(0);
                                       // Compute the coarse level mass
                                       // matrix
@@ -976,15 +1015,15 @@ FETools::compute_projection_matrices(const FiniteElement<dim>& fe,
 }
 
 
-template <int dim,
-          template <int> class DH1,
-          template <int> class DH2,
+template <int dim, int spacedim,
+          template <int, int> class DH1,
+          template <int, int> class DH2,
           class InVector, class OutVector>
 void
-FETools::interpolate(const DH1<dim> &dof1,
-                     const InVector &u1,
-                     const DH2<dim> &dof2,
-                     OutVector      &u2)
+FETools::interpolate(const DH1<dim, spacedim> &dof1,
+                     const InVector           &u1,
+                     const DH2<dim, spacedim> &dof2,
+                     OutVector                &u2)
 {
   ConstraintMatrix dummy;
   dummy.close();
@@ -993,16 +1032,16 @@ FETools::interpolate(const DH1<dim> &dof1,
 
 
 
-template <int dim,
-          template <int> class DH1,
-          template <int> class DH2,              
+template <int dim, int spacedim,
+          template <int, int> class DH1,
+          template <int, int> class DH2,              
           class InVector, class OutVector>
 void
-FETools::interpolate (const DH1<dim>         &dof1,
-                      const InVector         &u1,
-                      const DH2<dim>         &dof2,
-                      const ConstraintMatrix &constraints,
-                      OutVector              &u2)
+FETools::interpolate (const DH1<dim, spacedim> &dof1,
+                      const InVector           &u1,
+                      const DH2<dim, spacedim> &dof2,
+                      const ConstraintMatrix   &constraints,
+                      OutVector                &u2)
 {
   Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
 
@@ -1022,15 +1061,15 @@ FETools::interpolate (const DH1<dim>         &dof1,
                                    // have a map for interpolation
                                    // matrices. shared_ptr make sure
                                    // that memory is released again
-  std::map<const FiniteElement<dim> *,
-           std::map<const FiniteElement<dim> *,
+  std::map<const FiniteElement<dim,spacedim> *,
+           std::map<const FiniteElement<dim,spacedim> *,
                     boost::shared_ptr<FullMatrix<double> > > >
     interpolation_matrices;
   
-  typename DH1<dim>::active_cell_iterator cell1 = dof1.begin_active(),
-                                          endc1 = dof1.end();
-  typename DH2<dim>::active_cell_iterator cell2 = dof2.begin_active(),
-                                          endc2 = dof2.end();
+  typename DH1<dim,spacedim>::active_cell_iterator cell1 = dof1.begin_active(),
+                                                   endc1 = dof1.end();
+  typename DH2<dim,spacedim>::active_cell_iterator cell2 = dof2.begin_active(),
+                                                   endc2 = dof2.end();
 
   std::vector<unsigned int> touch_count(dof2.n_dofs(),0);
   std::vector<unsigned int> dofs;
@@ -1115,11 +1154,11 @@ FETools::interpolate (const DH1<dim>         &dof1,
 
 
 
-template <int dim, class InVector, class OutVector>
+template <int dim, class InVector, class OutVector, int spacedim>
 void
-FETools::back_interpolate(const DoFHandler<dim>    &dof1,
+FETools::back_interpolate(const DoFHandler<dim,spacedim>    &dof1,
                           const InVector           &u1,
-                          const FiniteElement<dim> &fe2,
+                          const FiniteElement<dim,spacedim> &fe2,
                           OutVector                &u1_interpolated)
 {
   Assert(dof1.get_fe().n_components() == fe2.n_components(),
@@ -1143,7 +1182,7 @@ FETools::back_interpolate(const DoFHandler<dim>    &dof1,
   Vector<typename OutVector::value_type> u1_local(dofs_per_cell1);
   Vector<typename OutVector::value_type> u1_int_local(dofs_per_cell1);
   
-  typename DoFHandler<dim>::active_cell_iterator cell = dof1.begin_active(),
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
                                                 endc = dof1.end();
 
   FullMatrix<double> interpolation_matrix(dofs_per_cell1, dofs_per_cell1);
@@ -1167,11 +1206,11 @@ FETools::back_interpolate(const DoFHandler<dim>    &dof1,
   
 template <int dim,
           template <int> class DH,
-          class InVector, class OutVector>
+          class InVector, class OutVector, int spacedim>
 void
 FETools::back_interpolate(const DH<dim>            &dof1,
                           const InVector           &u1,
-                          const FiniteElement<dim> &fe2,
+                          const FiniteElement<dim,spacedim> &fe2,
                           OutVector                &u1_interpolated)
 {
   Assert(u1.size() == dof1.n_dofs(),
@@ -1237,11 +1276,11 @@ FETools::back_interpolate(const DH<dim>            &dof1,
 
 
   
-template <int dim, class InVector, class OutVector>
-void FETools::back_interpolate(const DoFHandler<dim> &dof1,
+template <int dim, class InVector, class OutVector, int spacedim>
+void FETools::back_interpolate(const DoFHandler<dim,spacedim> &dof1,
                               const ConstraintMatrix &constraints1,
                               const InVector &u1,
-                              const DoFHandler<dim> &dof2,
+                              const DoFHandler<dim,spacedim> &dof2,
                               const ConstraintMatrix &constraints2,
                               OutVector &u1_interpolated)
 {
@@ -1275,10 +1314,10 @@ void FETools::back_interpolate(const DoFHandler<dim> &dof1,
 
 
   
-template <int dim, class InVector, class OutVector>
-void FETools::interpolation_difference (const DoFHandler<dim> &dof1,
+template <int dim, class InVector, class OutVector, int spacedim>
+void FETools::interpolation_difference (const DoFHandler<dim,spacedim> &dof1,
                                        const InVector &u1,
-                                       const FiniteElement<dim> &fe2,
+                                       const FiniteElement<dim,spacedim> &fe2,
                                        OutVector &u1_difference)
 {
   Assert(dof1.get_fe().n_components() == fe2.n_components(),
@@ -1306,7 +1345,7 @@ void FETools::interpolation_difference (const DoFHandler<dim> &dof1,
   FETools::get_interpolation_difference_matrix(dof1.get_fe(), fe2,
                                               difference_matrix);
   
-  typename DoFHandler<dim>::active_cell_iterator cell = dof1.begin_active(),
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
                                                 endc = dof1.end();
   
   for (; cell!=endc; ++cell)
@@ -1325,11 +1364,11 @@ void FETools::interpolation_difference (const DoFHandler<dim> &dof1,
 
 
 
-template <int dim, class InVector, class OutVector>
-void FETools::interpolation_difference(const DoFHandler<dim> &dof1,
+template <int dim, class InVector, class OutVector, int spacedim>
+void FETools::interpolation_difference(const DoFHandler<dim,spacedim> &dof1,
                                       const ConstraintMatrix &constraints1,
                                       const InVector &u1,
-                                      const DoFHandler<dim> &dof2,
+                                      const DoFHandler<dim,spacedim> &dof2,
                                       const ConstraintMatrix &constraints2,
                                       OutVector &u1_difference)
 {
@@ -1348,10 +1387,10 @@ void FETools::interpolation_difference(const DoFHandler<dim> &dof1,
 }
 
   
-template <int dim, class InVector, class OutVector>
-void FETools::project_dg(const DoFHandler<dim> &dof1,
+template <int dim, class InVector, class OutVector, int spacedim>
+void FETools::project_dg(const DoFHandler<dim,spacedim> &dof1,
                         const InVector &u1,
-                        const DoFHandler<dim> &dof2,
+                        const DoFHandler<dim,spacedim> &dof2,
                         OutVector &u2)
 {
   Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
@@ -1360,9 +1399,9 @@ void FETools::project_dg(const DoFHandler<dim> &dof1,
   Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));  
   Assert(u2.size()==dof2.n_dofs(), ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
 
-  typename DoFHandler<dim>::active_cell_iterator cell1 = dof1.begin_active();
-  typename DoFHandler<dim>::active_cell_iterator cell2 = dof2.begin_active();
-  typename DoFHandler<dim>::active_cell_iterator end = dof2.end();
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell1 = dof1.begin_active();
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell2 = dof2.begin_active();
+  typename DoFHandler<dim,spacedim>::active_cell_iterator end = dof2.end();
 
   const unsigned int n1 = dof1.get_fe().dofs_per_cell;
   const unsigned int n2 = dof2.get_fe().dofs_per_cell;
@@ -1390,10 +1429,10 @@ void FETools::project_dg(const DoFHandler<dim> &dof1,
 }
 
   
-template <int dim, class InVector, class OutVector>
-void FETools::extrapolate(const DoFHandler<dim> &dof1,
+template <int dim, class InVector, class OutVector, int spacedim>
+void FETools::extrapolate(const DoFHandler<dim,spacedim> &dof1,
                          const InVector &u1,
-                         const DoFHandler<dim> &dof2,
+                         const DoFHandler<dim,spacedim> &dof2,
                          OutVector &u2)
 {
   ConstraintMatrix dummy;
@@ -1403,10 +1442,10 @@ void FETools::extrapolate(const DoFHandler<dim> &dof1,
 
 
 
-template <int dim, class InVector, class OutVector>
-void FETools::extrapolate(const DoFHandler<dim> &dof1,
+template <int dim, class InVector, class OutVector, int spacedim>
+void FETools::extrapolate(const DoFHandler<dim,spacedim> &dof1,
                          const InVector &u1,
-                         const DoFHandler<dim> &dof2,
+                         const DoFHandler<dim,spacedim> &dof2,
                          const ConstraintMatrix &constraints,
                          OutVector &u2)
 {
@@ -1429,7 +1468,7 @@ void FETools::extrapolate(const DoFHandler<dim> &dof1,
                                   // treat these cells and would
                                   // generate a bogus result
   {
-    typename DoFHandler<dim>::cell_iterator cell = dof2.begin(0),
+    typename DoFHandler<dim,spacedim>::cell_iterator cell = dof2.begin(0),
                                            endc = dof2.end(0);
     for (; cell!=endc; ++cell)
       Assert (cell->has_children(), ExcGridNotRefinedAtLeastOnce());
@@ -1438,7 +1477,7 @@ void FETools::extrapolate(const DoFHandler<dim> &dof1,
                                   // then traverse grid bottom up
   for (unsigned int level=0; level<dof1.get_tria().n_levels()-1; ++level)
     {
-      typename DoFHandler<dim>::cell_iterator cell=dof2.begin(level),
+      typename DoFHandler<dim,spacedim>::cell_iterator cell=dof2.begin(level),
                                              endc=dof2.end(level);
 
       for (; cell!=endc; ++cell)
@@ -1475,10 +1514,10 @@ void FETools::extrapolate(const DoFHandler<dim> &dof1,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 FETools::add_fe_name(const std::string& parameter_name,
-                    const FEFactoryBase<dim>* factory)
+                    const FEFactoryBase<dim,spacedim>* factory)
 {
                                   // Erase everything after the
                                   // actual class name
@@ -1504,7 +1543,7 @@ FETools::add_fe_name(const std::string& parameter_name,
 
 
 template <int dim>
-FiniteElement<dim> *
+FiniteElement<dim, dim> *
 FETools::get_fe_from_name (const std::string &parameter_name)
 {
                                   // Create a version of the name
@@ -1554,7 +1593,7 @@ FETools::get_fe_from_name (const std::string &parameter_name)
   
   try
     {    
-      FiniteElement<dim> *fe = get_fe_from_name_aux<dim> (name);
+      FiniteElement<dim,dim> *fe = get_fe_from_name_aux<dim,dim> (name);
 
                                        // Make sure the auxiliary function
                                        // ate up all characters of the name.
@@ -1574,9 +1613,16 @@ FETools::get_fe_from_name (const std::string &parameter_name)
 }
 
 
+// template <int dim>
+// FiniteElement<dim> *
+// FETools::get_fe_from_name (const std::string &parameter_name)
+// {
+//     return get_fe_from_name<dim,dim>(parameter_name);
+// }
 
-template <int dim>
-FiniteElement<dim>*
+
+template <int dim, int spacedim>
+FiniteElement<dim,spacedim>*
 FETools::get_fe_from_name_aux (std::string &name)
 {
                                   // Extract the name of the
@@ -1605,7 +1651,7 @@ FETools::get_fe_from_name_aux (std::string &name)
                                       // recursive calls if one of
                                       // these calls should throw
                                       // an exception
-      std::vector<FiniteElement<dim>*> base_fes;
+      std::vector<FiniteElement<dim,spacedim>*> base_fes;
       std::vector<unsigned int>        base_multiplicities;
       try
        {
@@ -1621,7 +1667,7 @@ FETools::get_fe_from_name_aux (std::string &name)
                                               // Now, the name of the
                                               // first base element is
                                               // first... Let's get it
-             base_fes.push_back (get_fe_from_name_aux<dim> (name));
+             base_fes.push_back (get_fe_from_name_aux<dim,spacedim> (name));
                                               // next check whether
                                               // FESystem placed a
                                               // multiplicity after
@@ -1677,7 +1723,7 @@ FETools::get_fe_from_name_aux (std::string &name)
                                             // everything went ok. so
                                             // generate the composed
                                             // element
-           FiniteElement<dim> *system_element = 0;
+           FiniteElement<dim,spacedim> *system_element = 0;
            switch (base_fes.size())
              {
                case 1:
@@ -1803,10 +1849,10 @@ FETools::get_fe_from_name_aux (std::string &name)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 FETools::
-compute_projection_from_quadrature_points_matrix (const FiniteElement<dim> &fe,
+compute_projection_from_quadrature_points_matrix (const FiniteElement<dim,spacedim> &fe,
                                                   const Quadrature<dim>    &lhs_quadrature,
                                                   const Quadrature<dim>    &rhs_quadrature,
                                                   FullMatrix<double>       &X)
@@ -1844,10 +1890,10 @@ compute_projection_from_quadrature_points_matrix (const FiniteElement<dim> &fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 FETools::
-compute_interpolation_to_quadrature_points_matrix (const FiniteElement<dim> &fe,
+compute_interpolation_to_quadrature_points_matrix (const FiniteElement<dim,spacedim> &fe,
                                                    const Quadrature<dim>    &quadrature,
                                                    FullMatrix<double>       &I_q)
 {
@@ -1941,6 +1987,25 @@ void FETools::interpolate<deal_II_dimension>
 (const DoFHandler<deal_II_dimension> &, const Vector<double> &,
  const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
  Vector<double> &);
+
+#if deal_II_dimension != 3
+template
+void FETools::compute_embedding_matrices<deal_II_dimension,double,deal_II_dimension+1>
+(const FiniteElement<deal_II_dimension,deal_II_dimension+1> &, std::vector<std::vector<FullMatrix<double> > >&);
+template
+void FETools::compute_projection_matrices<deal_II_dimension,double,deal_II_dimension+1>
+(const FiniteElement<deal_II_dimension,deal_II_dimension+1> &, std::vector<std::vector<FullMatrix<double> > >&);
+template
+void FETools::interpolate<deal_II_dimension,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const Vector<double> &,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, Vector<double> &);
+template
+void FETools::interpolate<deal_II_dimension,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const Vector<double> &,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const ConstraintMatrix &,
+ Vector<double> &);
+#endif
+
 template
 void FETools::back_interpolate<deal_II_dimension>
 (const DoFHandler<deal_II_dimension> &, const Vector<double> &,
@@ -1985,6 +2050,19 @@ void FETools::interpolate<deal_II_dimension>
 (const DoFHandler<deal_II_dimension> &, const Vector<float> &,
  const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
  Vector<float> &);
+
+#if deal_II_dimension != 3
+template
+void FETools::interpolate<deal_II_dimension,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const Vector<float> &,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, Vector<float> &);
+template
+void FETools::interpolate<deal_II_dimension>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const Vector<float> &,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const ConstraintMatrix &,
+ Vector<float> &);
+#endif
+
 template
 void FETools::back_interpolate<deal_II_dimension>
 (const DoFHandler<deal_II_dimension> &, const Vector<float> &,
@@ -2077,6 +2155,19 @@ void FETools::interpolate<deal_II_dimension>
 (const DoFHandler<deal_II_dimension> &, const BlockVector<double> &,
  const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
  BlockVector<double> &);
+
+#if deal_II_dimension != 3
+template
+void FETools::interpolate<deal_II_dimension,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const BlockVector<double> &,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, BlockVector<double> &);
+template
+void FETools::interpolate<deal_II_dimension,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const BlockVector<double> &,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const ConstraintMatrix &,
+ BlockVector<double> &);
+#endif
+
 template
 void FETools::back_interpolate<deal_II_dimension>
 (const DoFHandler<deal_II_dimension> &, const BlockVector<double> &,
@@ -2130,6 +2221,19 @@ void FETools::interpolate<deal_II_dimension>
 (const DoFHandler<deal_II_dimension> &, const BlockVector<float> &,
  const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
  BlockVector<float> &);
+
+#if deal_II_dimension != 3
+template
+void FETools::interpolate<deal_II_dimension,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const BlockVector<float> &,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, BlockVector<float> &);
+template
+void FETools::interpolate<deal_II_dimension,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const BlockVector<float> &,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const ConstraintMatrix &,
+ BlockVector<float> &);
+#endif
+
 template
 void FETools::back_interpolate<deal_II_dimension>
 (const DoFHandler<deal_II_dimension> &, const BlockVector<float> &,
@@ -2241,10 +2345,13 @@ void FETools::interpolate<deal_II_dimension>
  const hp::DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
  Vector<float> &);
 
-template FiniteElement<deal_II_dimension> *
+
+template FiniteElement<deal_II_dimension,deal_II_dimension> *
 FETools::get_fe_from_name<deal_II_dimension> (const std::string &);
-template void
-FETools::add_fe_name<deal_II_dimension>(
+
+
+template 
+void FETools::add_fe_name<deal_II_dimension>(
   const std::string& name,
   const FEFactoryBase<deal_II_dimension>* factory);
   
@@ -2264,6 +2371,7 @@ compute_interpolation_to_quadrature_points_matrix (const FiniteElement<deal_II_d
                                                    FullMatrix<double>       &I_q);
 
 
+
 /*----------------------------   fe_tools.cc     ---------------------------*/
 
 DEAL_II_NAMESPACE_CLOSE
index dc37d675e74d042bba3dab479855164f79ff82cb..d3f790b0d07f0ef01ba7c768327261d8536280fd 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
-/* ---------------- FEValuesBase<dim>::CellIteratorBase --------- */
+/* ---------------- FEValuesBase<dim,spacedim>::CellIteratorBase --------- */
 
-template <int dim>
-FEValuesBase<dim>::CellIteratorBase::~CellIteratorBase ()
+template <int dim, int spacedim>
+FEValuesBase<dim,spacedim>::CellIteratorBase::~CellIteratorBase ()
 {}
 
 
 
-/* ---------------- FEValuesBase<dim>::CellIterator<CI> --------- */
+/* ---------------- FEValuesBase<dim,spacedim>::CellIterator<CI> --------- */
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
-FEValuesBase<dim>::CellIterator<CI>::CellIterator (const CI &cell)
+FEValuesBase<dim,spacedim>::CellIterator<CI>::CellIterator (const CI &cell)
                 :
                 cell(cell)
 {}
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
-FEValuesBase<dim>::CellIterator<CI>::
-operator const typename Triangulation<dim>::cell_iterator () const
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
+operator const typename Triangulation<dim,spacedim>::cell_iterator () const
 {
   return cell;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 unsigned int
-FEValuesBase<dim>::CellIterator<CI>::n_dofs_for_dof_handler () const
+FEValuesBase<dim,spacedim>::CellIterator<CI>::n_dofs_for_dof_handler () const
 {
   return cell->get_dof_handler().n_dofs();
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const Vector<double> &in,
                              Vector<double>       &out) const
 {
@@ -82,10 +82,10 @@ get_interpolated_dof_values (const Vector<double> &in,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const Vector<float> &in,
                              Vector<float>       &out) const
 {
@@ -93,10 +93,10 @@ get_interpolated_dof_values (const Vector<float> &in,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const Vector<long double> &in,
                              Vector<long double>       &out) const
 {
@@ -104,10 +104,10 @@ get_interpolated_dof_values (const Vector<long double> &in,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const BlockVector<double> &in,
                              Vector<double>            &out) const
 {
@@ -115,10 +115,10 @@ get_interpolated_dof_values (const BlockVector<double> &in,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const BlockVector<float> &in,
                              Vector<float>            &out) const
 {
@@ -126,10 +126,10 @@ get_interpolated_dof_values (const BlockVector<float> &in,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const BlockVector<long double> &in,
                              Vector<long double>            &out) const
 {
@@ -140,10 +140,10 @@ get_interpolated_dof_values (const BlockVector<long double> &in,
 
 #ifdef DEAL_II_USE_PETSC
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const PETScWrappers::Vector &in,
                              Vector<PetscScalar>         &out) const
 {
@@ -152,10 +152,10 @@ get_interpolated_dof_values (const PETScWrappers::Vector &in,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const PETScWrappers::BlockVector &in,
                              Vector<PetscScalar>              &out) const
 {
@@ -166,10 +166,11 @@ get_interpolated_dof_values (const PETScWrappers::BlockVector &in,
 
 #ifdef DEAL_II_USE_TRILINOS
 
-template <int dim>
+
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const TrilinosWrappers::Vector &in,
                              Vector<TrilinosScalar>         &out) const
 {
@@ -178,10 +179,10 @@ get_interpolated_dof_values (const TrilinosWrappers::Vector &in,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename CI>
 void
-FEValuesBase<dim>::CellIterator<CI>::
+FEValuesBase<dim,spacedim>::CellIterator<CI>::
 get_interpolated_dof_values (const TrilinosWrappers::BlockVector &in,
                              Vector<TrilinosScalar>              &out) const
 {
@@ -215,50 +216,50 @@ get_interpolated_dof_values (const TrilinosWrappers::MPI::BlockVector &in,
 #endif
 
 
-/* ---------------- FEValuesBase<dim>::TriaCellIterator --------- */
+/* ---------------- FEValuesBase<dim,spacedim>::TriaCellIterator --------- */
 
-template <int dim>
+template <int dim, int spacedim>
 const char * const
-FEValuesBase<dim>::TriaCellIterator::message_string
+FEValuesBase<dim,spacedim>::TriaCellIterator::message_string
 = ("You have previously called the FEValues::reinit function with a\n"
-   "cell iterator of type Triangulation<dim>::cell_iterator. However,\n"
+   "cell iterator of type Triangulation<dim,spacedim>::cell_iterator. However,\n"
    "when you do this, you cannot call some functions in the FEValues\n"
    "class, such as the get_function_values/gradients/hessians\n"
    "functions. If you need these functions, then you need to call\n"
    "FEValues::reinit with an iterator type that allows to extract\n"
-   "degrees of freedom, such as DoFHandler<dim>::cell_iterator.");
+   "degrees of freedom, such as DoFHandler<dim,spacedim>::cell_iterator.");
 
 
-template <int dim>
-FEValuesBase<dim>::TriaCellIterator::
-TriaCellIterator (const typename Triangulation<dim>::cell_iterator &cell)
+template <int dim, int spacedim>
+FEValuesBase<dim,spacedim>::TriaCellIterator::
+TriaCellIterator (const typename Triangulation<dim,spacedim>::cell_iterator &cell)
                 :
                 cell(cell)
 {}
 
 
 
-template <int dim>
-FEValuesBase<dim>::TriaCellIterator::
-operator const typename Triangulation<dim>::cell_iterator () const
+template <int dim, int spacedim>
+FEValuesBase<dim,spacedim>::TriaCellIterator::
+operator const typename Triangulation<dim,spacedim>::cell_iterator () const
 {
   return cell;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FEValuesBase<dim>::TriaCellIterator::n_dofs_for_dof_handler () const
+FEValuesBase<dim,spacedim>::TriaCellIterator::n_dofs_for_dof_handler () const
 {
   Assert (false, ExcMessage (message_string));
   return 0;
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const Vector<double> &,
                              Vector<double>       &) const
 {
@@ -266,9 +267,9 @@ get_interpolated_dof_values (const Vector<double> &,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const Vector<float> &,
                              Vector<float>       &) const
 {
@@ -276,9 +277,9 @@ get_interpolated_dof_values (const Vector<float> &,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const Vector<long double> &,
                              Vector<long double>       &) const
 {
@@ -286,9 +287,9 @@ get_interpolated_dof_values (const Vector<long double> &,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const BlockVector<double> &,
                              Vector<double>            &) const
 {
@@ -297,9 +298,9 @@ get_interpolated_dof_values (const BlockVector<double> &,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const BlockVector<float> &,
                              Vector<float>            &) const
 {
@@ -307,9 +308,9 @@ get_interpolated_dof_values (const BlockVector<float> &,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const BlockVector<long double> &,
                              Vector<long double>            &) const
 {
@@ -320,9 +321,9 @@ get_interpolated_dof_values (const BlockVector<long double> &,
 
 #ifdef DEAL_II_USE_PETSC
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const PETScWrappers::Vector &,
                              Vector<PetscScalar>         &) const
 {
@@ -331,9 +332,9 @@ get_interpolated_dof_values (const PETScWrappers::Vector &,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const PETScWrappers::BlockVector &,
                              Vector<PetscScalar>              &) const
 {
@@ -344,9 +345,9 @@ get_interpolated_dof_values (const PETScWrappers::BlockVector &,
 
 #ifdef DEAL_II_USE_TRILINOS
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const TrilinosWrappers::Vector &,
                              Vector<TrilinosScalar>         &) const
 {
@@ -355,9 +356,9 @@ get_interpolated_dof_values (const TrilinosWrappers::Vector &,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesBase<dim>::TriaCellIterator::
+FEValuesBase<dim,spacedim>::TriaCellIterator::
 get_interpolated_dof_values (const TrilinosWrappers::BlockVector &,
                              Vector<TrilinosScalar>              &) const
 {
@@ -394,10 +395,10 @@ get_interpolated_dof_values (const TrilinosWrappers::MPI::BlockVector &,
 /* --------------------- FEValuesData ----------------- */
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValuesData<dim>::initialize (const unsigned int        n_quadrature_points,
-                              const FiniteElement<dim> &fe,
+FEValuesData<dim,spacedim>::initialize (const unsigned int        n_quadrature_points,
+                              const FiniteElement<dim,spacedim> &fe,
                               const UpdateFlags         flags)
 {
   this->update_flags = flags;
@@ -432,11 +433,11 @@ FEValuesData<dim>::initialize (const unsigned int        n_quadrature_points,
 
   if (flags & update_gradients)
     this->shape_gradients.resize (n_nonzero_shape_components,
-                                  std::vector<Tensor<1,dim> > (n_quadrature_points));
+                                  std::vector<Tensor<1,spacedim> > (n_quadrature_points));
 
   if (flags & update_hessians)
     this->shape_hessians.resize (n_nonzero_shape_components,
-                                        std::vector<Tensor<2,dim> > (n_quadrature_points));
+                                        std::vector<Tensor<2,spacedim> > (n_quadrature_points));
   
   if (flags & update_quadrature_points)
     this->quadrature_points.resize(n_quadrature_points);
@@ -461,18 +462,21 @@ FEValuesData<dim>::initialize (const unsigned int        n_quadrature_points,
 
   if (flags & update_cell_JxW_values)
     this->cell_JxW_values.resize(n_quadrature_points);
+
+  if (flags & update_cell_normal_vectors)
+    this->cell_normal_vectors.resize(n_quadrature_points);
 }
 
 
 /*------------------------------- FEValuesBase ---------------------------*/
 
 
-template <int dim>
-FEValuesBase<dim>::FEValuesBase (const unsigned int n_q_points,
+template <int dim, int spacedim>
+FEValuesBase<dim,spacedim>::FEValuesBase (const unsigned int n_q_points,
                                 const unsigned int dofs_per_cell,
                                 const UpdateFlags flags,
-                                const Mapping<dim>       &mapping,
-                                const FiniteElement<dim> &fe)
+                                const Mapping<dim,spacedim>       &mapping,
+                                const FiniteElement<dim,spacedim> &fe)
                :
                n_quadrature_points (n_q_points),
                dofs_per_cell (dofs_per_cell),
@@ -486,8 +490,8 @@ FEValuesBase<dim>::FEValuesBase (const unsigned int n_q_points,
 
 
 
-template <int dim>
-FEValuesBase<dim>::~FEValuesBase ()
+template <int dim, int spacedim>
+FEValuesBase<dim,spacedim>::~FEValuesBase ()
 {
                                   // delete those fields that were
                                   // created by the mapping and
@@ -496,14 +500,14 @@ FEValuesBase<dim>::~FEValuesBase ()
                                   // have assumed ownership
   if (fe_data != 0)
     {
-      typename Mapping<dim>::InternalDataBase *tmp1=fe_data;
+      typename Mapping<dim,spacedim>::InternalDataBase *tmp1=fe_data;
       fe_data=0;
       delete tmp1;
     }
 
   if (mapping_data != 0)
     {
-      typename Mapping<dim>::InternalDataBase *tmp1=mapping_data;
+      typename Mapping<dim,spacedim>::InternalDataBase *tmp1=mapping_data;
       mapping_data=0;
       delete tmp1;
     }
@@ -511,9 +515,9 @@ FEValuesBase<dim>::~FEValuesBase ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector, typename number>
-void FEValuesBase<dim>::get_function_values (
+void FEValuesBase<dim,spacedim>::get_function_values (
   const InputVector            &fe_function,
   std::vector<number> &values) const
 {
@@ -550,9 +554,9 @@ void FEValuesBase<dim>::get_function_values (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector, typename number>
-void FEValuesBase<dim>::get_function_values (
+void FEValuesBase<dim,spacedim>::get_function_values (
   const InputVector& fe_function,
   const VectorSlice<const std::vector<unsigned int> >& indices,
   std::vector<number> &values) const
@@ -587,9 +591,9 @@ void FEValuesBase<dim>::get_function_values (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector, typename number>
-void FEValuesBase<dim>::get_function_values (
+void FEValuesBase<dim,spacedim>::get_function_values (
   const InputVector&            fe_function,
   std::vector<Vector<number> >& values) const
 {
@@ -645,9 +649,9 @@ void FEValuesBase<dim>::get_function_values (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector, typename number>
-void FEValuesBase<dim>::get_function_values (
+void FEValuesBase<dim,spacedim>::get_function_values (
   const InputVector& fe_function,
   const VectorSlice<const std::vector<unsigned int> >& indices,
   std::vector<Vector<number> >& values) const
@@ -711,9 +715,9 @@ void FEValuesBase<dim>::get_function_values (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector, typename number>
-void FEValuesBase<dim>::get_function_values (
+void FEValuesBase<dim,spacedim>::get_function_values (
   const InputVector& fe_function,
   const VectorSlice<const std::vector<unsigned int> >& indices,
   std::vector<std::vector<number> >& values,
@@ -804,12 +808,12 @@ void FEValuesBase<dim>::get_function_values (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector>
 void
-FEValuesBase<dim>::get_function_gradients (
+FEValuesBase<dim,spacedim>::get_function_gradients (
   const InputVector           &fe_function,
-  std::vector<Tensor<1,dim> > &gradients) const
+  std::vector<Tensor<1,spacedim> > &gradients) const
 {
   Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
 
@@ -829,7 +833,7 @@ FEValuesBase<dim>::get_function_gradients (
   present_cell->get_interpolated_dof_values(fe_function, dof_values);
 
                                   // initialize with zero
-  std::fill_n (gradients.begin(), n_quadrature_points, Tensor<1,dim>());
+  std::fill_n (gradients.begin(), n_quadrature_points, Tensor<1,spacedim>());
 
                                   // add up contributions of trial
                                   // functions. note that here we
@@ -840,7 +844,7 @@ FEValuesBase<dim>::get_function_gradients (
   for (unsigned int point=0; point<n_quadrature_points; ++point)
     for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
       {
-       Tensor<1,dim> tmp = this->shape_grad(shape_func,point);
+       Tensor<1,spacedim> tmp = this->shape_grad(shape_func,point);
        tmp *= dof_values(shape_func);
        gradients[point] += tmp;
       };
@@ -848,12 +852,12 @@ FEValuesBase<dim>::get_function_gradients (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector>
-void FEValuesBase<dim>::get_function_gradients (
+void FEValuesBase<dim,spacedim>::get_function_gradients (
   const InputVector& fe_function,
   const VectorSlice<const std::vector<unsigned int> >& indices,
-  std::vector<Tensor<1,dim> > &values) const
+  std::vector<Tensor<1,spacedim> > &values) const
 {
   Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
                                   // This function fills a single
@@ -869,7 +873,7 @@ void FEValuesBase<dim>::get_function_gradients (
          ExcDimensionMismatch(values.size(), n_quadrature_points));
   
                                   // initialize with zero
-  std::fill_n (values.begin(), n_quadrature_points, Tensor<1,dim>());
+  std::fill_n (values.begin(), n_quadrature_points, Tensor<1,spacedim>());
   
                                   // add up contributions of trial
                                   // functions. note that here we
@@ -886,12 +890,12 @@ void FEValuesBase<dim>::get_function_gradients (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector>
 void
-FEValuesBase<dim>::get_function_gradients (
+FEValuesBase<dim,spacedim>::get_function_gradients (
   const InputVector                         &fe_function,
-  std::vector<std::vector<Tensor<1,dim> > > &gradients) const
+  std::vector<std::vector<Tensor<1,spacedim> > > &gradients) const
 {
   Assert (gradients.size() == n_quadrature_points,
          ExcDimensionMismatch(gradients.size(), n_quadrature_points));
@@ -915,7 +919,7 @@ FEValuesBase<dim>::get_function_gradients (
 
                                   // initialize with zero
   for (unsigned i=0;i<gradients.size();++i)
-    std::fill_n (gradients[i].begin(), gradients[i].size(), Tensor<1,dim>());
+    std::fill_n (gradients[i].begin(), gradients[i].size(), Tensor<1,spacedim>());
 
                                   // add up contributions of trial
                                   // functions. now check whether the
@@ -927,7 +931,7 @@ FEValuesBase<dim>::get_function_gradients (
     for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
       if (fe->is_primitive (shape_func))
        {
-         Tensor<1,dim> tmp = this->shape_grad(shape_func,point);
+         Tensor<1,spacedim> tmp = this->shape_grad(shape_func,point);
          tmp *= dof_values(shape_func);
          gradients[point][fe->system_to_component_index(shape_func).first]
            += tmp;
@@ -935,7 +939,7 @@ FEValuesBase<dim>::get_function_gradients (
       else
        for (unsigned int c=0; c<n_components; ++c)
          {
-           Tensor<1,dim> tmp = this->shape_grad_component(shape_func,point,c);
+           Tensor<1,spacedim> tmp = this->shape_grad_component(shape_func,point,c);
            tmp *= dof_values(shape_func);
            gradients[point][c] += tmp;
          }
@@ -943,12 +947,12 @@ FEValuesBase<dim>::get_function_gradients (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector>
-void FEValuesBase<dim>::get_function_gradients (
+void FEValuesBase<dim,spacedim>::get_function_gradients (
   const InputVector& fe_function,
   const VectorSlice<const std::vector<unsigned int> >& indices,
-  std::vector<std::vector<Tensor<1,dim> > >& values,
+  std::vector<std::vector<Tensor<1,spacedim> > >& values,
   bool quadrature_points_fastest) const
 {
   const unsigned int n_components = fe->n_components();
@@ -996,7 +1000,7 @@ void FEValuesBase<dim>::get_function_gradients (
     
                                   // initialize with zero
   for (unsigned i=0;i<values.size();++i)
-    std::fill_n (values[i].begin(), values[i].size(), Tensor<1,dim>());
+    std::fill_n (values[i].begin(), values[i].size(), Tensor<1,spacedim>());
 
                                   // add up contributions of trial
                                   // functions. now check whether the
@@ -1034,12 +1038,12 @@ void FEValuesBase<dim>::get_function_gradients (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector>
 void
-FEValuesBase<dim>::
+FEValuesBase<dim,spacedim>::
 get_function_hessians (const InputVector           &fe_function,
-                             std::vector<Tensor<2,dim> > &hessians) const
+                             std::vector<Tensor<2,spacedim> > &hessians) const
 {
   Assert (fe->n_components() == 1,
          ExcDimensionMismatch(fe->n_components(), 1));
@@ -1058,7 +1062,7 @@ get_function_hessians (const InputVector           &fe_function,
   present_cell->get_interpolated_dof_values(fe_function, dof_values);
 
                                   // initialize with zero
-  std::fill_n (hessians.begin(), n_quadrature_points, Tensor<2,dim>());
+  std::fill_n (hessians.begin(), n_quadrature_points, Tensor<2,spacedim>());
 
                                   // add up contributions of trial
                                   // functions. note that here we
@@ -1069,7 +1073,7 @@ get_function_hessians (const InputVector           &fe_function,
   for (unsigned int point=0; point<n_quadrature_points; ++point)
     for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
       {
-       Tensor<2,dim> tmp = this->shape_hessian(shape_func,point);
+       Tensor<2,spacedim> tmp = this->shape_hessian(shape_func,point);
        tmp *= dof_values(shape_func);
        hessians[point] += tmp;
       };
@@ -1077,12 +1081,12 @@ get_function_hessians (const InputVector           &fe_function,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector>
-void FEValuesBase<dim>::get_function_hessians (
+void FEValuesBase<dim,spacedim>::get_function_hessians (
   const InputVector& fe_function,
   const VectorSlice<const std::vector<unsigned int> >& indices,
-  std::vector<Tensor<2,dim> > &values) const
+  std::vector<Tensor<2,spacedim> > &values) const
 {
   Assert (this->update_flags & update_second_derivatives, ExcAccessToUninitializedField());
                                   // This function fills a single
@@ -1098,7 +1102,7 @@ void FEValuesBase<dim>::get_function_hessians (
          ExcDimensionMismatch(values.size(), n_quadrature_points));
   
                                   // initialize with zero
-  std::fill_n (values.begin(), n_quadrature_points, Tensor<2,dim>());
+  std::fill_n (values.begin(), n_quadrature_points, Tensor<2,spacedim>());
   
                                   // add up contributions of trial
                                   // functions. note that here we
@@ -1115,12 +1119,12 @@ void FEValuesBase<dim>::get_function_hessians (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector>
 void
-FEValuesBase<dim>::
+FEValuesBase<dim,spacedim>::
 get_function_hessians (const InputVector                         &fe_function,
-                             std::vector<std::vector<Tensor<2,dim> > > &second_derivs,
+                             std::vector<std::vector<Tensor<2,spacedim> > > &second_derivs,
                              bool quadrature_points_fastest) const
 {
   Assert (n_quadrature_points == second_derivs.size(),
@@ -1145,7 +1149,7 @@ get_function_hessians (const InputVector                         &fe_function,
 
                                   // initialize with zero
   for (unsigned i=0;i<second_derivs.size();++i)
-    std::fill_n (second_derivs[i].begin(), second_derivs[i].size(), Tensor<2,dim>());
+    std::fill_n (second_derivs[i].begin(), second_derivs[i].size(), Tensor<2,spacedim>());
 
                                   // add up contributions of trial
                                   // functions
@@ -1154,7 +1158,7 @@ get_function_hessians (const InputVector                         &fe_function,
       for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
        if (fe->is_primitive(shape_func))
          {
-           Tensor<2,dim> tmp(shape_hessian(shape_func,point));
+           Tensor<2,spacedim> tmp(shape_hessian(shape_func,point));
            tmp *= dof_values(shape_func);
            second_derivs[fe->system_to_component_index(shape_func).first][point]
              += tmp;
@@ -1162,7 +1166,7 @@ get_function_hessians (const InputVector                         &fe_function,
        else
          for (unsigned int c=0; c<n_components; ++c)
            {
-             Tensor<2,dim> tmp = this->shape_hessian_component(shape_func,point,c);
+             Tensor<2,spacedim> tmp = this->shape_hessian_component(shape_func,point,c);
              tmp *= dof_values(shape_func);
              second_derivs[c][point] += tmp;
            }
@@ -1171,7 +1175,7 @@ get_function_hessians (const InputVector                         &fe_function,
       for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
        if (fe->is_primitive(shape_func))
          {
-           Tensor<2,dim> tmp(shape_hessian(shape_func,point));
+           Tensor<2,spacedim> tmp(shape_hessian(shape_func,point));
            tmp *= dof_values(shape_func);
            second_derivs[point][fe->system_to_component_index(shape_func).first]
              += tmp;
@@ -1179,7 +1183,7 @@ get_function_hessians (const InputVector                         &fe_function,
        else
          for (unsigned int c=0; c<n_components; ++c)
            {
-             Tensor<2,dim> tmp = this->shape_hessian_component(shape_func,point,c);
+             Tensor<2,spacedim> tmp = this->shape_hessian_component(shape_func,point,c);
              tmp *= dof_values(shape_func);
              second_derivs[point][c] += tmp;
            }
@@ -1187,12 +1191,12 @@ get_function_hessians (const InputVector                         &fe_function,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <class InputVector>
-void FEValuesBase<dim>::get_function_hessians (
+void FEValuesBase<dim,spacedim>::get_function_hessians (
   const InputVector& fe_function,
   const VectorSlice<const std::vector<unsigned int> >& indices,
-  std::vector<std::vector<Tensor<2,dim> > >& values,
+  std::vector<std::vector<Tensor<2,spacedim> > >& values,
   bool quadrature_points_fastest) const
 {
   Assert (this->update_flags & update_second_derivatives, ExcAccessToUninitializedField());
@@ -1240,7 +1244,7 @@ void FEValuesBase<dim>::get_function_hessians (
   
                                   // initialize with zero
   for (unsigned i=0;i<values.size();++i)
-    std::fill_n (values[i].begin(), values[i].size(), Tensor<2,dim>());
+    std::fill_n (values[i].begin(), values[i].size(), Tensor<2,spacedim>());
 
                                   // add up contributions of trial
                                   // functions. now check whether the
@@ -1278,9 +1282,21 @@ void FEValuesBase<dim>::get_function_hessians (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
+const std::vector<Point<spacedim> > &
+FEValuesBase<dim,spacedim>::get_cell_normal_vectors () const
+{
+  typedef FEValuesBase<dim,spacedim> FEVB;
+  Assert (this->update_flags & update_cell_normal_vectors,
+         typename FEVB::ExcAccessToUninitializedField());
+  return this->cell_normal_vectors;
+}
+
+
+
+template <int dim, int spacedim>
 unsigned int
-FEValuesBase<dim>::memory_consumption () const
+FEValuesBase<dim,spacedim>::memory_consumption () const
 {
   return (MemoryConsumption::memory_consumption (this->shape_values) +
          MemoryConsumption::memory_consumption (this->shape_gradients) +
@@ -1307,9 +1323,9 @@ FEValuesBase<dim>::memory_consumption () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 UpdateFlags
-FEValuesBase<dim>::compute_update_flags (const UpdateFlags update_flags) const
+FEValuesBase<dim,spacedim>::compute_update_flags (const UpdateFlags update_flags) const
 {
   
                                   // first find out which objects
@@ -1332,21 +1348,21 @@ FEValuesBase<dim>::compute_update_flags (const UpdateFlags update_flags) const
 /*------------------------------- FEValues -------------------------------*/
 
 
-template <int dim>
-const unsigned int FEValues<dim>::dimension;
+template <int dim, int spacedim>
+const unsigned int FEValues<dim,spacedim>::dimension;
 
-template <int dim>
-const unsigned int FEValues<dim>::integral_dimension;
+template <int dim, int spacedim>
+const unsigned int FEValues<dim,spacedim>::integral_dimension;
 
 
 
-template <int dim>
-FEValues<dim>::FEValues (const Mapping<dim>       &mapping,
-                        const FiniteElement<dim> &fe,
+template <int dim, int spacedim>
+FEValues<dim,spacedim>::FEValues (const Mapping<dim,spacedim>       &mapping,
+                        const FiniteElement<dim,spacedim> &fe,
                         const Quadrature<dim>    &q,
                         const UpdateFlags         update_flags)
                :
-               FEValuesBase<dim> (q.size(),
+               FEValuesBase<dim,spacedim> (q.size(),
                                   fe.dofs_per_cell,
                                   update_default,
                                   mapping,
@@ -1358,15 +1374,15 @@ FEValues<dim>::FEValues (const Mapping<dim>       &mapping,
 
 
 
-template <int dim>
-FEValues<dim>::FEValues (const FiniteElement<dim> &fe,
+template <int dim, int spacedim>
+FEValues<dim,spacedim>::FEValues (const FiniteElement<dim,spacedim> &fe,
                         const Quadrature<dim>    &q,
                         const UpdateFlags         update_flags)
                :
-               FEValuesBase<dim> (q.size(),
+               FEValuesBase<dim,spacedim> (q.size(),
                                   fe.dofs_per_cell,
                                   update_default,
-                                  StaticMappingQ1<dim>::mapping,
+                                           StaticMappingQ1<dim,spacedim>::mapping,
                                   fe),
   quadrature (q)
 {
@@ -1376,14 +1392,23 @@ FEValues<dim>::FEValues (const FiniteElement<dim> &fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValues<dim>::initialize (const UpdateFlags update_flags)
+FEValues<dim,spacedim>::initialize (const UpdateFlags update_flags)
 {
                                   // you can't compute normal vectors
                                   // on cells, only on faces
+  typedef FEValuesBase<dim,spacedim> FEVB;
   Assert ((update_flags & update_normal_vectors) == false,
-         typename FEValuesBase<dim>::ExcInvalidUpdateFlag());
+         typename FEVB::ExcInvalidUpdateFlag());
+
+                                  // You can compute normal vectors
+                                  // to the cells only in the
+                                  // codimension one case.
+  if(dim == spacedim)
+    Assert ( (update_flags & update_cell_normal_vectors) == false,
+            typename FEVB::ExcInvalidUpdateFlag());
+
 
   const UpdateFlags flags = this->compute_update_flags (update_flags);
   
@@ -1395,22 +1420,24 @@ FEValues<dim>::initialize (const UpdateFlags update_flags)
   this->fe_data      = this->fe->get_data(flags, *this->mapping, quadrature);
 
                                   // set up objects within this class
-  FEValuesData<dim>::initialize (this->n_quadrature_points, *this->fe, flags);
+  FEValuesData<dim,spacedim>::initialize (this->n_quadrature_points, *this->fe, flags);
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator &cell)
+FEValues<dim,spacedim>::reinit (const typename DoFHandler<dim,spacedim>::cell_iterator &cell)
 {
                                   // assert that the finite elements
                                   // passed to the constructor and
                                   // used by the DoFHandler used by
                                   // this cell, are the same
+
+  typedef FEValuesBase<dim,spacedim> FEVB;
   Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
          static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
-         typename FEValuesBase<dim>::ExcFEDontMatch());
+         typename FEVB::ExcFEDontMatch());
 
                                    // set new cell. auto_ptr will take
                                    // care that old object gets
@@ -1418,8 +1445,8 @@ FEValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator &cell)
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::template
-     CellIterator<typename DoFHandler<dim>::cell_iterator> (cell));
+    (new typename FEValuesBase<dim,spacedim>::template
+     CellIterator<typename DoFHandler<dim,spacedim>::cell_iterator> (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -1431,17 +1458,18 @@ FEValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator &cell)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell)
+FEValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell)
 {
                                   // assert that the finite elements
                                   // passed to the constructor and
                                   // used by the DoFHandler used by
                                   // this cell, are the same
+    typedef FEValuesBase<dim,spacedim> FEVB;
   Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
          static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
-         typename FEValuesBase<dim>::ExcFEDontMatch());
+         typename FEVB::ExcFEDontMatch());
 
                                    // set new cell. auto_ptr will take
                                    // care that old object gets
@@ -1449,8 +1477,8 @@ FEValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell)
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::template
-     CellIterator<typename hp::DoFHandler<dim>::cell_iterator> (cell));
+    (new typename FEValuesBase<dim,spacedim>::template
+     CellIterator<typename hp::DoFHandler<dim,spacedim>::cell_iterator> (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -1461,10 +1489,31 @@ FEValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell)
 }
 
 
+#if deal_II_dimension == 1
 
-template <int dim>
+template <>
 void
-FEValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterator &cell)
+FEValues<1,2>::reinit (const MGDoFHandler<1,2>::cell_iterator &)
+{
+  Assert(false, ExcNotImplemented());
+}
+
+#endif
+
+#if deal_II_dimension == 2
+
+template <>
+void
+FEValues<2,3>::reinit (const MGDoFHandler<2,3>::cell_iterator &)
+{
+  Assert(false, ExcNotImplemented());
+}
+
+#endif
+
+template <int dim, int spacedim>
+void
+FEValues<dim,spacedim>::reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell)
 {
                                   // assert that the finite elements
                                   // passed to the constructor and
@@ -1475,7 +1524,7 @@ FEValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterator &cell)
   
 //  Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
 //       static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
-//       typename FEValuesBase<dim>::ExcFEDontMatch());
+//       typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
 
                                    // set new cell. auto_ptr will take
                                    // care that old object gets
@@ -1483,8 +1532,8 @@ FEValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterator &cell)
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::template
-     CellIterator<typename MGDoFHandler<dim>::cell_iterator> (cell));
+    (new typename FEValuesBase<dim,spacedim>::template
+     CellIterator<typename MGDoFHandler<dim,spacedim>::cell_iterator> (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -1496,8 +1545,8 @@ FEValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterator &cell)
 
 
 
-template <int dim>
-void FEValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator &cell)
+template <int dim, int spacedim>
+void FEValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell)
 {
                                    // no FE in this cell, so no check
                                    // necessary here
@@ -1508,7 +1557,7 @@ void FEValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator &ce
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::TriaCellIterator (cell));
+    (new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
                                    // this was the part of the work
                                    // that is dependent on the actual
                                    // data type of the iterator. now
@@ -1519,8 +1568,8 @@ void FEValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator &ce
 
 
 
-template <int dim>
-void FEValues<dim>::do_reinit ()
+template <int dim, int spacedim>
+void FEValues<dim,spacedim>::do_reinit ()
 {
   this->get_mapping().fill_fe_values(*this->present_cell,
                                     quadrature,
@@ -1529,7 +1578,8 @@ void FEValues<dim>::do_reinit ()
                                     this->JxW_values,
                                     this->jacobians,
                                     this->jacobian_grads,
-                                    this->inverse_jacobians);
+                                    this->inverse_jacobians,
+                                    this->cell_normal_vectors);
   
   this->get_fe().fill_fe_values(this->get_mapping(),
                                *this->present_cell,
@@ -1544,11 +1594,11 @@ void FEValues<dim>::do_reinit ()
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FEValues<dim>::memory_consumption () const
+FEValues<dim,spacedim>::memory_consumption () const
 {
-  return (FEValuesBase<dim>::memory_consumption () +
+  return (FEValuesBase<dim,spacedim>::memory_consumption () +
          MemoryConsumption::memory_consumption (quadrature));
 }
 
@@ -1556,15 +1606,15 @@ FEValues<dim>::memory_consumption () const
 /*------------------------------- FEFaceValuesBase --------------------------*/
 
 
-template <int dim>
-FEFaceValuesBase<dim>::FEFaceValuesBase (const unsigned int n_q_points,
+template <int dim, int spacedim>
+FEFaceValuesBase<dim,spacedim>::FEFaceValuesBase (const unsigned int n_q_points,
                                         const unsigned int dofs_per_cell,
                                         const UpdateFlags,
-                                        const Mapping<dim> &mapping,      
-                                        const FiniteElement<dim> &fe,
+                                        const Mapping<dim,spacedim> &mapping,      
+                                        const FiniteElement<dim,spacedim> &fe,
                                         const Quadrature<dim-1>& quadrature)
                :
-               FEValuesBase<dim> (n_q_points,
+               FEValuesBase<dim,spacedim> (n_q_points,
                                   dofs_per_cell,
                                   update_default,
                                   mapping,
@@ -1574,53 +1624,55 @@ FEFaceValuesBase<dim>::FEFaceValuesBase (const unsigned int n_q_points,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 const std::vector<Point<dim> > &
-FEFaceValuesBase<dim>::get_normal_vectors () const
+FEFaceValuesBase<dim,spacedim>::get_normal_vectors () const
 {
+  typedef FEValuesBase<dim,spacedim> FEVB;
   Assert (this->update_flags & update_normal_vectors,
-         typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+         typename FEVB::ExcAccessToUninitializedField());
   return this->normal_vectors;
 }
 
 
 
-template <int dim>
-const std::vector<Tensor<1,dim> > &
-FEFaceValuesBase<dim>::get_boundary_forms () const
+template <int dim, int spacedim>
+const std::vector<Tensor<1,spacedim> > &
+FEFaceValuesBase<dim,spacedim>::get_boundary_forms () const
 {
+  typedef FEValuesBase<dim,spacedim> FEVB;
   Assert (this->update_flags & update_boundary_forms,
-         typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+         typename FEVB::ExcAccessToUninitializedField());
   return this->boundary_forms;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-FEFaceValuesBase<dim>::memory_consumption () const
+FEFaceValuesBase<dim,spacedim>::memory_consumption () const
 {
-  return (FEValuesBase<dim>::memory_consumption () +
+  return (FEValuesBase<dim,spacedim>::memory_consumption () +
          MemoryConsumption::memory_consumption (quadrature));
 }
 
 
 /*------------------------------- FEFaceValues -------------------------------*/
 
-template <int dim>
-const unsigned int FEFaceValues<dim>::dimension;
+template <int dim, int spacedim>
+const unsigned int FEFaceValues<dim,spacedim>::dimension;
 
-template <int dim>
-const unsigned int FEFaceValues<dim>::integral_dimension;
+template <int dim, int spacedim>
+const unsigned int FEFaceValues<dim,spacedim>::integral_dimension;
 
 
-template <int dim>
-FEFaceValues<dim>::FEFaceValues (const Mapping<dim>       &mapping,
-                                const FiniteElement<dim> &fe,
+template <int dim, int spacedim>
+FEFaceValues<dim,spacedim>::FEFaceValues (const Mapping<dim,spacedim>       &mapping,
+                                const FiniteElement<dim,spacedim> &fe,
                                 const Quadrature<dim-1>  &quadrature,
                                 const UpdateFlags         update_flags)
                :
-               FEFaceValuesBase<dim> (quadrature.size(),
+               FEFaceValuesBase<dim,spacedim> (quadrature.size(),
                                       fe.dofs_per_cell,
                                       update_flags,
                                       mapping,
@@ -1631,12 +1683,12 @@ FEFaceValues<dim>::FEFaceValues (const Mapping<dim>       &mapping,
 
 
 
-template <int dim>
-FEFaceValues<dim>::FEFaceValues (const FiniteElement<dim> &fe,
+template <int dim, int spacedim>
+FEFaceValues<dim,spacedim>::FEFaceValues (const FiniteElement<dim,spacedim> &fe,
                                 const Quadrature<dim-1>  &quadrature,
                                 const UpdateFlags         update_flags)
                :
-               FEFaceValuesBase<dim> (quadrature.size(),
+               FEFaceValuesBase<dim,spacedim> (quadrature.size(),
                                       fe.dofs_per_cell,
                                       update_flags,
                                       StaticMappingQ1<dim>::mapping,
@@ -1648,9 +1700,9 @@ FEFaceValues<dim>::FEFaceValues (const FiniteElement<dim> &fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FEFaceValues<dim>::initialize (const UpdateFlags update_flags)
+FEFaceValues<dim,spacedim>::initialize (const UpdateFlags update_flags)
 {
   const UpdateFlags flags = this->compute_update_flags (update_flags);
   
@@ -1662,13 +1714,13 @@ FEFaceValues<dim>::initialize (const UpdateFlags update_flags)
   this->fe_data      = this->fe->get_face_data(flags, *this->mapping, this->quadrature);
 
                                   // set up objects within this class
-  FEValuesData<dim>::initialize(this->n_quadrature_points, *this->fe, flags);
+  FEValuesData<dim,spacedim>::initialize(this->n_quadrature_points, *this->fe, flags);
 }
 
 
 
-template <int dim>
-void FEFaceValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator &cell,
+template <int dim, int spacedim>
+void FEFaceValues<dim,spacedim>::reinit (const typename DoFHandler<dim,spacedim>::cell_iterator &cell,
                                const unsigned int              face_no)
 {
                                   // assert that the finite elements
@@ -1677,7 +1729,7 @@ void FEFaceValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator &c
                                   // this cell, are the same
 //   Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
 //       static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
-//       typename FEValuesBase<dim>::ExcFEDontMatch());
+//       typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
 
   Assert (face_no < GeometryInfo<dim>::faces_per_cell,
          ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
@@ -1688,8 +1740,8 @@ void FEFaceValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator &c
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::template
-     CellIterator<typename DoFHandler<dim>::cell_iterator> (cell));
+    (new typename FEValuesBase<dim,spacedim>::template
+     CellIterator<typename DoFHandler<dim,spacedim>::cell_iterator> (cell));
   
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -1701,18 +1753,19 @@ void FEFaceValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator &c
 
 
 
-template <int dim>
-void FEFaceValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell,
+template <int dim, int spacedim>
+void FEFaceValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
                                const unsigned int              face_no)
 {
                                   // assert that the finite elements
                                   // passed to the constructor and
                                   // used by the DoFHandler used by
                                   // this cell, are the same
+  typedef FEValuesBase<dim,spacedim> FEVB;
   Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
          static_cast<const FiniteElementData<dim>&>(
            cell->get_dof_handler().get_fe()[cell->active_fe_index ()]),
-         typename FEValuesBase<dim>::ExcFEDontMatch());
+         typename FEVB::ExcFEDontMatch());
 
   Assert (face_no < GeometryInfo<dim>::faces_per_cell,
          ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
@@ -1723,8 +1776,8 @@ void FEFaceValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iterato
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::template
-     CellIterator<typename hp::DoFHandler<dim>::cell_iterator> (cell));
+    (new typename FEValuesBase<dim,spacedim>::template
+     CellIterator<typename hp::DoFHandler<dim,spacedim>::cell_iterator> (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -1735,17 +1788,40 @@ void FEFaceValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iterato
 }
 
 
-template <int dim>
-void FEFaceValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterator &cell,
+#if deal_II_dimension == 1
+
+template <>
+void FEFaceValues<1,2>::reinit (const MGDoFHandler<1,2>::cell_iterator &,
+                               const unsigned int)
+{
+  Assert(false,ExcNotImplemented());
+}
+
+#endif
+
+#if deal_II_dimension == 2
+
+template <>
+void FEFaceValues<2,3>::reinit (const MGDoFHandler<2,3>::cell_iterator &,
+                               const unsigned int)
+{
+  Assert(false,ExcNotImplemented());
+}
+
+#endif
+
+template <int dim, int spacedim>
+void FEFaceValues<dim,spacedim>::reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
                                const unsigned int              face_no)
 {
                                   // assert that the finite elements
                                   // passed to the constructor and
                                   // used by the DoFHandler used by
                                   // this cell, are the same
+  typedef FEValuesBase<dim,spacedim> FEVB;
   Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
          static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
-         typename FEValuesBase<dim>::ExcFEDontMatch());
+         typename FEVB::ExcFEDontMatch());
 
   Assert (face_no < GeometryInfo<dim>::faces_per_cell,
          ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
@@ -1756,8 +1832,8 @@ void FEFaceValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterator
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::template
-     CellIterator<typename MGDoFHandler<dim>::cell_iterator> (cell));
+    (new typename FEValuesBase<dim,spacedim>::template
+     CellIterator<typename MGDoFHandler<dim,spacedim>::cell_iterator> (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -1768,8 +1844,8 @@ void FEFaceValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterator
 }
 
 
-template <int dim>
-void FEFaceValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator &cell,
+template <int dim, int spacedim>
+void FEFaceValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                const unsigned int              face_no)
 {
   Assert (face_no < GeometryInfo<dim>::faces_per_cell,
@@ -1781,7 +1857,7 @@ void FEFaceValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::TriaCellIterator (cell));
+    (new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -1793,13 +1869,13 @@ void FEFaceValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator
 
 
 
-template <int dim>
-void FEFaceValues<dim>::do_reinit (const unsigned int face_no)
+template <int dim, int spacedim>
+void FEFaceValues<dim,spacedim>::do_reinit (const unsigned int face_no)
 {
                                   // first of all, set the
                                   // present_face_index (if
                                   // available)
-  const typename Triangulation<dim>::cell_iterator cell=*this->present_cell;
+  const typename Triangulation<dim,spacedim>::cell_iterator cell=*this->present_cell;
   this->present_face_index=cell->face_index(face_no);
   
   this->get_mapping().fill_fe_face_values(*this->present_cell, face_no,
@@ -1826,21 +1902,21 @@ void FEFaceValues<dim>::do_reinit (const unsigned int face_no)
 /*------------------------------- FESubFaceValues -------------------------------*/
 
 
-template <int dim>
-const unsigned int FESubfaceValues<dim>::dimension;
+template <int dim, int spacedim>
+const unsigned int FESubfaceValues<dim,spacedim>::dimension;
 
-template <int dim>
-const unsigned int FESubfaceValues<dim>::integral_dimension;
+template <int dim, int spacedim>
+const unsigned int FESubfaceValues<dim,spacedim>::integral_dimension;
 
 
 
-template <int dim>
-FESubfaceValues<dim>::FESubfaceValues (const Mapping<dim>       &mapping,
-                                      const FiniteElement<dim> &fe,
+template <int dim, int spacedim>
+FESubfaceValues<dim,spacedim>::FESubfaceValues (const Mapping<dim,spacedim>       &mapping,
+                                      const FiniteElement<dim,spacedim> &fe,
                                       const Quadrature<dim-1>  &quadrature,
                                       const UpdateFlags         update_flags)
                :
-               FEFaceValuesBase<dim> (quadrature.size(),
+               FEFaceValuesBase<dim,spacedim> (quadrature.size(),
                                       fe.dofs_per_cell,
                                       update_flags,
                                       mapping,
@@ -1851,12 +1927,12 @@ FESubfaceValues<dim>::FESubfaceValues (const Mapping<dim>       &mapping,
 
 
 
-template <int dim>
-FESubfaceValues<dim>::FESubfaceValues (const FiniteElement<dim> &fe,
+template <int dim, int spacedim>
+FESubfaceValues<dim,spacedim>::FESubfaceValues (const FiniteElement<dim,spacedim> &fe,
                                       const Quadrature<dim-1>  &quadrature,
                                       const UpdateFlags         update_flags)
                :
-               FEFaceValuesBase<dim> (quadrature.size(),
+               FEFaceValuesBase<dim,spacedim> (quadrature.size(),
                                       fe.dofs_per_cell,
                                       update_flags,
                                       StaticMappingQ1<dim>::mapping,
@@ -1868,9 +1944,9 @@ FESubfaceValues<dim>::FESubfaceValues (const FiniteElement<dim> &fe,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-FESubfaceValues<dim>::initialize (const UpdateFlags update_flags)
+FESubfaceValues<dim,spacedim>::initialize (const UpdateFlags update_flags)
 {
   const UpdateFlags flags = this->compute_update_flags (update_flags);
   
@@ -1884,13 +1960,13 @@ FESubfaceValues<dim>::initialize (const UpdateFlags update_flags)
                                                  this->quadrature);
 
                                   // set up objects within this class
-  FEValuesData<dim>::initialize(this->n_quadrature_points, *this->fe, flags);
+  FEValuesData<dim,spacedim>::initialize(this->n_quadrature_points, *this->fe, flags);
 }
 
 
 
-template <int dim>
-void FESubfaceValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator &cell,
+template <int dim, int spacedim>
+void FESubfaceValues<dim,spacedim>::reinit (const typename DoFHandler<dim,spacedim>::cell_iterator &cell,
                                   const unsigned int         face_no,
                                   const unsigned int         subface_no)
 {
@@ -1900,7 +1976,7 @@ void FESubfaceValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator
                                   // this cell, are the same
 //   Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
 //       static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
-//       typename FEValuesBase<dim>::ExcFEDontMatch());
+//       typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
   Assert (face_no < GeometryInfo<dim>::faces_per_cell,
          ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
                                   // We would like to check for
@@ -1929,8 +2005,8 @@ void FESubfaceValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::template
-     CellIterator<typename DoFHandler<dim>::cell_iterator> (cell));
+    (new typename FEValuesBase<dim,spacedim>::template
+     CellIterator<typename DoFHandler<dim,spacedim>::cell_iterator> (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -1942,8 +2018,8 @@ void FESubfaceValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator
 
 
 
-template <int dim>
-void FESubfaceValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell,
+template <int dim, int spacedim>
+void FESubfaceValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
                                   const unsigned int         face_no,
                                   const unsigned int         subface_no)
 {
@@ -1951,10 +2027,11 @@ void FESubfaceValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iter
                                   // passed to the constructor and
                                   // used by the hp::DoFHandler used by
                                   // this cell, are the same
+  typedef FEValuesBase<dim,spacedim> FEVB;
   Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
          static_cast<const FiniteElementData<dim>&>(
            cell->get_dof_handler().get_fe()[cell->active_fe_index ()]),
-         typename FEValuesBase<dim>::ExcFEDontMatch());
+         typename FEVB::ExcFEDontMatch());
   Assert (face_no < GeometryInfo<dim>::faces_per_cell,
          ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
   Assert (subface_no < cell->face(face_no)->number_of_children(),
@@ -1970,8 +2047,8 @@ void FESubfaceValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iter
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset
-    (new typename FEValuesBase<dim>::template
-     CellIterator<typename hp::DoFHandler<dim>::cell_iterator> (cell));
+    (new typename FEValuesBase<dim,spacedim>::template
+     CellIterator<typename hp::DoFHandler<dim,spacedim>::cell_iterator> (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -1982,14 +2059,15 @@ void FESubfaceValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iter
 }
 
   
-template <int dim>
-void FESubfaceValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterator &cell,
+template <int dim, int spacedim>
+void FESubfaceValues<dim,spacedim>::reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
                                   const unsigned int         face_no,
                                   const unsigned int         subface_no)
 {
-   Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
+  typedef FEValuesBase<dim,spacedim> FEVB;
+  Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
           static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
-          typename FEValuesBase<dim>::ExcFEDontMatch());
+          typename FEVB::ExcFEDontMatch());
   Assert (face_no < GeometryInfo<dim>::faces_per_cell,
          ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
   Assert (subface_no < cell->face(face_no)->number_of_children(),
@@ -2005,8 +2083,8 @@ void FESubfaceValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterat
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::template
-     CellIterator<typename MGDoFHandler<dim>::cell_iterator> (cell));
+    (new typename FEValuesBase<dim,spacedim>::template
+     CellIterator<typename MGDoFHandler<dim,spacedim>::cell_iterator> (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -2018,8 +2096,8 @@ void FESubfaceValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterat
 
 
 
-template <int dim>
-void FESubfaceValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator &cell,
+template <int dim, int spacedim>
+void FESubfaceValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                   const unsigned int         face_no,
                                   const unsigned int         subface_no)
 {
@@ -2034,7 +2112,7 @@ void FESubfaceValues<dim>::reinit (const typename Triangulation<dim>::cell_itera
                                    // object gets destroyed in the
                                    // destruction of this class
   this->present_cell.reset 
-    (new typename FEValuesBase<dim>::TriaCellIterator (cell));
+    (new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
 
                                    // this was the part of the work
                                    // that is dependent on the actual
@@ -2046,13 +2124,13 @@ void FESubfaceValues<dim>::reinit (const typename Triangulation<dim>::cell_itera
 
 
 
-template <int dim>
-void FESubfaceValues<dim>::do_reinit (const unsigned int face_no,
-                                      const unsigned int subface_no)
+template <int dim, int spacedim>
+void FESubfaceValues<dim,spacedim>::do_reinit (const unsigned int face_no,
+                                               const unsigned int subface_no)
 {
                                   // first of all, set the present_face_index
                                   // (if available)
-  const typename Triangulation<dim>::cell_iterator cell=*this->present_cell;
+  const typename Triangulation<dim,spacedim>::cell_iterator cell=*this->present_cell;
 
   if (!cell->face(face_no)->has_children())
                                     // no subfaces at all, so set
@@ -2160,9 +2238,26 @@ template class FEFaceValues<deal_II_dimension>;
 template class FESubfaceValues<deal_II_dimension>;
 #endif
 
+#if deal_II_dimension != 3
+template class FEValuesData<deal_II_dimension,deal_II_dimension+1>;
+template class FEValuesBase<deal_II_dimension,deal_II_dimension+1>;
+template class FEValues<deal_II_dimension,deal_II_dimension+1>;
+template class FEValuesBase<deal_II_dimension,deal_II_dimension+1>:: 
+  CellIterator<DoFHandler<deal_II_dimension,deal_II_dimension+1>::cell_iterator>; 
+//template class FEValuesBase<deal_II_dimension,deal_II_dimension+1>::
+//  CellIterator<MGDoFHandler<deal_II_dimension,deal_II_dimension+1>::cell_iterator>;
+
+// #if deal_II_dimension == 2
+// template class FEFaceValuesBase<deal_II_dimension,deal_II_dimension+1>;
+// template class FEFaceValues<deal_II_dimension,deal_II_dimension+1>;
+// template class FESubfaceValues<deal_II_dimension,deal_II_dimension+1>;
+// #endif
 
-//---------------------------------------------------------------------------
 
+
+#endif
+
+//---------------------------------------------------------------------------
 // Instantiations are in a different file using the macro IN for the vector type.
 // This way, we avoid code reduplication
 
index f0e22889606cdf6d867f794d10d16473e8e45f36..a85fcd5ae1f3edda4a8bf90e1387a35921436803 100644 (file)
@@ -16,7 +16,7 @@
 for (VEC : SERIAL_VECTORS)
   {  
     template
-      void FEValuesBase<deal_II_dimension>::get_function_values<VEC>
+       void FEValuesBase<deal_II_dimension>::get_function_values<VEC>
       (const VEC&, std::vector<double>&) const;
     template
       void FEValuesBase<deal_II_dimension>::get_function_values<VEC>
@@ -84,4 +84,80 @@ for (VEC : SERIAL_VECTORS)
       void FEValuesBase<deal_II_dimension>::get_function_hessians<VEC>
       (const VEC&, const VectorSlice<const std::vector<unsigned int> >&,
        std::vector<std::vector<Tensor<2,deal_II_dimension> > > &, bool) const;
+
+
+#if deal_II_dimension != 3
+
+    template
+       void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, std::vector<double>&) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, std::vector<float>&) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&, std::vector<double>&) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&, std::vector<float>&) const;
+
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, std::vector<Vector<double> > &) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, std::vector<Vector<float> > &) const;
+
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&,
+       std::vector<Vector<double> > &) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&,
+       std::vector<Vector<float> > &) const;
+
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&,
+       std::vector<std::vector<double> > &, bool) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_values<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&,
+       std::vector<std::vector<float> > &, bool) const;
+
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_gradients<VEC>
+      (const VEC&, std::vector<Tensor<1,deal_II_dimension+1> > &) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_gradients<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&,
+       std::vector<Tensor<1,deal_II_dimension+1> > &) const;
+
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_gradients<VEC>
+      (const VEC&, std::vector<std::vector<Tensor<1,deal_II_dimension+1> > > &) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_gradients<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&,
+       std::vector<std::vector<Tensor<1,deal_II_dimension+1> > > &, bool) const;
+
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_hessians<VEC>
+      (const VEC&, std::vector<Tensor<2,deal_II_dimension+1> > &) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_hessians<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&,
+       std::vector<Tensor<2,deal_II_dimension+1> > &) const;
+
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_hessians<VEC>
+      (const VEC&, std::vector<std::vector<Tensor<2,deal_II_dimension+1> > > &, bool) const;
+    template
+      void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_hessians<VEC>
+      (const VEC&, const VectorSlice<const std::vector<unsigned int> >&,
+       std::vector<std::vector<Tensor<2,deal_II_dimension+1> > > &, bool) const;
+
+#endif
+
   }
index aa7a4d831055fbb76733dee08481a48f57cb9e81..5a2ae421865b7d4c84a4a44f80846f7f884bd285 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int dim>
-Mapping<dim>::~Mapping ()
+template <int dim, int spacedim>
+Mapping<dim, spacedim>::~Mapping ()
 {}
 
 
 /*------------------------------ InternalDataBase ------------------------------*/
 
 
-template <int dim>
-Mapping<dim>::InternalDataBase::InternalDataBase ():
+template <int dim, int spacedim>
+Mapping<dim, spacedim>::InternalDataBase::InternalDataBase ():
                update_flags(update_default),
                update_once(update_default),
                update_each(update_default),
@@ -35,15 +35,15 @@ Mapping<dim>::InternalDataBase::InternalDataBase ():
 
 
 
-template <int dim>
-Mapping<dim>::InternalDataBase::~InternalDataBase ()
+template <int dim, int spacedim>
+Mapping<dim, spacedim>::InternalDataBase::~InternalDataBase ()
 {}
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-Mapping<dim>::InternalDataBase::memory_consumption () const
+Mapping<dim, spacedim>::InternalDataBase::memory_consumption () const
 {
   return sizeof(*this);
 }
@@ -55,4 +55,8 @@ Mapping<dim>::InternalDataBase::memory_consumption () const
 
 template class Mapping<deal_II_dimension>;
 
+#if deal_II_dimension != 3
+template class Mapping<deal_II_dimension,deal_II_dimension+1>;
+#endif
+
 DEAL_II_NAMESPACE_CLOSE
index 01397f323be9a90166784e5aea1348e320110ec5..215d63c2216612746ea29996d5675ac46f4d7fe8 100644 (file)
@@ -22,10 +22,10 @@ DEAL_II_NAMESPACE_OPEN
 
 
 
-template <int dim>
-MappingC1<dim>::MappingC1 ()
+template <int dim, int spacedim>
+MappingC1<dim,spacedim>::MappingC1 ()
                :
-               MappingQ<dim> (3)
+               MappingQ<dim,spacedim> (3)
 {
   Assert (dim > 1, ExcImpossibleInDim(dim));
 }
@@ -190,9 +190,9 @@ MappingC1<2>::add_line_support_points (const Triangulation<2>::cell_iterator &ce
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingC1<dim>::add_line_support_points (const typename Triangulation<dim>::cell_iterator &,
+MappingC1<dim,spacedim>::add_line_support_points (const typename Triangulation<dim>::cell_iterator &,
                                         std::vector<Point<dim> > &) const
 {
   Assert (false, ExcNotImplemented());
@@ -232,9 +232,9 @@ MappingC1<2>::add_quad_support_points (const Triangulation<2>::cell_iterator &,
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingC1<dim>::add_quad_support_points (const typename Triangulation<dim>::cell_iterator &,
+MappingC1<dim,spacedim>::add_quad_support_points (const typename Triangulation<dim>::cell_iterator &,
                                         std::vector<Point<dim> > &) const
 {
   Assert (false, ExcNotImplemented());
@@ -242,11 +242,11 @@ MappingC1<dim>::add_quad_support_points (const typename Triangulation<dim>::cell
 
 
 
-template <int dim>
-Mapping<dim> *
-MappingC1<dim>::clone () const
+template<int dim, int spacedim>
+Mapping<dim, spacedim> *
+MappingC1<dim,spacedim>::clone () const
 {
-  return new MappingC1<dim>(*this);
+  return new MappingC1<dim,spacedim>(*this);
 }
 
 
index b36b23d0047bd37160a3d54e2173aefdce4c7158..604f819c0331ae02cade60c29ab34f664c66da9c 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int dim>
-const unsigned int MappingCartesian<dim>::invalid_face_number;
+template<int dim, int spacedim>
+const unsigned int MappingCartesian<dim,spacedim>::invalid_face_number;
 
 
 
-template<int dim>
-MappingCartesian<dim>::InternalData::InternalData (const Quadrature<dim>& q)
+template<int dim, int spacedim>
+MappingCartesian<dim, spacedim>::InternalData::InternalData (const Quadrature<dim>& q)
                :
                quadrature_points (q.get_points ())
 {}
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 unsigned int
-MappingCartesian<dim>::InternalData::memory_consumption () const
+MappingCartesian<dim, spacedim>::InternalData::memory_consumption () const
 {
-  return (Mapping<dim>::InternalDataBase::memory_consumption() +
+  return (Mapping<dim, spacedim>::InternalDataBase::memory_consumption() +
          MemoryConsumption::memory_consumption (length) +
          MemoryConsumption::memory_consumption (quadrature_points));
 }
@@ -54,18 +54,18 @@ MappingCartesian<dim>::InternalData::memory_consumption () const
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 UpdateFlags
-MappingCartesian<dim>::update_once (const UpdateFlags) const
+MappingCartesian<dim, spacedim>::update_once (const UpdateFlags) const
 {
   return update_default;
 }
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 UpdateFlags
-MappingCartesian<dim>::update_each (const UpdateFlags in) const
+MappingCartesian<dim, spacedim>::update_each (const UpdateFlags in) const
 {
   UpdateFlags out = in;
   if (out & update_boundary_forms)
@@ -76,9 +76,9 @@ MappingCartesian<dim>::update_each (const UpdateFlags in) const
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-MappingCartesian<dim>::get_data (const UpdateFlags      update_flags,
+template<int dim, int spacedim>
+typename Mapping<dim, spacedim>::InternalDataBase *
+MappingCartesian<dim, spacedim>::get_data (const UpdateFlags      update_flags,
                                 const Quadrature<dim> &q) const
 {
   InternalData* data = new InternalData (q);
@@ -92,9 +92,9 @@ MappingCartesian<dim>::get_data (const UpdateFlags      update_flags,
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-MappingCartesian<dim>::get_face_data (const UpdateFlags update_flags,
+template<int dim, int spacedim>
+typename Mapping<dim, spacedim>::InternalDataBase *
+MappingCartesian<dim, spacedim>::get_face_data (const UpdateFlags update_flags,
                                      const Quadrature<dim-1>& quadrature) const
 {
   InternalData* data
@@ -109,9 +109,9 @@ MappingCartesian<dim>::get_face_data (const UpdateFlags update_flags,
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-MappingCartesian<dim>::get_subface_data (const UpdateFlags update_flags,
+template<int dim, int spacedim>
+typename Mapping<dim, spacedim>::InternalDataBase *
+MappingCartesian<dim, spacedim>::get_subface_data (const UpdateFlags update_flags,
                                         const Quadrature<dim-1> &quadrature) const
 {
   InternalData* data
@@ -127,9 +127,9 @@ MappingCartesian<dim>::get_subface_data (const UpdateFlags update_flags,
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingCartesian<dim>::compute_fill (const typename Triangulation<dim>::cell_iterator &cell,
+MappingCartesian<dim, spacedim>::compute_fill (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                     const unsigned int        face_no,
                                     const unsigned int        sub_no,
                                     InternalData             &data,
@@ -294,17 +294,18 @@ MappingCartesian<dim>::compute_fill (const typename Triangulation<dim>::cell_ite
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingCartesian<dim>::
-fill_fe_values (const typename Triangulation<dim>::cell_iterator& cell,
+MappingCartesian<dim, spacedim>::
+fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator& cell,
                 const Quadrature<dim>& q, 
-                typename Mapping<dim>::InternalDataBase& mapping_data,
-                std::vector<Point<dim> >& quadrature_points,
+               typename Mapping<dim,spacedim>::InternalDataBase& mapping_data,
+                std::vector<Point<spacedim> >& quadrature_points,
                 std::vector<double>& JxW_values,
-               std::vector<Tensor<2,dim> >& jacobians,
-               std::vector<Tensor<3,dim> >& jacobian_grads,
-               std::vector<Tensor<2,dim> >& inverse_jacobians) const
+               std::vector<Tensor<2,spacedim> >& jacobians,
+               std::vector<Tensor<3,spacedim> >& jacobian_grads,
+               std::vector<Tensor<2,spacedim> >& inverse_jacobians,
+               std::vector<Point<spacedim> >       &) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -361,12 +362,12 @@ fill_fe_values (const typename Triangulation<dim>::cell_iterator& cell,
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingCartesian<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_iterator &cell,
+MappingCartesian<dim, spacedim>::fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                            const unsigned int            face_no,
                                            const Quadrature<dim-1>      &q,
-                                           typename Mapping<dim>::InternalDataBase &mapping_data,
+                                           typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
                                            std::vector<Point<dim> >     &quadrature_points,
                                            std::vector<double>          &JxW_values,
                                            std::vector<Tensor<1,dim> >  &boundary_forms,
@@ -406,13 +407,13 @@ MappingCartesian<dim>::fill_fe_face_values (const typename Triangulation<dim>::c
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingCartesian<dim>::fill_fe_subface_values (const typename Triangulation<dim>::cell_iterator &cell,
+MappingCartesian<dim, spacedim>::fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                               const unsigned int       face_no,
                                               const unsigned int       sub_no,
                                               const Quadrature<dim-1> &q,
-                                              typename Mapping<dim>::InternalDataBase &mapping_data,
+                                              typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
                                               std::vector<Point<dim> >     &quadrature_points,
                                               std::vector<double>          &JxW_values,
                                               std::vector<Tensor<1,dim> >  &boundary_forms,
@@ -503,13 +504,13 @@ MappingCartesian<1>::fill_fe_subface_values (const Triangulation<1>::cell_iterat
 #endif
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingCartesian<dim>::transform_covariant (
-  const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+MappingCartesian<dim, spacedim>::transform_covariant (
+  const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<1,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+  const typename Mapping<dim, spacedim>::InternalDataBase &mapping_data) const
 {
   const InternalData &data = dynamic_cast<const InternalData&> (mapping_data);
 
@@ -527,13 +528,13 @@ MappingCartesian<dim>::transform_covariant (
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingCartesian<dim>::transform_covariant (
-  const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+MappingCartesian<dim, spacedim>::transform_covariant (
+  const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<2,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+  const typename Mapping<dim, spacedim>::InternalDataBase &mapping_data) const
 {
   const InternalData &data = dynamic_cast<const InternalData&> (mapping_data);
 
@@ -552,13 +553,13 @@ MappingCartesian<dim>::transform_covariant (
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingCartesian<dim>::transform_contravariant (
-  const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+MappingCartesian<dim, spacedim>::transform_contravariant (
+  const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<1,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+  const typename Mapping<dim, spacedim>::InternalDataBase &mapping_data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -580,13 +581,13 @@ MappingCartesian<dim>::transform_contravariant (
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingCartesian<dim>::transform_contravariant (
-  const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+MappingCartesian<dim, spacedim>::transform_contravariant (
+  const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<2,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+  const typename Mapping<dim, spacedim>::InternalDataBase &mapping_data) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -609,10 +610,10 @@ MappingCartesian<dim>::transform_contravariant (
 
 
 
-template <int dim>
-Point<dim>
-MappingCartesian<dim>::transform_unit_to_real_cell (
-  const typename Triangulation<dim>::cell_iterator &cell,
+template <int dim, int spacedim>
+Point<spacedim>
+MappingCartesian<dim, spacedim>::transform_unit_to_real_cell (
+  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
   const Point<dim>                                 &p) const
 {
   Tensor<1,dim> length;
@@ -644,12 +645,15 @@ MappingCartesian<dim>::transform_unit_to_real_cell (
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 Point<dim>
-MappingCartesian<dim>::transform_real_to_unit_cell (
-  const typename Triangulation<dim>::cell_iterator &cell,
-  const Point<dim>                                 &p) const
+MappingCartesian<dim, spacedim>::transform_real_to_unit_cell (
+  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+  const Point<spacedim>                            &p) const
 {
+
+  if(dim != spacedim)
+      Assert(false, ExcNotImplemented());
   const Point<dim> &start = cell->vertex(0);
   Point<dim> real = p;
   real -= start;
@@ -675,11 +679,11 @@ MappingCartesian<dim>::transform_real_to_unit_cell (
 }
 
 
-template <int dim>
-Mapping<dim> *
-MappingCartesian<dim>::clone () const
+template<int dim, int spacedim>
+Mapping<dim, spacedim> *
+MappingCartesian<dim, spacedim>::clone () const
 {
-  return new MappingCartesian<dim>(*this);
+  return new MappingCartesian<dim, spacedim>(*this);
 }
 
 
index c4053122f652db4d25d65b800124a61c1e8fd1c0..cb54d08cd3dac090c9915bcbaec565e34a350f9f 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
-template<int dim>
-MappingQ<dim>::InternalData::InternalData (const unsigned int n_shape_functions)
+template<int dim, int spacedim>
+MappingQ<dim,spacedim>::InternalData::InternalData (const unsigned int n_shape_functions)
                :
-               MappingQ1<dim>::InternalData(n_shape_functions),
+               MappingQ1<dim,spacedim>::InternalData(n_shape_functions),
                 use_mapping_q1_on_current_cell(false),
                mapping_q1_data(1 << dim)
 {
@@ -44,11 +44,11 @@ MappingQ<dim>::InternalData::InternalData (const unsigned int n_shape_functions)
 
 
 
-template<int dim>
+template<int dim, int spacedim>
 unsigned int
-MappingQ<dim>::InternalData::memory_consumption () const 
+MappingQ<dim,spacedim>::InternalData::memory_consumption () const 
 {
-  return (MappingQ1<dim>::InternalData::memory_consumption () +
+  return (MappingQ1<dim,spacedim>::InternalData::memory_consumption () +
          MemoryConsumption::memory_consumption (unit_normals) +
          MemoryConsumption::memory_consumption (use_mapping_q1_on_current_cell) +
          MemoryConsumption::memory_consumption (mapping_q1_data));
@@ -97,8 +97,8 @@ MappingQ<1>::~MappingQ ()
 
 
 
-template<int dim>
-MappingQ<dim>::MappingQ (const unsigned int p,
+template<int dim, int spacedim>
+MappingQ<dim,spacedim>::MappingQ (const unsigned int p,
                         const bool use_mapping_q_on_all_cells)
                 :
                degree(p),
@@ -154,10 +154,10 @@ MappingQ<dim>::MappingQ (const unsigned int p,
 }
 
 
-template<int dim>
-MappingQ<dim>::MappingQ (const MappingQ<dim> &mapping)
+template<int dim, int spacedim>
+MappingQ<dim,spacedim>::MappingQ (const MappingQ<dim,spacedim> &mapping)
                :
-               MappingQ1<dim>(),
+               MappingQ1<dim,spacedim>(),
                degree(mapping.degree),
                n_inner(mapping.n_inner),
                n_outer(n_outer),
@@ -173,8 +173,8 @@ MappingQ<dim>::MappingQ (const MappingQ<dim> &mapping)
 }
 
 
-template<int dim>
-MappingQ<dim>::~MappingQ ()
+template<int dim, int spacedim>
+MappingQ<dim,spacedim>::~MappingQ ()
 {
   delete tensor_pols;
 }
@@ -195,10 +195,10 @@ MappingQ<1>::compute_shapes_virtual (const std::vector<Point<1> > &unit_points,
 
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::compute_shapes_virtual (const std::vector<Point<dim> > &unit_points,
-                                      typename MappingQ1<dim>::InternalData &data) const
+MappingQ<dim,spacedim>::compute_shapes_virtual (const std::vector<Point<dim> > &unit_points,
+                                      typename MappingQ1<dim,spacedim>::InternalData &data) const
 {
   const unsigned int n_points=unit_points.size();
   std::vector<double> values;
@@ -247,9 +247,9 @@ MappingQ<dim>::compute_shapes_virtual (const std::vector<Point<dim> > &unit_poin
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-MappingQ<dim>::get_data (const UpdateFlags update_flags,
+template<int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+MappingQ<dim,spacedim>::get_data (const UpdateFlags update_flags,
                         const Quadrature<dim> &quadrature) const
 {
   InternalData *data = new InternalData(n_shape_functions);
@@ -263,9 +263,9 @@ MappingQ<dim>::get_data (const UpdateFlags update_flags,
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-MappingQ<dim>::get_face_data (const UpdateFlags update_flags,
+template<int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+MappingQ<dim,spacedim>::get_face_data (const UpdateFlags update_flags,
                              const Quadrature<dim-1>& quadrature) const
 {
   InternalData *data = new InternalData(n_shape_functions);
@@ -281,9 +281,9 @@ MappingQ<dim>::get_face_data (const UpdateFlags update_flags,
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-MappingQ<dim>::get_subface_data (const UpdateFlags update_flags,
+template<int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+MappingQ<dim,spacedim>::get_subface_data (const UpdateFlags update_flags,
                                 const Quadrature<dim-1>& quadrature) const
 {
   InternalData *data = new InternalData(n_shape_functions);
@@ -299,16 +299,18 @@ MappingQ<dim>::get_subface_data (const UpdateFlags update_flags,
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator &cell,
-                              const Quadrature<dim>                &q,
-                              typename Mapping<dim>::InternalDataBase       &mapping_data,
-                              std::vector<Point<dim> >             &quadrature_points,
-                              std::vector<double>                  &JxW_values,
-                              std::vector<Tensor<2,dim> >          &jacobians,
-                              std::vector<Tensor<3,dim> >          &jacobian_grads,
-                              std::vector<Tensor<2,dim> >          &inverse_jacobians) const
+MappingQ<dim,spacedim>::fill_fe_values (
+                               const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                              const Quadrature<dim>                                     &q,
+                              typename Mapping<dim,spacedim>::InternalDataBase          &mapping_data,
+                              std::vector<Point<spacedim> >                             &quadrature_points,
+                              std::vector<double>                                       &JxW_values,
+                              std::vector<Tensor<2,spacedim> >                          &jacobians,
+                              std::vector<Tensor<3,spacedim> >                          &jacobian_grads,
+                              std::vector<Tensor<2,spacedim> >                          &inverse_jacobians,
+                              std::vector<Point<spacedim> >                             &cell_normal_vectors) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -327,25 +329,26 @@ MappingQ<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator
                                   // depending on this result, use
                                   // this or the other data object
                                   // for the mapping
-  typename MappingQ1<dim>::InternalData *p_data=0;
+  typename MappingQ1<dim,spacedim>::InternalData *p_data=0;
   if (data.use_mapping_q1_on_current_cell)
     p_data=&data.mapping_q1_data;
   else
     p_data=&data;
   
-  MappingQ1<dim>::fill_fe_values(cell, q, *p_data,
-                                quadrature_points, JxW_values,
-                                jacobians, jacobian_grads, inverse_jacobians);
+  MappingQ1<dim,spacedim>::fill_fe_values(cell, q, *p_data,
+                                         quadrature_points, JxW_values,
+                                         jacobians, jacobian_grads, inverse_jacobians,
+                                         cell_normal_vectors);
 }
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_iterator &cell,
+MappingQ<dim,spacedim>::fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                    const unsigned int       face_no,
                                    const Quadrature<dim-1> &q,
-                                   typename Mapping<dim>::InternalDataBase &mapping_data,
+                                   typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
                                    std::vector<Point<dim> >     &quadrature_points,
                                    std::vector<double>          &JxW_values,
                                    std::vector<Tensor<1,dim> >  &exterior_forms,
@@ -378,7 +381,7 @@ MappingQ<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_iter
                                   // depending on this result, use
                                   // this or the other data object
                                   // for the mapping
-  typename MappingQ1<dim>::InternalData *p_data=0;
+  typename MappingQ1<dim,spacedim>::InternalData *p_data=0;
   if (data.use_mapping_q1_on_current_cell)
     p_data=&data.mapping_q1_data;
   else
@@ -403,13 +406,13 @@ MappingQ<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_iter
 }
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::fill_fe_subface_values (const typename Triangulation<dim>::cell_iterator &cell,
+MappingQ<dim,spacedim>::fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                       const unsigned int       face_no,
                                       const unsigned int       sub_no,
                                       const Quadrature<dim-1> &q,
-                                      typename Mapping<dim>::InternalDataBase &mapping_data,
+                                      typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
                                       std::vector<Point<dim> >     &quadrature_points,
                                       std::vector<double>          &JxW_values,
                                       std::vector<Tensor<1,dim> >  &exterior_forms,
@@ -442,7 +445,7 @@ MappingQ<dim>::fill_fe_subface_values (const typename Triangulation<dim>::cell_i
                                   // depending on this result, use
                                   // this or the other data object
                                   // for the mapping
-  typename MappingQ1<dim>::InternalData *p_data=0;
+  typename MappingQ1<dim,spacedim>::InternalData *p_data=0;
   if (data.use_mapping_q1_on_current_cell)
     p_data=&data.mapping_q1_data;
   else
@@ -478,9 +481,9 @@ MappingQ<1>::set_laplace_on_quad_vector(Table<2,double> &) const
 
 #else
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::set_laplace_on_quad_vector(Table<2,double> &loqvs) const
+MappingQ<dim,spacedim>::set_laplace_on_quad_vector(Table<2,double> &loqvs) const
 {
   Assert(degree>1, ExcInternalError());
   const unsigned int n_inner_2d=(degree-1)*(degree-1);
@@ -733,9 +736,9 @@ MappingQ<3>::set_laplace_on_hex_vector(Table<2,double> &lohvs) const
 #endif
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::set_laplace_on_hex_vector(Table<2,double> &) const
+MappingQ<dim,spacedim>::set_laplace_on_hex_vector(Table<2,double> &) const
 {
   Assert(false, ExcInternalError());
 }
@@ -755,9 +758,9 @@ MappingQ<1>::compute_laplace_vector(Table<2,double> &) const
 #else
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::compute_laplace_vector(Table<2,double> &lvs) const
+MappingQ<dim,spacedim>::compute_laplace_vector(Table<2,double> &lvs) const
 {
   Assert(lvs.n_rows()==0, ExcInternalError());
   Assert(dim==2 || dim==3, ExcNotImplemented());
@@ -818,9 +821,9 @@ MappingQ<dim>::compute_laplace_vector(Table<2,double> &lvs) const
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::apply_laplace_vector(const Table<2,double> &lvs,
+MappingQ<dim,spacedim>::apply_laplace_vector(const Table<2,double> &lvs,
                                    std::vector<Point<dim> > &a) const
 {
                                    // check whether the data we need
@@ -861,10 +864,10 @@ MappingQ<dim>::apply_laplace_vector(const Table<2,double> &lvs,
 }
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::compute_mapping_support_points(
-  const typename Triangulation<dim>::cell_iterator &cell,
+MappingQ<dim,spacedim>::compute_mapping_support_points(
+  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
   std::vector<Point<dim> > &a) const
 {
                                   // if this is a cell for which we
@@ -888,9 +891,9 @@ MappingQ<dim>::compute_mapping_support_points(
 }
 
   
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::compute_support_points_laplace(const typename Triangulation<dim>::cell_iterator &cell,
+MappingQ<dim,spacedim>::compute_support_points_laplace(const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                              std::vector<Point<dim> > &a) const
 {
                                   // in any case, we need the
@@ -948,9 +951,9 @@ MappingQ<1>::add_line_support_points (const Triangulation<1>::cell_iterator &,
 #endif
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::add_line_support_points (const typename Triangulation<dim>::cell_iterator &cell,
+MappingQ<dim,spacedim>::add_line_support_points (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                        std::vector<Point<dim> > &a) const
 {
   static const StraightBoundary<dim> straight_boundary;
@@ -960,7 +963,7 @@ MappingQ<dim>::add_line_support_points (const typename Triangulation<dim>::cell_
     {
       for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
        {
-         const typename Triangulation<dim>::line_iterator line = cell->line(line_no);
+         const typename Triangulation<dim,spacedim>::line_iterator line = cell->line(line_no);
          const Boundary<dim> * const boundary
            = (line->at_boundary() ?
               &line->get_triangulation().get_boundary(line->boundary_indicator()) :
@@ -985,7 +988,7 @@ MappingQ<dim>::add_line_support_points (const typename Triangulation<dim>::cell_
                                       // it
       for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
        {
-         const typename Triangulation<dim>::line_iterator line = cell->line(line_no);
+         const typename Triangulation<dim,spacedim>::line_iterator line = cell->line(line_no);
          
          const Boundary<dim> * const boundary
            = (line->at_boundary() ?
@@ -1188,10 +1191,10 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
 #endif
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::
-add_quad_support_points(const typename Triangulation<dim>::cell_iterator &,
+MappingQ<dim,spacedim>::
+add_quad_support_points(const typename Triangulation<dim,spacedim>::cell_iterator &,
                         std::vector<Point<dim> > &) const
 {
   Assert (dim > 2, ExcImpossibleInDim(dim));
@@ -1199,16 +1202,16 @@ add_quad_support_points(const typename Triangulation<dim>::cell_iterator &,
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::transform_covariant (
-  const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+MappingQ<dim,spacedim>::transform_covariant (
+  const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<1,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data) const
 {
-  const typename MappingQ1<dim>::InternalData *q1_data =
-    dynamic_cast<const typename MappingQ1<dim>::InternalData *> (&mapping_data);
+  const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
+    dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
   Assert(q1_data!=0, ExcInternalError());
 
   Assert (output.size() + offset <= input.size(), ExcInternalError());
@@ -1234,16 +1237,16 @@ MappingQ<dim>::transform_covariant (
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::transform_covariant (
-  const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+MappingQ<dim,spacedim>::transform_covariant (
+  const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<2,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data) const
 {
-  const typename MappingQ1<dim>::InternalData *q1_data =
-    dynamic_cast<const typename MappingQ1<dim>::InternalData *> (&mapping_data);
+  const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
+    dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
   Assert(q1_data!=0, ExcInternalError());
 
   Assert (output.size() + offset <= input.size(), ExcInternalError());
@@ -1269,16 +1272,16 @@ MappingQ<dim>::transform_covariant (
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::transform_contravariant (
-  const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+MappingQ<dim,spacedim>::transform_contravariant (
+  const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<1,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data) const
 {
-  const typename MappingQ1<dim>::InternalData *q1_data =
-    dynamic_cast<const typename MappingQ1<dim>::InternalData *> (&mapping_data);
+  const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
+    dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
   Assert(q1_data!=0, ExcInternalError());
   
   Assert (output.size() + offset <= input.size(), ExcInternalError());
@@ -1304,16 +1307,16 @@ MappingQ<dim>::transform_contravariant (
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ<dim>::transform_contravariant (
-  const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+MappingQ<dim,spacedim>::transform_contravariant (
+  const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<2,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data) const
 {
-  const typename MappingQ1<dim>::InternalData *q1_data =
-    dynamic_cast<const typename MappingQ1<dim>::InternalData *> (&mapping_data);
+  const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
+    dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
   Assert(q1_data!=0, ExcInternalError());
   
   Assert (output.size() + offset <= input.size(), ExcInternalError());
@@ -1339,10 +1342,10 @@ MappingQ<dim>::transform_contravariant (
 
 
 
-template <int dim>
-Point<dim>
-MappingQ<dim>::
-transform_unit_to_real_cell (const typename Triangulation<dim>::cell_iterator &cell,
+template<int dim, int spacedim>
+Point<spacedim>
+MappingQ<dim,spacedim>::
+transform_unit_to_real_cell (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                              const Point<dim>                                 &p) const
 {
                                   // Use the get_data function to
@@ -1358,7 +1361,7 @@ transform_unit_to_real_cell (const typename Triangulation<dim>::cell_iterator &c
   mdata->use_mapping_q1_on_current_cell = !(use_mapping_q_on_all_cells
                                            || cell->has_boundary_lines());
 
-  typename MappingQ1<dim>::InternalData
+  typename MappingQ1<dim,spacedim>::InternalData
     *p_data = (mdata->use_mapping_q1_on_current_cell ?
                &mdata->mapping_q1_data :
                &*mdata);
@@ -1370,15 +1373,15 @@ transform_unit_to_real_cell (const typename Triangulation<dim>::cell_iterator &c
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 Point<dim>
-MappingQ<dim>::
-transform_real_to_unit_cell (const typename Triangulation<dim>::cell_iterator &cell,
-                             const Point<dim>                                 &p) const
+MappingQ<dim,spacedim>::
+transform_real_to_unit_cell (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                             const Point<spacedim>                            &p) const
 {
                                   // first a Newton iteration based
                                   // on a Q1 mapping
-  Point<dim> p_unit = MappingQ1<dim>::transform_real_to_unit_cell(cell, p);
+  Point<dim> p_unit = MappingQ1<dim,spacedim>::transform_real_to_unit_cell(cell, p);
   
                                    // then a Newton iteration based on
                                    // the full MappingQ if we need
@@ -1405,20 +1408,20 @@ transform_real_to_unit_cell (const typename Triangulation<dim>::cell_iterator &c
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 unsigned int
-MappingQ<dim>::get_degree() const
+MappingQ<dim,spacedim>::get_degree() const
 {
   return degree;
 }
 
 
 
-template <int dim>
-Mapping<dim> *
-MappingQ<dim>::clone () const
+template<int dim, int spacedim>
+Mapping<dim,spacedim> *
+MappingQ<dim,spacedim>::clone () const
 {
-  return new MappingQ<dim>(*this);
+  return new MappingQ<dim,spacedim>(*this);
 }
 
   
index fec6d69eb458df854d6faa82979c4ecc5259892b..989bc02ef8c393f43b02727ea2d48f07a3b04ab1 100644 (file)
 #include <algorithm>
 #include <memory>
 
+
 DEAL_II_NAMESPACE_OPEN
 
 
 
-template <int dim>
-const unsigned int MappingQ1<dim>::n_shape_functions;
+template <int dim, int spacedim>
+const unsigned int MappingQ1<dim,spacedim>::n_shape_functions;
 
 
 
-template<int dim>
-MappingQ1<dim>::InternalData::InternalData (const unsigned int n_shape_functions)
+template<int dim, int spacedim>
+MappingQ1<dim,spacedim>::InternalData::InternalData (const unsigned int n_shape_functions)
                :
                is_mapping_q1_data(true),
                n_shape_functions (n_shape_functions)
@@ -44,11 +45,11 @@ MappingQ1<dim>::InternalData::InternalData (const unsigned int n_shape_functions
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 unsigned int
-MappingQ1<dim>::InternalData::memory_consumption () const
+MappingQ1<dim,spacedim>::InternalData::memory_consumption () const
 {
-  return (Mapping<dim>::InternalDataBase::memory_consumption() +
+  return (Mapping<dim,spacedim>::InternalDataBase::memory_consumption() +
          MemoryConsumption::memory_consumption (shape_values) +
          MemoryConsumption::memory_consumption (shape_derivatives) +
          MemoryConsumption::memory_consumption (covariant) +
@@ -63,271 +64,296 @@ MappingQ1<dim>::InternalData::memory_consumption () const
 
 
 
-template <int dim>
-MappingQ1<dim>::MappingQ1 ()
+template<int dim, int spacedim>
+MappingQ1<dim,spacedim>::MappingQ1 ()
 {}
 
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::compute_shapes (const std::vector<Point<dim> > &unit_points,
+MappingQ1<dim,spacedim>::compute_shapes (const std::vector<Point<dim> > &unit_points,
                                InternalData &data) const
 {
+                                  // choose either the function implemented
+                                  // in this class, or whatever a virtual
+                                  // function call resolves to
   if (data.is_mapping_q1_data)
-    MappingQ1<dim>::compute_shapes_virtual(unit_points, data);
+    MappingQ1<dim,spacedim>::compute_shapes_virtual(unit_points, data);
   else
     compute_shapes_virtual(unit_points, data);
 }
 
 
-#if (deal_II_dimension == 1)
-
-
-template<>
-void
-MappingQ1<1>::compute_shapes_virtual (const std::vector<Point<1> > &unit_points,
-                                     InternalData& data) const
+namespace internal
 {
-  const unsigned int n_points=unit_points.size();
-  for (unsigned int k = 0 ; k < n_points ; ++k)
+  namespace MappingQ1
+  {
+    template <int spacedim>
+    void
+    compute_shapes_virtual (const unsigned int            n_shape_functions,
+                           const std::vector<Point<1> > &unit_points,
+                           typename dealii::MappingQ1<1,spacedim>::InternalData& data) 
     {
-      double x = unit_points[k](0);
-      
-      if (data.shape_values.size()!=0)
+      const unsigned int n_points=unit_points.size();
+      for (unsigned int k = 0 ; k < n_points ; ++k)
        {
-         Assert(data.shape_values.size()==n_shape_functions*n_points,
-                ExcInternalError());
-         data.shape(k,0) = 1.-x;
-         data.shape(k,1) = x;
-       }
-      if (data.shape_derivatives.size()!=0)
-       {
-         Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
-                ExcInternalError());
-         data.derivative(k,0)[0] = -1.;
-         data.derivative(k,1)[0] = 1.;
-       }
-      if (data.shape_second_derivatives.size()!=0)
-       {
-         Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
-                ExcInternalError());
-         data.second_derivative(k,0)[0][0] = 0;
-         data.second_derivative(k,1)[0][0] = 0;
+         double x = unit_points[k](0);
+      
+         if (data.shape_values.size()!=0)
+           {
+             Assert(data.shape_values.size()==n_shape_functions*n_points,
+                    ExcInternalError());
+             data.shape(k,0) = 1.-x;
+             data.shape(k,1) = x;
+           }
+         if (data.shape_derivatives.size()!=0)
+           {
+             Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
+                    ExcInternalError());
+             data.derivative(k,0)[0] = -1.;
+             data.derivative(k,1)[0] = 1.;
+           }
+         if (data.shape_second_derivatives.size()!=0)
+           {
+                                              // the following may or may not
+                                              // work if dim != spacedim
+             Assert (spacedim == 1, ExcNotImplemented());
+             
+             Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
+                    ExcInternalError());
+             data.second_derivative(k,0)[0][0] = 0;
+             data.second_derivative(k,1)[0][0] = 0;
+           }
        }
-
     }
-}
-
-#endif
-
-#if (deal_II_dimension == 2)
 
 
-template<>
-void
-MappingQ1<2>::compute_shapes_virtual (const std::vector<Point<2> > &unit_points,
-                                     InternalData &data) const
-{
-  const unsigned int n_points=unit_points.size();
-  for (unsigned int k = 0 ; k < n_points ; ++k)
+    template <int spacedim>
+    void
+    compute_shapes_virtual (const unsigned int            n_shape_functions,
+                           const std::vector<Point<2> > &unit_points,
+                           typename dealii::MappingQ1<2,spacedim>::InternalData& data) 
     {
-      double x = unit_points[k](0);
-      double y = unit_points[k](1);
-      
-      if (data.shape_values.size()!=0)
-       {
-         Assert(data.shape_values.size()==n_shape_functions*n_points,
-                ExcInternalError());
-         data.shape(k,0) = (1.-x)*(1.-y);
-         data.shape(k,1) = x*(1.-y);
-         data.shape(k,2) = (1.-x)*y;
-         data.shape(k,3) = x*y;
-       }
-      if (data.shape_derivatives.size()!=0)
+      const unsigned int n_points=unit_points.size();
+      for (unsigned int k = 0 ; k < n_points ; ++k)
        {
-         Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
-                ExcInternalError());
-         data.derivative(k,0)[0] = (y-1.);
-         data.derivative(k,1)[0] = (1.-y);
-         data.derivative(k,2)[0] = -y;
-         data.derivative(k,3)[0] = y;
-         data.derivative(k,0)[1] = (x-1.);
-         data.derivative(k,1)[1] = -x;
-         data.derivative(k,2)[1] = (1.-x);
-         data.derivative(k,3)[1] = x;
-       }
-      if (data.shape_second_derivatives.size()!=0)
-       {
-         Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
-                ExcInternalError());
-         data.second_derivative(k,0)[0][0] = 0;
-         data.second_derivative(k,1)[0][0] = 0;
-         data.second_derivative(k,2)[0][0] = 0;
-         data.second_derivative(k,3)[0][0] = 0;
-         data.second_derivative(k,0)[0][1] = 1.;
-         data.second_derivative(k,1)[0][1] = -1.;
-         data.second_derivative(k,2)[0][1] = -1.;
-         data.second_derivative(k,3)[0][1] = 1.;
-         data.second_derivative(k,0)[1][0] = 1.;
-         data.second_derivative(k,1)[1][0] = -1.;
-         data.second_derivative(k,2)[1][0] = -1.;
-         data.second_derivative(k,3)[1][0] = 1.;
-         data.second_derivative(k,0)[1][1] = 0;
-         data.second_derivative(k,1)[1][1] = 0;
-         data.second_derivative(k,2)[1][1] = 0;
-         data.second_derivative(k,3)[1][1] = 0;
+         double x = unit_points[k](0);
+         double y = unit_points[k](1);
+      
+         if (data.shape_values.size()!=0)
+           {
+             Assert(data.shape_values.size()==n_shape_functions*n_points,
+                    ExcInternalError());
+             data.shape(k,0) = (1.-x)*(1.-y);
+             data.shape(k,1) = x*(1.-y);
+             data.shape(k,2) = (1.-x)*y;
+             data.shape(k,3) = x*y;
+           }
+         if (data.shape_derivatives.size()!=0)
+           {
+             Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
+                    ExcInternalError());
+             data.derivative(k,0)[0] = (y-1.);
+             data.derivative(k,1)[0] = (1.-y);
+             data.derivative(k,2)[0] = -y;
+             data.derivative(k,3)[0] = y;
+             data.derivative(k,0)[1] = (x-1.);
+             data.derivative(k,1)[1] = -x;
+             data.derivative(k,2)[1] = (1.-x);
+             data.derivative(k,3)[1] = x;
+           }
+         if (data.shape_second_derivatives.size()!=0)
+           {
+                                              // the following may or may not
+                                              // work if dim != spacedim
+             Assert (spacedim == 2, ExcNotImplemented());
+             
+             Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
+                    ExcInternalError());
+             data.second_derivative(k,0)[0][0] = 0;
+             data.second_derivative(k,1)[0][0] = 0;
+             data.second_derivative(k,2)[0][0] = 0;
+             data.second_derivative(k,3)[0][0] = 0;
+             data.second_derivative(k,0)[0][1] = 1.;
+             data.second_derivative(k,1)[0][1] = -1.;
+             data.second_derivative(k,2)[0][1] = -1.;
+             data.second_derivative(k,3)[0][1] = 1.;
+             data.second_derivative(k,0)[1][0] = 1.;
+             data.second_derivative(k,1)[1][0] = -1.;
+             data.second_derivative(k,2)[1][0] = -1.;
+             data.second_derivative(k,3)[1][0] = 1.;
+             data.second_derivative(k,0)[1][1] = 0;
+             data.second_derivative(k,1)[1][1] = 0;
+             data.second_derivative(k,2)[1][1] = 0;
+             data.second_derivative(k,3)[1][1] = 0;
+           }
        }
     }
-}
 
-#endif
-
-#if (deal_II_dimension == 3)
 
 
-template<>
-void
-MappingQ1<3>::compute_shapes_virtual (const std::vector<Point<3> > &unit_points,
-                                     InternalData &data) const
-{
-  const unsigned int n_points=unit_points.size();
-  for (unsigned int k = 0 ; k < n_points ; ++k)
+    template <int spacedim>
+    void
+    compute_shapes_virtual (const unsigned int            n_shape_functions,
+                           const std::vector<Point<3> > &unit_points,
+                           typename dealii::MappingQ1<3,spacedim>::InternalData& data) 
     {
-      double x = unit_points[k](0);
-      double y = unit_points[k](1);
-      double z = unit_points[k](2);
-      
-      if (data.shape_values.size()!=0)
+      const unsigned int n_points=unit_points.size();
+      for (unsigned int k = 0 ; k < n_points ; ++k)
        {
-         Assert(data.shape_values.size()==n_shape_functions*n_points,
-                ExcInternalError());
-         data.shape(k,0) = (1.-x)*(1.-y)*(1.-z);
-         data.shape(k,1) = x*(1.-y)*(1.-z);
-         data.shape(k,2) = (1.-x)*y*(1.-z);
-         data.shape(k,3) = x*y*(1.-z);
-         data.shape(k,4) = (1.-x)*(1.-y)*z;
-         data.shape(k,5) = x*(1.-y)*z;
-         data.shape(k,6) = (1.-x)*y*z;
-         data.shape(k,7) = x*y*z;
-       }
-      if (data.shape_derivatives.size()!=0)
-       {
-         Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
-                ExcInternalError());
-         data.derivative(k,0)[0] = (y-1.)*(1.-z);
-         data.derivative(k,1)[0] = (1.-y)*(1.-z);
-         data.derivative(k,2)[0] = -y*(1.-z);
-         data.derivative(k,3)[0] = y*(1.-z);
-         data.derivative(k,4)[0] = (y-1.)*z;
-         data.derivative(k,5)[0] = (1.-y)*z;
-         data.derivative(k,6)[0] = -y*z;
-         data.derivative(k,7)[0] = y*z;
-         data.derivative(k,0)[1] = (x-1.)*(1.-z);
-         data.derivative(k,1)[1] = -x*(1.-z);
-         data.derivative(k,2)[1] = (1.-x)*(1.-z);
-         data.derivative(k,3)[1] = x*(1.-z);
-         data.derivative(k,4)[1] = (x-1.)*z;
-         data.derivative(k,5)[1] = -x*z;
-         data.derivative(k,6)[1] = (1.-x)*z;
-         data.derivative(k,7)[1] = x*z;
-         data.derivative(k,0)[2] = (x-1)*(1.-y);
-         data.derivative(k,1)[2] = x*(y-1.);
-         data.derivative(k,2)[2] = (x-1.)*y;
-         data.derivative(k,3)[2] = -x*y;
-         data.derivative(k,4)[2] = (1.-x)*(1.-y);
-         data.derivative(k,5)[2] = x*(1.-y);
-         data.derivative(k,6)[2] = (1.-x)*y;
-         data.derivative(k,7)[2] = x*y;
-       }
-      if (data.shape_second_derivatives.size()!=0)
-       {
-         Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
-                ExcInternalError());
-         data.second_derivative(k,0)[0][0] = 0;
-         data.second_derivative(k,1)[0][0] = 0;
-         data.second_derivative(k,2)[0][0] = 0;
-         data.second_derivative(k,3)[0][0] = 0;
-         data.second_derivative(k,4)[0][0] = 0;
-         data.second_derivative(k,5)[0][0] = 0;
-         data.second_derivative(k,6)[0][0] = 0;
-         data.second_derivative(k,7)[0][0] = 0;
-         data.second_derivative(k,0)[1][1] = 0;
-         data.second_derivative(k,1)[1][1] = 0;
-         data.second_derivative(k,2)[1][1] = 0;
-         data.second_derivative(k,3)[1][1] = 0;
-         data.second_derivative(k,4)[1][1] = 0;
-         data.second_derivative(k,5)[1][1] = 0;
-         data.second_derivative(k,6)[1][1] = 0;
-         data.second_derivative(k,7)[1][1] = 0;
-         data.second_derivative(k,0)[2][2] = 0;
-         data.second_derivative(k,1)[2][2] = 0;
-         data.second_derivative(k,2)[2][2] = 0;
-         data.second_derivative(k,3)[2][2] = 0;
-         data.second_derivative(k,4)[2][2] = 0;
-         data.second_derivative(k,5)[2][2] = 0;
-         data.second_derivative(k,6)[2][2] = 0;
-         data.second_derivative(k,7)[2][2] = 0;
-
-         data.second_derivative(k,0)[0][1] = (1.-z);
-         data.second_derivative(k,1)[0][1] = -(1.-z);
-         data.second_derivative(k,2)[0][1] = -(1.-z);
-         data.second_derivative(k,3)[0][1] = (1.-z);
-         data.second_derivative(k,4)[0][1] = z;
-         data.second_derivative(k,5)[0][1] = -z;
-         data.second_derivative(k,6)[0][1] = -z;
-         data.second_derivative(k,7)[0][1] = z;
-         data.second_derivative(k,0)[1][0] = (1.-z);
-         data.second_derivative(k,1)[1][0] = -(1.-z);
-         data.second_derivative(k,2)[1][0] = -(1.-z);
-         data.second_derivative(k,3)[1][0] = (1.-z);
-         data.second_derivative(k,4)[1][0] = z;
-         data.second_derivative(k,5)[1][0] = -z;
-         data.second_derivative(k,6)[1][0] = -z;
-         data.second_derivative(k,7)[1][0] = z;
-
-         data.second_derivative(k,0)[0][2] = (1.-y);
-         data.second_derivative(k,1)[0][2] = -(1.-y);
-         data.second_derivative(k,2)[0][2] = y;
-         data.second_derivative(k,3)[0][2] = -y;
-         data.second_derivative(k,4)[0][2] = -(1.-y);
-         data.second_derivative(k,5)[0][2] = (1.-y);
-         data.second_derivative(k,6)[0][2] = -y;
-         data.second_derivative(k,7)[0][2] = y;
-         data.second_derivative(k,0)[2][0] = (1.-y);
-         data.second_derivative(k,1)[2][0] = -(1.-y);
-         data.second_derivative(k,2)[2][0] = y;
-         data.second_derivative(k,3)[2][0] = -y;
-         data.second_derivative(k,4)[2][0] = -(1.-y);
-         data.second_derivative(k,5)[2][0] = (1.-y);
-         data.second_derivative(k,6)[2][0] = -y;
-         data.second_derivative(k,7)[2][0] = y;
+         double x = unit_points[k](0);
+         double y = unit_points[k](1);
+         double z = unit_points[k](2);
+      
+         if (data.shape_values.size()!=0)
+           {
+             Assert(data.shape_values.size()==n_shape_functions*n_points,
+                    ExcInternalError());
+             data.shape(k,0) = (1.-x)*(1.-y)*(1.-z);
+             data.shape(k,1) = x*(1.-y)*(1.-z);
+             data.shape(k,2) = (1.-x)*y*(1.-z);
+             data.shape(k,3) = x*y*(1.-z);
+             data.shape(k,4) = (1.-x)*(1.-y)*z;
+             data.shape(k,5) = x*(1.-y)*z;
+             data.shape(k,6) = (1.-x)*y*z;
+             data.shape(k,7) = x*y*z;
+           }
+         if (data.shape_derivatives.size()!=0)
+           {
+             Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
+                    ExcInternalError());
+             data.derivative(k,0)[0] = (y-1.)*(1.-z);
+             data.derivative(k,1)[0] = (1.-y)*(1.-z);
+             data.derivative(k,2)[0] = -y*(1.-z);
+             data.derivative(k,3)[0] = y*(1.-z);
+             data.derivative(k,4)[0] = (y-1.)*z;
+             data.derivative(k,5)[0] = (1.-y)*z;
+             data.derivative(k,6)[0] = -y*z;
+             data.derivative(k,7)[0] = y*z;
+             data.derivative(k,0)[1] = (x-1.)*(1.-z);
+             data.derivative(k,1)[1] = -x*(1.-z);
+             data.derivative(k,2)[1] = (1.-x)*(1.-z);
+             data.derivative(k,3)[1] = x*(1.-z);
+             data.derivative(k,4)[1] = (x-1.)*z;
+             data.derivative(k,5)[1] = -x*z;
+             data.derivative(k,6)[1] = (1.-x)*z;
+             data.derivative(k,7)[1] = x*z;
+             data.derivative(k,0)[2] = (x-1)*(1.-y);
+             data.derivative(k,1)[2] = x*(y-1.);
+             data.derivative(k,2)[2] = (x-1.)*y;
+             data.derivative(k,3)[2] = -x*y;
+             data.derivative(k,4)[2] = (1.-x)*(1.-y);
+             data.derivative(k,5)[2] = x*(1.-y);
+             data.derivative(k,6)[2] = (1.-x)*y;
+             data.derivative(k,7)[2] = x*y;
+           }
+         if (data.shape_second_derivatives.size()!=0)
+           {
+                                              // the following may or may not
+                                              // work if dim != spacedim
+             Assert (spacedim == 3, ExcNotImplemented());
+             
+             Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
+                    ExcInternalError());
+             data.second_derivative(k,0)[0][0] = 0;
+             data.second_derivative(k,1)[0][0] = 0;
+             data.second_derivative(k,2)[0][0] = 0;
+             data.second_derivative(k,3)[0][0] = 0;
+             data.second_derivative(k,4)[0][0] = 0;
+             data.second_derivative(k,5)[0][0] = 0;
+             data.second_derivative(k,6)[0][0] = 0;
+             data.second_derivative(k,7)[0][0] = 0;
+             data.second_derivative(k,0)[1][1] = 0;
+             data.second_derivative(k,1)[1][1] = 0;
+             data.second_derivative(k,2)[1][1] = 0;
+             data.second_derivative(k,3)[1][1] = 0;
+             data.second_derivative(k,4)[1][1] = 0;
+             data.second_derivative(k,5)[1][1] = 0;
+             data.second_derivative(k,6)[1][1] = 0;
+             data.second_derivative(k,7)[1][1] = 0;
+             data.second_derivative(k,0)[2][2] = 0;
+             data.second_derivative(k,1)[2][2] = 0;
+             data.second_derivative(k,2)[2][2] = 0;
+             data.second_derivative(k,3)[2][2] = 0;
+             data.second_derivative(k,4)[2][2] = 0;
+             data.second_derivative(k,5)[2][2] = 0;
+             data.second_derivative(k,6)[2][2] = 0;
+             data.second_derivative(k,7)[2][2] = 0;
+
+             data.second_derivative(k,0)[0][1] = (1.-z);
+             data.second_derivative(k,1)[0][1] = -(1.-z);
+             data.second_derivative(k,2)[0][1] = -(1.-z);
+             data.second_derivative(k,3)[0][1] = (1.-z);
+             data.second_derivative(k,4)[0][1] = z;
+             data.second_derivative(k,5)[0][1] = -z;
+             data.second_derivative(k,6)[0][1] = -z;
+             data.second_derivative(k,7)[0][1] = z;
+             data.second_derivative(k,0)[1][0] = (1.-z);
+             data.second_derivative(k,1)[1][0] = -(1.-z);
+             data.second_derivative(k,2)[1][0] = -(1.-z);
+             data.second_derivative(k,3)[1][0] = (1.-z);
+             data.second_derivative(k,4)[1][0] = z;
+             data.second_derivative(k,5)[1][0] = -z;
+             data.second_derivative(k,6)[1][0] = -z;
+             data.second_derivative(k,7)[1][0] = z;
+
+             data.second_derivative(k,0)[0][2] = (1.-y);
+             data.second_derivative(k,1)[0][2] = -(1.-y);
+             data.second_derivative(k,2)[0][2] = y;
+             data.second_derivative(k,3)[0][2] = -y;
+             data.second_derivative(k,4)[0][2] = -(1.-y);
+             data.second_derivative(k,5)[0][2] = (1.-y);
+             data.second_derivative(k,6)[0][2] = -y;
+             data.second_derivative(k,7)[0][2] = y;
+             data.second_derivative(k,0)[2][0] = (1.-y);
+             data.second_derivative(k,1)[2][0] = -(1.-y);
+             data.second_derivative(k,2)[2][0] = y;
+             data.second_derivative(k,3)[2][0] = -y;
+             data.second_derivative(k,4)[2][0] = -(1.-y);
+             data.second_derivative(k,5)[2][0] = (1.-y);
+             data.second_derivative(k,6)[2][0] = -y;
+             data.second_derivative(k,7)[2][0] = y;
          
-         data.second_derivative(k,0)[1][2] = (1.-x);
-         data.second_derivative(k,1)[1][2] = x;
-         data.second_derivative(k,2)[1][2] = -(1.-x);
-         data.second_derivative(k,3)[1][2] = -x;
-         data.second_derivative(k,4)[1][2] = -(1.-x);
-         data.second_derivative(k,5)[1][2] = -x;
-         data.second_derivative(k,6)[1][2] = (1.-x);
-         data.second_derivative(k,7)[1][2] = x;
-         data.second_derivative(k,0)[2][1] = (1.-x);
-         data.second_derivative(k,1)[2][1] = x;
-         data.second_derivative(k,2)[2][1] = -(1.-x);
-         data.second_derivative(k,3)[2][1] = -x;
-         data.second_derivative(k,4)[2][1] = -(1.-x);
-         data.second_derivative(k,5)[2][1] = -x;
-         data.second_derivative(k,6)[2][1] = (1.-x);
-         data.second_derivative(k,7)[2][1] = x;
+             data.second_derivative(k,0)[1][2] = (1.-x);
+             data.second_derivative(k,1)[1][2] = x;
+             data.second_derivative(k,2)[1][2] = -(1.-x);
+             data.second_derivative(k,3)[1][2] = -x;
+             data.second_derivative(k,4)[1][2] = -(1.-x);
+             data.second_derivative(k,5)[1][2] = -x;
+             data.second_derivative(k,6)[1][2] = (1.-x);
+             data.second_derivative(k,7)[1][2] = x;
+             data.second_derivative(k,0)[2][1] = (1.-x);
+             data.second_derivative(k,1)[2][1] = x;
+             data.second_derivative(k,2)[2][1] = -(1.-x);
+             data.second_derivative(k,3)[2][1] = -x;
+             data.second_derivative(k,4)[2][1] = -(1.-x);
+             data.second_derivative(k,5)[2][1] = -x;
+             data.second_derivative(k,6)[2][1] = (1.-x);
+             data.second_derivative(k,7)[2][1] = x;
+           }
        }
     }
+  }
+}
+
+
+template<int dim, int spacedim>
+void
+MappingQ1<dim, spacedim>::
+compute_shapes_virtual (const std::vector<Point<dim> > &unit_points,
+                       InternalData& data) const
+{
+  internal::MappingQ1::
+    compute_shapes_virtual<spacedim> (n_shape_functions,
+                                     unit_points, data);
 }
 
-#endif
 
-template <int dim>
+
+template<int dim, int spacedim>
 UpdateFlags
-MappingQ1<dim>::update_once (const UpdateFlags in) const
+MappingQ1<dim,spacedim>::update_once (const UpdateFlags in) const
 {
   UpdateFlags out = UpdateFlags(in & (update_transformation_values
                                      | update_transformation_gradients));
@@ -340,6 +366,7 @@ MappingQ1<dim>::update_once (const UpdateFlags in) const
   if (in & (update_covariant_transformation
            | update_contravariant_transformation
            | update_JxW_values
+           | update_cell_normal_vectors
            | update_boundary_forms
            | update_normal_vectors
            | update_jacobians
@@ -352,9 +379,9 @@ MappingQ1<dim>::update_once (const UpdateFlags in) const
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 UpdateFlags
-MappingQ1<dim>::update_each (const UpdateFlags in) const
+MappingQ1<dim,spacedim>::update_each (const UpdateFlags in) const
 {
                                   // Select flags of concern for the
                                   // transformation.
@@ -362,6 +389,7 @@ MappingQ1<dim>::update_each (const UpdateFlags in) const
                                      | update_covariant_transformation
                                      | update_contravariant_transformation
                                      | update_JxW_values
+                                     | update_cell_normal_vectors
                                      | update_cell_JxW_values
                                      | update_boundary_forms
                                      | update_normal_vectors
@@ -395,6 +423,7 @@ MappingQ1<dim>::update_each (const UpdateFlags in) const
   
       if (out & (update_covariant_transformation
                 | update_JxW_values
+                | update_cell_normal_vectors
                 | update_jacobians
                 | update_jacobian_grads
                 | update_boundary_forms
@@ -412,15 +441,19 @@ MappingQ1<dim>::update_each (const UpdateFlags in) const
                                       // updated for each cell.
       if (out & update_contravariant_transformation)
        out |= update_JxW_values | update_cell_JxW_values;
+
+      if (out & update_cell_normal_vectors)
+       out |= update_JxW_values | update_cell_normal_vectors;
+
     }
   
   return out;
 }
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::compute_data (const UpdateFlags      update_flags,
+MappingQ1<dim,spacedim>::compute_data (const UpdateFlags      update_flags,
                              const Quadrature<dim> &q,
                              const unsigned int     n_original_q_points,
                              InternalData          &data) const
@@ -453,10 +486,10 @@ MappingQ1<dim>::compute_data (const UpdateFlags      update_flags,
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-MappingQ1<dim>::get_data (const UpdateFlags update_flags,
-                         const Quadrature<dim>& q) const
+template<int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+MappingQ1<dim,spacedim>::get_data (const UpdateFlags update_flags,
+                                  const Quadrature<dim>& q) const
 {
   InternalData* data = new InternalData(n_shape_functions);
   compute_data (update_flags, q, q.size(), *data);
@@ -464,90 +497,78 @@ MappingQ1<dim>::get_data (const UpdateFlags update_flags,
 }
 
 
-#if deal_II_dimension == 1
 
-template <>
-void
-MappingQ1<1>::compute_face_data (const UpdateFlags update_flags,
-                                 const Quadrature<1>& q,
-                                 const unsigned int n_original_q_points,
-                                 InternalData& data) const
-{
-  compute_data (update_flags, q, n_original_q_points, data);
-}
-
-#else
-
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::compute_face_data (const UpdateFlags update_flags,
+MappingQ1<dim,spacedim>::compute_face_data (const UpdateFlags update_flags,
                                   const Quadrature<dim>& q,
                                   const unsigned int n_original_q_points,
                                   InternalData& data) const
 {
   compute_data (update_flags, q, n_original_q_points, data);
 
-  if (data.update_flags & update_boundary_forms)
+  if (dim > 1)
     {
-      data.aux.resize (dim-1, std::vector<Tensor<1,dim> > (n_original_q_points));
-      
-                                      // Compute tangentials to the
-                                      // unit cell.
-      const unsigned int nfaces = GeometryInfo<dim>::faces_per_cell;
-      data.unit_tangentials.resize (nfaces*(dim-1),
-                                    std::vector<Tensor<1,dim> > (n_original_q_points));
-      if (dim==2)
+      if (data.update_flags & update_boundary_forms)
        {
-                                          // ensure a counterclock wise
-                                          // orientation of tangentials
-         static const int tangential_orientation[4]={-1,1,1,-1};
-         for (unsigned int i=0; i<nfaces; ++i)
+         data.aux.resize (dim-1, std::vector<Tensor<1,spacedim> > (n_original_q_points));
+      
+                                          // Compute tangentials to the
+                                          // unit cell.
+         const unsigned int nfaces = GeometryInfo<dim>::faces_per_cell;
+         data.unit_tangentials.resize (nfaces*(dim-1),
+                                       std::vector<Tensor<1,spacedim> > (n_original_q_points));
+         if (dim==2)
            {
-             Tensor<1,dim> tang;             
-             tang[1-i/2]=tangential_orientation[i];
-             std::fill (data.unit_tangentials[i].begin(),
-                        data.unit_tangentials[i].end(), tang);
+                                              // ensure a counterclock wise
+                                              // orientation of tangentials
+             static const int tangential_orientation[4]={-1,1,1,-1};
+             for (unsigned int i=0; i<nfaces; ++i)
+               {
+                 Tensor<1,spacedim> tang;            
+                 tang[1-i/2]=tangential_orientation[i];
+                 std::fill (data.unit_tangentials[i].begin(),
+                            data.unit_tangentials[i].end(), tang);
+               }
            }
-       }
-      else if (dim==3)
-       {
-         for (unsigned int i=0; i<nfaces; ++i)
+         else if (dim==3)
            {
-             Tensor<1,dim> tang1, tang2;
+             for (unsigned int i=0; i<nfaces; ++i)
+               {
+                 Tensor<1,spacedim> tang1, tang2;
 
-             const unsigned int nd=
-               GeometryInfo<dim>::unit_normal_direction[i];
+                 const unsigned int nd=
+                   GeometryInfo<dim>::unit_normal_direction[i];
              
-                                              // first tangential
-                                              // vector in direction
-                                              // of the (nd+1)%3 axis
-                                              // and inverted in case
-                                              // of unit inward normal
-             tang1[(nd+1)%dim]=GeometryInfo<dim>::unit_normal_orientation[i];
-                                              // second tangential
-                                              // vector in direction
-                                              // of the (nd+2)%3 axis
-             tang2[(nd+2)%dim]=1.;
-
-                                              // same unit tangents
-                                              // for all quadrature
-                                              // points on this face
-             std::fill (data.unit_tangentials[i].begin(),
-                        data.unit_tangentials[i].end(), tang1);
-             std::fill (data.unit_tangentials[nfaces+i].begin(),
-                        data.unit_tangentials[nfaces+i].end(), tang2);
+                                                  // first tangential
+                                                  // vector in direction
+                                                  // of the (nd+1)%3 axis
+                                                  // and inverted in case
+                                                  // of unit inward normal
+                 tang1[(nd+1)%dim]=GeometryInfo<dim>::unit_normal_orientation[i];
+                                                  // second tangential
+                                                  // vector in direction
+                                                  // of the (nd+2)%3 axis
+                 tang2[(nd+2)%dim]=1.;
+
+                                                  // same unit tangents
+                                                  // for all quadrature
+                                                  // points on this face
+                 std::fill (data.unit_tangentials[i].begin(),
+                            data.unit_tangentials[i].end(), tang1);
+                 std::fill (data.unit_tangentials[nfaces+i].begin(),
+                            data.unit_tangentials[nfaces+i].end(), tang2);
+               }
            }
        }
     }
 }
 
-#endif
-
   
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-MappingQ1<dim>::get_face_data (const UpdateFlags        update_flags,
+template<int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+MappingQ1<dim,spacedim>::get_face_data (const UpdateFlags        update_flags,
                               const Quadrature<dim-1> &quadrature) const
 {
   InternalData* data = new InternalData(n_shape_functions);
@@ -561,9 +582,9 @@ MappingQ1<dim>::get_face_data (const UpdateFlags        update_flags,
 
 
 
-template <int dim>
-typename Mapping<dim>::InternalDataBase *
-MappingQ1<dim>::get_subface_data (const UpdateFlags update_flags,
+template<int dim, int spacedim>
+typename Mapping<dim,spacedim>::InternalDataBase *
+MappingQ1<dim,spacedim>::get_subface_data (const UpdateFlags update_flags,
                                  const Quadrature<dim-1>& quadrature) const
 {
   InternalData* data = new InternalData(n_shape_functions);
@@ -577,15 +598,15 @@ MappingQ1<dim>::get_subface_data (const UpdateFlags update_flags,
 
 
 
-
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::compute_fill (const typename Triangulation<dim>::cell_iterator &cell,
-                             const unsigned int       n_q_points,
-                             const DataSetDescriptor  data_set,
-                             InternalData            &data,
-                             std::vector<Point<dim> > &quadrature_points) const
+MappingQ1<dim,spacedim>::compute_fill (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                                      const unsigned int  n_q_points,
+                                              const DataSetDescriptor  data_set,
+                                      InternalData  &data,
+                                      std::vector<Point<spacedim> > &quadrature_points) const
 {
+
   const UpdateFlags update_flags(data.current_update_flags());
 
   if (update_flags & update_quadrature_points)
@@ -594,7 +615,7 @@ MappingQ1<dim>::compute_fill (const typename Triangulation<dim>::cell_iterator &
              ExcDimensionMismatch(quadrature_points.size(), n_q_points));
       std::fill(quadrature_points.begin(),
                quadrature_points.end(),
-               Point<dim>());
+               Point<spacedim>());
     }
 
   if (update_flags & update_covariant_transformation)
@@ -609,7 +630,7 @@ MappingQ1<dim>::compute_fill (const typename Triangulation<dim>::cell_iterator &
              ExcDimensionMismatch(data.contravariant.size(), n_q_points));
       std::fill(data.contravariant.begin(),
                data.contravariant.end(),
-               Tensor<2,dim>());
+               Tensor<2,spacedim>());
     }
 
                                   // if necessary, recompute the
@@ -644,27 +665,64 @@ MappingQ1<dim>::compute_fill (const typename Triangulation<dim>::cell_iterator &
   if (update_flags & update_contravariant_transformation)
     for (unsigned int point=0; point<n_q_points; ++point)
       for (unsigned int k=0; k<data.n_shape_functions; ++k)
-        for (unsigned int i=0; i<dim; ++i)
-          for (unsigned int j=0; j<dim; ++j)
-           data.contravariant[point][i][j]
-             += (data.derivative(point+data_set, k)[j]
-                 *
-                 data.mapping_support_points[k][i]);
-
-                                      // invert contravariant for
-                                      // covariant transformation
-                                      // matrices
-  if (update_flags & update_covariant_transformation)
+       if (dim==spacedim)
+         {
+           for (unsigned int i=0; i<dim; ++i)
+             for (unsigned int j=0; j<dim; ++j)
+               data.contravariant[point][i][j]
+                 += (data.derivative(point+data_set, k)[j]
+                     *
+                     data.mapping_support_points[k][i]);
+         }
+  
+                                   // CODIMENSION 1 
+                                   // Jacobians are rectangular
+                                   // matrices
+       else if (dim==spacedim-1)
+         {   
+           for (unsigned int i=0; i<spacedim; ++i)
+             for (unsigned int j=0; j<dim; ++j)
+               data.contravariant[point][i][j]
+                 += (data.derivative(point+data_set, k)[j]
+                     *
+                     data.mapping_support_points[k][i]);
+         }    
+
+
+  FullMatrix<double> contravariant_matrix(spacedim,dim);
+  FullMatrix<double> covariant_matrix(dim,spacedim);
+                                   // invert contravariant for
+                                   // covariant transformation
+                                   // matrices
+  if ((update_flags & update_covariant_transformation)&&(dim==spacedim))
     for (unsigned int point=0; point<n_q_points; ++point)
       data.covariant[point] = invert(data.contravariant[point]);
+                                   // CODIMENSION 1 
+                                   // calculate left-inversion of the
+                                   // contravariant matrices to obtain
+                                   // covariant ones (auxiliary
+                                   // rectangular fullmatrices are used)
+  else if ((update_flags & update_covariant_transformation)&&(dim==spacedim-1))
+    for (unsigned int point=0; point<n_q_points; ++point)
+     {
+       contravariant_matrix.
+        copy_from(data.contravariant[point],0,spacedim-1,0,dim-1);  
+       covariant_matrix.
+        left_invert(contravariant_matrix);
+       covariant_matrix.
+        copy_to(data.covariant[point],0,dim-1,0,spacedim-1);
+     }
+
+
+  
 }
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::compute_mapping_support_points(
-  const typename Triangulation<dim>::cell_iterator &cell,
-  std::vector<Point<dim> > &a) const
+MappingQ1<dim,spacedim>::compute_mapping_support_points(
+  const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+  std::vector<Point<spacedim> > &a) const
 {
   a.resize(GeometryInfo<dim>::vertices_per_cell);
 
@@ -672,25 +730,24 @@ MappingQ1<dim>::compute_mapping_support_points(
     a[i] = cell->vertex(i);
 }
 
-
-
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator &cell,
+MappingQ1<dim,spacedim>::fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                const Quadrature<dim>                     &q,
-                               typename Mapping<dim>::InternalDataBase   &mapping_data,
-                               std::vector<Point<dim> >                  &quadrature_points,
+                               typename Mapping<dim,spacedim>::InternalDataBase   &mapping_data,
+                               std::vector<Point<spacedim> >             &quadrature_points,
                                std::vector<double>                       &JxW_values,
-                               std::vector<Tensor<2,dim> >               &jacobians,
-                               std::vector<Tensor<3,dim> >               &jacobian_grads,
-                               std::vector<Tensor<2,dim> >               &inverse_jacobians) const
+                               std::vector<Tensor<2,spacedim> >          &jacobians,
+                               std::vector<Tensor<3,spacedim> >          &jacobian_grads,
+                               std::vector<Tensor<2,spacedim> >          &inverse_jacobians,
+                               std::vector<Point<spacedim> >             &cell_normal_vectors) const
 {
   InternalData *data_ptr = dynamic_cast<InternalData *> (&mapping_data);
   Assert(data_ptr!=0, ExcInternalError());
   InternalData &data=*data_ptr;
 
   const unsigned int n_q_points=q.size();
-  
+
   compute_fill (cell, n_q_points, DataSetDescriptor::cell (),
                 data, quadrature_points);
 
@@ -698,15 +755,61 @@ MappingQ1<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator
   const UpdateFlags update_flags(data.current_update_flags());
   const std::vector<double> &weights=q.get_weights();
 
-                                  // Multiply quadrature weights
-                                  // by Jacobian determinants
-  if (update_flags & update_JxW_values)
+
+                                  // Multiply quadrature weights by
+                                  // Jacobian determinants or by norm
+                                  // of the cross product of the
+                                  // columns of the Jacobian and
+                                  // store the cell normal vectors in
+                                  // the case <2,3>
+  if (update_flags & (update_cell_normal_vectors
+                     | update_JxW_values))
     {      
       Assert (JxW_values.size() == n_q_points,
-             ExcDimensionMismatch(JxW_values.size(), n_q_points));
-      for (unsigned int point=0; point<n_q_points; ++point)
-       JxW_values[point]
-         = determinant(data.contravariant[point])*weights[point];
+              ExcDimensionMismatch(JxW_values.size(), n_q_points));
+
+      Assert( !(update_flags & update_cell_normal_vectors ) ||
+             (cell_normal_vectors.size() == n_q_points),
+            ExcDimensionMismatch(cell_normal_vectors.size(), n_q_points));
+       for (unsigned int point=0; point<n_q_points; ++point)
+         { 
+
+           if (dim==spacedim)
+             JxW_values[point]
+               = determinant(data.contravariant[point])*weights[point];
+
+           if ( (dim==1) && (spacedim==2) )
+             {
+               data.contravariant[point]=transpose(data.contravariant[point]);
+               JxW_values[point]
+                 = data.contravariant[point][0].norm()*weights[point];
+               if(update_flags & update_cell_normal_vectors) 
+               {
+                 cell_normal_vectors[point][0]=-data.contravariant[point][0][1]
+                     /data.contravariant[point][0].norm();
+                 cell_normal_vectors[point][1]=data.contravariant[point][0][0]
+                     /data.contravariant[point][0].norm();
+               }
+             }
+           if ( (dim==2) && (spacedim==3) )
+             {
+               data.contravariant[point]=transpose(data.contravariant[point]);
+               cross_product(data.contravariant[point][2], 
+                             data.contravariant[point][0],
+                             data.contravariant[point][1]
+                             );
+               JxW_values[point]
+                 = data.contravariant[point][2].norm()*weights[point];
+                                         //the cell normal vector
+                                         //(normal to the surface)
+                                          //is stored in the 3d
+                                         //subtensor of the contravariant tensor
+               data.contravariant[point][2]/=data.contravariant[point][2].norm();
+               if(update_flags & update_cell_normal_vectors) 
+                 cell_normal_vectors[point]=data.contravariant[point][2];
+             }
+           
+         }
     }
 
                                   // copy values from InternalData to vector
@@ -728,7 +831,7 @@ MappingQ1<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator
              ExcDimensionMismatch(jacobian_grads.size(), n_q_points));
       std::fill(jacobian_grads.begin(),
                jacobian_grads.end(),
-               Tensor<3,dim>());
+               Tensor<3,spacedim>());
 
       for (unsigned int point=0; point<n_q_points; ++point)
        for (unsigned int k=0; k<data.n_shape_functions; ++k)
@@ -753,21 +856,39 @@ MappingQ1<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator
 }
 
 
+template<>
+void
+MappingQ1<2,3>::compute_fill_face (const Triangulation<2,3>::cell_iterator &,
+                                  const unsigned int,
+                                  const unsigned int,
+                                  const unsigned int,
+                                  const DataSetDescriptor,
+                                  const std::vector<double>&,
+                                  InternalData &,
+                                  std::vector<Point<2> >&,
+                                  std::vector<double>&,
+                                  std::vector<Tensor<1,2> > &,
+                                  std::vector<Point<3> > &,
+                                  std::vector<double>&) const 
+{
+       Assert(false, ExcNotImplemented());
+}
+
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::compute_fill_face (const typename Triangulation<dim>::cell_iterator &cell,
-                                  const unsigned int      face_no,
-                                  const unsigned int      subface_no,
-                                  const unsigned int      n_q_points,
-                                  const DataSetDescriptor data_set,
-                                  const std::vector<double>   &weights,
-                                  InternalData           &data,
-                                  std::vector<Point<dim> >    &quadrature_points,
-                                  std::vector<double>         &JxW_values,
+MappingQ1<dim,spacedim>::compute_fill_face (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                                  const unsigned int               face_no,
+                                  const unsigned int               subface_no,
+                                  const unsigned int               n_q_points,
+                                  const DataSetDescriptor          data_set,
+                                  const std::vector<double>        &weights,
+                                  InternalData                     &data,
+                                  std::vector<Point<dim> >         &quadrature_points,
+                                  std::vector<double>              &JxW_values,
                                   std::vector<Tensor<1,dim> > &boundary_forms,
-                                  std::vector<Point<dim> >    &normal_vectors,
-                                  std::vector<double>         &cell_JxW_values) const
+                                  std::vector<Point<spacedim> >    &normal_vectors,
+                                  std::vector<double>              &cell_JxW_values) const
 {
   compute_fill (cell, n_q_points, data_set, data, quadrature_points);
 
@@ -867,17 +988,17 @@ MappingQ1<dim>::compute_fill_face (const typename Triangulation<dim>::cell_itera
 }
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_iterator &cell,
-                                    const unsigned int       face_no,
-                                    const Quadrature<dim-1> &q,
-                                    typename Mapping<dim>::InternalDataBase &mapping_data,
-                                    std::vector<Point<dim> >     &quadrature_points,
-                                    std::vector<double>          &JxW_values,
-                                    std::vector<Tensor<1,dim> >  &boundary_forms,
-                                    std::vector<Point<dim> >     &normal_vectors,
-                                    std::vector<double>          &cell_JxW_values) const
+MappingQ1<dim,spacedim>::fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                                    const unsigned int                               face_no,
+                                    const Quadrature<dim-1>                          &q,
+                                    typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+                                    std::vector<Point<dim> >                         &quadrature_points,
+                                    std::vector<double>                              &JxW_values,
+                                    std::vector<Tensor<1,dim> >                      &boundary_forms,
+                                    std::vector<Point<spacedim> >                    &normal_vectors,
+                                    std::vector<double>                              &cell_JxW_values) const
 {
   InternalData *data_ptr = dynamic_cast<InternalData *> (&mapping_data);
   Assert(data_ptr!=0, ExcInternalError());
@@ -902,17 +1023,17 @@ MappingQ1<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_ite
 }
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::fill_fe_subface_values (const typename Triangulation<dim>::cell_iterator &cell,
+MappingQ1<dim,spacedim>::fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                        const unsigned int       face_no,
                                        const unsigned int       sub_no,
                                        const Quadrature<dim-1> &q,
-                                       typename Mapping<dim>::InternalDataBase &mapping_data,
+                                       typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
                                        std::vector<Point<dim> >     &quadrature_points,
                                        std::vector<double>          &JxW_values,
                                        std::vector<Tensor<1,dim> >  &boundary_forms,
-                                       std::vector<Point<dim> >     &normal_vectors,
+                                       std::vector<Point<spacedim> >     &normal_vectors,
                                        std::vector<double>          &cell_JxW_values) const
 {
   InternalData *data_ptr = dynamic_cast<InternalData *> (&mapping_data);
@@ -991,16 +1112,70 @@ MappingQ1<1>::fill_fe_subface_values (const Triangulation<1>::cell_iterator &,
 {
   Assert(false, ExcNotImplemented());
 }
+
+
+template <>
+void
+MappingQ1<1,2>::compute_fill_face (const Triangulation<1,2>::cell_iterator &,
+                                const unsigned int,
+                                const unsigned int,
+                                const unsigned int,
+                                const DataSetDescriptor,
+                                const std::vector<double> &,
+                                InternalData &,
+                                std::vector<Point<1> > &,
+                                std::vector<double> &,
+                                std::vector<Tensor<1,1> > &,
+                                std::vector<Point<2> > &,
+                                std::vector<double>          &/*cell_JxW_values*/) const
+{
+  Assert(false, ExcNotImplemented());
+}
+
+
+template <>
+void
+MappingQ1<1,2>::fill_fe_face_values (const Triangulation<1,2>::cell_iterator &,
+                                  const unsigned,
+                                  const Quadrature<0>&,
+                                  Mapping<1,2>::InternalDataBase&,
+                                  std::vector<Point<1> >&,
+                                  std::vector<double>&,
+                                  std::vector<Tensor<1,1> >&,
+                                  std::vector<Point<2> >&,
+                                  std::vector<double>          &/*cell_JxW_values*/) const
+{
+  Assert(false, ExcNotImplemented());
+}
+
+
+template <>
+void
+MappingQ1<1,2>::fill_fe_subface_values (const Triangulation<1,2>::cell_iterator &,
+                                     const unsigned,
+                                     const unsigned,
+                                     const Quadrature<0>&,
+                                     Mapping<1,2>::InternalDataBase&,
+                                     std::vector<Point<1> >&,
+                                     std::vector<double>&,
+                                     std::vector<Tensor<1,1> >&,
+                                     std::vector<Point<2> >&,
+                                     std::vector<double>          &/*cell_JxW_values*/) const
+{
+  Assert(false, ExcNotImplemented());
+}
+
+
 #endif
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::transform_covariant (
+MappingQ1<dim,spacedim>::transform_covariant (
   const VectorSlice<const std::vector<Tensor<1,dim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<1,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data) const
 {
   const InternalData *data_ptr = dynamic_cast<const InternalData *> (&mapping_data);
   Assert(data_ptr!=0, ExcInternalError());
@@ -1016,38 +1191,113 @@ MappingQ1<dim>::transform_covariant (
 }
 
 
+template<>
+void
+MappingQ1<1,2>::transform_covariant (
+  const VectorSlice<const std::vector<Tensor<1,1> > > input,
+  const unsigned int                 offset,
+  VectorSlice<std::vector<Tensor<1,2> > > output,
+  const Mapping<1,2>::InternalDataBase &mapping_data) const
+{
+  const InternalData *data_ptr = dynamic_cast<const InternalData *> (&mapping_data);
+  Assert(data_ptr!=0, ExcInternalError());
+  const InternalData &data=*data_ptr;
+
+  Assert (data.update_flags & update_covariant_transformation,
+         FEValuesBase<1>::ExcAccessToUninitializedField());
+
+  Assert (output.size() + offset <= input.size(), ExcInternalError());
+
+  Tensor<1,2> auxiliary;
+  auxiliary[1]=0.;
 
-template <int dim>
+  for (unsigned int i=0; i<output.size(); ++i)
+  {
+    auxiliary[0]=input[i+offset][0];
+    contract (output[i], auxiliary, data.covariant[i]);
+  }
+}
+
+template<>
 void
-MappingQ1<dim>::transform_covariant (
-  const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+MappingQ1<2,3>::transform_covariant (
+  const VectorSlice<const std::vector<Tensor<1,2> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<2,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<1,3> > > output,
+  const Mapping<2,3>::InternalDataBase &mapping_data) const
 {
   const InternalData *data_ptr = dynamic_cast<const InternalData *> (&mapping_data);
   Assert(data_ptr!=0, ExcInternalError());
   const InternalData &data=*data_ptr;
 
   Assert (data.update_flags & update_covariant_transformation,
-         typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+         FEValuesBase<2>::ExcAccessToUninitializedField());
 
   Assert (output.size() + offset <= input.size(), ExcInternalError());
 
+  Tensor<1,3> auxiliary;
+  auxiliary[2]=0.;
+    
   for (unsigned int i=0; i<output.size(); ++i)
-    contract (output[i], input[i+offset], data.covariant[i]);
+  {
+    auxiliary[0]=input[i+offset][0];
+    auxiliary[1]=input[i+offset][1];
+    contract (output[i], auxiliary, data.covariant[i]);
+  }
 }
 
+template <int dim, int spacedim>
+void
+MappingQ1<dim, spacedim>::transform_covariant (
+    const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+    const unsigned int                 offset,
+    VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+    const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data) const
+{
+    const InternalData *data_ptr = dynamic_cast<const InternalData *> (&mapping_data);
+    Assert(data_ptr!=0, ExcInternalError());
+    const InternalData &data=*data_ptr;
+
+    Assert (data.update_flags & update_covariant_transformation,
+           typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+
+    Assert (output.size() + offset <= input.size(), ExcInternalError());
 
+    for (unsigned int i=0; i<output.size(); ++i)
+       contract (output[i], input[i+offset], data.covariant[i]);
+}
 
-template <int dim>
+template <>
 void
-MappingQ1<dim>::
+MappingQ1<1, 2>::transform_covariant (
+    const VectorSlice<const std::vector<Tensor<2,1> > > ,
+    const unsigned int,
+    VectorSlice<std::vector<Tensor<2,2> > > ,
+    const Mapping<1,2>::InternalDataBase &) const
+{
+    Assert(false, ExcNotImplemented());
+}
+
+template <>
+void
+MappingQ1<2, 3>::transform_covariant (
+    const VectorSlice<const std::vector<Tensor<2,2> > > ,
+    const unsigned int,
+    VectorSlice<std::vector<Tensor<2,3> > > ,
+    const Mapping<2,3>::InternalDataBase &) const
+{
+    Assert(false, ExcNotImplemented());
+}
+
+
+template<int dim, int spacedim>
+void
+MappingQ1<dim,spacedim>::
 transform_contravariant (
-  const VectorSlice<const std::vector<Tensor<1,dim> > > input,
+  const VectorSlice<const std::vector<Tensor<1,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<1,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<1,spacedim> > > output,
+  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data) const
 {
   const InternalData* data_ptr = dynamic_cast<const InternalData *> (&mapping_data);
   Assert(data_ptr!=0, ExcInternalError());
@@ -1064,13 +1314,13 @@ transform_contravariant (
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::transform_contravariant (
-  const VectorSlice<const std::vector<Tensor<2,dim> > > input,
+MappingQ1<dim,spacedim>::transform_contravariant (
+  const VectorSlice<const std::vector<Tensor<2,spacedim> > > input,
   const unsigned int                 offset,
-  VectorSlice<std::vector<Tensor<2,dim> > > output,
-  const typename Mapping<dim>::InternalDataBase &mapping_data) const
+  VectorSlice<std::vector<Tensor<2,spacedim> > > output,
+  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data) const
 {
   const InternalData* data_ptr = dynamic_cast<const InternalData *> (&mapping_data);
   Assert(data_ptr!=0, ExcInternalError());
@@ -1087,10 +1337,10 @@ MappingQ1<dim>::transform_contravariant (
 
 
 
-template <int dim>
-Point<dim>
-MappingQ1<dim>::
-transform_unit_to_real_cell (const typename Triangulation<dim>::cell_iterator &cell,
+template<int dim, int spacedim>
+Point<spacedim>
+MappingQ1<dim,spacedim>::
+transform_unit_to_real_cell (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                              const Point<dim>                                 &p) const
 {
                                   // Use the get_data function to
@@ -1113,9 +1363,9 @@ transform_unit_to_real_cell (const typename Triangulation<dim>::cell_iterator &c
 
 
 
-template <int dim>
-Point<dim>
-MappingQ1<dim>::
+template<int dim, int spacedim>
+Point<spacedim>
+MappingQ1<dim,spacedim>::
 transform_unit_to_real_cell_internal (const InternalData &data) const
 {
   const unsigned int n_mapping_points=data.mapping_support_points.size();
@@ -1123,7 +1373,7 @@ transform_unit_to_real_cell_internal (const InternalData &data) const
   
                                   // use now the InternalData to
                                   // compute the point in real space.
-  Point<dim> p_real;
+  Point<spacedim> p_real;
   for (unsigned int i=0; i<data.mapping_support_points.size(); ++i)
     p_real += data.mapping_support_points[i] * data.shape(0,i);
 
@@ -1132,11 +1382,11 @@ transform_unit_to_real_cell_internal (const InternalData &data) const
 
 
 
-template <int dim>
+template<int dim, int spacedim>
 Point<dim>
-MappingQ1<dim>::
-transform_real_to_unit_cell (const typename Triangulation<dim>::cell_iterator &cell,
-                             const Point<dim>                                 &p) const
+MappingQ1<dim,spacedim>::
+transform_real_to_unit_cell (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+                             const Point<spacedim>                            &p) const
 {
                                   // Let the start value of the
                                   // newton iteration be the center
@@ -1154,11 +1404,11 @@ transform_real_to_unit_cell (const typename Triangulation<dim>::cell_iterator &c
   const Quadrature<dim> point_quadrature(p_unit);
   std::auto_ptr<InternalData>
     mdata(dynamic_cast<InternalData *> (
-            MappingQ1<dim>::get_data(update_transformation_values
+            MappingQ1<dim,spacedim>::get_data(update_transformation_values
                                      | update_transformation_gradients,
                                      point_quadrature)));
 
-  MappingQ1<dim>::compute_mapping_support_points (cell,
+  MappingQ1<dim,spacedim>::compute_mapping_support_points (cell,
                                                   mdata->mapping_support_points);
   Assert(mdata->mapping_support_points.size() ==
          GeometryInfo<dim>::vertices_per_cell,
@@ -1170,14 +1420,36 @@ transform_real_to_unit_cell (const typename Triangulation<dim>::cell_iterator &c
   return p_unit;
 }
 
+template<>
+void
+MappingQ1<1,2>::
+transform_real_to_unit_cell_internal
+(const Triangulation<1,2>::cell_iterator &,
+ const Point<2>                            &,
+ InternalData                                     &,
+ Point<1>                                       &) const
+{
+       Assert(false, ExcNotImplemented());
+}
+template<>
+void
+MappingQ1<2,3>::
+transform_real_to_unit_cell_internal
+(const Triangulation<2,3>::cell_iterator &,
+ const Point<3>                            &,
+ InternalData                                     &,
+ Point<2>                                       &) const
+{
+       Assert(false, ExcNotImplemented());
+}
 
 
-template <int dim>
+template<int dim, int spacedim>
 void
-MappingQ1<dim>::
+MappingQ1<dim,spacedim>::
 transform_real_to_unit_cell_internal
-(const typename Triangulation<dim>::cell_iterator &cell,
- const Point<dim>                                 &p,
+(const typename Triangulation<dim,spacedim>::cell_iterator &cell,
+ const Point<spacedim>                            &p,
  InternalData                                     &mdata,
  Point<dim>                                       &p_unit) const
 {
@@ -1185,7 +1457,7 @@ transform_real_to_unit_cell_internal
   Assert(n_shapes!=0, ExcInternalError());
   Assert(mdata.shape_derivatives.size()==n_shapes, ExcInternalError());
   
-  std::vector<Point<dim> > &points=mdata.mapping_support_points;
+  std::vector<Point<spacedim> > &points=mdata.mapping_support_points;
   Assert(points.size()==n_shapes, ExcInternalError());
   
                                   // Newton iteration to solve
@@ -1201,8 +1473,8 @@ transform_real_to_unit_cell_internal
 
   
                                   // f(x)
-  Point<dim> p_real(transform_unit_to_real_cell_internal(mdata));
-  Point<dim> f = p_real-p;
+  Point<spacedim> p_real(transform_unit_to_real_cell_internal(mdata));
+  Point<spacedim> f = p_real-p;
 
   const double eps=1e-15*cell->diameter();
   unsigned int loop=0;
@@ -1213,7 +1485,7 @@ transform_real_to_unit_cell_internal
       for (unsigned int k=0; k<mdata.n_shape_functions; ++k)
        {
          const Tensor<1,dim> &grad_transform=mdata.derivative(0,k);
-         const Point<dim> &point=points[k];
+         const Point<spacedim> &point=points[k];
          
          for (unsigned int i=0; i<dim; ++i)
            for (unsigned int j=0; j<dim; ++j)
@@ -1241,17 +1513,18 @@ transform_real_to_unit_cell_internal
 
 
 
-template <int dim>
-Mapping<dim> *
-MappingQ1<dim>::clone () const
+template<int dim, int spacedim>
+Mapping<dim,spacedim> *
+MappingQ1<dim,spacedim>::clone () const
 {
-  return new MappingQ1<dim>(*this);
+  return new MappingQ1<dim,spacedim>(*this);
 }
 
 //---------------------------------------------------------------------------
 
 
-template <int dim> MappingQ1<dim> StaticMappingQ1<dim>::mapping;
+template<int dim, int spacedim>
+MappingQ1<dim,spacedim> StaticMappingQ1<dim,spacedim>::mapping;
 
 
 
@@ -1260,6 +1533,8 @@ template <int dim> MappingQ1<dim> StaticMappingQ1<dim>::mapping;
 template class MappingQ1<deal_II_dimension>;
 template struct StaticMappingQ1<deal_II_dimension>;
 
-
-
+#if deal_II_dimension != 3
+template class MappingQ1<deal_II_dimension,deal_II_dimension+1>;
+template struct StaticMappingQ1<deal_II_dimension,deal_II_dimension+1>;
+#endif
 DEAL_II_NAMESPACE_CLOSE
index 033a0009302316b3a0e36f51aca5222bd0e68fb0..7f4f1d5ac139f7d96d32bd0980393a5d10e2a76e 100644 (file)
@@ -23,8 +23,8 @@
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int dim, class EulerVectorType>
-MappingQ1Eulerian<dim, EulerVectorType>::
+template <int dim, class EulerVectorType, int spacedim>
+MappingQ1Eulerian<dim, EulerVectorType, spacedim>::
 MappingQ1Eulerian (const EulerVectorType  &euler_transform_vectors,
                   const DoFHandler<dim> &shiftmap_dof_handler)
                      :
@@ -34,9 +34,9 @@ MappingQ1Eulerian (const EulerVectorType  &euler_transform_vectors,
 
 
 
-template <int dim, class EulerVectorType>
+template <int dim, class EulerVectorType, int spacedim>
 void
-MappingQ1Eulerian<dim, EulerVectorType>::
+MappingQ1Eulerian<dim, EulerVectorType, spacedim>::
 compute_mapping_support_points(const typename Triangulation<dim>::cell_iterator &cell,
                               std::vector<Point<dim> > &a) const
 {
@@ -106,11 +106,11 @@ compute_mapping_support_points(const typename Triangulation<dim>::cell_iterator
 
 
 
-template <int dim, class EulerVectorType>
-Mapping<dim> *
-MappingQ1Eulerian<dim, EulerVectorType>::clone () const
+template <int dim, class EulerVectorType, int spacedim>
+Mapping<dim,spacedim> *
+MappingQ1Eulerian<dim, EulerVectorType, spacedim>::clone () const
 {
-  return new MappingQ1Eulerian<dim,EulerVectorType>(*this);
+  return new MappingQ1Eulerian<dim,EulerVectorType,spacedim>(*this);
 }
 
 
index a78968ab79a64b88f9ae64bfc731c44760ac1f6b..4526338402175bd7026c2a5e3841996f83b9cd00 100644 (file)
@@ -29,13 +29,13 @@ DEAL_II_NAMESPACE_OPEN
 
 // .... MAPPING Q EULERIAN CONSTRUCTOR
 
-template <int dim, class EulerVectorType>
-MappingQEulerian<dim, EulerVectorType>::
+template <int dim, class EulerVectorType, int spacedim>
+MappingQEulerian<dim, EulerVectorType, spacedim>::
 MappingQEulerian (const unsigned int degree,
                  const EulerVectorType &euler_vector,
                  const DoFHandler<dim> &euler_dof_handler)
                :
-               MappingQ<dim>(degree, true),
+               MappingQ<dim,spacedim>(degree, true),
                euler_vector(euler_vector),
                euler_dof_handler(&euler_dof_handler),
                support_quadrature(degree),
@@ -46,11 +46,11 @@ MappingQEulerian (const unsigned int degree,
 
 
 
-template <int dim, class EulerVectorType>
-Mapping<dim> *
-MappingQEulerian<dim, EulerVectorType>::clone () const
+template <int dim, class EulerVectorType, int spacedim>
+Mapping<dim,spacedim> *
+MappingQEulerian<dim, EulerVectorType, spacedim>::clone () const
 {
-  return new MappingQEulerian<dim,EulerVectorType>(this->get_degree(),
+  return new MappingQEulerian<dim,EulerVectorType,spacedim>(this->get_degree(),
                                                   euler_vector,
                                                   *euler_dof_handler);
 }
@@ -59,8 +59,8 @@ MappingQEulerian<dim, EulerVectorType>::clone () const
 
 // .... SUPPORT QUADRATURE CONSTRUCTOR
 
-template <int dim, class EulerVectorType>
-MappingQEulerian<dim,EulerVectorType>::
+template <int dim, class EulerVectorType, int spacedim>
+MappingQEulerian<dim,EulerVectorType,spacedim>::
 SupportQuadrature::
 SupportQuadrature (const unsigned int map_degree)
                :
@@ -99,9 +99,9 @@ SupportQuadrature (const unsigned int map_degree)
 
 // .... COMPUTE MAPPING SUPPORT POINTS
 
-template <int dim, class EulerVectorType>
+template <int dim, class EulerVectorType, int spacedim>
 void
-MappingQEulerian<dim, EulerVectorType>::
+MappingQEulerian<dim, EulerVectorType, spacedim>::
 compute_mapping_support_points
 (const typename Triangulation<dim>::cell_iterator &cell,
  std::vector<Point<dim> > &a) const
index dae12f9c8595a58d67aa17569c5a49b57ca1ab8e..6ab34fb45c83ba36d058ff4f3834ba1391676887 100644 (file)
@@ -75,23 +75,23 @@ namespace
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-GridGenerator::hyper_rectangle (Triangulation<dim> &tria,
-                               const Point<dim>   &p_1,
-                               const Point<dim>   &p_2,
+GridGenerator::hyper_rectangle (Triangulation<dim,spacedim> &tria,
+                               const Point<spacedim>   &p_1,
+                               const Point<spacedim>   &p_2,
                                const bool          colorize)
 {
                                   // First, normalize input such that
                                   // p1 is lower in all coordinate directions.
-  Point<dim> p1(p_1);
-  Point<dim> p2(p_2);
+  Point<spacedim> p1(p_1);
+  Point<spacedim> p2(p_2);
   
-  for (unsigned int i=0;i<dim;++i)
+  for (unsigned int i=0;i<spacedim;++i)
     if (p1(i) > p2(i))
       std::swap (p1(i), p2(i));
   
-  std::vector<Point<dim> > vertices (GeometryInfo<dim>::vertices_per_cell);
+  std::vector<Point<spacedim> > vertices (GeometryInfo<dim>::vertices_per_cell);
   switch (dim)
     {
       case 1:
@@ -133,7 +133,7 @@ GridGenerator::hyper_rectangle (Triangulation<dim> &tria,
   tria.create_triangulation (vertices, cells, SubCellData());
 
                                   // Assign boundary indicators
-  if (colorize)
+  if (colorize && (spacedim == dim))
     colorize_hyper_rectangle (tria);
 }
 
@@ -142,9 +142,9 @@ GridGenerator::hyper_rectangle (Triangulation<dim> &tria,
 #if deal_II_dimension == 1
 
 // Implementation for 1D only
-template <int dim>
+template <int dim, int spacedim>
 void
-GridGenerator::colorize_hyper_rectangle (Triangulation<dim> &)
+GridGenerator::colorize_hyper_rectangle (Triangulation<dim,spacedim> &)
 {
                                   // Nothing to do in 1D
 }
@@ -153,13 +153,13 @@ GridGenerator::colorize_hyper_rectangle (Triangulation<dim> &)
 #else
 
 // Implementation for dimensions except 1
-template <int dim>
+template <int dim, int spacedim>
 void
-GridGenerator::colorize_hyper_rectangle (Triangulation<dim> &tria)
+GridGenerator::colorize_hyper_rectangle (Triangulation<dim,spacedim> &tria)
 {
                                   // there is only one cell, so
                                   // simple task
-  const typename Triangulation<dim>::cell_iterator cell = tria.begin();
+  const typename Triangulation<dim,spacedim>::cell_iterator cell = tria.begin();
   for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
     cell->face(f)->set_boundary_indicator (f);
 }
@@ -167,16 +167,20 @@ GridGenerator::colorize_hyper_rectangle (Triangulation<dim> &tria)
 #endif
 
 
-template <int dim>
-void GridGenerator::hyper_cube (Triangulation<dim> &tria,
+template <int dim, int spacedim>
+void GridGenerator::hyper_cube (Triangulation<dim,spacedim> &tria,
                                const double        left,
                                const double        right)
 {
   Assert (left < right,
          ExcMessage ("Invalid left and right bounds of hypercube"));
   
-  Point<dim> p1;
-  Point<dim> p2;
+  Point<spacedim> p1;
+  Point<spacedim> p2;
+
+  p1(spacedim-1) = 0;
+  p2(spacedim-1) = 0;
+
   for (unsigned int i=0;i<dim;++i)
     {
       p1(i) = left;
@@ -2799,4 +2803,18 @@ GridGenerator::
 laplace_transformation<deal_II_dimension> (Triangulation<deal_II_dimension> &,
                                           const std::map<unsigned int,Point<deal_II_dimension> > &);
 
+#if deal_II_dimension != 3
+
+template void
+GridGenerator::hyper_cube<deal_II_dimension, deal_II_dimension+1> (
+  Triangulation<deal_II_dimension,deal_II_dimension+1> &, const double, const double);
+template void
+GridGenerator::hyper_rectangle<deal_II_dimension,deal_II_dimension+1> (
+  Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+  const Point<deal_II_dimension+1>&, const Point<deal_II_dimension+1>&,
+  const bool);
+
+#endif
+
+
 DEAL_II_NAMESPACE_CLOSE
index 90b9098225a9bb0327a175a2a23a68b0cc349b09..b059e1016773f1bdfc2bf819907c6f14d606a2b7 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int dim>
-GridIn<dim>::GridIn () :
+template <int dim, int spacedim>
+GridIn<dim, spacedim>::GridIn () :
                tria(0), default_format(ucd)
 {}
 
 
-template <int dim>
-void GridIn<dim>::attach_triangulation (Triangulation<dim> &t)
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::attach_triangulation (Triangulation<dim, spacedim> &t)
 {
   tria = &t;
 }
 
 
-template <int dim>
-void GridIn<dim>::read_ucd (std::istream &in)
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::read_ucd (std::istream &in)
 {
   Assert (tria != 0, ExcNoTriangulationSelected());
   AssertThrow (in, ExcIO());
@@ -64,7 +64,7 @@ void GridIn<dim>::read_ucd (std::istream &in)
      >> dummy;        // model data
 
                                   // set up array of vertices
-  std::vector<Point<dim> >     vertices (n_vertices);
+  std::vector<Point<spacedim> >     vertices (n_vertices);
                                   // set up mapping between numbering
                                   // in ucd-file (key) and in the
                                   // vertices vector
@@ -80,7 +80,7 @@ void GridIn<dim>::read_ucd (std::istream &in)
         >> x[0] >> x[1] >> x[2];
 
                                       // store vertex
-      for (unsigned int d=0; d<dim; ++d)
+      for (unsigned int d=0; d<spacedim; ++d)
        vertices[vertex](d) = x[d];
                                       // store mapping; note that
                                       // vertices_indices[i] is automatically
@@ -204,15 +204,16 @@ void GridIn<dim>::read_ucd (std::istream &in)
                                   // do some clean-up on vertices...
   GridTools::delete_unused_vertices (vertices, cells, subcelldata);
                                   // ... and cells
-  GridReordering<dim>::invert_all_cells_of_negative_grid (vertices, cells);
-  GridReordering<dim>::reorder_cells (cells);
+  if(dim==spacedim)
+    GridReordering<dim,spacedim>::invert_all_cells_of_negative_grid (vertices, cells);
+  GridReordering<dim,spacedim>::reorder_cells (cells);
   tria->create_triangulation_compatibility (vertices, cells, subcelldata);
 }
 
 
 
-template <int dim>
-void GridIn<dim>::read_dbmesh (std::istream &in)
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::read_dbmesh (std::istream &in)
 {
   Assert (tria != 0, ExcNoTriangulationSelected());
   Assert (dim==2, ExcNotImplemented());
@@ -264,7 +265,7 @@ void GridIn<dim>::read_dbmesh (std::istream &in)
   double dummy;
   
   in >> n_vertices;
-  std::vector<Point<dim> >     vertices (n_vertices);
+  std::vector<Point<spacedim> >     vertices (n_vertices);
   for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
     {
                                       // read vertex coordinates
@@ -371,15 +372,15 @@ void GridIn<dim>::read_dbmesh (std::istream &in)
                                   // do some clean-up on vertices...
   GridTools::delete_unused_vertices (vertices, cells, subcelldata);
                                   // ...and cells
-  GridReordering<dim>::invert_all_cells_of_negative_grid (vertices, cells);
-  GridReordering<dim>::reorder_cells (cells);
+  GridReordering<dim,spacedim>::invert_all_cells_of_negative_grid (vertices, cells);
+  GridReordering<dim,spacedim>::reorder_cells (cells);
   tria->create_triangulation_compatibility (vertices, cells, subcelldata);
 }
 
 
 
-template <int dim>
-void GridIn<dim>::read_xda (std::istream &)
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::read_xda (std::istream &)
 {
   Assert (false, ExcNotImplemented());
 }
@@ -545,8 +546,8 @@ void GridIn<3>::read_xda (std::istream &in)
 
 
 
-template <int dim>
-void GridIn<dim>::read_msh (std::istream &in)
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::read_msh (std::istream &in)
 {
   Assert (tria != 0, ExcNoTriangulationSelected());
   AssertThrow (in, ExcIO());
@@ -597,7 +598,7 @@ void GridIn<dim>::read_msh (std::istream &in)
   
                                   // now read the nodes list
   in >> n_vertices;
-  std::vector<Point<dim> >     vertices (n_vertices);
+  std::vector<Point<spacedim> >     vertices (n_vertices);
                                   // set up mapping between numbering
                                   // in msh-file (nod) and in the
                                   // vertices vector
@@ -612,7 +613,7 @@ void GridIn<dim>::read_msh (std::istream &in)
       in >> vertex_number
         >> x[0] >> x[1] >> x[2];
      
-      for (unsigned int d=0; d<dim; ++d)
+      for (unsigned int d=0; d<spacedim; ++d)
        vertices[vertex](d) = x[d];
                                       // store mapping
       vertex_indices[vertex_number] = vertex;
@@ -827,8 +828,9 @@ void GridIn<dim>::read_msh (std::istream &in)
                                   // do some clean-up on vertices...
   GridTools::delete_unused_vertices (vertices, cells, subcelldata);
                                   // ... and cells
-  GridReordering<dim>::invert_all_cells_of_negative_grid (vertices, cells);
-  GridReordering<dim>::reorder_cells (cells);
+  if(dim==spacedim)
+    GridReordering<dim,spacedim>::invert_all_cells_of_negative_grid (vertices, cells);
+  GridReordering<dim,spacedim>::reorder_cells (cells);
   tria->create_triangulation_compatibility (vertices, cells, subcelldata);
 }
 
@@ -841,12 +843,23 @@ void GridIn<1>::read_netcdf (const std::string &)
   AssertThrow(false, ExcImpossibleInDim(1));
 }
 
+template <>
+void GridIn<1,2>::read_netcdf (const std::string &)
+{
+  AssertThrow(false, ExcImpossibleInDim(1));
+}
+
 #endif
 
 
 
 #if deal_II_dimension == 2
 
+template <>
+void GridIn<2, 3>::read_netcdf (const std::string &) {
+    Assert(false, ExcNotImplemented());
+}
+
 template <>
 void GridIn<2>::read_netcdf (const std::string &filename)
 {
@@ -857,6 +870,7 @@ void GridIn<2>::read_netcdf (const std::string &filename)
   AssertThrow(false, ExcNeedsNetCDF());
 #else
   const unsigned int dim=2;
+  const unsigned int spacedim=2;
   const bool output=false;
   Assert (tria != 0, ExcNoTriangulationSelected());
                                   // this function assumes the TAU
@@ -1049,7 +1063,7 @@ void GridIn<2>::read_netcdf (const std::string &filename)
   points_zc->get(&*point_values[2].begin(), n_vertices);
 
                                   // and fill the vertices
-  std::vector<Point<dim> > vertices (n_vertices);
+  std::vector<Point<spacedim> > vertices (n_vertices);
   for (unsigned int i=0; i<n_vertices; ++i)
     {
       vertices[i](0)=point_values[x2d][i];
@@ -1112,7 +1126,7 @@ void GridIn<2>::read_netcdf (const std::string &filename)
 
   SubCellData subcelldata;
   GridTools::delete_unused_vertices(vertices, cells, subcelldata);
-  GridReordering<dim>::reorder_cells (cells);
+  GridReordering<dim,spacedim>::reorder_cells (cells);
   tria->create_triangulation_compatibility (vertices, cells, subcelldata);  
 #endif
 }
@@ -1132,6 +1146,7 @@ void GridIn<3>::read_netcdf (const std::string &filename)
   AssertThrow(false, ExcNeedsNetCDF());
 #else
   const unsigned int dim=3;
+  const unsigned int spacedim=3;
   const bool output=false;
   Assert (tria != 0, ExcNoTriangulationSelected());
                                   // this function assumes the TAU
@@ -1232,7 +1247,7 @@ void GridIn<3>::read_netcdf (const std::string &filename)
     }
 
                                   // and fill the vertices
-  std::vector<Point<dim> > vertices (n_vertices);
+  std::vector<Point<spacedim> > vertices (n_vertices);
   for (unsigned int i=0; i<n_vertices; ++i)
     {
       vertices[i](0)=point_values[0][i];
@@ -1320,16 +1335,16 @@ void GridIn<3>::read_netcdf (const std::string &filename)
     }
 
   GridTools::delete_unused_vertices(vertices, cells, subcelldata);
-  GridReordering<dim>::invert_all_cells_of_negative_grid (vertices, cells);
-  GridReordering<dim>::reorder_cells (cells);
+  GridReordering<dim,spacedim>::invert_all_cells_of_negative_grid (vertices, cells);
+  GridReordering<dim,spacedim>::reorder_cells (cells);
   tria->create_triangulation_compatibility (vertices, cells, subcelldata);  
 #endif
 }
 
 #endif
 
-template <int dim>
-void GridIn<dim>::parse_tecplot_header(std::string &header,
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::parse_tecplot_header(std::string &header,
                                       std::vector<unsigned int> &tecplot2deal,
                                       unsigned int &n_vars,
                                       unsigned int &n_vertices,
@@ -1533,6 +1548,7 @@ template <>
 void GridIn<2>::read_tecplot (std::istream &in)
 {
   const unsigned int dim=2;
+  const unsigned int spacedim=2;
   Assert (tria != 0, ExcNoTriangulationSelected());
   AssertThrow (in, ExcIO());
   
@@ -1577,8 +1593,8 @@ void GridIn<2>::read_tecplot (std::istream &in)
                                   // with 0. in order not to use -1 for all the
                                   // connectivity information, a 0th vertex
                                   // (unused) is inserted at the origin.
-  std::vector<Point<dim> > vertices(n_vertices+1);
-  vertices[0]=Point<dim>();
+  std::vector<Point<spacedim> > vertices(n_vertices+1);
+  vertices[0]=Point<spacedim>();
                                   // reserve space for cells
   std::vector<CellData<dim> > cells(n_cells);
   SubCellData                 subcelldata;
@@ -1753,22 +1769,22 @@ void GridIn<2>::read_tecplot (std::istream &in)
   AssertThrow (in, ExcIO());
 
                                   // do some cleanup on cells
-  GridReordering<dim>::invert_all_cells_of_negative_grid (vertices, cells);
-  GridReordering<dim>::reorder_cells (cells);
+  GridReordering<dim,spacedim>::invert_all_cells_of_negative_grid (vertices, cells);
+  GridReordering<dim,spacedim>::reorder_cells (cells);
   tria->create_triangulation_compatibility (vertices, cells, subcelldata);
 }
 
 #endif
 
-template <int dim>
-void GridIn<dim>::read_tecplot(std::istream &)
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::read_tecplot(std::istream &)
 {
   Assert(false, ExcNotImplemented());
 }
 
 
-template <int dim>
-void GridIn<dim>::skip_empty_lines (std::istream &in)
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::skip_empty_lines (std::istream &in)
 {    
   std::string line;
   while (in) 
@@ -1795,8 +1811,8 @@ void GridIn<dim>::skip_empty_lines (std::istream &in)
 
 
 
-template <int dim>
-void GridIn<dim>::skip_comment_lines (std::istream &in,
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::skip_comment_lines (std::istream &in,
                                      const char    comment_start)
 {
   char c;
@@ -1819,9 +1835,9 @@ void GridIn<dim>::skip_comment_lines (std::istream &in,
 
 
 
-template <int dim>
-void GridIn<dim>::debug_output_grid (const std::vector<CellData<dim> > &/*cells*/,
-                                    const std::vector<Point<dim> >    &/*vertices*/,
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::debug_output_grid (const std::vector<CellData<dim> > &/*cells*/,
+                                    const std::vector<Point<spacedim> >    &/*vertices*/,
                                     std::ostream                      &/*out*/)
 {
   Assert (false, ExcNotImplemented());
@@ -1976,8 +1992,8 @@ GridIn<3>::debug_output_grid (const std::vector<CellData<3> > &cells,
 
 #endif
 
-template <int dim>
-void GridIn<dim>::read (const std::string& filename,
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::read (const std::string& filename,
                        Format format)
 {
                                   // Search file class for meshes
@@ -2009,8 +2025,8 @@ void GridIn<dim>::read (const std::string& filename,
 }
 
 
-template <int dim>
-void GridIn<dim>::read (std::istream& in,
+template <int dim, int spacedim>
+void GridIn<dim, spacedim>::read (std::istream& in,
                        Format format)
 {
   if (format == Default)
@@ -2052,9 +2068,9 @@ void GridIn<dim>::read (std::istream& in,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 std::string
-GridIn<dim>::default_suffix (const Format format) 
+GridIn<dim, spacedim>::default_suffix (const Format format) 
 {
   switch (format) 
     {
@@ -2078,9 +2094,9 @@ GridIn<dim>::default_suffix (const Format format)
 
 
 
-template <int dim>
-typename GridIn<dim>::Format
-GridIn<dim>::parse_format (const std::string &format_name)
+template <int dim, int spacedim>
+typename GridIn<dim, spacedim>::Format
+GridIn<dim, spacedim>::parse_format (const std::string &format_name)
 {
   if (format_name == "dbmesh")
     return dbmesh;
@@ -2128,8 +2144,8 @@ GridIn<dim>::parse_format (const std::string &format_name)
 
 
 
-template <int dim>
-std::string GridIn<dim>::get_format_names () 
+template <int dim, int spacedim>
+std::string GridIn<dim, spacedim>::get_format_names () 
 {
   return "dbmesh|msh|ucd|xda|netcdf|tecplot";
 }
@@ -2139,4 +2155,8 @@ std::string GridIn<dim>::get_format_names ()
 //explicit instantiations
 template class GridIn<deal_II_dimension>;
 
+#if deal_II_dimension != 3
+template class GridIn<deal_II_dimension, deal_II_dimension+1>;
+#endif
+
 DEAL_II_NAMESPACE_CLOSE
index e235c896b68103b59199156823639f29a9d81e6f..75a72c5fd15f149e61245c4b8e68890cd79517cc 100644 (file)
@@ -281,8 +281,8 @@ void GridOut::write_dx (const Triangulation<dim> &tria,
 #endif
 
 
-template <int dim>
-void GridOut::write_msh (const Triangulation<dim> &tria,
+template <int dim, int spacedim>
+void GridOut::write_msh (const Triangulation<dim, spacedim> &tria,
                         std::ostream             &out) const
 {
   AssertThrow (out, ExcIO());
@@ -290,13 +290,13 @@ void GridOut::write_msh (const Triangulation<dim> &tria,
                                   // get the positions of the
                                   // vertices and whether they are
                                   // used.
-  const std::vector<Point<dim> > &vertices    = tria.get_vertices();
+  const std::vector<Point<spacedim> > &vertices    = tria.get_vertices();
   const std::vector<bool>        &vertex_used = tria.get_used_vertices();
   
   const unsigned int n_vertices = tria.n_used_vertices();
 
-  typename Triangulation<dim>::active_cell_iterator       cell=tria.begin_active();
-  const typename Triangulation<dim>::active_cell_iterator endc=tria.end();
+  typename Triangulation<dim,spacedim>::active_cell_iterator       cell=tria.begin_active();
+  const typename Triangulation<dim,spacedim>::active_cell_iterator endc=tria.end();
 
                                   // Write Header
                                   // The file format is:
@@ -326,7 +326,7 @@ void GridOut::write_msh (const Triangulation<dim> &tria,
        out << i+1                 // vertex index
            << "  "
            << vertices[i];
-       for (unsigned int d=dim+1; d<=3; ++d)
+       for (unsigned int d=spacedim+1; d<=3; ++d)
          out << " 0";             // fill with zeroes
        out << std::endl;
       };
@@ -424,8 +424,8 @@ void GridOut::write_msh (const Triangulation<dim> &tria,
 }
 
 
-template <int dim>
-void GridOut::write_ucd (const Triangulation<dim> &tria,
+template <int dim, int spacedim>
+void GridOut::write_ucd (const Triangulation<dim,spacedim> &tria,
                         std::ostream             &out) const
 {
   AssertThrow (out, ExcIO());
@@ -433,13 +433,13 @@ void GridOut::write_ucd (const Triangulation<dim> &tria,
                                   // get the positions of the
                                   // vertices and whether they are
                                   // used.
-  const std::vector<Point<dim> > &vertices    = tria.get_vertices();
-  const std::vector<bool>        &vertex_used = tria.get_used_vertices();
+  const std::vector<Point<spacedim> > &vertices    = tria.get_vertices();
+  const std::vector<bool>             &vertex_used = tria.get_used_vertices();
 
   const unsigned int n_vertices = tria.n_used_vertices();
 
-  typename Triangulation<dim>::active_cell_iterator       cell=tria.begin_active();
-  const typename Triangulation<dim>::active_cell_iterator endc=tria.end();
+  typename Triangulation<dim,spacedim>::active_cell_iterator       cell=tria.begin_active();
+  const typename Triangulation<dim,spacedim>::active_cell_iterator endc=tria.end();
 
                                   // write preamble
   if (ucd_flags.write_preamble)
@@ -482,7 +482,7 @@ void GridOut::write_ucd (const Triangulation<dim> &tria,
        out << i+1                 // vertex index
            << "  "
            << vertices[i];
-       for (unsigned int d=dim+1; d<=3; ++d)
+       for (unsigned int d=spacedim+1; d<=3; ++d)
          out << " 0";             // fill with zeroes
        out << '\n';
       };
@@ -700,6 +700,16 @@ unsigned int GridOut::n_boundary_lines (const Triangulation<1> &) const
   return 0;
 }
 
+
+unsigned int GridOut::n_boundary_faces (const Triangulation<1,2> &) const
+{
+  return 0;
+}
+
+unsigned int GridOut::n_boundary_lines (const Triangulation<1,2> &) const
+{
+  return 0;
+}
 #endif
 
 
@@ -710,14 +720,18 @@ unsigned int GridOut::n_boundary_lines (const Triangulation<2> &) const
   return 0;
 }
 
+unsigned int GridOut::n_boundary_lines (const Triangulation<2,3> &) const
+{
+  return 0;
+}
 #endif
 
 
 
-template <int dim>
-unsigned int GridOut::n_boundary_faces (const Triangulation<dim> &tria) const
+template <int dim, int spacedim>
+unsigned int GridOut::n_boundary_faces (const Triangulation<dim,spacedim> &tria) const
 {
-  typename Triangulation<dim>::active_face_iterator face, endf;
+    typename Triangulation<dim,spacedim>::active_face_iterator face, endf;
   unsigned int n_faces = 0;
 
   for (face=tria.begin_active_face(), endf=tria.end_face();
@@ -731,10 +745,10 @@ unsigned int GridOut::n_boundary_faces (const Triangulation<dim> &tria) const
 
 
 
-template <int dim>
-unsigned int GridOut::n_boundary_lines (const Triangulation<dim> &tria) const
+template <int dim, int spacedim>
+unsigned int GridOut::n_boundary_lines (const Triangulation<dim, spacedim> &tria) const
 {
-  typename Triangulation<dim>::active_line_iterator edge, endedge;
+    typename Triangulation<dim, spacedim>::active_line_iterator edge, endedge;
   unsigned int n_lines = 0;
 
   for (edge=tria.begin_active_line(), endedge=tria.end_line();
@@ -758,6 +772,14 @@ void GridOut::write_msh_faces (const Triangulation<1> &,
 }
 
 
+void GridOut::write_msh_faces (const Triangulation<1,2> &,
+                              const unsigned int,
+                              std::ostream &) const
+{
+  return;
+}
+
+
 void GridOut::write_msh_lines (const Triangulation<1> &,
                               const unsigned int,
                               std::ostream &) const
@@ -765,6 +787,13 @@ void GridOut::write_msh_lines (const Triangulation<1> &,
   return;
 }
 
+void GridOut::write_msh_lines (const Triangulation<1,2> &,
+                              const unsigned int,
+                              std::ostream &) const
+{
+  return;
+}
+
 #endif
 
 
@@ -777,16 +806,23 @@ void GridOut::write_msh_lines (const Triangulation<2> &,
   return;
 }
 
+void GridOut::write_msh_lines (const Triangulation<2,3> &,
+                              const unsigned int,
+                              std::ostream &) const
+{
+  return;
+}
+
 #endif
 
 
 
-template <int dim>
-void GridOut::write_msh_faces (const Triangulation<dim> &tria,
+template <int dim, int spacedim>
+void GridOut::write_msh_faces (const Triangulation<dim,spacedim> &tria,
                               const unsigned int        starting_index,
                               std::ostream             &out) const
 {
-  typename Triangulation<dim>::active_face_iterator face, endf;
+    typename Triangulation<dim,spacedim>::active_face_iterator face, endf;
   unsigned int index=starting_index;
 
   for (face=tria.begin_active_face(), endf=tria.end_face();
@@ -817,12 +853,12 @@ void GridOut::write_msh_faces (const Triangulation<dim> &tria,
 }
 
 
-template <int dim>
-void GridOut::write_msh_lines (const Triangulation<dim> &tria,
+template <int dim, int spacedim>
+void GridOut::write_msh_lines (const Triangulation<dim, spacedim> &tria,
                               const unsigned int        starting_index,
                               std::ostream             &out) const
 {
-  typename Triangulation<dim>::active_line_iterator line, endl;
+    typename Triangulation<dim,spacedim>::active_line_iterator line, endl;
   unsigned int index=starting_index;
 
   for (line=tria.begin_active_line(), endl=tria.end_line();
@@ -856,6 +892,12 @@ void GridOut::write_ucd_faces (const Triangulation<1> &,
   return;
 }
 
+void GridOut::write_ucd_faces (const Triangulation<1,2> &,
+                              const unsigned int,
+                              std::ostream &) const
+{
+  return;
+}
 
 void GridOut::write_ucd_lines (const Triangulation<1> &,
                               const unsigned int,
@@ -864,6 +906,13 @@ void GridOut::write_ucd_lines (const Triangulation<1> &,
   return;
 }
 
+void GridOut::write_ucd_lines (const Triangulation<1,2> &,
+                              const unsigned int,
+                              std::ostream &) const
+{
+  return;
+}
+
 #endif
 
 
@@ -877,16 +926,23 @@ void GridOut::write_ucd_lines (const Triangulation<2> &,
   return;
 }
 
+void GridOut::write_ucd_lines (const Triangulation<2,3> &,
+                              const unsigned int,
+                              std::ostream &) const
+{
+  return;
+}
+
 #endif
 
 
 
-template <int dim>
-void GridOut::write_ucd_faces (const Triangulation<dim> &tria,
+template <int dim, int spacedim>
+void GridOut::write_ucd_faces (const Triangulation<dim, spacedim> &tria,
                               const unsigned int        starting_index,
                               std::ostream             &out) const
 {
-  typename Triangulation<dim>::active_face_iterator face, endf;
+    typename Triangulation<dim,spacedim>::active_face_iterator face, endf;
   unsigned int index=starting_index;
 
   for (face=tria.begin_active_face(), endf=tria.end_face();
@@ -915,12 +971,12 @@ void GridOut::write_ucd_faces (const Triangulation<dim> &tria,
 
 
 
-template <int dim>
-void GridOut::write_ucd_lines (const Triangulation<dim> &tria,
+template <int dim, int spacedim>
+void GridOut::write_ucd_lines (const Triangulation<dim, spacedim> &tria,
                               const unsigned int        starting_index,
                               std::ostream             &out) const
 {
-  typename Triangulation<dim>::active_line_iterator line, endl;
+    typename Triangulation<dim, spacedim>::active_line_iterator line, endl;
   unsigned int index=starting_index;
 
   for (line=tria.begin_active_line(), endl=tria.end_line();
@@ -1801,12 +1857,12 @@ void GridOut::write_eps (
 #endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 void GridOut::write (
-  const Triangulation<dim> &tria,
+    const Triangulation<dim, spacedim> &tria,
   std::ostream             &out,
   const OutputFormat        output_format,
-  const Mapping<dim>       *mapping) const
+  const Mapping<dim,spacedim>       *mapping) const
 {
   switch (output_format)
     {
@@ -1842,11 +1898,11 @@ void GridOut::write (
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void GridOut::write (
-  const Triangulation<dim> &tria,
+    const Triangulation<dim, spacedim> &tria,
   std::ostream             &out,
-  const Mapping<dim>       *mapping) const
+  const Mapping<dim,spacedim>       *mapping) const
 {
   write(tria, out, default_format, mapping);
 }
@@ -1864,24 +1920,34 @@ template void GridOut::write_msh
 template void GridOut::write_xfig
 (const Triangulation<deal_II_dimension>&,
  std::ostream&,
- const Mapping<deal_II_dimension>*) const;
+ const Mapping<deal_II_dimension,deal_II_dimension>*) const;
 template void GridOut::write_gnuplot
 (const Triangulation<deal_II_dimension>&,
  std::ostream&,
- const Mapping<deal_II_dimension>*) const;
+ const Mapping<deal_II_dimension,deal_II_dimension>*) const;
 template void GridOut::write_ucd<deal_II_dimension>
 (const Triangulation<deal_II_dimension> &,
  std::ostream &) const;
 template void GridOut::write_eps<deal_II_dimension>
 (const Triangulation<deal_II_dimension> &,
  std::ostream &,
- const Mapping<deal_II_dimension> *) const;
+ const Mapping<deal_II_dimension,deal_II_dimension> *) const;
 template void GridOut::write<deal_II_dimension>
 (const Triangulation<deal_II_dimension> &,
  std::ostream &, const OutputFormat,
- const Mapping<deal_II_dimension> *) const;
+ const Mapping<deal_II_dimension,deal_II_dimension> *) const;
 template void GridOut::write<deal_II_dimension>
 (const Triangulation<deal_II_dimension> &,
- std::ostream &, const Mapping<deal_II_dimension> *) const;
+ std::ostream &, const Mapping<deal_II_dimension,deal_II_dimension> *) const;
+
+#if deal_II_dimension == 1 || deal_II_dimension ==2
+// explicit instantiations for codimension one
+template void GridOut::write_msh
+(const Triangulation<deal_II_dimension, deal_II_dimension+1>&,
+ std::ostream&) const;
+template void GridOut::write_ucd
+(const Triangulation<deal_II_dimension, deal_II_dimension+1> &,
+ std::ostream &) const;
+#endif
 
 DEAL_II_NAMESPACE_CLOSE
index 4d29f5353d95e3d4a90e9dc4dfafd037ac4e3190..e6b0922c1c60d613b2617653408b434188cd1106 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -100,49 +100,62 @@ namespace
 }
 
 
-template <class Vector>
-void GridRefinement::qsort_index (const Vector              &a,
-                                  std::vector<unsigned int> &ind,
-                                  int                        l,
-                                  int                        r)
+namespace
 {
-  int i,j;
-  typename Vector::value_type v;
+                                  /**
+                                   * Sorts the vector @p ind as an
+                                   * index vector of @p a in
+                                   * increasing order.  This
+                                   * implementation of quicksort
+                                   * seems to be faster than the
+                                   * STL version and is needed in
+                                   * @p refine_and_coarsen_optimize
+                                   */
+
+  template <class Vector>
+  void qsort_index (const Vector              &a,
+                   std::vector<unsigned int> &ind,
+                   int                        l,
+                   int                        r)
+  {
+    int i,j;
+    typename Vector::value_type v;
   
-  if (r<=l)
-    return;
+    if (r<=l)
+      return;
 
-  v = a(ind[r]);
-  i = l-1;
-  j = r;
-  do
-    {
-      do 
-       {
-         ++i;
-       }
-      while ((a(ind[i])>v) && (i<r));
-      do
-       {
-         --j;
-       }
-      while ((a(ind[j])<v) && (j>0));
+    v = a(ind[r]);
+    i = l-1;
+    j = r;
+    do
+      {
+       do 
+         {
+           ++i;
+         }
+       while ((a(ind[i])>v) && (i<r));
+       do
+         {
+           --j;
+         }
+       while ((a(ind[j])<v) && (j>0));
       
-      if (i<j)
-        std::swap (ind[i], ind[j]);
-      else
-        std::swap (ind[i], ind[r]);
-    }
-  while (i<j);
-  qsort_index(a,ind,l,i-1);
-  qsort_index(a,ind,i+1,r);  
+       if (i<j)
+         std::swap (ind[i], ind[j]);
+       else
+         std::swap (ind[i], ind[r]);
+      }
+    while (i<j);
+    qsort_index(a,ind,l,i-1);
+    qsort_index(a,ind,i+1,r);  
+  }
 }
 
 
 
 
-template <int dim, class Vector>
-void GridRefinement::refine (Triangulation<dim> &tria,
+template <int dim, class Vector, int spacedim>
+void GridRefinement::refine (Triangulation<dim,spacedim> &tria,
                             const Vector       &criteria,
                             const double        threshold)
 {
@@ -156,7 +169,7 @@ void GridRefinement::refine (Triangulation<dim> &tria,
   if (criteria.all_zero())
     return;
   
-  typename Triangulation<dim>::active_cell_iterator cell = tria.begin_active();
+  typename Triangulation<dim,spacedim>::active_cell_iterator cell = tria.begin_active();
   const unsigned int n_cells = criteria.size();
 
   double new_threshold=threshold;
@@ -179,8 +192,8 @@ void GridRefinement::refine (Triangulation<dim> &tria,
 
 
 
-template <int dim, class Vector>
-void GridRefinement::coarsen (Triangulation<dim> &tria,
+template <int dim, class Vector, int spacedim>
+void GridRefinement::coarsen (Triangulation<dim,spacedim> &tria,
                              const Vector       &criteria,
                              const double        threshold)
 {
@@ -188,7 +201,7 @@ void GridRefinement::coarsen (Triangulation<dim> &tria,
          ExcDimensionMismatch(criteria.size(), tria.n_active_cells()));
   Assert (criteria.is_non_negative (), ExcInvalidParameterValue());
 
-  typename Triangulation<dim>::active_cell_iterator cell = tria.begin_active();
+  typename Triangulation<dim,spacedim>::active_cell_iterator cell = tria.begin_active();
   const unsigned int n_cells = criteria.size();
   
   for (unsigned int index=0; index<n_cells; ++cell, ++index)
@@ -199,9 +212,9 @@ void GridRefinement::coarsen (Triangulation<dim> &tria,
 
 
 
-template <int dim, class Vector>
+template <int dim, class Vector, int spacedim>
 void
-GridRefinement::refine_and_coarsen_fixed_number (Triangulation<dim> &tria,
+GridRefinement::refine_and_coarsen_fixed_number (Triangulation<dim,spacedim> &tria,
                                                 const Vector       &criteria,
                                                 const double        top_fraction,
                                                 const double        bottom_fraction,
@@ -304,9 +317,9 @@ GridRefinement::refine_and_coarsen_fixed_number (Triangulation<dim> &tria,
 
 
 
-template <int dim, class Vector>
+template <int dim, class Vector, int spacedim>
 void
-GridRefinement::refine_and_coarsen_fixed_fraction (Triangulation<dim> &tria,
+GridRefinement::refine_and_coarsen_fixed_fraction (Triangulation<dim,spacedim> &tria,
                                                   const Vector       &criteria,
                                                   const double        top_fraction,
                                                   const double        bottom_fraction,
@@ -433,9 +446,9 @@ GridRefinement::refine_and_coarsen_fixed_fraction (Triangulation<dim> &tria,
 
 
 
-template <int dim, class Vector>
+template <int dim, class Vector, int spacedim>
 void
-GridRefinement::refine_and_coarsen_optimize (Triangulation<dim> &tria,
+GridRefinement::refine_and_coarsen_optimize (Triangulation<dim,spacedim> &tria,
                                             const Vector       &criteria)
 {
   Assert (criteria.size() == tria.n_active_cells(),
@@ -604,6 +617,132 @@ refine_and_coarsen_optimize (Triangulation<deal_II_dimension> &,
                              const PETScWrappers::Vector &);
 #endif
 
+//<<<<<<< .working
+
+
+#if deal_II_dimension != 3
+// explicit instantiations
+template
+void
+GridRefinement::
+refine (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+        const Vector<float> &,
+        const double);
+
+template
+void
+GridRefinement::
+refine (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+        const Vector<double> &,
+        const double);
+
+template
+void
+GridRefinement::
+coarsen (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+         const Vector<float> &,
+         const double);
+
+template
+void
+GridRefinement::
+coarsen (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+         const Vector<double> &,
+         const double);
+
+
+template
+void
+GridRefinement::
+refine_and_coarsen_fixed_number (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+                                 const Vector<double> &,
+                                 const double,
+                                 const double,
+                                const unsigned int);
+
+template
+void
+GridRefinement::
+refine_and_coarsen_fixed_number (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+                                 const Vector<float> &,
+                                 const double,
+                                 const double,
+                                const unsigned int);
+
+template
+void
+GridRefinement::
+refine_and_coarsen_fixed_fraction (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+                                   const Vector<double> &,
+                                   const double,
+                                   const double,
+                                  const unsigned int);
+
+template
+void
+GridRefinement::
+refine_and_coarsen_fixed_fraction (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+                                   const Vector<float> &,
+                                   const double,
+                                   const double,
+                                  const unsigned int);
+
+template
+void
+GridRefinement::
+refine_and_coarsen_optimize (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+                             const Vector<float> &);
+
+template
+void
+GridRefinement::
+refine_and_coarsen_optimize (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+                             const Vector<double> &);
+
+#ifdef DEAL_II_USE_PETSC
+template
+void
+GridRefinement::
+refine (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+        const PETScWrappers::Vector &,
+        const double);
+
+template
+void
+GridRefinement::
+coarsen (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+         const PETScWrappers::Vector &,
+         const double);
+
+
+template
+void
+GridRefinement::
+refine_and_coarsen_fixed_number (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+                                 const PETScWrappers::Vector &,
+                                 const double,
+                                 const double,
+                                const unsigned int);
+
+template
+void
+GridRefinement::
+refine_and_coarsen_fixed_fraction (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+                                   const PETScWrappers::Vector &,
+                                   const double,
+                                   const double,
+                                  const unsigned int);
+
+template
+void
+GridRefinement::
+refine_and_coarsen_optimize (Triangulation<deal_II_dimension,deal_II_dimension+1> &,
+                             const PETScWrappers::Vector &);
+#endif
+
+#endif
+
+//=======
 
 #ifdef DEAL_II_USE_TRILINOS
 template
index 4595e6ec0a37657eed16a97860de098a51af208e..ac74fcb43df28883a67ef59a6837208d7f1ad692 100644 (file)
@@ -43,6 +43,23 @@ GridReordering<1>::invert_all_cells_of_negative_grid(const std::vector<Point<1>
                                   // nothing to be done in 1d
 }
 
+template<>
+void
+GridReordering<1,2>::reorder_cells (std::vector<CellData<1> > &)
+{
+                                  // there should not be much to do
+                                  // in 1d...
+}
+
+
+template<>
+void
+GridReordering<1,2>::invert_all_cells_of_negative_grid(const std::vector<Point<2> > &,
+                                                    std::vector<CellData<1> > &)
+{
+                                  // nothing to be done in 1d
+}
+
 #endif
 
 
@@ -566,6 +583,8 @@ namespace internal
 } // namespace internal
 
 
+
+
 template<>
 void
 GridReordering<2>::reorder_cells (std::vector<CellData<2> > &original_cells)
@@ -581,6 +600,12 @@ GridReordering<2>::reorder_cells (std::vector<CellData<2> > &original_cells)
 }
 
 
+template<>
+void
+GridReordering<2,3>::reorder_cells (std::vector<CellData<2> > &original_cells) {
+    GridReordering<2>::reorder_cells(original_cells);
+}
+
 template<>
 void
 GridReordering<2>::invert_all_cells_of_negative_grid(const std::vector<Point<2> > &all_vertices,
@@ -622,8 +647,16 @@ GridReordering<2>::invert_all_cells_of_negative_grid(const std::vector<Point<2>
   AssertThrow(n_negative_cells==0 || n_negative_cells==cells.size(), ExcInternalError());
 }
 
-#endif // deal_II_dimension == 2
 
+template<>
+void
+GridReordering<2,3>::invert_all_cells_of_negative_grid(const std::vector<Point<3> > &,
+                                                    std::vector<CellData<2> >    &)
+{
+  Assert(false, ExcNotImplemented());
+}
+
+#endif
 
 
 #if deal_II_dimension == 3
index b534ab5b81c232173482c073b1ccbc4a6e40d7e6..b7962c11368091a70ab91e25035c44db953e67c1 100644 (file)
@@ -40,14 +40,14 @@ DEAL_II_NAMESPACE_OPEN
 // and the like
 namespace
 {
-   template<int dim>
-   const Triangulation<dim> &get_tria(const Triangulation<dim> &tria)
+    template<int dim, int spacedim>
+    const Triangulation<dim, spacedim> &get_tria(const Triangulation<dim, spacedim> &tria)
    {
       return tria;
    }
 
-   template<int dim, template<int> class Container>
-   const Triangulation<dim> &get_tria(const Container<dim> &container)
+    template<int dim, template<int, int> class Container, int spacedim>
+    const Triangulation<dim> &get_tria(const Container<dim,spacedim> &container)
    {
       return container.get_tria();
    }
@@ -55,9 +55,9 @@ namespace
 
 #if deal_II_dimension != 1
 
-template <int dim>
+template <int dim, int spacedim>
 double
-GridTools::diameter (const Triangulation<dim> &tria)
+GridTools::diameter (const Triangulation<dim, spacedim> &tria)
 {
                                   // the algorithm used simply
                                   // traverses all cells and picks
@@ -72,12 +72,12 @@ GridTools::diameter (const Triangulation<dim> &tria)
                                   // marking is O(N) in the number of
                                   // cells/vertices, while computing
                                   // the maximal distance is O(N*N)
-  const std::vector<Point<dim> > &vertices = tria.get_vertices ();
+  const std::vector<Point<spacedim> > &vertices = tria.get_vertices ();
   std::vector<bool> boundary_vertices (vertices.size(), false);
 
-  typename Triangulation<dim>::active_cell_iterator
+  typename Triangulation<dim,spacedim>::active_cell_iterator
     cell = tria.begin_active();
-  const typename Triangulation<dim>::active_cell_iterator
+  const typename Triangulation<dim,spacedim>::active_cell_iterator
     endc = tria.end();
   for (; cell!=endc; ++cell)
     for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
@@ -131,7 +131,7 @@ GridTools::diameter (const Triangulation<1> &tria)
 
 template <>
 double
-GridTools::cell_measure (const std::vector<Point<3> > &all_vertices,
+GridTools::cell_measure<3>(const std::vector<Point<3> > &all_vertices,
                         const unsigned int (&vertex_indices)[GeometryInfo<3>::vertices_per_cell])
 {
                                   // note that this is the
@@ -249,9 +249,9 @@ GridTools::cell_measure (const std::vector<Point<3> > &all_vertices,
 
 #endif
 
-
 #if deal_II_dimension == 2
 
+
 template <>
 double
 GridTools::cell_measure(const std::vector<Point<2> > &all_vertices,
@@ -270,18 +270,25 @@ GridTools::cell_measure(const std::vector<Point<2> > &all_vertices,
   # of this cell in real space. 
   x := array(0..3);
   y := array(0..3);
+  z := array(0..3);
   tphi[0] := (1-xi)*(1-eta):
   tphi[1] :=     xi*(1-eta):
   tphi[2] := (1-xi)*eta:
   tphi[3] :=     xi*eta:
   x_real := sum(x[s]*tphi[s], s=0..3):
   y_real := sum(y[s]*tphi[s], s=0..3):
-  detJ := diff(x_real,xi)*diff(y_real,eta) - diff(x_real,eta)*diff(y_real,xi):
+  z_real := sum(z[s]*tphi[s], s=0..3):
+  
+  Jxi := <diff(x_real,xi)  | diff(y_real,xi) | diff(z_real,xi)>;
+  Jeta := <diff(x_real,eta)| diff(y_real,eta)| diff(z_real,eta)>;
+  with(VectorCalculus):  
+  J := CrossProduct(Jxi, Jeta);
+  detJ := sqrt(J[1]^2 + J[2]^2 +J[3]^2);
 
-  measure := simplify ( int ( int (detJ, xi=0..1), eta=0..1)):
-  readlib(C):
+  # measure := evalf (Int (Int (detJ, xi=0..1, method = _NCrule ) , eta=0..1, method = _NCrule  ) ):
+  readlib(C):
 
-  C(measure, optimized);
+  C(measure, optimized);
 
   additional optimizaton: divide by 2 only one time
 */
@@ -305,7 +312,7 @@ GridTools::cell_measure(const std::vector<Point<2> > &all_vertices,
 
 template <int dim>
 double
-GridTools::cell_measure(const std::vector<Point<dim> > &all_vertices,
+GridTools::cell_measure(const std::vector<Point<dim> > &,
                        const unsigned int (&) [GeometryInfo<dim>::vertices_per_cell])
 {
   Assert(false, ExcNotImplemented());
@@ -314,9 +321,9 @@ GridTools::cell_measure(const std::vector<Point<dim> > &all_vertices,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-GridTools::delete_unused_vertices (std::vector<Point<dim> >    &vertices,
+GridTools::delete_unused_vertices (std::vector<Point<spacedim> >    &vertices,
                                   std::vector<CellData<dim> > &cells,
                                   SubCellData                 &subcelldata)
 {
@@ -360,7 +367,7 @@ GridTools::delete_unused_vertices (std::vector<Point<dim> >    &vertices,
                                   // which we really need to a new
                                   // array and replace the old one by
                                   // the new one
-  std::vector<Point<dim> > tmp;
+  std::vector<Point<spacedim> > tmp;
   tmp.reserve (std::count(vertex_used.begin(), vertex_used.end(), true));
   for (unsigned int v=0; v<vertices.size(); ++v)
     if (vertex_used[v] == true)
@@ -370,9 +377,9 @@ GridTools::delete_unused_vertices (std::vector<Point<dim> >    &vertices,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-GridTools::delete_duplicated_vertices (std::vector<Point<dim> >    &vertices,
+GridTools::delete_duplicated_vertices (std::vector<Point<spacedim> >    &vertices,
                                       std::vector<CellData<dim> > &cells,
                                       SubCellData                 &subcelldata,
                                       std::vector<unsigned int>   &considered_vertices,
@@ -444,20 +451,20 @@ GridTools::delete_duplicated_vertices (std::vector<Point<dim> >    &vertices,
   namespace
 #endif
 {
-  template <int dim>
+  template <int spacedim>
   class ShiftPoint
   {
     public:
-      ShiftPoint (const Point<dim> &shift)
+      ShiftPoint (const Point<spacedim> &shift)
                      :
                      shift(shift)
        {}
-      Point<dim> operator() (const Point<dim> p) const
+      Point<spacedim> operator() (const Point<spacedim> p) const
        {
          return p+shift;
        }
     private:
-      const Point<dim> shift;
+      const Point<spacedim> shift;
   };
 
 
@@ -483,7 +490,7 @@ GridTools::delete_duplicated_vertices (std::vector<Point<dim> >    &vertices,
 #endif
 
 
-  template <int dim>
+  template <int spacedim>
   class ScalePoint
   {
     public:
@@ -491,7 +498,7 @@ GridTools::delete_duplicated_vertices (std::vector<Point<dim> >    &vertices,
                      :
                      factor(factor)
        {}
-      Point<dim> operator() (const Point<dim> p) const
+      Point<spacedim> operator() (const Point<spacedim> p) const
        {
          return p*factor;
        }
@@ -501,15 +508,15 @@ GridTools::delete_duplicated_vertices (std::vector<Point<dim> >    &vertices,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-GridTools::shift (const Point<dim>   &shift_vector,
-                 Triangulation<dim> &triangulation)
+GridTools::shift (const Point<spacedim>   &shift_vector,
+                 Triangulation<dim, spacedim> &triangulation)
 {
 #ifdef DEAL_II_ANON_NAMESPACE_BOGUS_WARNING
-  transform (TRANS::ShiftPoint<dim>(shift_vector), triangulation);
+  transform (TRANS::ShiftPoint<spacedim>(shift_vector), triangulation);
 #else
-  transform (ShiftPoint<dim>(shift_vector), triangulation);
+  transform (ShiftPoint<spacedim>(shift_vector), triangulation);
 #endif  
 }
 
@@ -530,32 +537,32 @@ GridTools::rotate (const double      angle,
 #endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 GridTools::scale (const double        scaling_factor,
-                 Triangulation<dim> &triangulation)
+                 Triangulation<dim, spacedim> &triangulation)
 {
   Assert (scaling_factor>0, ExcScalingFactorNotPositive (scaling_factor));
 #ifdef DEAL_II_ANON_NAMESPACE_BOGUS_WARNING
-  transform (TRANS::ScalePoint<dim>(scaling_factor), triangulation);
+  transform (TRANS::ScalePoint<spacedim>(scaling_factor), triangulation);
 #else
-  transform (ScalePoint<dim>(scaling_factor), triangulation);
+  transform (ScalePoint<spacedim>(scaling_factor), triangulation);
 #endif  
 }
 
 
-template <int dim, template <int> class Container>
+template <int dim, template <int, int> class Container, int spacedim>
 unsigned int
-GridTools::find_closest_vertex (const Container<dim> &container,
-                                const Point<dim> &p)
+GridTools::find_closest_vertex (const Container<dim,spacedim> &container,
+                                const Point<spacedim> &p)
 {
                                    // first get the underlying
                                    // triangulation from the
                                    // container and determine vertices
                                    // and used vertices
-   const Triangulation<dim> &tria = get_tria(container);
+   const Triangulation<dim, spacedim> &tria = get_tria(container);
 
-   const std::vector< Point<dim> > &vertices = tria.get_vertices();
+   const std::vector< Point<spacedim> > &vertices = tria.get_vertices();
    const std::vector< bool       > &used     = tria.get_used_vertices();
 
                                    // At the beginning, the first
@@ -587,9 +594,9 @@ GridTools::find_closest_vertex (const Container<dim> &container,
 }
 
 
-template<int dim, template<int> class Container>
-std::vector<typename Container<dim>::active_cell_iterator>
-GridTools::find_cells_adjacent_to_vertex(const Container<dim> &container,
+template<int dim, template<int, int> class Container, int spacedim>
+std::vector<typename Container<dim,spacedim>::active_cell_iterator>
+GridTools::find_cells_adjacent_to_vertex(const Container<dim,spacedim> &container,
                                          const unsigned int    vertex)
 {
                                    // make sure that the given vertex is
@@ -605,9 +612,9 @@ GridTools::find_cells_adjacent_to_vertex(const Container<dim> &container,
                                  // once. A bug in the previous version 
                                  // prevented some cases to be 
                                  // treated correctly
-   std::set<typename Container<dim>::active_cell_iterator> adj_cells_set;
+            std::set<typename Container<dim,spacedim>::active_cell_iterator> adj_cells_set;
    
-   typename Container<dim>::active_cell_iterator
+   typename Container<dim,spacedim>::active_cell_iterator
       cell = container.begin_active(),
       endc = container.end();
    
@@ -637,7 +644,7 @@ GridTools::find_cells_adjacent_to_vertex(const Container<dim> &container,
                         GeometryInfo<dim>::vertex_to_face[v][vface];
                      if (!cell->at_boundary(face))
                       {
-                        typename Container<dim>::cell_iterator
+                        typename Container<dim,spacedim>::cell_iterator
                            nb = cell->neighbor(face);
                         
                                                          // Here we
@@ -679,11 +686,11 @@ GridTools::find_cells_adjacent_to_vertex(const Container<dim> &container,
                break;
             }
    
-   std::vector<typename Container<dim>::active_cell_iterator> adjacent_cells;
+   std::vector<typename Container<dim,spacedim>::active_cell_iterator> adjacent_cells;
 
                                        // We now produce the output vector
                                        // from the set that we assembled above.
-   typename std::set<typename Container<dim>::active_cell_iterator>::iterator 
+   typename std::set<typename Container<dim,spacedim>::active_cell_iterator>::iterator 
        it = adj_cells_set.begin(), 
        endit = adj_cells_set.end();
    for(; it != endit; ++it) 
@@ -696,23 +703,23 @@ GridTools::find_cells_adjacent_to_vertex(const Container<dim> &container,
 }  
 
 
-template <int dim, typename Container>
-typename Container::active_cell_iterator
-GridTools::find_active_cell_around_point (const Container  &container,
-                                          const Point<dim> &p)
+template <int dim, template<int, int> class Container, int spacedim>
+typename Container<dim,spacedim>::active_cell_iterator
+GridTools::find_active_cell_around_point (const Container<dim,spacedim>  &container,
+                                          const Point<spacedim> &p)
 {
-   return find_active_cell_around_point(StaticMappingQ1<dim>::mapping,
+   return find_active_cell_around_point(StaticMappingQ1<dim,spacedim>::mapping,
                                        container, p).first;
 }
 
 
-template <int dim, template <int> class Container>
-std::pair<typename Container<dim>::active_cell_iterator, Point<dim> >
-GridTools::find_active_cell_around_point (const Mapping<dim>   &mapping,
-                                          const Container<dim> &container,
-                                          const Point<dim>     &p)
+template <int dim, template <int, int> class Container, int spacedim>
+std::pair<typename Container<dim,spacedim>::active_cell_iterator, Point<spacedim> >
+GridTools::find_active_cell_around_point (const Mapping<dim,spacedim>   &mapping,
+                                          const Container<dim,spacedim> &container,
+                                          const Point<spacedim>     &p)
 {
-   typedef typename Container<dim>::active_cell_iterator cell_iterator;
+   typedef typename Container<dim,spacedim>::active_cell_iterator cell_iterator;
 
                                    // The best distance is set to the
                                    // maximum allowable distance from
@@ -720,7 +727,7 @@ GridTools::find_active_cell_around_point (const Mapping<dim>   &mapping,
                                    // max. deviation of 1e-10
    double best_distance = 1e-10;
    int    best_level = -1;
-   std::pair<cell_iterator, Point<dim> > best_cell;
+   std::pair<cell_iterator, Point<spacedim> > best_cell;
 
                                    // Find closest vertex and determine
                                    // all adjacent cells
@@ -735,7 +742,7 @@ GridTools::find_active_cell_around_point (const Mapping<dim>   &mapping,
 
    for(; cell != endc; ++cell)
       {
-         const Point<dim> p_cell = mapping.transform_real_to_unit_cell(*cell, p);
+         const Point<spacedim> p_cell = mapping.transform_real_to_unit_cell(*cell, p);
 
                                    // calculate the infinity norm of
                                    // the distance vector to the unit cell.
@@ -762,13 +769,13 @@ GridTools::find_active_cell_around_point (const Mapping<dim>   &mapping,
 
 
 
-template <int dim>
-std::pair<typename hp::DoFHandler<dim>::active_cell_iterator, Point<dim> >
-GridTools::find_active_cell_around_point (const hp::MappingCollection<dim>   &mapping,
-                                          const hp::DoFHandler<dim> &container,
-                                          const Point<dim>     &p)
+template <int dim, int spacedim>
+std::pair<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator, Point<spacedim> >
+GridTools::find_active_cell_around_point (const hp::MappingCollection<dim,spacedim>   &mapping,
+                                          const hp::DoFHandler<dim,spacedim> &container,
+                                          const Point<spacedim>     &p)
 {
-   typedef typename hp::DoFHandler<dim>::active_cell_iterator cell_iterator;
+   typedef typename hp::DoFHandler<dim,spacedim>::active_cell_iterator cell_iterator;
 
                                    // The best distance is set to the
                                    // maximum allowable distance from
@@ -776,7 +783,7 @@ GridTools::find_active_cell_around_point (const hp::MappingCollection<dim>   &ma
                                    // max. deviation of 1e-10
    double best_distance = 1e-10;
    int    best_level = -1;
-   std::pair<cell_iterator, Point<dim> > best_cell;
+   std::pair<cell_iterator, Point<spacedim> > best_cell;
 
                                    // Find closest vertex and determine
                                    // all adjacent cells
@@ -791,7 +798,7 @@ GridTools::find_active_cell_around_point (const hp::MappingCollection<dim>   &ma
 
    for(; cell != endc; ++cell)
       {
-         const Point<dim> p_cell
+         const Point<spacedim> p_cell
           = mapping[(*cell)->active_fe_index()].transform_real_to_unit_cell(*cell, p);
 
                                    // calculate the infinity norm of
@@ -819,10 +826,10 @@ GridTools::find_active_cell_around_point (const hp::MappingCollection<dim>   &ma
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 GridTools::
-get_face_connectivity_of_cells (const Triangulation<dim> &triangulation,
+get_face_connectivity_of_cells (const Triangulation<dim,spacedim> &triangulation,
                                SparsityPattern          &cell_connectivity)
 {
                                   // as built in this function, we
@@ -845,7 +852,7 @@ get_face_connectivity_of_cells (const Triangulation<dim> &triangulation,
   std::vector<unsigned int> saved_user_indices;
   triangulation.save_user_indices (saved_user_indices);
   unsigned int index = 0;
-  for (typename Triangulation<dim>::active_cell_iterator
+  for (typename Triangulation<dim,spacedim>::active_cell_iterator
          cell = triangulation.begin_active();
        cell != triangulation.end(); ++cell, ++index)
     cell->set_user_index (index);
@@ -867,7 +874,7 @@ get_face_connectivity_of_cells (const Triangulation<dim> &triangulation,
                                   // add entries in both directions
                                   // for both cells
   index = 0;
-  for (typename Triangulation<dim>::active_cell_iterator
+  for (typename Triangulation<dim,spacedim>::active_cell_iterator
          cell = triangulation.begin_active();
        cell != triangulation.end(); ++cell, ++index)
     {
@@ -890,17 +897,17 @@ get_face_connectivity_of_cells (const Triangulation<dim> &triangulation,
                                   // the triangulation as constant (we here
                                   // return it to its original state)
   cell_connectivity.compress ();
-  const_cast<Triangulation<dim>&>(triangulation)
+  const_cast<Triangulation<dim,spacedim>&>(triangulation)
     .load_user_indices (saved_user_indices);  
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 GridTools::
-partition_triangulation (const unsigned int  n_partitions,
-                         Triangulation<dim> &triangulation)
+partition_triangulation (const unsigned int           n_partitions,
+                         Triangulation<dim,spacedim> &triangulation)
 {
   Assert (n_partitions > 0, ExcInvalidNumberOfPartitions(n_partitions));
 
@@ -930,12 +937,12 @@ partition_triangulation (const unsigned int  n_partitions,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 GridTools::
-partition_triangulation (const unsigned int     n_partitions,
-                        const SparsityPattern &cell_connection_graph,
-                         Triangulation<dim>    &triangulation)
+partition_triangulation (const unsigned int           n_partitions,
+                        const SparsityPattern        &cell_connection_graph,
+                         Triangulation<dim,spacedim>  &triangulation)
 {
   Assert (n_partitions > 0, ExcInvalidNumberOfPartitions(n_partitions));
   Assert (cell_connection_graph.n_rows() == triangulation.n_active_cells(),
@@ -964,7 +971,7 @@ partition_triangulation (const unsigned int     n_partitions,
                                    // subdomain ids
   std::vector<unsigned int> dof_indices(1);
   unsigned int index = 0;
-  for (typename Triangulation<dim>::active_cell_iterator
+  for (typename Triangulation<dim,spacedim>::active_cell_iterator
          cell = triangulation.begin_active();
        cell != triangulation.end(); ++cell, ++index)
     cell->set_subdomain_id (partition_indices[index]);
@@ -972,17 +979,17 @@ partition_triangulation (const unsigned int     n_partitions,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 GridTools::
-get_subdomain_association (const Triangulation<dim>  &triangulation,
+get_subdomain_association (const Triangulation<dim, spacedim>  &triangulation,
                            std::vector<unsigned int> &subdomain)
 {
   Assert (subdomain.size() == triangulation.n_active_cells(),
           ExcDimensionMismatch (subdomain.size(),
                                 triangulation.n_active_cells()));
   unsigned int index = 0;
-  for (typename Triangulation<dim>::active_cell_iterator
+  for (typename Triangulation<dim, spacedim>::active_cell_iterator
          cell = triangulation.begin_active();
        cell!=triangulation.end(); ++cell, ++index)
     subdomain[index] = cell->subdomain_id();
@@ -992,14 +999,14 @@ get_subdomain_association (const Triangulation<dim>  &triangulation,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
 GridTools::
-count_cells_with_subdomain_association (const Triangulation<dim> &triangulation,
+count_cells_with_subdomain_association (const Triangulation<dim, spacedim> &triangulation,
                                         const unsigned int        subdomain)
 {
   unsigned int count = 0;
-  for (typename Triangulation<dim>::active_cell_iterator
+  for (typename Triangulation<dim, spacedim>::active_cell_iterator
          cell = triangulation.begin_active();
        cell!=triangulation.end(); ++cell)
     if (cell->subdomain_id() == subdomain)
@@ -1104,12 +1111,10 @@ GridTools::get_finest_common_cells (const Container &mesh_1,
   return cell_list;
 }
 
-
-
-template <int dim>
+template <int dim, int spacedim>
 bool
-GridTools::have_same_coarse_mesh (const Triangulation<dim> &mesh_1,
-                                  const Triangulation<dim> &mesh_2)
+GridTools::have_same_coarse_mesh (const Triangulation<dim, spacedim> &mesh_1,
+                                  const Triangulation<dim, spacedim> &mesh_2)
 {
                                    // make sure the two meshes have
                                    // the same number of coarse cells
@@ -1119,7 +1124,7 @@ GridTools::have_same_coarse_mesh (const Triangulation<dim> &mesh_1,
                                    // if so, also make sure they have
                                    // the same vertices on the cells
                                    // of the coarse mesh
-  typename Triangulation<dim>::cell_iterator
+  typename Triangulation<dim, spacedim>::cell_iterator
     cell_1 = mesh_1.begin(0),
     cell_2 = mesh_2.begin(0),
     endc   = mesh_1.end(0);
@@ -1148,12 +1153,12 @@ GridTools::have_same_coarse_mesh (const Container &mesh_1,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 double
-GridTools::minimal_cell_diameter (const Triangulation<dim> &triangulation)
+GridTools::minimal_cell_diameter (const Triangulation<dim, spacedim> &triangulation)
 {
   double min_diameter = triangulation.begin_active()->diameter();
-  for (typename Triangulation<dim>::active_cell_iterator
+  for (typename Triangulation<dim, spacedim>::active_cell_iterator
         cell = triangulation.begin_active(); cell != triangulation.end();
        ++cell)
     min_diameter = std::min (min_diameter,
@@ -1163,12 +1168,12 @@ GridTools::minimal_cell_diameter (const Triangulation<dim> &triangulation)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 double
-GridTools::maximal_cell_diameter (const Triangulation<dim> &triangulation)
+GridTools::maximal_cell_diameter (const Triangulation<dim, spacedim> &triangulation)
 {
   double max_diameter = triangulation.begin_active()->diameter();
-  for (typename Triangulation<dim>::active_cell_iterator
+  for (typename Triangulation<dim, spacedim>::active_cell_iterator
         cell = triangulation.begin_active(); cell != triangulation.end();
        ++cell)
     max_diameter = std::max (max_diameter,
@@ -1178,11 +1183,11 @@ GridTools::maximal_cell_diameter (const Triangulation<dim> &triangulation)
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-GridTools::create_union_triangulation (const Triangulation<dim> &triangulation_1,
-                                      const Triangulation<dim> &triangulation_2,
-                                      Triangulation<dim>       &result)
+GridTools::create_union_triangulation (const Triangulation<dim, spacedim> &triangulation_1,
+                                      const Triangulation<dim, spacedim> &triangulation_2,
+                                      Triangulation<dim, spacedim>       &result)
 {
   Assert (have_same_coarse_mesh (triangulation_1, triangulation_2),
          ExcMessage ("The two input triangulations are not derived from "
@@ -1206,11 +1211,11 @@ GridTools::create_union_triangulation (const Triangulation<dim> &triangulation_1
   for (unsigned int iteration=0; iteration<triangulation_2.n_levels();
        ++iteration)
     {
-      InterGridMap<Triangulation<dim> > intergrid_map;
+      InterGridMap<Triangulation<dim, spacedim> > intergrid_map;
       intergrid_map.make_mapping (result, triangulation_2);
 
       bool any_cell_flagged = false;
-      for (typename Triangulation<dim>::active_cell_iterator
+      for (typename Triangulation<dim, spacedim>::active_cell_iterator
             result_cell = result.begin_active();
           result_cell != result.end(); ++result_cell)
        if (intergrid_map[result_cell]->has_children())
@@ -1237,6 +1242,12 @@ double
 GridTools::diameter<deal_II_dimension> (const Triangulation<deal_II_dimension> &);
 #endif
 
+#if deal_II_dimension == 2
+template
+double
+GridTools::diameter<deal_II_dimension, deal_II_dimension+1> (const Triangulation<deal_II_dimension, deal_II_dimension+1> &);
+#endif
+
 template
 void GridTools::delete_unused_vertices (std::vector<Point<deal_II_dimension> > &,
                                        std::vector<CellData<deal_II_dimension> > &,
@@ -1307,6 +1318,48 @@ GridTools::create_union_triangulation (const Triangulation<deal_II_dimension> &t
                                       const Triangulation<deal_II_dimension> &triangulation_2,
                                       Triangulation<deal_II_dimension>       &result);
 
+
+#if deal_II_dimension != 3
+
+template
+void GridTools::delete_unused_vertices (std::vector<Point<deal_II_dimension+1> > &,
+                                       std::vector<CellData<deal_II_dimension> > &,
+                                       SubCellData &);
+
+template
+void GridTools::delete_duplicated_vertices (std::vector<Point<deal_II_dimension+1> > &,
+                                           std::vector<CellData<deal_II_dimension> > &,
+                                           SubCellData &,
+                                           std::vector<unsigned int> &,
+                                           double);
+
+template
+void GridTools::shift<deal_II_dimension, deal_II_dimension+1> (const Point<deal_II_dimension+1> &,
+                                         Triangulation<deal_II_dimension, deal_II_dimension+1> &);
+
+template
+void GridTools::scale<deal_II_dimension, deal_II_dimension+1> (const double,
+                                         Triangulation<deal_II_dimension, deal_II_dimension+1> &);
+
+
+
+template
+std::list<std::pair<Triangulation<deal_II_dimension,deal_II_dimension+1>::cell_iterator,
+                    Triangulation<deal_II_dimension,deal_II_dimension+1>::cell_iterator> >
+GridTools::
+get_finest_common_cells (const Triangulation<deal_II_dimension,deal_II_dimension+1> &mesh_1,
+                         const Triangulation<deal_II_dimension,deal_II_dimension+1> &mesh_2);
+
+template
+std::list<std::pair<DoFHandler<deal_II_dimension,deal_II_dimension+1>::cell_iterator,
+                    DoFHandler<deal_II_dimension,deal_II_dimension+1>::cell_iterator> >
+GridTools::
+get_finest_common_cells (const DoFHandler<deal_II_dimension,deal_II_dimension+1> &mesh_1,
+                         const DoFHandler<deal_II_dimension,deal_II_dimension+1> &mesh_2);
+
+#endif
+
+
 #include "grid_tools.inst"
 
 DEAL_II_NAMESPACE_CLOSE
index 0030deab7fd61cd7d7064b0ddd9897583b9239cd..5bee2929b1dd3fea0bd5a797a36e9b06f7328e44 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
-// helper function to aquire the number of levels within a grid
-template <class GridClass>
-unsigned int
-get_n_levels (const GridClass &grid)
+namespace
 {
-                                  // all objects we deal with are able
-                                  // to deliver a pointer to the
-                                  // underlying triangulation.
-                                  //
-                                  // for the triangulation as GridClass
-                                  // of this object, there is a
-                                  // specialization of this function
-  return grid.get_tria().n_levels();
-}
+// helper function to aquire the number of levels within a grid
+  template <class GridClass>
+  unsigned int
+  get_n_levels (const GridClass &grid)
+  {
+                                    // all objects we deal with are able
+                                    // to deliver a pointer to the
+                                    // underlying triangulation.
+                                    //
+                                    // for the triangulation as GridClass
+                                    // of this object, there is a
+                                    // specialization of this function
+    return grid.get_tria().n_levels();
+  }
 
 
 // specialization for grid==tria
-template <int dim>
-unsigned int
-get_n_levels (const Triangulation<dim> &grid)
-{
-                                  // if GridClass==Triangulation, then
-                                  // we can ask directly.
-  return grid.n_levels();
+  template <int dim>
+  unsigned int
+  get_n_levels (const Triangulation<dim> &grid)
+  {
+                                    // if GridClass==Triangulation, then
+                                    // we can ask directly.
+    return grid.n_levels();
+  }
 }
 
 
index 6991acaa0e6a94606bcba02db38af530d2f9c3e7..2af2ef6236aab5211de5f0b5f249e2f10f25615f 100644 (file)
@@ -44,8 +44,8 @@ namespace
                                   // its children are further
                                   // refined. this function can only
                                   // be called for non-active cells.
-  template <int dim>
-  bool cell_is_patch_level_1 (const TriaIterator<dim, dealii::CellAccessor<dim> > &cell)
+  template <int dim, int spacedim>
+  bool cell_is_patch_level_1 (const TriaIterator<dealii::CellAccessor<dim, spacedim> > &cell)
   {
     Assert (cell->active() == false, ExcInternalError());
 
@@ -64,8 +64,8 @@ namespace
                                   // children are active and have their coarsen
                                   // flag set. In case only part of the coarsen
                                   // flags are set, remove them.
-  template <int dim>
-  bool cell_will_be_coarsened (const TriaIterator<dim, dealii::CellAccessor<dim> > &cell)
+  template <int dim, int spacedim>
+  bool cell_will_be_coarsened (const TriaIterator<dealii::CellAccessor<dim,spacedim> > &cell)
   {
                                     // only cells with children should be
                                     // considered for coarsening
@@ -120,17 +120,18 @@ namespace
                                   // thus, this is an internal function, users
                                   // should call one of the two alternatives
                                   // following below.
-  template <int dim>
-  bool face_will_be_refined_by_neighbor_internal(const TriaIterator<dim, dealii::CellAccessor<dim> > &cell,
-                                                const unsigned int                                   face_no,
-                                                RefinementCase<dim-1>                                    &expected_face_ref_case)
+  template <int dim, int spacedim>
+  bool
+  face_will_be_refined_by_neighbor_internal(const TriaIterator<dealii::CellAccessor<dim,spacedim> > &cell,
+                                           const unsigned int                                   face_no,
+                                           RefinementCase<dim-1>                                    &expected_face_ref_case)
   {
                                     // first of all: set the default value for
                                     // expected_face_ref_case, which is no
                                     // refinement at all
     expected_face_ref_case=RefinementCase<dim-1>::no_refinement;
     
-    const typename Triangulation<dim>::cell_iterator neighbor=cell->neighbor(face_no);
+    const typename Triangulation<dim,spacedim>::cell_iterator neighbor=cell->neighbor(face_no);
 
                                     // If we are at the boundary, there is no
                                     // neighbor which could refine the face
@@ -175,7 +176,7 @@ namespace
                                                  neighbor->face_rotation(neighbor_neighbor));
        if (face_ref_case != RefinementCase<dim-1>::no_refinement)
          {
-           const typename Triangulation<dim>::face_iterator neighbor_face=neighbor->face(neighbor_neighbor);
+             const typename Triangulation<dim,spacedim>::face_iterator neighbor_face=neighbor->face(neighbor_neighbor);
            const int this_face_index=cell->face_index(face_no);
 
                                             // there are still two basic
@@ -259,11 +260,12 @@ namespace
     return false;
   }
 
-                                  // verison of above function for both active
+                                  // version of above function for both active
                                   // and non-active cells
-  template <int dim>
-  bool face_will_be_refined_by_neighbor(const TriaIterator<dim, dealii::CellAccessor<dim> > &cell,
-                                       const unsigned int                                   face_no)
+  template <int dim, int spacedim>
+  bool
+  face_will_be_refined_by_neighbor(const TriaIterator<dealii::CellAccessor<dim, spacedim> > &cell,
+                                  const unsigned int                                   face_no)
   {
     RefinementCase<dim-1> dummy = RefinementCase<dim-1>::no_refinement;
     return face_will_be_refined_by_neighbor_internal(cell, face_no, dummy);
@@ -273,10 +275,11 @@ namespace
                                   // only. Additionally returning the refine
                                   // case (to come) of the face under
                                   // consideration
-  template <int dim>
-  bool face_will_be_refined_by_neighbor(const TriaActiveIterator<dim, dealii::CellAccessor<dim> > &cell,
-                                       const unsigned int                                         face_no,
-                                       RefinementCase<dim-1>                                          &expected_face_ref_case)
+  template <int dim, int spacedim>
+  bool
+  face_will_be_refined_by_neighbor(const TriaActiveIterator<dealii::CellAccessor<dim,spacedim> > &cell,
+                                  const unsigned int                                         face_no,
+                                  RefinementCase<dim-1>                                          &expected_face_ref_case)
   {
     return face_will_be_refined_by_neighbor_internal(cell, face_no,
                                                     expected_face_ref_case);
@@ -284,16 +287,16 @@ namespace
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   bool
-  satisfies_level1_at_vertex_rule (const Triangulation<dim> &triangulation)
+  satisfies_level1_at_vertex_rule (const Triangulation<dim,spacedim> &triangulation)
   {
     std::vector<unsigned int> min_adjacent_cell_level (triangulation.n_vertices(),
                                                       triangulation.n_levels());
     std::vector<unsigned int> max_adjacent_cell_level (triangulation.n_vertices(),
                                                       0);
       
-    for (typename Triangulation<dim>::active_cell_iterator
+    for (typename Triangulation<dim,spacedim>::active_cell_iterator
           cell = triangulation.begin_active();
         cell != triangulation.end(); ++cell)
       for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
@@ -314,2850 +317,9657 @@ namespace
          return false;
     return true;
   }
-  
-}// end of anonymous namespace
-
-
-template <int dim>
-const StraightBoundary<dim>
-Triangulation<dim>::straight_boundary = StraightBoundary<dim>();
-
-
-
-template <int dim>
-const unsigned int
-Triangulation<dim>::dimension;
 
 
 
-template <int dim>
-Triangulation<dim>::Triangulation (const MeshSmoothing smooth_grid) :
-               Subscriptor (),
-               faces(NULL),
-               anisotropic_refinement(false),
-               smooth_grid(smooth_grid)
-{
-                                  // set default boundary for all
-                                  // possible components
-  for (unsigned int i=0;i<255;++i)
-    boundary[i] = &straight_boundary;
-}
+                                  /**
+                                   * Fill the vector @p line_cell_count
+                                   * needed by @p delete_children with the
+                                   * number of cells bounded by a given
+                                   * line.
+                                   */
+  template <int dim, int spacedim>
+  std::vector<unsigned int>
+  count_cells_bounded_by_line (const Triangulation<dim,spacedim> &triangulation)
+  {
+    if (dim >= 2)
+      {
+       std::vector<unsigned int> line_cell_count(triangulation.n_raw_lines(),0);
+       typename Triangulation<dim,spacedim>::cell_iterator
+         cell=triangulation.begin(),
+         endc=triangulation.end();
+       for (; cell!=endc; ++cell)
+         for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+           ++line_cell_count[cell->line_index(l)];
+       return line_cell_count;
+      }
+    else
+      return std::vector<unsigned int>();
+  }
 
 
-template <int dim>
-Triangulation<dim>::Triangulation (const Triangulation<dim> &) 
-               :
-               Subscriptor ()
-                                  // do not set any subscriptors;
-                                  // anyway, calling this constructor
-                                  // is an error!
-{
-  Assert (false, ExcInternalError());
-}
 
 
-template <int dim>
-Triangulation<dim>::~Triangulation ()
-{
-  for (unsigned int i=0; i<levels.size(); ++i)
-    delete levels[i];
-  levels.clear ();
-  delete faces;
-}
+                                  /**
+                                   * Fill the vector @p quad_cell_count
+                                   * needed by @p delete_children with the
+                                   * number of cells bounded by a given
+                                   * quad.
+                                   */
+  template <int dim, int spacedim>
+  std::vector<unsigned int>
+  count_cells_bounded_by_quad (const Triangulation<dim,spacedim> &triangulation)
+  {
+    if (dim >= 3)
+      {
+       std::vector<unsigned int> quad_cell_count (triangulation.n_raw_quads(),0);
+       typename Triangulation<dim,spacedim>::cell_iterator
+         cell=triangulation.begin(),
+         endc=triangulation.end();
+       for (; cell!=endc; ++cell)
+         for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
+           ++quad_cell_count[cell->quad_index(q)];
+       return quad_cell_count;
+      }
+    else
+      return std::vector<unsigned int>();
+  }
 
 
-template <int dim>
-void Triangulation<dim>::clear () 
-{
-  clear_despite_subscriptions();
-}
 
+                                  /**
+                                   * In 3d, set the neighbor information of
+                                   * all outer neighbor of all children of
+                                   * the given cell <tt>cell</tt>, if
+                                   * <tt>refining=true</tt>. In this
+                                   * constellation the function is called
+                                   * after the creation of children in @p
+                                   * execute_refinement. If
+                                   * <tt>refining=false</tt>, it is assumed,
+                                   * that the given cell is just coarsened,
+                                   * i.e. that its children are about to be
+                                   * deleted, thus they do not need new
+                                   * neighbor information.
+                                   *
+                                   * In both cases, the neighbor information
+                                   * of the cell's neighbors are updated, if
+                                   * necessary.
+                                   */
+  template <int spacedim>
+  void
+  update_neighbors (const typename Triangulation<3, spacedim>::cell_iterator &cell,
+                   const bool                                                refining)
+  {
+    const unsigned int dim = 3;
+    
+    Assert(cell->has_children(),
+          ExcMessage("Only cells with children can ask for an update of neighbor information."));
 
-template <int dim>
-void
-Triangulation<dim>::set_boundary (const unsigned int number,
-                                 const Boundary<dim>& boundary_object)
-{
-  Assert(number<255, ExcIndexRange(number,0,255));
+    typedef
+      typename Triangulation<dim, spacedim>::cell_iterator cell_iterator;
+    typedef
+      typename Triangulation<dim, spacedim>::face_iterator face_iterator;
+    
+    
+    const RefinementCase<dim> ref_case=cell->refinement_case();
   
-  boundary[number] = &boundary_object;
-}
+                                    // visit each face in turn
+    for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+      {
+       cell_iterator neighbor=cell->neighbor(f);
+                                        // as default: set all children neighbors
+                                        // to the cell's neighbor first, if we
+                                        // are to set neighbors after refining.
+       if (refining)
+         for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_face; ++c)
+           cell->child(GeometryInfo<dim>::child_cell_on_face(ref_case,f,c))
+             ->set_neighbor(f, neighbor);
+       else
+                                          // in this case, if we are refined
+                                          // anisotropically in a way that does
+                                          // not refine the current face, then
+                                          // set our child's neighbor as our
+                                          // neighbor (the child's neighbor might
+                                          // be more current...).
+         if (GeometryInfo<dim>::face_refinement_case(cell->refinement_case(), f) == RefinementCase<dim-1>::no_refinement)
+           {
+             const typename Triangulation<dim, spacedim>::active_cell_iterator
+               child_on_this_face=cell->child(GeometryInfo<dim>::child_cell_on_face(cell->refinement_case(),
+                                                                                    f,
+                                                                                    cell->face_orientation(f),
+                                                                                    cell->face_flip(f),
+                                                                                    cell->face_rotation(f),
+                                                                                    RefinementCase<dim>::no_refinement));
+             neighbor=child_on_this_face->neighbor(f);
+             cell->set_neighbor(f, child_on_this_face->neighbor(f));
+           }
+               
+       if (neighbor.state()!=IteratorState::valid)
+                                          // the neighbor is at the
+                                          // boundary, so simply copy
+                                          // this to all children at
+                                          // this face. As this has
+                                          // been done already, there
+                                          // is nothing more to do here
+         {}
+       else if (neighbor->active())
+         {
+                   
+                                            // the neighbor is active,
+                                            // so it cannot be refined
+                                            // along the given face. We
+                                            // have to set the neighbor
+                                            // of our children to this
+                                            // neighbor. This has been
+                                            // done already. If our
+                                            // face is not refined AND
+                                            // if the neighbor is not
+                                            // coarser we also have to
+                                            // adjust the neighbor's
+                                            // neighborship info.
+           if ((GeometryInfo<dim>::face_refinement_case(ref_case,f) ==
+                RefinementCase<dim-1>::no_refinement)
+               &&
+               !cell->neighbor_is_coarser(f))
+             {
+               if (refining)
+                 neighbor->set_neighbor(cell->neighbor_of_neighbor(f),
+                                        cell->child(GeometryInfo<dim>::child_cell_on_face(ref_case,f,0)));
+               else
+                 neighbor->set_neighbor(cell->neighbor_of_neighbor(f),
+                                        cell);
+             }                             
+         }// else if (neighbor->active())
+       else
+         {
+           const bool f_or=cell->face_orientation(f);
+           const bool f_fl=cell->face_flip(f);
+           const bool f_ro=cell->face_rotation(f);
+         
+                                            // now the neighbor has children, so
+                                            // it is kind of complicated.
+           const RefinementCase<dim-1> our_face_ref_case
+             = GeometryInfo<dim>::face_refinement_case(ref_case,f,f_or,f_fl,f_ro);
+           const RefinementCase<dim-1> face_ref_case
+             = cell->face(f)->refinement_case();
+                   
+           switch (face_ref_case)
+             {
+               case RefinementCase<dim>::no_refinement:
+                                                      // in this case neither our
+                                                      // cell nor the neighbor is
+                                                      // refined along face
+                                                      // f. however, the above
+                                                      // case should have caught
+                                                      // this situation, as the
+                                                      // neighbor has to be
+                                                      // active then.
+                     Assert (false, ExcInternalError());
+                     break;
+               case RefinementCase<dim>::cut_x:
+               case RefinementCase<dim>::cut_y:
+               case RefinementCase<dim>::cut_xy:
+               {
+                         
+                                                  // this is really tricky and
+                                                  // originally there were some
+                                                  // 800 lines of code which were
+                                                  // still buggy. thus we use a
+                                                  // different kind of approach
+                                                  // here: we create a map of our
+                                                  // child cells at the given
+                                                  // face with the (sub)face as
+                                                  // key. Then create a
+                                                  // corresponding (multi-)map of
+                                                  // the neighbor and its
+                                                  // children. As a third
+                                                  // ingredient, we need a map
+                                                  // pointing us from a face to
+                                                  // its parent.
+                 const unsigned int nb_nb=cell->neighbor_face_no(f);
+                         
+                 std::map<face_iterator, cell_iterator> our_children;
+                                                  // we only need to fill this
+                                                  // map, if the cell was just
+                                                  // refined. after coarsening,
+                                                  // we should use our own cell
+                                                  // instead
+                 if (refining)
+                   for (unsigned int c=0; c<std::max(GeometryInfo<dim-1>::n_children(our_face_ref_case),1U); ++c)
+                     {
+                       cell_iterator child
+                         =
+                         cell->child(GeometryInfo<dim>::child_cell_on_face(ref_case,
+                                                                           f,c,
+                                                                           f_or,
+                                                                           f_fl,
+                                                                           f_ro,
+                                                                           our_face_ref_case));
+                       our_children.insert(std::make_pair(child->face(f),child));
+                     }
+                 else
+                   our_children.insert(std::make_pair(cell->face(f),cell));
+                         
+                 std::map<face_iterator,face_iterator> parents;
+                 for (unsigned int face_child=0; face_child<neighbor->face(nb_nb)->n_children(); ++face_child)
+                   parents.insert(std::make_pair(neighbor->face(nb_nb)->child(face_child),neighbor->face(nb_nb)));
+                 bool inserted=true;
+                 while (inserted)
+                   {
+                     inserted=false;
+                     typename std::map<face_iterator,face_iterator>::iterator
+                       cur_face = parents.begin();
+                     for (;cur_face!=parents.end(); ++cur_face)
+                       if (cur_face->first->has_children())
+                         for (unsigned int fc=0; fc<cur_face->first->n_children(); ++fc)
+                           if (parents.find(cur_face->first->child(fc))==parents.end())
+                             {
+                               parents.insert(std::make_pair(cur_face->first->child(fc),cur_face->first));
+                               inserted=true;
+                             }
+                   }
+                         
+                 const bool nb_f_or=neighbor->face_orientation(nb_nb);
+                 const bool nb_f_fl=neighbor->face_flip(nb_nb);
+                 const bool nb_f_ro=neighbor->face_rotation(nb_nb);
+                         
+                 std::multimap<face_iterator,cell_iterator> nb_children;
+                 nb_children.insert(std::make_pair(neighbor->face(nb_nb),neighbor));
+                         
+                 int current_level=neighbor->level();
+                 inserted=true;
+                 while (inserted)
+                   {
+                     inserted=false;
+                     typename std::multimap<face_iterator,cell_iterator>::iterator
+                       it = nb_children.begin();
+                     for (;it!=nb_children.end(); ++it)
+                                                        // only treat
+                                                        // untreated
+                                                        // cells,
+                                                        // i.e. those
+                                                        // with
+                                                        // level()==current_level
+                       if (it->second->level()==current_level &&
+                           it->second->has_children())
+                         {
+                           RefinementCase<dim-1> nb_face_ref_case
+                             =GeometryInfo<dim>::face_refinement_case(it->second->refinement_case(),
+                                                                      nb_nb,
+                                                                      nb_f_or,
+                                                                      nb_f_fl,
+                                                                      nb_f_ro);
+                           for (unsigned int c=0; c<std::max(GeometryInfo<dim-1>::n_children(nb_face_ref_case),1U); ++c)
+                             {
+                               cell_iterator child=
+                                 it->second->child(GeometryInfo<dim>::child_cell_on_face(it->second->refinement_case(),
+                                                                                         nb_nb,c,
+                                                                                         nb_f_or,
+                                                                                         nb_f_fl,
+                                                                                         nb_f_ro,
+                                                                                         nb_face_ref_case));
+                               nb_children.insert(std::make_pair(child->face(nb_nb),child));
+                               inserted=true;
+                             }
+                         }
+                     ++current_level;
+                   }
 
+                                                  // now loop over all of our
+                                                  // children and set their
+                                                  // neighbor, if available. only
+                                                  // necessary, if we are
+                                                  // refining.
+
+                                                  // declare some iterator which
+                                                  // are needed in any case
+                 typename std::map<face_iterator,cell_iterator>::iterator
+                   our_it = our_children.begin(),
+                   end_our_it = our_children.end();
+                 typename std::multimap<face_iterator,cell_iterator>::iterator
+                   nb_it, end_nb_it;
+               
+                 if (refining)
+                   {
+                     for (; our_it!=end_our_it; ++our_it)
+                       {
+                         face_iterator parent_face=our_it->first;
+                         bool further_parents=true;
+                       
+                         while(further_parents &&
+                               nb_children.find(parent_face)==nb_children.end())
+                           {
+                             if (parents.find(parent_face)==parents.end())
+                               further_parents=false;
+                             parent_face=parents.find(parent_face)->second;
+                           }
+                             
+                         if (further_parents)
+                                                            // we found a
+                                                            // corresponding
+                                                            // neighbor_child. if
+                                                            // not, do nothing,
+                                                            // as the default
+                                                            // neighbor set above
+                                                            // is correct.
+                           {
+                             nb_it=nb_children.lower_bound(parent_face);
+                             end_nb_it=nb_children.upper_bound(parent_face);
+                           
+                                                              // advance to
+                                                              // the last
+                                                              // child at
+                                                              // the given
+                                                              // face, as
+                                                              // this is on
+                                                              // the
+                                                              // highest
+                                                              // level and
+                                                              // thus the
+                                                              // finest one
+                                                              // possible
+                             for (; nb_it!=end_nb_it; ++nb_it)
+                               our_it->second->set_neighbor(f, nb_it->second);
+                           }
+                       }
+                   }
+               
+                                                  // now do the same for the
+                                                  // neighbor and its
+                                                  // children. this is also
+                                                  // necessary if we are
+                                                  // coarsening
+                 nb_it=nb_children.begin();
+                 end_nb_it=nb_children.end();
+                         
+                 for (; nb_it!=end_nb_it; ++nb_it)
+                   {
+                     face_iterator parent_face=nb_it->first;
+                     bool further_parents=true;
+                   
+                     while(further_parents &&
+                           our_children.find(parent_face)==our_children.end())
+                       {
+                         if (parents.find(parent_face)==parents.end())
+                           further_parents=false;
+                         parent_face=parents.find(parent_face)->second;
+                       }
+                   
+                     if (further_parents)
+                                                        // we found a
+                                                        // corresponding
+                                                        // child. if
+                                                        // not, do
+                                                        // nothing, as
+                                                        // the old
+                                                        // neighbor is
+                                                        // still
+                                                        // correct.
+                       {
+                                                          // here, we
+                                                          // only have
+                                                          // one child
+                                                          // at any
+                                                          // given
+                                                          // face, so
+                                                          // we do not
+                                                          // need a
+                                                          // loop.
+                         our_it=our_children.find(parent_face);
+                         nb_it->second->set_neighbor(nb_nb, our_it->second);
+                       }
+                   }
+                 break;
+               }
+               default:
+                     Assert(false, ExcInternalError());
+                     break;
+             }// switch (our_face_ref_case)
+                   
+         }// else -> neighbor has children
+      }// for all faces
+  }
 
 
-template <int dim>
-void
-Triangulation<dim>::set_boundary (const unsigned int number)
-{
-  set_boundary (number, straight_boundary);
-}
+                                  /**
+                                   * For a given Triangulation, update the
+                                   * number cache for lines. For 1d, we have
+                                   * to deal with the fact that lines have
+                                   * levels, whereas for higher dimensions
+                                   * they do not.
+                                   */
+  template <int dim, int spacedim>
+  void compute_number_cache (const Triangulation<dim,spacedim>       &triangulation,
+                            internal::Triangulation::NumberCache<1> &number_cache) 
+  {
+    typedef
+      typename Triangulation<dim,spacedim>::line_iterator line_iterator;
+    typedef
+      typename Triangulation<dim,spacedim>::active_line_iterator active_line_iterator;
+    
+                                    ///////////////////////////////////
+                                    // update the number of lines
+                                    // on the different levels in
+                                    // the cache
+    number_cache.n_lines_level.resize (triangulation.n_levels());
+    number_cache.n_lines = 0;
+
+    number_cache.n_active_lines_level.resize (triangulation.n_levels());
+    number_cache.n_active_lines = 0;
+
+                                    // for 1d, lines have levels so take
+                                    // count the objects per level and
+                                    // globally
+    if (dim == 1)
+      {
+       for (unsigned int level=0; level<triangulation.n_levels(); ++level)
+         {
+                                            // count lines on this level
+           number_cache.n_lines_level[level] = 0;
+
+           line_iterator line = triangulation.begin_line (level),
+                         endc = (level == triangulation.n_levels()-1 ?
+                                 line_iterator(triangulation.end_line()) :
+                                 triangulation.begin_line (level+1));
+           for (; line!=endc; ++line)
+             ++number_cache.n_lines_level[level];
+      
+                                            // update total number of lines
+           number_cache.n_lines += number_cache.n_lines_level[level];
+         }
 
+                                        // do the update for the number of
+                                        // active lines as well
+       for (unsigned int level=0; level<triangulation.n_levels(); ++level)
+         {
+                                            // count lines on this level
+           number_cache.n_active_lines_level[level] = 0;
 
+           active_line_iterator line = triangulation.begin_active_line (level),
+                                endc = triangulation.end_active_line (level);
+           for (; line!=endc; ++line)
+             ++number_cache.n_active_lines_level[level];
+      
+                                            // update total number of lines
+           number_cache.n_active_lines += number_cache.n_active_lines_level[level];
+         }
+      }
+    else
+      {
+                                        // for dim>1, there are no
+                                        // levels for lines
+       {
+         line_iterator line = triangulation.begin_line (),
+                       endc = triangulation.end_line();
+         for (; line!=endc; ++line)
+           ++number_cache.n_lines;
+       }
 
-template <int dim>
-const Boundary<dim> &
-Triangulation<dim>::get_boundary (const unsigned int number) const 
-{
-  Assert(number<255, ExcIndexRange(number,0,255));
-  
-  return *(boundary[number]);
-}
+       {
+         active_line_iterator line = triangulation.begin_active_line (),
+                              endc = triangulation.end_line();
+         for (; line!=endc; ++line)
+           ++number_cache.n_active_lines;
+       }
+      }
+  }
 
+                                  /**
+                                   * For a given Triangulation, update the
+                                   * number cache for quads. For 2d, we have
+                                   * to deal with the fact that quads have
+                                   * levels, whereas for higher dimensions
+                                   * they do not.
+                                   *
+                                   * At the end of the function, we call the
+                                   * respective function to update the number
+                                   * cache for lines.
+                                   */
+  template <int dim, int spacedim>
+  void compute_number_cache (const Triangulation<dim,spacedim>       &triangulation,
+                            internal::Triangulation::NumberCache<2> &number_cache) 
+  {
+    typedef
+      typename Triangulation<dim,spacedim>::quad_iterator quad_iterator;
+    typedef
+      typename Triangulation<dim,spacedim>::active_quad_iterator active_quad_iterator;
+    
+                                    ///////////////////////////////////
+                                    // update the number of quads
+                                    // on the different levels in
+                                    // the cache
+    number_cache.n_quads_level.resize (triangulation.n_levels());
+    number_cache.n_quads = 0;
+
+    number_cache.n_active_quads_level.resize (triangulation.n_levels());
+    number_cache.n_active_quads = 0;
+
+                                    // for 2d, quads have levels so take
+                                    // count the objects per level and
+                                    // globally
+    if (dim == 2)
+      {
+       for (unsigned int level=0; level<triangulation.n_levels(); ++level)
+         {
+                                            // count quads on this level
+           number_cache.n_quads_level[level] = 0;
+
+           quad_iterator quad = triangulation.begin_quad (level),
+                         endc = (level == triangulation.n_levels()-1 ?
+                                 quad_iterator(triangulation.end_quad()) :
+                                 triangulation.begin_quad (level+1));
+           for (; quad!=endc; ++quad)
+             ++number_cache.n_quads_level[level];
+      
+                                            // update total number of quads
+           number_cache.n_quads += number_cache.n_quads_level[level];
+         }
 
-#if deal_II_dimension == 1
+                                        // do the update for the number of
+                                        // active quads as well
+       for (unsigned int level=0; level<triangulation.n_levels(); ++level)
+         {
+                                            // count quads on this level
+           number_cache.n_active_quads_level[level] = 0;
 
-template <>
-std::vector<unsigned char>
-Triangulation<1>::get_boundary_indicators () const 
-{
-  return std::vector<unsigned char> (0);
-}
+           active_quad_iterator quad = triangulation.begin_active_quad (level),
+                                endc = triangulation.end_active_quad (level);
+           for (; quad!=endc; ++quad)
+             ++number_cache.n_active_quads_level[level];
+      
+                                            // update total number of quads
+           number_cache.n_active_quads += number_cache.n_active_quads_level[level];
+         }
+      }
+    else
+      {
+                                        // for dim>2, there are no
+                                        // levels for quads
+       {
+         quad_iterator quad = triangulation.begin_quad (),
+                       endc = triangulation.end_quad();
+         for (; quad!=endc; ++quad)
+           ++number_cache.n_quads;
+       }
 
-#else
+       {
+         active_quad_iterator quad = triangulation.begin_active_quad (),
+                              endc = triangulation.end_quad();
+         for (; quad!=endc; ++quad)
+           ++number_cache.n_active_quads;
+       }
+      }
 
-template <int dim>
-std::vector<unsigned char>
-Triangulation<dim>::get_boundary_indicators () const 
-{
-  std::vector<bool> bi_exists(255, false);
-  active_cell_iterator cell=begin_active();
-  for (; cell!=end(); ++cell)
-    for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-      if (cell->at_boundary(face))
-       bi_exists[cell->face(face)->boundary_indicator()]=true;
+                                    // update lines
+    compute_number_cache (triangulation,
+                         static_cast<internal::Triangulation::NumberCache<1>&>(number_cache));
+  }
 
-  const unsigned int n_bi=
-    std::count(bi_exists.begin(), bi_exists.end(), true);
+                                  /**
+                                   * For a given Triangulation, update the
+                                   * number cache for hexes. For 3d, we have
+                                   * to deal with the fact that hexes have
+                                   * levels, whereas for higher dimensions
+                                   * they do not.
+                                   *
+                                   * At the end of the function, we call the
+                                   * respective function to update the number
+                                   * cache for quads, which will in turn call
+                                   * the respective function for lines.
+                                   */
+  template <int dim, int spacedim>
+  void compute_number_cache (const Triangulation<dim,spacedim>       &triangulation,
+                            internal::Triangulation::NumberCache<3> &number_cache) 
+  {
+    typedef
+      typename Triangulation<dim,spacedim>::hex_iterator hex_iterator;
+    typedef
+      typename Triangulation<dim,spacedim>::active_hex_iterator active_hex_iterator;
+    
+                                    ///////////////////////////////////
+                                    // update the number of hexes
+                                    // on the different levels in
+                                    // the cache
+    number_cache.n_hexes_level.resize (triangulation.n_levels());
+    number_cache.n_hexes = 0;
+
+    number_cache.n_active_hexes_level.resize (triangulation.n_levels());
+    number_cache.n_active_hexes = 0;
+
+                                    // for 3d, hexes have levels so take
+                                    // count the objects per level and
+                                    // globally
+    if (dim == 3)
+      {
+       for (unsigned int level=0; level<triangulation.n_levels(); ++level)
+         {
+                                            // count hexes on this level
+           number_cache.n_hexes_level[level] = 0;
+
+           hex_iterator hex = triangulation.begin_hex (level),
+                       endc = (level == triangulation.n_levels()-1 ?
+                               hex_iterator(triangulation.end_hex()) :
+                               triangulation.begin_hex (level+1));
+           for (; hex!=endc; ++hex)
+             ++number_cache.n_hexes_level[level];
+      
+                                            // update total number of hexes
+           number_cache.n_hexes += number_cache.n_hexes_level[level];
+         }
 
-  std::vector<unsigned char> boundary_indicators(n_bi);
-  unsigned int bi_counter=0;
-  for (unsigned int i=0; i<bi_exists.size(); ++i)
-    if (bi_exists[i]==true)
-      boundary_indicators[bi_counter++]=i;
+                                        // do the update for the number of
+                                        // active hexes as well
+       for (unsigned int level=0; level<triangulation.n_levels(); ++level)
+         {
+                                            // count hexes on this level
+           number_cache.n_active_hexes_level[level] = 0;
 
-  return boundary_indicators;
-}
+           active_hex_iterator hex = triangulation.begin_active_hex (level),
+                              endc = triangulation.end_active_hex (level);
+           for (; hex!=endc; ++hex)
+             ++number_cache.n_active_hexes_level[level];
+      
+                                            // update total number of hexes
+           number_cache.n_active_hexes += number_cache.n_active_hexes_level[level];
+         }
+      }
+    else
+      {
+                                        // for dim>3, there are no
+                                        // levels for hexs
+       {
+         hex_iterator hex  = triangulation.begin_hex (),
+                      endc = triangulation.end_hex();
+         for (; hex!=endc; ++hex)
+           ++number_cache.n_hexes;
+       }
 
-#endif
+       {
+         active_hex_iterator hex  = triangulation.begin_active_hex (),
+                             endc = triangulation.end_hex();
+         for (; hex!=endc; ++hex)
+           ++number_cache.n_active_hexes;
+       }
+      }
 
-/*--------- Put the next functions a bit out-or-order to avoid use before
-  --------- explicit specialization, which is not allowed.                */
 
-#if deal_II_dimension == 1
+                                    // update quads and lines
+    compute_number_cache (triangulation,
+                         static_cast<internal::Triangulation::NumberCache<2>&>(number_cache));
+  }
 
-template <>
-Triangulation<1>::cell_iterator
-Triangulation<1>::begin (const unsigned int level) const
-{
-  return begin_line (level);
-}
 
 
-template <>
-Triangulation<1>::raw_cell_iterator
-Triangulation<1>::end () const
-{
-  return end_line ();
-}
+                                  /**
+                                   * A set of three functions that
+                                   * reorder the data given to
+                                   * create_triangulation_compatibility
+                                   * from the "classic" to the
+                                   * "current" format of vertex
+                                   * numbering of cells and
+                                   * faces. These functions do the
+                                   * reordering of their arguments
+                                   * in-place.
+                                   */
+  void
+  reorder_compatibility (const std::vector<CellData<1> >      &,
+                        const SubCellData                    &)
+  {
+                                    // nothing to do here: the format
+                                    // hasn't changed for 1d
+  }
+  
 
-#endif
+  void
+  reorder_compatibility (std::vector<CellData<2> > &cells,
+                        const SubCellData         &)
+  {
+    for (unsigned int cell=0; cell<cells.size(); ++cell)
+      std::swap(cells[cell].vertices[2],cells[cell].vertices[3]);
+  }
+  
 
+  void
+  reorder_compatibility (std::vector<CellData<3> > &cells,
+                        SubCellData               &subcelldata)
+  {
+    unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
+    for (unsigned int cell=0; cell<cells.size(); ++cell)
+      {
+       for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
+         tmp[i] = cells[cell].vertices[i];
+       for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
+         cells[cell].vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
+      }
 
-#if deal_II_dimension == 2
+                                    // now points in boundary quads
+    std::vector<CellData<2> >::iterator boundary_quad
+      = subcelldata.boundary_quads.begin();
+    std::vector<CellData<2> >::iterator end_quad
+      = subcelldata.boundary_quads.end();
+    for (unsigned int quad_no=0; boundary_quad!=end_quad; ++boundary_quad, ++quad_no)
+      std::swap(boundary_quad->vertices[2], boundary_quad->vertices[3]);
+  }
 
-template <>
-Triangulation<2>::cell_iterator
-Triangulation<2>::begin (const unsigned int level) const
-{
-  return begin_quad (level);
-}
 
 
-template <>
-Triangulation<2>::raw_cell_iterator
-Triangulation<2>::end () const
-{
-  return end_quad ();
-}
+                                    /**
+                                     * Return the index of the vertex
+                                     * in the middle of this object,
+                                     * if it exists. In order to
+                                     * exist, the object needs to be
+                                     * refined - for 2D and 3D it
+                                     * needs to be refined
+                                     * isotropically or else the
+                                     * anisotropic children have to
+                                     * be refined again. If the
+                                     * middle vertex does not exist,
+                                     * return
+                                     * <tt>numbers::invalid_unsigned_int</tt>.
+                                     *
+                                     * This function should not really be
+                                     * used in application programs.
+                                     */
+  template <int dim, int spacedim>
+  unsigned int
+  middle_vertex_index(const typename Triangulation<dim,spacedim>::line_iterator &line)
+  {
+    if (line->has_children())
+      return line->child(0)->vertex_index(1);
+    return numbers::invalid_unsigned_int;
+  }
+  
 
-#endif
-
-
-#if deal_II_dimension == 3
-
-template <>
-Triangulation<3>::cell_iterator
-Triangulation<3>::begin (const unsigned int level) const
-{
-  return begin_hex (level);
-}
-
-
-template <>
-Triangulation<3>::raw_cell_iterator
-Triangulation<3>::end () const
-{
-  return end_hex ();
-}
-
-#endif
-
-
-/*-----------------------------------------------------------------*/
-
-
-template <int dim>
-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;
-  anisotropic_refinement = old_tria.anisotropic_refinement;
-  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];
-
-  levels.reserve (old_tria.levels.size());
-  for (unsigned int level=0; level<old_tria.levels.size(); ++level)
-    levels.push_back (new internal::Triangulation::TriaLevel<dim>(*old_tria.levels[level]));
-
-  number_cache = old_tria.number_cache;
-  
-                                  // inform RefinementListeners of old_tria of
-                                  // the copy operation
-  typename std::list<RefinementListener *>::iterator ref_listener =
-    old_tria.refinement_listeners.begin (),
-    end_listener = old_tria.refinement_listeners.end ();
-  for (; ref_listener != end_listener; ++ref_listener)
-    (*ref_listener)->copy_notification (old_tria, *this);
-  
-                                  // note that we need not copy the
-                                  // subscriptor!
-}
-
-
-#if deal_II_dimension == 1
-
-template <>
-void Triangulation<1>::create_triangulation_compatibility (
-  const std::vector<Point<1> >    &v,
-  const std::vector<CellData<1> > &cells,
-  const SubCellData               &subcelldata)
-{
-                                  // no reordering required
-  create_triangulation(v, cells, subcelldata);
-}
-
-
-template <>
-void Triangulation<1>::create_triangulation (const std::vector<Point<1> >    &v,
-                                            const std::vector<CellData<1> > &cells,
-                                            const SubCellData &subcelldata)
-{
-                                  // note: since no boundary
-                                  // information can be given in one
-                                  // dimension, the @p{subcelldata}
-                                  // field is ignored. (only used for
-                                  // error checking, which is a good
-                                  // idea in any case)
-  
-  const unsigned int dim=1;
-  
-  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());
-
-                                  // copy vertices
-  vertices = v;
-  vertices_used = std::vector<bool> (v.size(), true);
-    
-                                  // store the indices of the lines
-                                  // which are adjacent to a given
-                                  // vertex
-  std::vector<std::vector<int> > lines_at_vertex (v.size());
-
-                                  // reserve enough space
-  levels.push_back (new internal::Triangulation::TriaLevel<dim>);
-  levels[0]->reserve_space (cells.size(), dim);
-  levels[0]->cells.reserve_space (0,cells.size());
+  template <int dim, int spacedim>
+  unsigned int
+  middle_vertex_index(const typename Triangulation<dim,spacedim>::quad_iterator &quad)
+  {
+    switch (static_cast<unsigned char> (quad->refinement_case()))
+      {
+       case RefinementCase<2>::cut_x:
+             return middle_vertex_index<dim,spacedim>(quad->child(0)->line(1));
+             break;
+       case RefinementCase<2>::cut_y:
+             return middle_vertex_index<dim,spacedim>(quad->child(0)->line(3));
+             break;
+       case RefinementCase<2>::cut_xy:
+             return quad->child(0)->vertex_index(3);
+             break;
+       default:
+             break;
+      }
+    return numbers::invalid_unsigned_int;
+  }
   
-                                  // make up cells
-  raw_line_iterator next_free_line = begin_raw_line ();
-  for (unsigned int cell=0; cell<cells.size(); ++cell) 
-    {
-      while (next_free_line->used())
-       ++next_free_line;
-      
-      next_free_line->set (internal::Triangulation
-                           ::TriaObject<1> (cells[cell].vertices[0],
-                                           cells[cell].vertices[1]));
-      next_free_line->set_used_flag ();
-      next_free_line->set_material_id (cells[cell].material_id);
-      next_free_line->clear_user_data ();
-      next_free_line->set_subdomain_id (0);
-      
-                                      // note that this cell is
-                                      // adjacent to these vertices
-      lines_at_vertex[cells[cell].vertices[0]].push_back (cell);
-      lines_at_vertex[cells[cell].vertices[1]].push_back (cell);
-    }
-
 
-                                  // some security tests
-  unsigned int boundary_nodes = 0;
-  for (unsigned int i=0; i<lines_at_vertex.size(); ++i)
-    switch (lines_at_vertex[i].size()) 
+  template <int dim, int spacedim>
+  unsigned int
+  middle_vertex_index(const typename Triangulation<dim,spacedim>::hex_iterator &hex)
+  {
+    switch (static_cast<unsigned char> (hex->refinement_case()))
       {
-       case 1:
-                                              // this vertex has only
-                                              // one adjacent line
-             ++boundary_nodes;
+       case RefinementCase<3>::cut_x:
+             return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(1));
+             break;
+       case RefinementCase<3>::cut_y:
+             return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(3));
+             break;
+       case RefinementCase<3>::cut_z:
+             return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(5));
+             break;
+       case RefinementCase<3>::cut_xy:
+             return middle_vertex_index<dim,spacedim>(hex->child(0)->line(11));
              break;
-       case 2:
+       case RefinementCase<3>::cut_xz:
+             return middle_vertex_index<dim,spacedim>(hex->child(0)->line(5));
+             break;
+       case RefinementCase<3>::cut_yz:
+             return middle_vertex_index<dim,spacedim>(hex->child(0)->line(7));
+             break;
+       case RefinementCase<3>::cut_xyz:
+             return hex->child(0)->vertex_index(7);
              break;
        default:
-                                              // a node must have one
-                                              // or two adjacent
-                                              // lines
-             clear_despite_subscriptions ();
-
-             AssertThrow (false, ExcInternalError());
+             break;
       }
-
-                                  // assert there are no more than
-                                  // two boundary nodes
-  if (boundary_nodes != 2)
-    {
-      clear_despite_subscriptions();
-      
-      AssertThrow (false, ExcInternalError());
-    }
+    return numbers::invalid_unsigned_int;
+  }
   
+}// end of anonymous namespace
 
 
-                                  // update neighborship info
-  active_line_iterator line = begin_active_line ();
-                                  // for all lines
-  for (; line!=end(); ++line)
-                                    // for each of the two vertices
-    for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
-                                      // if first cell adjacent to
-                                      // this vertex is the present
-                                      // one, then the neighbor is
-                                      // the second adjacent cell and
-                                      // vice versa
-      if (lines_at_vertex[line->vertex_index(vertex)][0] == line->index())
-       if (lines_at_vertex[line->vertex_index(vertex)].size() == 2) 
+
+/**
+ * A class into which we put many of the functions that implement
+ * functionality of the Triangulation class. The main reason for this
+ * class is as follows: the majority of the functions in Triangulation
+ * need to be implemented differently for dim==1, dim==2, and
+ * dim==3. However, their implementation is largly independent of the
+ * spacedim template parameter. So we would like to write things like
+ *
+ * template <int spacedim>
+ * void Triangulation<1,spacedim>::create_triangulation (...) {...}
+ *
+ * Unfortunately, C++ doesn't allow this: member functions of class
+ * templates have to be either not specialized at all, or fully
+ * specialized. No partial specialization is allowed. One possible
+ * solution would be to just duplicate the bodies of the functions and
+ * have equally implemented functions
+ *
+ * template <>
+ * void Triangulation<1,1>::create_triangulation (...) {...}
+ *
+ * template <>
+ * void Triangulation<1,2>::create_triangulation (...) {...}
+ *
+ * but that is clearly an unsatisfactory solution. Rather, what we do
+ * is introduce the current Implementation class in which we can write
+ * these functions as member templates over spacedim, i.e. we can have
+ *
+ * template <int dim_, int spacedim_>
+ * template <int spacedim>
+ * void Triangulation<dim_,spacedim_>::Implementation::
+ *            create_triangulation (...,
+ *                                  Triangulation<1,spacedim> &tria ) {...}
+ *
+ * The outer template parameters are here unused, only the inner
+ * ones are of real interest.
+ *
+ * One may ask why we put these functions into an inner class rather
+ * than an anonymous namespace, for example. There are threee main reasons:
+ *
+ * First, these implementation functions need to be friends of the
+ * Triangulation class. It is simpler to make the entire class a friend
+ * rather than listing all members of an implementation namespace as
+ * friends of the Triangulation class (there is no such thing as a "friend
+ * namespace XXX" directive).
+ *
+ * Secondly, by making this class a member class of the
+ * Triangulation<dim,spacedim> class, our implementation functions
+ * have immediate access to the typedefs and static functions of the
+ * surrounding Triangulation class. I.e., we do not have to write
+ * "typename Triangulation<dim,spacedim>::active_cell_iterator" but
+ * can write "active_cell_iterator" right away.
+ *
+ * Finally, by only forward declaring the class in the .h file and
+ * declaring it here with member functions inlined, there is no need
+ * to declare all sorts of helper functions in the .h file: Much of
+ * what is implementation specific can be done within the .cc file
+ * without exposing any of the interface to the outside.
+ */
+template <int dim_, int spacedim_>
+struct Triangulation<dim_,spacedim_>::Implementation
+{
+                                    /**
+                                     * Create a triangulation from
+                                     * given data. This function does
+                                     * this work for 1-dimensional
+                                     * triangulations independently
+                                     * of the actual space dimension.
+                                     */
+    template <int spacedim>
+    static
+    void
+    create_triangulation (const std::vector<Point<spacedim> > &v,
+                         const std::vector<CellData<1> >     &cells,
+                         const SubCellData                   &/*subcelldata*/,
+                         Triangulation<1,spacedim>           &triangulation)
+      {
+                                        // note: since no boundary
+                                        // information can be given in one
+                                        // dimension, the @p{subcelldata}
+                                        // field is ignored. (only used for
+                                        // error checking, which is a good
+                                        // idea in any case)  
+       const unsigned int dim=1;
+  
+                                        // copy vertices
+       triangulation.vertices = v;
+       triangulation.vertices_used = std::vector<bool> (v.size(), true);
+    
+                                        // store the indices of the lines
+                                        // which are adjacent to a given
+                                        // vertex
+       std::vector<std::vector<int> > lines_at_vertex (v.size());
+
+                                        // reserve enough space
+       triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+       triangulation.levels[0]->reserve_space (cells.size(), dim);
+       triangulation.levels[0]->cells.reserve_space (0,cells.size());
+  
+                                        // make up cells
+       raw_line_iterator next_free_line = triangulation.begin_raw_line ();
+       for (unsigned int cell=0; cell<cells.size(); ++cell) 
          {
-           const cell_iterator neighbor (const_cast<Triangulation<1>*>(this),
-                                         0,              // level
-                                         lines_at_vertex[line->vertex_index(vertex)][1]);
-           line->set_neighbor (vertex, neighbor);
+           while (next_free_line->used())
+             ++next_free_line;
+      
+           next_free_line->set (internal::Triangulation
+                                ::TriaObject<1> (cells[cell].vertices[0],
+                                                 cells[cell].vertices[1]));
+           next_free_line->set_used_flag ();
+           next_free_line->set_material_id (cells[cell].material_id);
+           next_free_line->clear_user_data ();
+           next_free_line->set_subdomain_id (0);
+      
+                                            // note that this cell is
+                                            // adjacent to these vertices
+           lines_at_vertex[cells[cell].vertices[0]].push_back (cell);
+           lines_at_vertex[cells[cell].vertices[1]].push_back (cell);
          }
-       else
-                                          // no second adjacent cell
-                                          // entered -> cell at
-                                          // boundary
-         line->set_neighbor (vertex, end());
-      else
-                                        // present line is not first
-                                        // adjacent one -> first
-                                        // adjacent one is neighbor
-       {
-         const cell_iterator neighbor (const_cast<Triangulation<1>*>(this),
-                                       0,              // level
-                                       lines_at_vertex[line->vertex_index(vertex)][0]);
-         line->set_neighbor (vertex, neighbor);
-       }
-
-
-                                  // re-compute numbers of lines, etc
-  update_number_cache ();  
-}
-
-#endif
-
-
-#if deal_II_dimension == 2
 
-template <>
-void Triangulation<2>::create_triangulation_compatibility (
-  const std::vector<Point<2> >    &v,
-  const std::vector<CellData<2> > &c,
-  const SubCellData               &subcelldata)
-{
-  const bool output=false;
 
-                                  // copy cell data as it will be
-                                  // modified in the following
-  std::vector<CellData<2> > cells(c);
-  
-  for (unsigned int cell=0; cell<cells.size(); ++cell)
-    {
-      if (output)
+                                        // some security tests
        {
-         std::cout << "cell" << cell << ": ";
-         for (unsigned int vertex=0; vertex<4; ++vertex)
-           std::cout << cells[cell].vertices[vertex] << " ";
-       }
-
-      std::swap(cells[cell].vertices[2],cells[cell].vertices[3]);
-      
+         unsigned int boundary_nodes = 0;
+         for (unsigned int i=0; i<lines_at_vertex.size(); ++i)
+           switch (lines_at_vertex[i].size()) 
+             {
+               case 1:
+                                                      // this vertex has only
+                                                      // one adjacent line
+                     ++boundary_nodes;
+                     break;
+               case 2:
+                     break;
+               default:
+                                                      // a node must have one
+                                                      // or two adjacent
+                                                      // lines
+                     AssertThrow (false, ExcInternalError());
+             }
 
-      if (output)
-       {
-         std::cout << "  after swap: ";
-         for (unsigned int vertex=0; vertex<4; ++vertex)
-           std::cout << cells[cell].vertices[vertex] << " ";
-         std::cout << std::endl;
+                                          // assert there are no more
+                                          // than two boundary
+                                          // nodes. note that if the
+                                          // space dimension is
+                                          // bigger than 1, then we
+                                          // can have fewer than 2
+                                          // nodes (for example a
+                                          // ring of cells -- no end
+                                          // points at all)
+         AssertThrow (((spacedim == 1) && (boundary_nodes == 2))
+                      ||
+                      ((spacedim > 1) && (boundary_nodes <= 2)),
+                      ExcMessage("The Triangulation has too many end points"));
        }
-    }
+       
 
-                                  // subcelldata.boundary_lines refer
-                                  // to the vertices in v. they don't
-                                  // need to be changed
-  
-  create_triangulation(v, cells, subcelldata);
-}
 
-template <>
-void Triangulation<2>::create_triangulation (const std::vector<Point<2> >    &v,
-                                            const std::vector<CellData<2> > &cells,
-                                            const SubCellData               &subcelldata)
-{
-  const unsigned int dim=2;
+                                        // update neighborship info
+       active_line_iterator line = triangulation.begin_active_line ();
+                                        // for all lines
+       for (; line!=triangulation.end(); ++line)
+                                          // for each of the two vertices
+         for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+                                            // if first cell adjacent to
+                                            // this vertex is the present
+                                            // one, then the neighbor is
+                                            // the second adjacent cell and
+                                            // vice versa
+           if (lines_at_vertex[line->vertex_index(vertex)][0] == line->index())
+             if (lines_at_vertex[line->vertex_index(vertex)].size() == 2) 
+               {
+                 const cell_iterator neighbor (&triangulation,
+                                               0,              // level
+                                               lines_at_vertex[line->vertex_index(vertex)][1]);
+                 line->set_neighbor (vertex, neighbor);
+               }
+             else
+                                                // no second adjacent cell
+                                                // entered -> cell at
+                                                // boundary
+               line->set_neighbor (vertex, triangulation.end());
+           else
+                                              // present line is not first
+                                              // adjacent one -> first
+                                              // adjacent one is neighbor
+             {
+               const cell_iterator neighbor (&triangulation,
+                                             0,              // level
+                                             lines_at_vertex[line->vertex_index(vertex)][0]);
+               line->set_neighbor (vertex, neighbor);
+             }
+      }
 
-  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());
 
-                                  // copy vertices
-  vertices = v;
-  vertices_used = std::vector<bool> (v.size(), true);
-
-                                  // make up a list of the needed
-                                  // lines each line is a pair of
-                                  // vertices. The list is kept
-                                  // sorted and it is guaranteed that
-                                  // each line is inserted only once.
-                                  // While the key of such an entry
-                                  // is the pair of vertices, the
-                                  // thing it points to is an
-                                  // iterator pointing to the line
-                                  // object itself. In the first run,
-                                  // these iterators are all invalid
-                                  // ones, but they are filled
-                                  // afterwards
-  std::map<std::pair<int,int>,line_iterator> needed_lines;
-  for (unsigned int cell=0; cell<cells.size(); ++cell)
-    {
-      for (unsigned int vertex=0; vertex<4; ++vertex)
-       if ( ! (cells[cell].vertices[vertex]<vertices.size()))
+                                    /**
+                                     * Create a triangulation from
+                                     * given data. This function does
+                                     * this work for 2-dimensional
+                                     * triangulations independently
+                                     * of the actual space dimension.
+                                     */
+    template <int spacedim>
+    static
+    void
+    create_triangulation (const std::vector<Point<spacedim> > &v,
+                         const std::vector<CellData<2> >     &cells,
+                         const SubCellData                   &subcelldata,
+                         Triangulation<2,spacedim>           &triangulation)
+      {
+       const unsigned int dim=2;
+
+                                        // copy vertices
+       triangulation.vertices = v;
+       triangulation.vertices_used = std::vector<bool> (v.size(), true);
+
+                                        // make up a list of the needed
+                                        // lines each line is a pair of
+                                        // vertices. The list is kept
+                                        // sorted and it is guaranteed that
+                                        // each line is inserted only once.
+                                        // While the key of such an entry
+                                        // is the pair of vertices, the
+                                        // thing it points to is an
+                                        // iterator pointing to the line
+                                        // object itself. In the first run,
+                                        // these iterators are all invalid
+                                        // ones, but they are filled
+                                        // afterwards
+       std::map<std::pair<int,int>,line_iterator> needed_lines;
+       for (unsigned int cell=0; cell<cells.size(); ++cell)
          {
-                                             // store the number of
-                                             // vertices, as this
-                                             // information will be
-                                             // deleted by clear()
-                                             // though we'd like to
-                                             // include it in the
-                                             // error message
-            const unsigned int n_vertices = vertices.size();
-
-           clear_despite_subscriptions();
-           
-           Assert (false,
-                   ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
-                                           n_vertices));
+           for (unsigned int vertex=0; vertex<4; ++vertex)
+             AssertThrow (cells[cell].vertices[vertex] < triangulation.vertices.size(),
+                          ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
+                                                 triangulation.vertices.size()));
+
+           for (unsigned int line=0; line<GeometryInfo<dim>::faces_per_cell; ++line)
+             {
+                                                // given a line vertex number
+                                                // (0,1) on a specific line we
+                                                // get the cell vertex number
+                                                // (0-4) through the
+                                                // line_to_cell_vertices
+                                                // function
+               std::pair<int,int> line_vertices(
+                 cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+                 cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
+
+                                                // assert that the line was
+                                                // not already inserted in
+                                                // reverse order. This
+                                                // happens in spite of the
+                                                // vertex rotation above,
+                                                // if the sense of the cell
+                                                // was incorrect.
+                                                //
+                                                // Here is what usually
+                                                // happened when this
+                                                // exception is thrown:
+                                                // consider these two cells
+                                                // and the vertices
+                                                //  3---4---5
+                                                //  |   |   |
+                                                //  0---1---2
+                                                // If in the input vector
+                                                // the two cells are given
+                                                // with vertices <0 1 4 3>
+                                                // and <4 1 2 5>, in the
+                                                // first cell the middle
+                                                // line would have
+                                                // direction 1->4, while in
+                                                // the second it would be
+                                                // 4->1.  This will cause
+                                                // the exception.
+               AssertThrow (needed_lines.find(std::make_pair(line_vertices.second,
+                                                             line_vertices.first))
+                            ==
+                            needed_lines.end(),
+                            ExcGridHasInvalidCell(cell));
+                 
+                                                // insert line, with
+                                                // invalid iterator if line
+                                                // already exists, then
+                                                // nothing bad happens here
+               needed_lines[line_vertices] = triangulation.end_line();
+             }
          }
 
 
-      for (unsigned int line=0; line<GeometryInfo<dim>::faces_per_cell; ++line)
+                                        // check that every vertex has at
+                                        // least two adjacent lines
        {
-                                          // given a line vertex number
-                                          // (0,1) on a specific line we
-                                          // get the cell vertex number
-                                          // (0-4) through the
-                                          // line_to_cell_vertices
-                                          // function
-         std::pair<int,int> line_vertices(
-           cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
-           cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
-
-                                          // assert that the line was
-                                          // not already inserted in
-                                          // reverse order. This
-                                          // happens in spite of the
-                                          // vertex rotation above,
-                                          // if the sense of the cell
-                                          // was incorrect.
-                                          //
-                                          // Here is what usually
-                                          // happened when this
-                                          // exception is thrown:
-                                          // consider these two cells
-                                          // and the vertices
-                                          //  3---4---5
-                                          //  |   |   |
-                                          //  0---1---2
-                                          // If in the input vector
-                                          // the two cells are given
-                                          // with vertices <0 1 4 3>
-                                          // and <4 1 2 5>, in the
-                                          // first cell the middle
-                                          // line would have
-                                          // direction 1->4, while in
-                                          // the second it would be
-                                          // 4->1.  This will cause
-                                          // the exception.
-         if (! (needed_lines.find(std::make_pair(line_vertices.second,
-                                                 line_vertices.first))
-                ==
-                needed_lines.end()))
+         std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
+         typename std::map<std::pair<int,int>,line_iterator>::iterator i;
+         for (i=needed_lines.begin(); i!=needed_lines.end(); i++) 
            {
-             clear_despite_subscriptions();
-             
-             AssertThrow (false,
-                          ExcGridHasInvalidCell(cell));
+                                              // touch the vertices of
+                                              // this line
+             ++vertex_touch_count[i->first.first];
+             ++vertex_touch_count[i->first.second];
            }
-                 
-                                          // insert line, with
-                                          // invalid iterator if line
-                                          // already exists, then
-                                          // nothing bad happens here
-         needed_lines[line_vertices] = end_line();
-       }
-    }
-
-
-                                  // check that every vertex has at
-                                  // least two adjacent lines
-  if (true) 
-    {
-      std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
-      std::map<std::pair<int,int>,line_iterator>::iterator i;
-      for (i=needed_lines.begin(); i!=needed_lines.end(); i++) 
-       {
-                                          // touch the vertices of
-                                          // this line
-         ++vertex_touch_count[i->first.first];
-         ++vertex_touch_count[i->first.second];
-       }
 
-                                      // assert minimum touch count
-                                      // is at least two. if not so,
-                                      // then clean triangulation and
-                                      // exit with an exception
-      if ( ! (* (std::min_element(vertex_touch_count.begin(),
-                                 vertex_touch_count.end())) >= 2))
-       {
-         clear_despite_subscriptions();
-         
-         AssertThrow (false, ExcGridHasInvalidVertices());
+                                          // assert minimum touch count
+                                          // is at least two. if not so,
+                                          // then clean triangulation and
+                                          // exit with an exception
+         AssertThrow (* (std::min_element(vertex_touch_count.begin(),
+                                          vertex_touch_count.end())) >= 2,
+                      ExcGridHasInvalidVertices());
        }
-    }
        
-                                  // reserve enough space
-  levels.push_back (new internal::Triangulation::TriaLevel<dim>);
-  faces = new internal::Triangulation::TriaFaces<dim>;
-  levels[0]->reserve_space (cells.size(), dim);
-  faces->lines.reserve_space (0,needed_lines.size());
-  levels[0]->cells.reserve_space (0,cells.size());
-
-                                  // make up lines
-  if (true) 
-    {
-      raw_line_iterator line = begin_raw_line();
-      std::map<std::pair<int,int>,line_iterator>::iterator i;
-      for (i = needed_lines.begin(); line!=end_line(); ++line, ++i) 
+                                        // reserve enough space
+       triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+       triangulation.faces = new internal::Triangulation::TriaFaces<dim>;
+       triangulation.levels[0]->reserve_space (cells.size(), dim);
+       triangulation.faces->lines.reserve_space (0,needed_lines.size());
+       triangulation.levels[0]->cells.reserve_space (0,cells.size());
+
+                                        // make up lines
        {
-         line->set (internal::Triangulation::TriaObject<1>(i->first.first,
-                                                           i->first.second));
-         line->set_used_flag ();
-         line->clear_user_flag ();
-         line->clear_user_data ();
-         i->second = line;
+         raw_line_iterator line = triangulation.begin_raw_line();
+         typename std::map<std::pair<int,int>,line_iterator>::iterator i;
+         for (i = needed_lines.begin();
+              line!=triangulation.end_line(); ++line, ++i) 
+           {
+             line->set (internal::Triangulation::TriaObject<1>(i->first.first,
+                                                               i->first.second));
+             line->set_used_flag ();
+             line->clear_user_flag ();
+             line->clear_user_data ();
+             i->second = line;
+           }
        }
-    }
 
 
-                                  // store for each line index
-                                  // the adjacent cells
-  std::map<int,std::vector<cell_iterator> > adjacent_cells;
+                                        // store for each line index
+                                        // the adjacent cells
+       std::map<int,std::vector<cell_iterator> > adjacent_cells;
 
-                                  // finally make up cells
-  if (true) 
-    {
-      raw_cell_iterator cell = begin_raw_quad();
-      for (unsigned int c=0; c<cells.size(); ++c, ++cell)
+                                        // finally make up cells
        {
-         line_iterator lines[GeometryInfo<dim>::lines_per_cell];
-         for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-           lines[line]=needed_lines[std::make_pair(
-                                      cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
-                                      cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)])];
-         
-         cell->set (internal::Triangulation::TriaObject<2> (lines[0]->index(),
-                                                            lines[1]->index(),
-                                                            lines[2]->index(),
-                                                            lines[3]->index()));
+         raw_cell_iterator cell = triangulation.begin_raw_quad();
+         for (unsigned int c=0; c<cells.size(); ++c, ++cell)
+           {
+             line_iterator lines[GeometryInfo<dim>::lines_per_cell];
+             for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+               lines[line]=needed_lines[std::make_pair(
+                   cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+                   cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)])];
          
-         cell->set_used_flag ();
-         cell->set_material_id (cells[c].material_id);
-         cell->clear_user_data ();
-         cell->set_subdomain_id (0);
+             cell->set (internal::Triangulation::TriaObject<2> (lines[0]->index(),
+                                                                lines[1]->index(),
+                                                                lines[2]->index(),
+                                                                lines[3]->index()));
          
-                                          // note that this cell is
-                                          // adjacent to the four
-                                          // lines
-         for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-           adjacent_cells[lines[line]->index()].push_back (cell);
-       }
-    }
-
-
-  for (line_iterator line=begin_line(); line!=end_line(); ++line) 
-    {
-      const unsigned int n_adj_cells = adjacent_cells[line->index()].size();
-                                      // assert that every line has
-                                      // one or two adjacent cells
-      if (! ((n_adj_cells >= 1) &&
-            (n_adj_cells <= 2)))
-       {
-         clear_despite_subscriptions();
+             cell->set_used_flag ();
+             cell->set_material_id (cells[c].material_id);
+             cell->clear_user_data ();
+             cell->set_subdomain_id (0);
          
-         AssertThrow (false, ExcInternalError());
-       }
-
-                                      // if only one cell: line is at
-                                      // boundary -> give it the
-                                      // boundary indicator zero by
-                                      // default
-      if (n_adj_cells == 1)
-       line->set_boundary_indicator (0);
-      else
-                                        // interior line -> 255
-       line->set_boundary_indicator (255);
-    }
-
-                                  // set boundary indicators where
-                                  // given
-  std::vector<CellData<1> >::const_iterator boundary_line
-    = subcelldata.boundary_lines.begin();
-  std::vector<CellData<1> >::const_iterator end_boundary_line
-    = subcelldata.boundary_lines.end();
-  for (; boundary_line!=end_boundary_line; ++boundary_line) 
-    {
-      line_iterator line;
-      std::pair<int,int> line_vertices(std::make_pair(boundary_line->vertices[0],
-                                                     boundary_line->vertices[1]));
-      if (needed_lines.find(line_vertices) != needed_lines.end())
-                                        // line found in this
-                                        // direction
-       line = needed_lines[line_vertices];
-      else 
-       {
-                                          // look whether it exists
-                                          // in reverse direction
-         std::swap (line_vertices.first, line_vertices.second);
-         if (needed_lines.find(line_vertices) != needed_lines.end())
-           line = needed_lines[line_vertices];
-         else 
-           {
-                                              // line does not exist
-             clear_despite_subscriptions();
-
-             AssertThrow (false, ExcLineInexistant(line_vertices.first,
-                                                   line_vertices.second));
+                                              // note that this cell is
+                                              // adjacent to the four
+                                              // lines
+             for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+               adjacent_cells[lines[line]->index()].push_back (cell);
            }
        }
 
-                                      // assert that we only set
-                                      // boundary info once
-      if (line->boundary_indicator() != 0 &&
-         line->boundary_indicator() != 255)
-       {
-         clear_despite_subscriptions();
-         
-         AssertThrow (false, ExcMultiplySetLineInfoOfLine(
-                        line_vertices.first, line_vertices.second));
-       }
-      
-                                      // Assert that only exterior lines
-                                      // are given a boundary indicator
-      if (line->boundary_indicator() == 255)
-       {
-         clear_despite_subscriptions();
-         
-         AssertThrow (false, ExcInteriorLineCantBeBoundary());
-       }
-
-      line->set_boundary_indicator (boundary_line->material_id);
-    }
 
+       for (line_iterator line=triangulation.begin_line();
+            line!=triangulation.end_line(); ++line) 
+         {
+           const unsigned int n_adj_cells = adjacent_cells[line->index()].size();
+                                            // assert that every line has
+                                            // one or two adjacent cells
+           AssertThrow ((n_adj_cells >= 1) &&
+                        (n_adj_cells <= 2),
+                        ExcInternalError());
+           
+                                            // if only one cell: line is at
+                                            // boundary -> give it the
+                                            // boundary indicator zero by
+                                            // default
+           if (n_adj_cells == 1)
+             line->set_boundary_indicator (0);
+           else
+                                              // interior line -> 255
+             line->set_boundary_indicator (255);
+         }
 
-                                  // finally update neighborship info
-  for (cell_iterator cell=begin(); cell!=end(); ++cell)
-    for (unsigned int side=0; side<4; ++side)
-      if (adjacent_cells[cell->line(side)->index()][0] == cell)
-                                        // first adjacent cell is
-                                        // this one
-       {
-         if (adjacent_cells[cell->line(side)->index()].size() == 2)
-                                            // there is another
-                                            // adjacent cell
-           cell->set_neighbor (side,
-                               adjacent_cells[cell->line(side)->index()][1]);
-       }
-                                  // first adjacent cell is not this
-                                  // one, -> it must be the neighbor
-                                  // we are looking for
-      else
-       cell->set_neighbor (side,
-                           adjacent_cells[cell->line(side)->index()][0]);
+                                        // set boundary indicators where
+                                        // given
+       std::vector<CellData<1> >::const_iterator boundary_line
+         = subcelldata.boundary_lines.begin();
+       std::vector<CellData<1> >::const_iterator end_boundary_line
+         = subcelldata.boundary_lines.end();
+       for (; boundary_line!=end_boundary_line; ++boundary_line) 
+         {
+           line_iterator line;
+           std::pair<int,int> line_vertices(std::make_pair(boundary_line->vertices[0],
+                                                           boundary_line->vertices[1]));
+           if (needed_lines.find(line_vertices) != needed_lines.end())
+                                              // line found in this
+                                              // direction
+             line = needed_lines[line_vertices];
+           else 
+             {
+                                                // look whether it exists
+                                                // in reverse direction
+               std::swap (line_vertices.first, line_vertices.second);
+               if (needed_lines.find(line_vertices) != needed_lines.end())
+                 line = needed_lines[line_vertices];
+               else 
+                                                  // line does not exist
+                 AssertThrow (false, ExcLineInexistant(line_vertices.first,
+                                                       line_vertices.second));
+             }
 
+                                            // assert that we only set
+                                            // boundary info once
+           AssertThrow (! (line->boundary_indicator() != 0 &&
+                           line->boundary_indicator() != 255),
+                        ExcMultiplySetLineInfoOfLine(line_vertices.first,
+                                                     line_vertices.second));
+      
+                                            // Assert that only exterior lines
+                                            // are given a boundary indicator
+           AssertThrow (! (line->boundary_indicator() == 255),
+                        ExcInteriorLineCantBeBoundary());
 
-                                  // re-compute numbers of lines, etc
-  update_number_cache ();  
-}
+           line->set_boundary_indicator (boundary_line->material_id);
+         }
 
-#endif
 
+                                        // finally update neighborship info
+       for (cell_iterator cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
+         for (unsigned int side=0; side<4; ++side)
+           if (adjacent_cells[cell->line(side)->index()][0] == cell)
+                                              // first adjacent cell is
+                                              // this one
+             {
+               if (adjacent_cells[cell->line(side)->index()].size() == 2)
+                                                  // there is another
+                                                  // adjacent cell
+                 cell->set_neighbor (side,
+                                     adjacent_cells[cell->line(side)->index()][1]);
+             }
+                                        // first adjacent cell is not this
+                                        // one, -> it must be the neighbor
+                                        // we are looking for
+           else
+             cell->set_neighbor (side,
+                                 adjacent_cells[cell->line(side)->index()][0]);        
+      }
 
-#if deal_II_dimension == 3
 
 /**
  * Invent an object which compares two internal::Triangulation::TriaObject<2>
  * against each other. This comparison is needed in order to establish a map
- * of TriaObject<2> to iterators in the Triangulation<3>::create_triangulation
+ * of TriaObject<2> to iterators in the Triangulation<3,3>::create_triangulation
  * function.
  *
  * Since this comparison is not canonical, we do not include it into the
  * general internal::Triangulation::TriaObject<2> class.
  */
-struct QuadComparator
-{
-    inline bool operator () (const internal::Triangulation::TriaObject<2> &q1,
-                             const internal::Triangulation::TriaObject<2> &q2) const
-      {
-                                        // here is room to optimize
-                                        // the repeated equality test
-                                        // of the previous lines, but
-                                        // I don't care at present
-       if ((q1.face(0) < q2.face(0))          ||
-           ((q1.face(0) == q2.face(0)) &&
-            (q1.face(1) <  q2.face(1)))       ||
-           ((q1.face(0) == q2.face(0)) &&
-            (q1.face(1) == q2.face(1)) &&
-            (q1.face(2) <  q2.face(2)))       ||
-           ((q1.face(0) == q2.face(0)) &&
-            (q1.face(1) == q2.face(1)) &&
-            (q1.face(2) == q2.face(2)) &&
-            (q1.face(3) <  q2.face(3))))
-         return true;
-       else
-         return false;
-      }
-};
-
-
-template <>
-void
-Triangulation<3>::create_triangulation_compatibility (
-  const std::vector<Point<3> >    &v,
-  const std::vector<CellData<3> > &c,
-  const SubCellData               &subc)
-{
-  const bool output1=false;
-  const bool output2=false;
-
-                                  // copy cell and subcell data as
-                                  // they will be modified in the
-                                  // following
-  std::vector<CellData<3> > cells(c);
-  SubCellData subcelldata(subc);
-  
-  unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
-  for (unsigned int cell=0; cell<cells.size(); ++cell)
-    {
-      if (output1)
-       {
-         std::cout << "cell" << cell << ": ";
-         for (unsigned int vertex=0;
-              vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
-           std::cout << cells[cell].vertices[vertex] << " ";
-       }
-
-      for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
-       tmp[i]=cells[cell].vertices[i];
-      for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
-       cells[cell].vertices[GeometryInfo<3>::ucd_to_deal[i]]=tmp[i];
-
-      if (output1)
-       {
-         std::cout << "  after swap: ";
-         for (unsigned int vertex=0;
-              vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
-           std::cout << cells[cell].vertices[vertex] << " ";
-         std::cout << std::endl;
-         std::cout << "vertices:" << std::endl;
-         for (unsigned int vertex=0;
-              vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
-           std::cout << v[cells[cell].vertices[vertex]] << std::endl;
-       }
-    }
-
-  if (output2)
+    struct QuadComparator
     {
-      std::cout << "vertices:" << std::endl;
-      for (unsigned int i=0; i<vertices.size(); ++i)
-       std::cout << vertices[i] << std::endl;
-    }
-                                  // now points in boundary quads
-  std::vector<CellData<2> >::iterator boundary_quad
-    = subcelldata.boundary_quads.begin();
-  std::vector<CellData<2> >::iterator end_quad
-    = subcelldata.boundary_quads.end();
-  for (unsigned int quad_no=0; boundary_quad!=end_quad; ++boundary_quad, ++quad_no)
-    {
-      if (output2)
-       std::cout << quad_no << ": " << boundary_quad->vertices[0]
-                 << ",  " << boundary_quad->vertices[1]
-                 << ",  " << boundary_quad->vertices[2]
-                 << ",  " << boundary_quad->vertices[3];
-      
-      std::swap(boundary_quad->vertices[2], boundary_quad->vertices[3]);
-
-      if (output2)
-       std::cout << ", after swap: " << boundary_quad->vertices[0]
-                 << ",  " << boundary_quad->vertices[1]
-                 << ",  " << boundary_quad->vertices[2]
-                 << ",  " << boundary_quad->vertices[3] << std::endl;
-    }  
-
-  create_triangulation(v, cells, subcelldata);
-}
-
+       inline bool operator () (const internal::Triangulation::TriaObject<2> &q1,
+                                const internal::Triangulation::TriaObject<2> &q2) const
+         {
+                                            // here is room to
+                                            // optimize the repeated
+                                            // equality test of the
+                                            // previous lines; the
+                                            // compiler will probably
+                                            // take care of most of
+                                            // it anyway
+           if ((q1.face(0) < q2.face(0))          ||
+               ((q1.face(0) == q2.face(0)) &&
+                (q1.face(1) <  q2.face(1)))       ||
+               ((q1.face(0) == q2.face(0)) &&
+                (q1.face(1) == q2.face(1)) &&
+                (q1.face(2) <  q2.face(2)))       ||
+               ((q1.face(0) == q2.face(0)) &&
+                (q1.face(1) == q2.face(1)) &&
+                (q1.face(2) == q2.face(2)) &&
+                (q1.face(3) <  q2.face(3))))
+             return true;
+           else
+             return false;
+         }
+    };
 
-template <>
-void
-Triangulation<3>::create_triangulation (const std::vector<Point<3> >    &v,
-                                        const std::vector<CellData<3> > &cells,
-                                        const SubCellData               &subcelldata)
-{
-  const unsigned int dim=3;
 
-  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());
 
-                                  // copy vertices
-  vertices = v;
-  vertices_used = std::vector<bool> (v.size(), true);
-
-                                  // check that all cells have
-                                  // positive volume. if not call the
-                                  // invert_all_cells_of_negative_grid
-                                  // and reorder_cells function of
-                                  // GridReordering before creating
-                                  // the triangulation
-  for (unsigned int cell_no=0; cell_no<cells.size(); ++cell_no)
-    if (GridTools::cell_measure(vertices, cells[cell_no].vertices) < 0)
+    template <int spacedim>
+    static
+    void
+    create_triangulation (const std::vector<Point<spacedim> > &v,
+                         const std::vector<CellData<3> >     &cells,
+                         const SubCellData                   &subcelldata,
+                         Triangulation<3,spacedim>           &triangulation)
       {
-       clear_despite_subscriptions();
-       
-       AssertThrow (false, ExcGridHasInvalidCell(cell_no));
-      }
-
-                                  ///////////////////////////////////////
-                                  // first set up some collections of data
-                                  //
-                                  // make up a list of the needed
-                                  // lines
-                                  //
-                                  // each line is a pair of
-                                  // vertices. The list is kept
-                                  // sorted and it is guaranteed that
-                                  // each line is inserted only once.
-                                  // While the key of such an entry
-                                  // is the pair of vertices, the
-                                  // thing it points to is an
-                                  // iterator pointing to the line
-                                  // object itself. In the first run,
-                                  // these iterators are all invalid
-                                  // ones, but they are filled
-                                  // afterwards same applies for the
-                                  // quads
-  std::map<std::pair<int,int>,line_iterator> needed_lines;
-  for (unsigned int cell=0; cell<cells.size(); ++cell)
-    {
-
-                                      // check whether vertex indices
-                                      // are valid ones
-      for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
-       if (! (cells[cell].vertices[vertex] < vertices.size()))
+       const unsigned int dim=3;
+
+                                        // copy vertices
+       triangulation.vertices = v;
+       triangulation.vertices_used = std::vector<bool> (v.size(), true);
+
+                                        // check that all cells have
+                                        // positive volume. if not call the
+                                        // invert_all_cells_of_negative_grid
+                                        // and reorder_cells function of
+                                        // GridReordering before creating
+                                        // the triangulation
+       for (unsigned int cell_no=0; cell_no<cells.size(); ++cell_no)
+         AssertThrow (GridTools::cell_measure(triangulation.vertices,
+                                              cells[cell_no].vertices) >= 0,
+                      ExcGridHasInvalidCell(cell_no));
+
+                                        ///////////////////////////////////////
+                                        // first set up some collections of data
+                                        //
+                                        // make up a list of the needed
+                                        // lines
+                                        //
+                                        // each line is a pair of
+                                        // vertices. The list is kept
+                                        // sorted and it is guaranteed that
+                                        // each line is inserted only once.
+                                        // While the key of such an entry
+                                        // is the pair of vertices, the
+                                        // thing it points to is an
+                                        // iterator pointing to the line
+                                        // object itself. In the first run,
+                                        // these iterators are all invalid
+                                        // ones, but they are filled
+                                        // afterwards same applies for the
+                                        // quads
+       typename std::map<std::pair<int,int>,line_iterator> needed_lines;
+       for (unsigned int cell=0; cell<cells.size(); ++cell)
          {
-                                             // store the number of
-                                             // vertices, as this
-                                             // information will be
-                                             // deleted by clear()
-                                             // though we'd like to
-                                             // include it in the
-                                             // error message
-            const unsigned int n_vertices = vertices.size();
-
-           clear_despite_subscriptions();            
-           
-           AssertThrow (false,
-                        ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
-                                               n_vertices));
-         }      
-
+                                            // check whether vertex indices
+                                            // are valid ones
+           for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+             AssertThrow (cells[cell].vertices[vertex] < triangulation.vertices.size(),
+                          ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
+                                                 triangulation.vertices.size()));
       
-      for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-       {
-                                          // given a line vertex number
-                                          // (0,1) on a specific line we
-                                          // get the cell vertex number
-                                          // (0-7) through the
-                                          // line_to_cell_vertices
-                                          // function
-         std::pair<int,int> line_vertices(
-           cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
-           cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
+           for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+             {
+                                                // given a line vertex number
+                                                // (0,1) on a specific line we
+                                                // get the cell vertex number
+                                                // (0-7) through the
+                                                // line_to_cell_vertices
+                                                // function
+               std::pair<int,int> line_vertices(
+                 cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+                 cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
          
-                                          // if that line was already inserted
-                                          // in reverse order do nothing, else
-                                          // insert the line
-         if ( (needed_lines.find(std::make_pair(line_vertices.second,
-                                                line_vertices.first))
-               ==
-               needed_lines.end()))
-           {
-                                              // insert line, with
-                                              // invalid iterator. if line
-                                              // already exists, then
-                                              // nothing bad happens here
-             needed_lines[line_vertices] = end_line();
-           }
-       }
-    }
-
+                                                // if that line was already inserted
+                                                // in reverse order do nothing, else
+                                                // insert the line
+               if ( (needed_lines.find(std::make_pair(line_vertices.second,
+                                                      line_vertices.first))
+                     ==
+                     needed_lines.end()))
+                 {
+                                                    // insert line, with
+                                                    // invalid iterator. if line
+                                                    // already exists, then
+                                                    // nothing bad happens here
+                   needed_lines[line_vertices] = triangulation.end_line();
+                 }
+             }
+         }
 
-                                  /////////////////////////////////
-                                  // now for some sanity-checks:
-                                  //
-                                  // check that every vertex has at
-                                  // least tree adjacent lines
-  if (true) 
-    {
-      std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
-      std::map<std::pair<int,int>,line_iterator>::iterator i;
-      for (i=needed_lines.begin(); i!=needed_lines.end(); i++) 
-       {
-                                          // touch the vertices of
-                                          // this line
-         ++vertex_touch_count[i->first.first];
-         ++vertex_touch_count[i->first.second];
-       }
 
-                                      // assert minimum touch count
-                                      // is at least three. if not so,
-                                      // then clean triangulation and
-                                      // exit with an exception
-      if (! (* (std::min_element(vertex_touch_count.begin(),
-                                vertex_touch_count.end())) >= 3))
+                                        /////////////////////////////////
+                                        // now for some sanity-checks:
+                                        //
+                                        // check that every vertex has at
+                                        // least tree adjacent lines
        {
-         clear_despite_subscriptions();
+         std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
+         typename std::map<std::pair<int,int>,line_iterator>::iterator i;
+         for (i=needed_lines.begin(); i!=needed_lines.end(); i++) 
+           {
+                                              // touch the vertices of
+                                              // this line
+             ++vertex_touch_count[i->first.first];
+             ++vertex_touch_count[i->first.second];
+           }
 
-         AssertThrow (false, ExcGridHasInvalidVertices());
+                                          // assert minimum touch count
+                                          // is at least three. if not so,
+                                          // then clean triangulation and
+                                          // exit with an exception
+         AssertThrow (* (std::min_element(vertex_touch_count.begin(),
+                                          vertex_touch_count.end())) >= 3,
+                      ExcGridHasInvalidVertices());
        }
-    }
 
 
-                                  ///////////////////////////////////
-                                  // actually set up data structures
-                                  // for the lines
-                                  // reserve enough space
-  levels.push_back (new internal::Triangulation::TriaLevel<dim>);
-  faces = new internal::Triangulation::TriaFaces<dim>;
-  levels[0]->reserve_space (cells.size(), dim);
-  faces->lines.reserve_space (0,needed_lines.size());
+                                        ///////////////////////////////////
+                                        // actually set up data structures
+                                        // for the lines
+                                        // reserve enough space
+       triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+       triangulation.faces = new internal::Triangulation::TriaFaces<dim>;
+       triangulation.levels[0]->reserve_space (cells.size(), dim);
+       triangulation.faces->lines.reserve_space (0,needed_lines.size());
 
-                                  // make up lines
-  if (true) 
-    {
-      raw_line_iterator line = begin_raw_line();
-      std::map<std::pair<int,int>,line_iterator>::iterator i;
-      for (i = needed_lines.begin(); line!=end_line(); ++line, ++i) 
+                                        // make up lines
        {
-         line->set (internal::Triangulation::TriaObject<1>(i->first.first,
-                                                           i->first.second));
-         line->set_used_flag ();
-         line->clear_user_flag ();
-         line->clear_user_data ();
-
-                                          // now set the iterator for
-                                          // this line
-         i->second = line;
+         raw_line_iterator line = triangulation.begin_raw_line();
+         typename std::map<std::pair<int,int>,line_iterator>::iterator i;
+         for (i = needed_lines.begin(); line!=triangulation.end_line(); ++line, ++i) 
+           {
+             line->set (internal::Triangulation::TriaObject<1>(i->first.first,
+                                                               i->first.second));
+             line->set_used_flag ();
+             line->clear_user_flag ();
+             line->clear_user_data ();
+
+                                              // now set the iterator for
+                                              // this line
+             i->second = line;
+           }
        }
-    }
 
 
-                                  ///////////////////////////////////////////
-                                  // make up the quads of this triangulation
-                                  //
-                                  // same thing: the iterators are
-                                  // set to the invalid value at
-                                  // first, we only collect the data
-                                  // now
-
-                                  // the bool array stores, wether the lines
-                                  // are in the standard orientation or not
-
-                                  // note that QuadComparator is a
-                                  // class declared and defined in
-                                  // this file
-  std::map<internal::Triangulation::TriaObject<2>,std::pair<quad_iterator,boost::array<bool,GeometryInfo<dim>::lines_per_face> >,QuadComparator>
-    needed_quads;
-  for (unsigned int cell=0; cell<cells.size(); ++cell) 
-    {
-                                      // the faces are quads which
-                                      // consist of four numbers
-                                      // denoting the index of the
-                                      // four lines bounding the
-                                      // quad. we can get this index
-                                      // by asking @p{needed_lines}
-                                      // for an iterator to this
-                                      // line, dereferencing it and
-                                      // thus return an iterator into
-                                      // the @p{lines} array of the
-                                      // triangulation, which is
-                                      // already set up. we can then
-                                      // ask this iterator for its
-                                      // index within the present
-                                      // level (the level is zero, of
-                                      // course)
-                                      //
-                                      // to make things easier, we
-                                      // don't create the lines
-                                      // (pairs of their vertex
-                                      // indices) in place, but
-                                      // before they are really
-                                      // needed.
-      std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
-       inverse_line_list[GeometryInfo<dim>::lines_per_cell];
-      unsigned int face_line_list[GeometryInfo<dim>::lines_per_face];
-      boost::array<bool,GeometryInfo<dim>::lines_per_face> orientation;
-      
-      for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-       {
-         line_list[line]=std::pair<int,int> (
-           cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
-           cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
-         inverse_line_list[line]=std::pair<int,int> (
-           cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
-           cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
-       }
+                                        ///////////////////////////////////////////
+                                        // make up the quads of this triangulation
+                                        //
+                                        // same thing: the iterators are
+                                        // set to the invalid value at
+                                        // first, we only collect the data
+                                        // now
+
+                                        // the bool array stores, wether the lines
+                                        // are in the standard orientation or not
+
+                                        // note that QuadComparator is a
+                                        // class declared and defined in
+                                        // this file
+       std::map<internal::Triangulation::TriaObject<2>,std::pair<quad_iterator,boost::array<bool,GeometryInfo<dim>::lines_per_face> >,QuadComparator>
+         needed_quads;
+       for (unsigned int cell=0; cell<cells.size(); ++cell) 
+         {
+                                            // the faces are quads which
+                                            // consist of four numbers
+                                            // denoting the index of the
+                                            // four lines bounding the
+                                            // quad. we can get this index
+                                            // by asking @p{needed_lines}
+                                            // for an iterator to this
+                                            // line, dereferencing it and
+                                            // thus return an iterator into
+                                            // the @p{lines} array of the
+                                            // triangulation, which is
+                                            // already set up. we can then
+                                            // ask this iterator for its
+                                            // index within the present
+                                            // level (the level is zero, of
+                                            // course)
+                                            //
+                                            // to make things easier, we
+                                            // don't create the lines
+                                            // (pairs of their vertex
+                                            // indices) in place, but
+                                            // before they are really
+                                            // needed.
+           std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
+             inverse_line_list[GeometryInfo<dim>::lines_per_cell];
+           unsigned int face_line_list[GeometryInfo<dim>::lines_per_face];
+           boost::array<bool,GeometryInfo<dim>::lines_per_face> orientation;
       
-      for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-        {
-                                          // set up a list of the lines to be
-                                          // used for this face. check the
-                                          // direction for each line
-                                          //
-                                          // given a face line number (0-3) on
-                                          // a specific face we get the cell
-                                          // line number (0-11) through the
-                                          // face_to_cell_lines function
-         for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
-           if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
-                                                    face_to_cell_lines(face,l)]) == needed_lines.end())
+           for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
              {
-               face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
-                                                        face_to_cell_lines(face,l)]]->index();
-               orientation[l]=true;
+               line_list[line]=std::pair<int,int> (
+                 cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+                 cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
+               inverse_line_list[line]=std::pair<int,int> (
+                 cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
+                 cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
              }
-           else
+      
+           for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
              {
-               face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
-                                                                face_to_cell_lines(face,l)]]->index();
-               orientation[l]=false;
-             }
+                                                // set up a list of the lines to be
+                                                // used for this face. check the
+                                                // direction for each line
+                                                //
+                                                // given a face line number (0-3) on
+                                                // a specific face we get the cell
+                                                // line number (0-11) through the
+                                                // face_to_cell_lines function
+               for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+                 if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
+                                                          face_to_cell_lines(face,l)]) == needed_lines.end())
+                   {
+                     face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
+                                                              face_to_cell_lines(face,l)]]->index();
+                     orientation[l]=true;
+                   }
+                 else
+                   {
+                     face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
+                                                                      face_to_cell_lines(face,l)]]->index();
+                     orientation[l]=false;
+                   }
            
          
-         internal::Triangulation::TriaObject<2> 
-            quad(face_line_list[0],
-                face_line_list[1],
-                face_line_list[2],
-                face_line_list[3]);
+               internal::Triangulation::TriaObject<2> 
+                 quad(face_line_list[0],
+                      face_line_list[1],
+                      face_line_list[2],
+                      face_line_list[3]);
          
-                                           // insert quad, with
-                                           // invalid iterator
-                                           //
-                                           // if quad already exists,
-                                           // then nothing bad happens
-                                           // here, as this will then
-                                           // simply become an
-                                           // interior face of the
-                                           // triangulation. however,
-                                           // we will run into major
-                                           // trouble if the face was
-                                           // already inserted in the
-                                           // opposite
-                                           // direction. there are
-                                           // really only two
-                                           // orientations for a face
-                                           // to be in, since the edge
-                                           // directions are already
-                                           // set. thus, vertex 0 is
-                                           // the one from which two
-                                           // edges originate, and
-                                           // vertex 3 is the one to
-                                           // which they converge. we
-                                           // are then left with
-                                           // orientations 0-1-2-3 and
-                                           // 2-3-0-1 for the order of
-                                           // lines. the
-                                           // corresponding quad can
-                                           // be easily constructed by
-                                           // exchanging lines. we do
-                                           // so here, just to check
-                                           // that that flipped quad
-                                           // isn't already in the
-                                           // triangulation. if it is,
-                                           // then don't insert the
-                                           // new one and instead
-                                           // later set the
-                                           // face_orientation flag
-          const internal::Triangulation::TriaObject<2>
-           test_quad_1(quad.face(2), quad.face(3),
-                       quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
-           test_quad_2(quad.face(0), quad.face(1),
-                       quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
-           test_quad_3(quad.face(3), quad.face(2),
-                       quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true,  face_rotation=false
-           test_quad_4(quad.face(1), quad.face(0),
-                       quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true,  face_rotation=true
-           test_quad_5(quad.face(2), quad.face(3),
-                       quad.face(1), quad.face(0)),//face_orientation=true,  face_flip=false, face_rotation=true
-           test_quad_6(quad.face(1), quad.face(0),
-                       quad.face(3), quad.face(2)),//face_orientation=true,  face_flip=true,  face_rotation=false
-           test_quad_7(quad.face(3), quad.face(2),
-                       quad.face(0), quad.face(1));//face_orientation=true,  face_flip=true,  face_rotation=true
-          if (needed_quads.find (test_quad_1) == needed_quads.end() &&
-             needed_quads.find (test_quad_2) == needed_quads.end() &&
-             needed_quads.find (test_quad_3) == needed_quads.end() &&
-             needed_quads.find (test_quad_4) == needed_quads.end() &&
-             needed_quads.find (test_quad_5) == needed_quads.end() &&
-             needed_quads.find (test_quad_6) == needed_quads.end() &&
-             needed_quads.find (test_quad_7) == needed_quads.end())
-            needed_quads[quad] = std::make_pair(end_quad(),orientation);
-        }
-    }
+                                                // insert quad, with
+                                                // invalid iterator
+                                                //
+                                                // if quad already exists,
+                                                // then nothing bad happens
+                                                // here, as this will then
+                                                // simply become an
+                                                // interior face of the
+                                                // triangulation. however,
+                                                // we will run into major
+                                                // trouble if the face was
+                                                // already inserted in the
+                                                // opposite
+                                                // direction. there are
+                                                // really only two
+                                                // orientations for a face
+                                                // to be in, since the edge
+                                                // directions are already
+                                                // set. thus, vertex 0 is
+                                                // the one from which two
+                                                // edges originate, and
+                                                // vertex 3 is the one to
+                                                // which they converge. we
+                                                // are then left with
+                                                // orientations 0-1-2-3 and
+                                                // 2-3-0-1 for the order of
+                                                // lines. the
+                                                // corresponding quad can
+                                                // be easily constructed by
+                                                // exchanging lines. we do
+                                                // so here, just to check
+                                                // that that flipped quad
+                                                // isn't already in the
+                                                // triangulation. if it is,
+                                                // then don't insert the
+                                                // new one and instead
+                                                // later set the
+                                                // face_orientation flag
+               const internal::Triangulation::TriaObject<2>
+                 test_quad_1(quad.face(2), quad.face(3),
+                             quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
+                 test_quad_2(quad.face(0), quad.face(1),
+                             quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
+                 test_quad_3(quad.face(3), quad.face(2),
+                             quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true,  face_rotation=false
+                 test_quad_4(quad.face(1), quad.face(0),
+                             quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true,  face_rotation=true
+                 test_quad_5(quad.face(2), quad.face(3),
+                             quad.face(1), quad.face(0)),//face_orientation=true,  face_flip=false, face_rotation=true
+                 test_quad_6(quad.face(1), quad.face(0),
+                             quad.face(3), quad.face(2)),//face_orientation=true,  face_flip=true,  face_rotation=false
+                 test_quad_7(quad.face(3), quad.face(2),
+                             quad.face(0), quad.face(1));//face_orientation=true,  face_flip=true,  face_rotation=true
+               if (needed_quads.find (test_quad_1) == needed_quads.end() &&
+                   needed_quads.find (test_quad_2) == needed_quads.end() &&
+                   needed_quads.find (test_quad_3) == needed_quads.end() &&
+                   needed_quads.find (test_quad_4) == needed_quads.end() &&
+                   needed_quads.find (test_quad_5) == needed_quads.end() &&
+                   needed_quads.find (test_quad_6) == needed_quads.end() &&
+                   needed_quads.find (test_quad_7) == needed_quads.end())
+                 needed_quads[quad] = std::make_pair(triangulation.end_quad(),orientation);
+             }
+         }
 
 
-                                  /////////////////////////////////
-                                  // enter the resulting quads into
-                                  // the arrays of the Triangulation
-                                  //
-                                  // first reserve enough space
-  faces->quads.reserve_space (0,needed_quads.size());
+                                        /////////////////////////////////
+                                        // enter the resulting quads into
+                                        // the arrays of the Triangulation
+                                        //
+                                        // first reserve enough space
+       triangulation.faces->quads.reserve_space (0,needed_quads.size());
   
-  if (true) 
-    {
-      raw_quad_iterator quad = begin_raw_quad();
-      std::map<internal::Triangulation::TriaObject<2>,std::pair<quad_iterator,boost::array<bool,GeometryInfo<dim>::lines_per_face> >,QuadComparator>
-        ::iterator q;
-      for (q = needed_quads.begin(); quad!=end_quad(); ++quad, ++q)
        {
-         quad->set (q->first);
-         quad->set_used_flag ();
-         quad->clear_user_flag ();
-         quad->clear_user_data ();
-                                          // set the line orientation
-         quad->set_line_orientation(0,q->second.second[0]);
-         quad->set_line_orientation(1,q->second.second[1]);
-         quad->set_line_orientation(2,q->second.second[2]);
-         quad->set_line_orientation(3,q->second.second[3]);
+         raw_quad_iterator quad = triangulation.begin_raw_quad();
+         typename std::map<internal::Triangulation::TriaObject<2>,
+                           std::pair<quad_iterator,
+                                     boost::array<bool,GeometryInfo<dim>::lines_per_face> >,
+                           QuadComparator>
+           ::iterator q;
+         for (q = needed_quads.begin(); quad!=triangulation.end_quad(); ++quad, ++q)
+           {
+             quad->set (q->first);
+             quad->set_used_flag ();
+             quad->clear_user_flag ();
+             quad->clear_user_data ();
+                                              // set the line orientation
+             quad->set_line_orientation(0,q->second.second[0]);
+             quad->set_line_orientation(1,q->second.second[1]);
+             quad->set_line_orientation(2,q->second.second[2]);
+             quad->set_line_orientation(3,q->second.second[3]);
          
 
-                                          // now set the iterator for
-                                          // this quad
-         q->second.first = quad;
+                                              // now set the iterator for
+                                              // this quad
+             q->second.first = quad;
+           }
        }
-    }
 
-                                  /////////////////////////////////
-                                  // finally create the cells
-  levels[0]->cells.reserve_space (cells.size());  
+                                        /////////////////////////////////
+                                        // finally create the cells
+       triangulation.levels[0]->cells.reserve_space (cells.size());  
 
-                                  // store for each quad index the
-                                  // adjacent cells
-  std::map<int,std::vector<cell_iterator> > adjacent_cells;
+                                        // store for each quad index the
+                                        // adjacent cells
+       std::map<int,std::vector<cell_iterator> > adjacent_cells;
 
-                                  // finally make up cells
-  if (true) 
-    {
-      raw_cell_iterator cell = begin_raw_hex();
-      for (unsigned int c=0; c<cells.size(); ++c, ++cell)
+                                        // finally make up cells
        {
-                                          // first find for each of
-                                          // the cells the quad
-                                          // iterator of the
-                                          // respective faces.
-                                          //
-                                          // to this end, set up the
-                                          // lines of this cell and
-                                          // find the quads that are
-                                          // bounded by these lines;
-                                          // these are then the faces
-                                          // of the present cell
-         std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
-           inverse_line_list[GeometryInfo<dim>::lines_per_cell];
-         unsigned int face_line_list[4];
-         for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+         raw_cell_iterator cell = triangulation.begin_raw_hex();
+         for (unsigned int c=0; c<cells.size(); ++c, ++cell)
            {
-             line_list[line]=std::make_pair(
-               cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
-               cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
-             inverse_line_list[line]=std::pair<int,int> (
-               cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
-               cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
-           }
-         
-                                          // get the iterators
-                                          // corresponding to the
-                                          // faces. also store
-                                          // whether they are
-                                          // reversed or not
-         quad_iterator face_iterator[GeometryInfo<dim>::faces_per_cell];
-          bool face_orientation[GeometryInfo<dim>::faces_per_cell];
-          bool face_flip[GeometryInfo<dim>::faces_per_cell];
-          bool face_rotation[GeometryInfo<dim>::faces_per_cell];
-          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-           {
-             for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
-               if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
-                                                        face_to_cell_lines(face,l)]) == needed_lines.end())
-                 face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
-                                                          face_to_cell_lines(face,l)]]->index();
-               else
-                 face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
-                                                                  face_to_cell_lines(face,l)]]->index();
-             
-             internal::Triangulation::TriaObject<2> 
-               quad(face_line_list[0],
-                    face_line_list[1],
-                    face_line_list[2],
-                    face_line_list[3]);
-             
-             if (needed_quads.find (quad) != needed_quads.end())
+                                              // first find for each of
+                                              // the cells the quad
+                                              // iterator of the
+                                              // respective faces.
+                                              //
+                                              // to this end, set up the
+                                              // lines of this cell and
+                                              // find the quads that are
+                                              // bounded by these lines;
+                                              // these are then the faces
+                                              // of the present cell
+             std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
+               inverse_line_list[GeometryInfo<dim>::lines_per_cell];
+             unsigned int face_line_list[4];
+             for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
                {
-                                                  // face is in standard
-                                                  // orientation (and not
-                                                  // flipped or rotated). this
-                                                  // must be true for at least
-                                                  // one of the two cells
-                                                  // containing this face
-                                                  // (i.e. for the cell which
-                                                  // originally inserted the
-                                                  // face)
-                 face_iterator[face] = needed_quads[quad].first;
-                 face_orientation[face] = true;
-                 face_flip[face]=false;
-                 face_rotation[face]=false;
+                 line_list[line]=std::make_pair(
+                   cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+                   cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
+                 inverse_line_list[line]=std::pair<int,int> (
+                   cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
+                   cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
                }
-             else
+         
+                                              // get the iterators
+                                              // corresponding to the
+                                              // faces. also store
+                                              // whether they are
+                                              // reversed or not
+             quad_iterator face_iterator[GeometryInfo<dim>::faces_per_cell];
+             bool face_orientation[GeometryInfo<dim>::faces_per_cell];
+             bool face_flip[GeometryInfo<dim>::faces_per_cell];
+             bool face_rotation[GeometryInfo<dim>::faces_per_cell];
+             for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
                {
-                                                  // face must be available in
-                                                  // reverse order
-                                                  // then. construct all
-                                                  // possibilities and check
-                                                  // them one after the other
-                 const internal::Triangulation::TriaObject<2>
-                   test_quad_1(quad.face(2), quad.face(3),
-                               quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
-                   test_quad_2(quad.face(0), quad.face(1),
-                               quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
-                   test_quad_3(quad.face(3), quad.face(2),
-                               quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true,  face_rotation=false
-                   test_quad_4(quad.face(1), quad.face(0),
-                               quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true,  face_rotation=true
-                   test_quad_5(quad.face(2), quad.face(3),
-                               quad.face(1), quad.face(0)),//face_orientation=true,  face_flip=false, face_rotation=true
-                   test_quad_6(quad.face(1), quad.face(0),
-                               quad.face(3), quad.face(2)),//face_orientation=true,  face_flip=true,  face_rotation=false
-                   test_quad_7(quad.face(3), quad.face(2),
-                               quad.face(0), quad.face(1));//face_orientation=true,  face_flip=true,  face_rotation=true
-                 if (needed_quads.find (test_quad_1) != needed_quads.end())
-                   {
-                     face_iterator[face] = needed_quads[test_quad_1].first;
-                     face_orientation[face] = false;
-                     face_flip[face]=false;
-                     face_rotation[face]=false;
-                   }
-                 else if (needed_quads.find (test_quad_2) != needed_quads.end())
-                   {
-                     face_iterator[face] = needed_quads[test_quad_2].first;
-                     face_orientation[face] = false;
-                     face_flip[face]=false;
-                     face_rotation[face]=true;
-                   }
-                 else if (needed_quads.find (test_quad_3) != needed_quads.end())
-                   {
-                     face_iterator[face] = needed_quads[test_quad_3].first;
-                     face_orientation[face] = false;
-                     face_flip[face]=true;
-                     face_rotation[face]=false;
-                   }
-                 else if (needed_quads.find (test_quad_4) != needed_quads.end())
-                   {
-                     face_iterator[face] = needed_quads[test_quad_4].first;
-                     face_orientation[face] = false;
-                     face_flip[face]=true;
-                     face_rotation[face]=true;
-                   }
-                 else if (needed_quads.find (test_quad_5) != needed_quads.end())
+                 for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+                   if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
+                                                            face_to_cell_lines(face,l)]) == needed_lines.end())
+                     face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
+                                                              face_to_cell_lines(face,l)]]->index();
+                   else
+                     face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
+                                                                      face_to_cell_lines(face,l)]]->index();
+             
+                 internal::Triangulation::TriaObject<2> 
+                   quad(face_line_list[0],
+                        face_line_list[1],
+                        face_line_list[2],
+                        face_line_list[3]);
+             
+                 if (needed_quads.find (quad) != needed_quads.end())
                    {
-                     face_iterator[face] = needed_quads[test_quad_5].first;
+                                                      // face is in standard
+                                                      // orientation (and not
+                                                      // flipped or rotated). this
+                                                      // must be true for at least
+                                                      // one of the two cells
+                                                      // containing this face
+                                                      // (i.e. for the cell which
+                                                      // originally inserted the
+                                                      // face)
+                     face_iterator[face] = needed_quads[quad].first;
                      face_orientation[face] = true;
                      face_flip[face]=false;
-                     face_rotation[face]=true;
-                   }
-                 else if (needed_quads.find (test_quad_6) != needed_quads.end())
-                   {
-                     face_iterator[face] = needed_quads[test_quad_6].first;
-                     face_orientation[face] = true;
-                     face_flip[face]=true;
                      face_rotation[face]=false;
                    }
-                 else if (needed_quads.find (test_quad_7) != needed_quads.end())
+                 else
                    {
-                     face_iterator[face] = needed_quads[test_quad_7].first;
-                     face_orientation[face] = true;
-                     face_flip[face]=true;
-                     face_rotation[face]=true;
-                   }
+                                                      // face must be available in
+                                                      // reverse order
+                                                      // then. construct all
+                                                      // possibilities and check
+                                                      // them one after the other
+                     const internal::Triangulation::TriaObject<2>
+                       test_quad_1(quad.face(2), quad.face(3),
+                                   quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
+                       test_quad_2(quad.face(0), quad.face(1),
+                                   quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
+                       test_quad_3(quad.face(3), quad.face(2),
+                                   quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true,  face_rotation=false
+                       test_quad_4(quad.face(1), quad.face(0),
+                                   quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true,  face_rotation=true
+                       test_quad_5(quad.face(2), quad.face(3),
+                                   quad.face(1), quad.face(0)),//face_orientation=true,  face_flip=false, face_rotation=true
+                       test_quad_6(quad.face(1), quad.face(0),
+                                   quad.face(3), quad.face(2)),//face_orientation=true,  face_flip=true,  face_rotation=false
+                       test_quad_7(quad.face(3), quad.face(2),
+                                   quad.face(0), quad.face(1));//face_orientation=true,  face_flip=true,  face_rotation=true
+                     if (needed_quads.find (test_quad_1) != needed_quads.end())
+                       {
+                         face_iterator[face] = needed_quads[test_quad_1].first;
+                         face_orientation[face] = false;
+                         face_flip[face]=false;
+                         face_rotation[face]=false;
+                       }
+                     else if (needed_quads.find (test_quad_2) != needed_quads.end())
+                       {
+                         face_iterator[face] = needed_quads[test_quad_2].first;
+                         face_orientation[face] = false;
+                         face_flip[face]=false;
+                         face_rotation[face]=true;
+                       }
+                     else if (needed_quads.find (test_quad_3) != needed_quads.end())
+                       {
+                         face_iterator[face] = needed_quads[test_quad_3].first;
+                         face_orientation[face] = false;
+                         face_flip[face]=true;
+                         face_rotation[face]=false;
+                       }
+                     else if (needed_quads.find (test_quad_4) != needed_quads.end())
+                       {
+                         face_iterator[face] = needed_quads[test_quad_4].first;
+                         face_orientation[face] = false;
+                         face_flip[face]=true;
+                         face_rotation[face]=true;
+                       }
+                     else if (needed_quads.find (test_quad_5) != needed_quads.end())
+                       {
+                         face_iterator[face] = needed_quads[test_quad_5].first;
+                         face_orientation[face] = true;
+                         face_flip[face]=false;
+                         face_rotation[face]=true;
+                       }
+                     else if (needed_quads.find (test_quad_6) != needed_quads.end())
+                       {
+                         face_iterator[face] = needed_quads[test_quad_6].first;
+                         face_orientation[face] = true;
+                         face_flip[face]=true;
+                         face_rotation[face]=false;
+                       }
+                     else if (needed_quads.find (test_quad_7) != needed_quads.end())
+                       {
+                         face_iterator[face] = needed_quads[test_quad_7].first;
+                         face_orientation[face] = true;
+                         face_flip[face]=true;
+                         face_rotation[face]=true;
+                       }
 
-                 else
-                                                    // we didn't find the
-                                                    // face in any direction,
-                                                    // so something went
-                                                    // wrong above
-                   Assert(false,ExcInternalError());
+                     else
+                                                        // we didn't find the
+                                                        // face in any direction,
+                                                        // so something went
+                                                        // wrong above
+                       Assert(false,ExcInternalError());
                  
-               }
-           }// for all faces
+                   }
+               }// for all faces
          
-                                          // make the cell out of
-                                          // these iterators
-         cell->set (internal::Triangulation
-                     ::TriaObject<3> (face_iterator[0]->index(),
-                                     face_iterator[1]->index(),
-                                     face_iterator[2]->index(),
-                                     face_iterator[3]->index(),
-                                     face_iterator[4]->index(),
-                                     face_iterator[5]->index()));
+                                              // make the cell out of
+                                              // these iterators
+             cell->set (internal::Triangulation
+                        ::TriaObject<3> (face_iterator[0]->index(),
+                                         face_iterator[1]->index(),
+                                         face_iterator[2]->index(),
+                                         face_iterator[3]->index(),
+                                         face_iterator[4]->index(),
+                                         face_iterator[5]->index()));
          
-         cell->set_used_flag ();
-         cell->set_material_id (cells[c].material_id);
-         cell->clear_user_flag ();
-         cell->clear_user_data ();
-         cell->set_subdomain_id (0);
-
-                                           // set orientation flag for
-                                           // each of the faces
-         for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
-           {
-             cell->set_face_orientation (quad, face_orientation[quad]);
-             cell->set_face_flip (quad, face_flip[quad]);
-             cell->set_face_rotation (quad, face_rotation[quad]);
-           }
+             cell->set_used_flag ();
+             cell->set_material_id (cells[c].material_id);
+             cell->clear_user_flag ();
+             cell->clear_user_data ();
+             cell->set_subdomain_id (0);
+
+                                              // set orientation flag for
+                                              // each of the faces
+             for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
+               {
+                 cell->set_face_orientation (quad, face_orientation[quad]);
+                 cell->set_face_flip (quad, face_flip[quad]);
+                 cell->set_face_rotation (quad, face_rotation[quad]);
+               }
          
           
-                                          // note that this cell is
-                                          // adjacent to the six
-                                          // quads
-         for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
-           adjacent_cells[face_iterator[quad]->index()].push_back (cell);
+                                              // note that this cell is
+                                              // adjacent to the six
+                                              // quads
+             for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
+               adjacent_cells[face_iterator[quad]->index()].push_back (cell);
 
 #ifdef DEBUG          
-                                          // make some checks on the
-                                          // lines and their
-                                          // ordering
-
-                                          // first map all cell lines
-                                          // to the two face lines
-                                          // which should
-                                          // coincide. all face lines
-                                          // are included with a cell
-                                          // line number (0-11)
-                                          // key. At the end all keys
-                                          // will be included twice
-                                          // (for each of the two
-                                          // coinciding lines once)
-         std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >
-           cell_to_face_lines;
-         for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-           for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_face; ++line)
-             cell_to_face_lines.insert(
-               std::pair<unsigned int, std::pair<unsigned int, unsigned int> > (
-                 GeometryInfo<dim>::face_to_cell_lines(face,line),
-                 std::pair<unsigned int, unsigned int> (face,line)));
-         std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >::const_iterator
-           map_iter=cell_to_face_lines.begin();
+                                              // make some checks on the
+                                              // lines and their
+                                              // ordering
+
+                                              // first map all cell lines
+                                              // to the two face lines
+                                              // which should
+                                              // coincide. all face lines
+                                              // are included with a cell
+                                              // line number (0-11)
+                                              // key. At the end all keys
+                                              // will be included twice
+                                              // (for each of the two
+                                              // coinciding lines once)
+             std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >
+               cell_to_face_lines;
+             for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+               for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_face; ++line)
+                 cell_to_face_lines.insert(
+                   std::pair<unsigned int, std::pair<unsigned int, unsigned int> > (
+                     GeometryInfo<dim>::face_to_cell_lines(face,line),
+                     std::pair<unsigned int, unsigned int> (face,line)));
+             std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >::const_iterator
+               map_iter=cell_to_face_lines.begin();
          
-         for (; map_iter!=cell_to_face_lines.end(); ++map_iter)
-           {
-             const unsigned int cell_line=map_iter->first;
-             const unsigned int face1=map_iter->second.first;
-             const unsigned int line1=map_iter->second.second;
-             ++map_iter;
-             Assert(map_iter!=cell_to_face_lines.end(), ExcInternalErrorOnCell(c));
-             Assert(map_iter->first==cell_line, ExcInternalErrorOnCell(c));
-             const unsigned int face2=map_iter->second.first;
-             const unsigned int line2=map_iter->second.second;
-
-                                              // check that the pair
-                                              // of lines really
-                                              // coincide. Take care
-                                              // about the face
-                                              // orientation;
-             Assert (face_iterator[face1]->line(GeometryInfo<dim>::standard_to_real_face_line(
-                                                  line1,
-                                                  face_orientation[face1],
-                                                  face_flip[face1],
-                                                  face_rotation[face1])) ==
-                     face_iterator[face2]->line(GeometryInfo<dim>::standard_to_real_face_line(
-                                                  line2,
-                                                  face_orientation[face2],
-                                                  face_flip[face2],
-                                                  face_rotation[face2])),
-                     ExcInternalErrorOnCell(c));
-           }
+             for (; map_iter!=cell_to_face_lines.end(); ++map_iter)
+               {
+                 const unsigned int cell_line=map_iter->first;
+                 const unsigned int face1=map_iter->second.first;
+                 const unsigned int line1=map_iter->second.second;
+                 ++map_iter;
+                 Assert(map_iter!=cell_to_face_lines.end(), ExcInternalErrorOnCell(c));
+                 Assert(map_iter->first==cell_line, ExcInternalErrorOnCell(c));
+                 const unsigned int face2=map_iter->second.first;
+                 const unsigned int line2=map_iter->second.second;
+
+                                                  // check that the pair
+                                                  // of lines really
+                                                  // coincide. Take care
+                                                  // about the face
+                                                  // orientation;
+                 Assert (face_iterator[face1]->line(GeometryInfo<dim>::standard_to_real_face_line(
+                                                      line1,
+                                                      face_orientation[face1],
+                                                      face_flip[face1],
+                                                      face_rotation[face1])) ==
+                         face_iterator[face2]->line(GeometryInfo<dim>::standard_to_real_face_line(
+                                                      line2,
+                                                      face_orientation[face2],
+                                                      face_flip[face2],
+                                                      face_rotation[face2])),
+                         ExcInternalErrorOnCell(c));
+               }
 #endif
+           }
        }
-    }
 
 
-                                  /////////////////////////////////////////
-                                  // find those quads which are at the
-                                  // boundary and mark them appropriately
-  for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad)
-    {
-      const unsigned int n_adj_cells = adjacent_cells[quad->index()].size();
-                                      // assert that every quad has
-                                      // one or two adjacent cells
-      if (! ((n_adj_cells >= 1) &&
-            (n_adj_cells <= 2)))
-       {
-         clear_despite_subscriptions();
-         
-         AssertThrow (false, ExcInternalError());
-       }
+                                        /////////////////////////////////////////
+                                        // find those quads which are at the
+                                        // boundary and mark them appropriately
+       for (quad_iterator quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
+         {
+           const unsigned int n_adj_cells = adjacent_cells[quad->index()].size();
+                                            // assert that every quad has
+                                            // one or two adjacent cells
+           AssertThrow ((n_adj_cells >= 1) &&
+                        (n_adj_cells <= 2),
+                        ExcInternalError());
 
-                                      // if only one cell: quad is at
-                                      // boundary -> give it the
-                                      // boundary indicator zero by
-                                      // default
-      if (n_adj_cells == 1)
-       quad->set_boundary_indicator (0);
-      else
-                                        // interior quad -> 255
-       quad->set_boundary_indicator (255);
-    }
+                                            // if only one cell: quad is at
+                                            // boundary -> give it the
+                                            // boundary indicator zero by
+                                            // default
+           if (n_adj_cells == 1)
+             quad->set_boundary_indicator (0);
+           else
+                                              // interior quad -> 255
+             quad->set_boundary_indicator (255);
+         }
 
-                                  /////////////////////////////////////////
-                                  // next find those lines which are at
-                                  // the boundary and mark all others as
-                                  // interior ones
-                                  //
-                                  // for this: first mark all lines
-                                  // as interior
-  for (line_iterator line=begin_line(); line!=end_line(); ++line)
-    line->set_boundary_indicator (255);
-                                  // next reset all lines bounding
-                                  // boundary quads as on the
-                                  // boundary also. note that since
-                                  // we are in 3d, there are cases
-                                  // where one or more lines of a
-                                  // quad that is not on the
-                                  // boundary, are actually boundary
-                                  // lines. they will not be marked
-                                  // when visiting this
-                                  // face. however, since we do not
-                                  // support dim-2 dimensional
-                                  // boundaries (i.e. internal lines
-                                  // constituting boundaries), every
-                                  // such line is also part of a face
-                                  // that is actually on the
-                                  // boundary, so sooner or later we
-                                  // get to mark that line for being
-                                  // on the boundary
-  for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad)
-    if (quad->at_boundary())
-      for (unsigned int l=0; l<4; ++l)
-       quad->line(l)->set_boundary_indicator (0);
+                                        /////////////////////////////////////////
+                                        // next find those lines which are at
+                                        // the boundary and mark all others as
+                                        // interior ones
+                                        //
+                                        // for this: first mark all lines
+                                        // as interior
+       for (line_iterator line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+         line->set_boundary_indicator (255);
+                                        // next reset all lines bounding
+                                        // boundary quads as on the
+                                        // boundary also. note that since
+                                        // we are in 3d, there are cases
+                                        // where one or more lines of a
+                                        // quad that is not on the
+                                        // boundary, are actually boundary
+                                        // lines. they will not be marked
+                                        // when visiting this
+                                        // face. however, since we do not
+                                        // support dim-2 dimensional
+                                        // boundaries (i.e. internal lines
+                                        // constituting boundaries), every
+                                        // such line is also part of a face
+                                        // that is actually on the
+                                        // boundary, so sooner or later we
+                                        // get to mark that line for being
+                                        // on the boundary
+       for (quad_iterator quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
+         if (quad->at_boundary())
+           for (unsigned int l=0; l<4; ++l)
+             quad->line(l)->set_boundary_indicator (0);
   
-                                  // Check that all cells have
-                                  // positive volume. As the input
-                                  // CellData already passed this
-                                  // test we don't really expect
-                                  // negative measures here
-  for (active_cell_iterator cell=begin_active(); cell!=end(); ++cell)
-    Assert(cell->measure()>0, ExcInternalError());
+                                        // Check that all cells have
+                                        // positive volume. As the input
+                                        // CellData already passed this
+                                        // test we don't really expect
+                                        // negative measures here
+       for (active_cell_iterator cell=triangulation.begin_active(); cell!=triangulation.end(); ++cell)
+         Assert(cell->measure()>0, ExcInternalError());
       
-                                  ///////////////////////////////////////
-                                  // now set boundary indicators
-                                  // where given
-                                  //
-                                  // first do so for lines
-  std::vector<CellData<1> >::const_iterator boundary_line
-    = subcelldata.boundary_lines.begin();
-  std::vector<CellData<1> >::const_iterator end_boundary_line
-    = subcelldata.boundary_lines.end();
-  for (; boundary_line!=end_boundary_line; ++boundary_line)
-    {
-      line_iterator line;
-      std::pair <int, int> line_vertices(std::make_pair(boundary_line->vertices[0],
-                                                       boundary_line->vertices[1]));
-      if (needed_lines.find(line_vertices) != needed_lines.end())
-                                        // line found in this
-                                        // direction
-       line = needed_lines[line_vertices];
+                                        ///////////////////////////////////////
+                                        // now set boundary indicators
+                                        // where given
+                                        //
+                                        // first do so for lines
+       std::vector<CellData<1> >::const_iterator boundary_line
+         = subcelldata.boundary_lines.begin();
+       std::vector<CellData<1> >::const_iterator end_boundary_line
+         = subcelldata.boundary_lines.end();
+       for (; boundary_line!=end_boundary_line; ++boundary_line)
+         {
+           line_iterator line;
+           std::pair <int, int> line_vertices(std::make_pair(boundary_line->vertices[0],
+                                                             boundary_line->vertices[1]));
+           if (needed_lines.find(line_vertices) != needed_lines.end())
+                                              // line found in this
+                                              // direction
+             line = needed_lines[line_vertices];
                  
-      else
-       {
-                                          // look wether it exists in
-                                          // reverse direction
-         std::swap (line_vertices.first, line_vertices.second);
-         if (needed_lines.find(line_vertices) != needed_lines.end())
-           line = needed_lines[line_vertices];
-         else
-           {
-             clear_despite_subscriptions ();
-                                              // line does not exist
-             AssertThrow (false, ExcLineInexistant(line_vertices.first,
-                                                   line_vertices.second));
-             line = end_line();
-           }
-       }
-                                      // Assert that only exterior
-                                      // lines are given a boundary
-                                      // indicator
-      if (!line->at_boundary())
-       {
-         clear_despite_subscriptions ();
-
-         AssertThrow (false, ExcInteriorLineCantBeBoundary());
-       }
-
-                                       // and make sure that we don't
-                                       // attempt to reset the
-                                       // boundary indicator to a
-                                       // different than the
-                                       // previously set value
-      if (line->boundary_indicator() != 0)
-       {
-         if (line->boundary_indicator() != boundary_line->material_id)
-           {
-             clear_despite_subscriptions ();
-
-             AssertThrow (false, ExcMessage (
-                            "Duplicate boundary lines are only allowed "
-                            "if they carry the same boundary indicator."));
-           }
-       }
-      line->set_boundary_indicator (boundary_line->material_id);
-    }
+           else
+             {
+                                                // look wether it exists in
+                                                // reverse direction
+               std::swap (line_vertices.first, line_vertices.second);
+               if (needed_lines.find(line_vertices) != needed_lines.end())
+                 line = needed_lines[line_vertices];
+               else
+                                                  // line does not exist
+                 AssertThrow (false, ExcLineInexistant(line_vertices.first,
+                                                       line_vertices.second));
+             }
+                                            // Assert that only exterior
+                                            // lines are given a boundary
+                                            // indicator
+           AssertThrow (line->at_boundary(),
+                        ExcInteriorLineCantBeBoundary());
+
+                                            // and make sure that we don't
+                                            // attempt to reset the
+                                            // boundary indicator to a
+                                            // different than the
+                                            // previously set value
+           if (line->boundary_indicator() != 0)
+             AssertThrow (line->boundary_indicator() == boundary_line->material_id,
+                          ExcMessage ("Duplicate boundary lines are only allowed "
+                                      "if they carry the same boundary indicator."));
+             
+           line->set_boundary_indicator (boundary_line->material_id);
+         }
 
   
-                                  // now go on with boundary faces
-  std::vector<CellData<2> >::const_iterator boundary_quad
-    = subcelldata.boundary_quads.begin();
-  std::vector<CellData<2> >::const_iterator end_boundary_quad
-    = subcelldata.boundary_quads.end();
-  for (; boundary_quad!=end_boundary_quad; ++boundary_quad)
-    {
-      quad_iterator quad;
-      line_iterator line[4];
+                                        // now go on with boundary faces
+       std::vector<CellData<2> >::const_iterator boundary_quad
+         = subcelldata.boundary_quads.begin();
+       std::vector<CellData<2> >::const_iterator end_boundary_quad
+         = subcelldata.boundary_quads.end();
+       for (; boundary_quad!=end_boundary_quad; ++boundary_quad)
+         {
+           quad_iterator quad;
+           line_iterator line[4];
  
-                                      // first find the lines that
-                                      // are made up of the given
-                                      // vertices, then build up a
-                                      // quad from these lines
-                                      // finally use the find
-                                      // function of the map template
-                                      // to find the quad
-      for (unsigned int i=0; i<4; ++i)
-       {
-         std::pair<int, int> line_vertices(
-           boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,0)],
-           boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,1)]);
+                                            // first find the lines that
+                                            // are made up of the given
+                                            // vertices, then build up a
+                                            // quad from these lines
+                                            // finally use the find
+                                            // function of the map template
+                                            // to find the quad
+           for (unsigned int i=0; i<4; ++i)
+             {
+               std::pair<int, int> line_vertices(
+                 boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,0)],
+                 boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,1)]);
          
-                                          // check whether line
-                                          // already exists
-         if (needed_lines.find(line_vertices) != needed_lines.end())
-           line[i] = needed_lines[line_vertices];
-         else
-                                            // look wether it exists
-                                            // in reverse direction
-           {
-             std::swap (line_vertices.first, line_vertices.second);
-             if (needed_lines.find(line_vertices) != needed_lines.end())
-               line[i] = needed_lines[line_vertices];
-             else
-               {
-                 clear_despite_subscriptions ();
-                                                  // line does not
-                                                  // exist
-                 AssertThrow (false, ExcLineInexistant(line_vertices.first,
-                                                       line_vertices.second));
-                 line[i] = end_line();
-               }
-           }
-       }
+                                                // check whether line
+                                                // already exists
+               if (needed_lines.find(line_vertices) != needed_lines.end())
+                 line[i] = needed_lines[line_vertices];
+               else
+                                                  // look wether it exists
+                                                  // in reverse direction
+                 {
+                   std::swap (line_vertices.first, line_vertices.second);
+                   if (needed_lines.find(line_vertices) != needed_lines.end())
+                     line[i] = needed_lines[line_vertices];
+                   else
+                                                      // line does
+                                                      // not exist
+                     AssertThrow (false, ExcLineInexistant(line_vertices.first,
+                                                           line_vertices.second));
+                 }
+             }
       
  
-                                      // Set up 2 quads that are
-                                      // built up from the lines for
-                                      // reasons of comparison to
-                                      // needed_quads.  The second
-                                      // quad is the reversed version
-                                      // of the first quad in order
-                                      // find the quad regardless of
-                                      // its orientation.  This is
-                                      // introduced for convenience
-                                      // and because boundary quad
-                                      // orientation does not carry
-                                      // any information.
-      internal::Triangulation::TriaObject<2> 
-        quad_compare_1(line[0]->index(), line[1]->index(),
-                       line[2]->index(), line[3]->index());
-      internal::Triangulation::TriaObject<2> 
-        quad_compare_2(line[2]->index(), line[3]->index(),
-                       line[0]->index(), line[1]->index());
+                                            // Set up 2 quads that are
+                                            // built up from the lines for
+                                            // reasons of comparison to
+                                            // needed_quads.  The second
+                                            // quad is the reversed version
+                                            // of the first quad in order
+                                            // find the quad regardless of
+                                            // its orientation.  This is
+                                            // introduced for convenience
+                                            // and because boundary quad
+                                            // orientation does not carry
+                                            // any information.
+           internal::Triangulation::TriaObject<2> 
+             quad_compare_1(line[0]->index(), line[1]->index(),
+                            line[2]->index(), line[3]->index());
+           internal::Triangulation::TriaObject<2> 
+             quad_compare_2(line[2]->index(), line[3]->index(),
+                            line[0]->index(), line[1]->index());
       
-                                      // try to find the quad with
-                                      // lines situated as
-                                      // constructed above.  if it
-                                      // could not be found, rotate
-                                      // the boundary lines 3 times
-                                      // until it is found or it does
-                                      // not exist.
-
-                                      // mapping from counterclock to
-                                      // lexicographic ordering of
-                                      // quad lines
-      static const unsigned int lex2cclock[4]={3,1,0,2};
-                                      // copy lines from
-                                      // lexicographic to
-                                      // counterclock ordering, as
-                                      // rotation is much simpler in
-                                      // counterclock ordering
-      line_iterator line_counterclock[4];
-      for (unsigned int i=0; i<4; ++i)
-       line_counterclock[lex2cclock[i]]=line[i];
-      unsigned int n_rotations=0;
-      bool not_found_quad_1;
-      while ( (not_found_quad_1=(needed_quads.find(quad_compare_1) == needed_quads.end())) && 
-             (                  needed_quads.find(quad_compare_2) == needed_quads.end()) &&
-             (n_rotations<4))
-       {
-                                          // use the rotate defined
-                                          // in <algorithms>
-         rotate(line_counterclock, line_counterclock+1, line_counterclock+4);
-                                          // update the quads with
-                                          // rotated lines (i runs in
-                                          // lexicographic ordering)
-         for (unsigned int i=0; i<4; ++i)
-           {
-             quad_compare_1.set_face(i,       line_counterclock[lex2cclock[i]]->index());
-             quad_compare_2.set_face((i+2)%4, line_counterclock[lex2cclock[i]]->index());
-           }
+                                            // try to find the quad with
+                                            // lines situated as
+                                            // constructed above.  if it
+                                            // could not be found, rotate
+                                            // the boundary lines 3 times
+                                            // until it is found or it does
+                                            // not exist.
+
+                                            // mapping from counterclock to
+                                            // lexicographic ordering of
+                                            // quad lines
+           static const unsigned int lex2cclock[4]={3,1,0,2};
+                                            // copy lines from
+                                            // lexicographic to
+                                            // counterclock ordering, as
+                                            // rotation is much simpler in
+                                            // counterclock ordering
+           line_iterator line_counterclock[4];
+           for (unsigned int i=0; i<4; ++i)
+             line_counterclock[lex2cclock[i]]=line[i];
+           unsigned int n_rotations=0;
+           bool not_found_quad_1;
+           while ( (not_found_quad_1=(needed_quads.find(quad_compare_1) == needed_quads.end())) && 
+                   (                  needed_quads.find(quad_compare_2) == needed_quads.end()) &&
+                   (n_rotations<4))
+             {
+                                                // use the rotate defined
+                                                // in <algorithms>
+               rotate(line_counterclock, line_counterclock+1, line_counterclock+4);
+                                                // update the quads with
+                                                // rotated lines (i runs in
+                                                // lexicographic ordering)
+               for (unsigned int i=0; i<4; ++i)
+                 {
+                   quad_compare_1.set_face(i,       line_counterclock[lex2cclock[i]]->index());
+                   quad_compare_2.set_face((i+2)%4, line_counterclock[lex2cclock[i]]->index());
+                 }
              
-         ++n_rotations;
-       }
+               ++n_rotations;
+             }
  
-      if (n_rotations==4)
-       {
-         clear_despite_subscriptions();
+           AssertThrow (n_rotations!=4,
+                        ExcQuadInexistant(line[0]->index(), line[1]->index(),
+                                          line[2]->index(), line[3]->index()));
 
-                                          // quad does not exist
-         AssertThrow (false, ExcQuadInexistant(line[0]->index(), line[1]->index(),
-                                               line[2]->index(), line[3]->index()));
-         quad = end_quad();
-       }
-                                      // exception not thrown,
-                                      // therefore assign the quad
-                                      // appropriately
-      if (not_found_quad_1)
-       quad = needed_quads[quad_compare_2].first;
-      else
-       quad = needed_quads[quad_compare_1].first;
+           if (not_found_quad_1)
+             quad = needed_quads[quad_compare_2].first;
+           else
+             quad = needed_quads[quad_compare_1].first;
+
+                                            // check whether this face is
+                                            // really an exterior one
+           AssertThrow (quad->at_boundary(),
+                        ExcInteriorQuadCantBeBoundary());
+
+                                            // and make sure that we don't
+                                            // attempt to reset the
+                                            // boundary indicator to a
+                                            // different than the
+                                            // previously set value
+           if (quad->boundary_indicator() != 0)
+             AssertThrow (quad->boundary_indicator() == boundary_quad->material_id,
+                          ExcMessage ("Duplicate boundary quads are only allowed "
+                                      "if they carry the same boundary indicator."));
+             
+           quad->set_boundary_indicator (boundary_quad->material_id); 
+         }
 
-                                      // check whether this face is
-                                      // really an exterior one
-      if (!quad->at_boundary())
-       {
-         clear_despite_subscriptions ();
 
-         AssertThrow(false, ExcInteriorQuadCantBeBoundary());
-       }
+                                        /////////////////////////////////////////
+                                        // finally update neighborship info
+       for (cell_iterator cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
+         for (unsigned int face=0; face<6; ++face)
+           if (adjacent_cells[cell->quad(face)->index()][0] == cell)
+                                              // first adjacent cell is
+                                              // this one
+             {
+               if (adjacent_cells[cell->quad(face)->index()].size() == 2)
+                                                  // there is another
+                                                  // adjacent cell
+                 cell->set_neighbor (face,
+                                     adjacent_cells[cell->quad(face)->index()][1]);
+             }
+                                        // first adjacent cell is not this
+                                        // one, -> it must be the neighbor
+                                        // we are looking for
+           else
+             cell->set_neighbor (face,
+                                 adjacent_cells[cell->quad(face)->index()][0]);
+      }
 
-                                       // and make sure that we don't
-                                       // attempt to reset the
-                                       // boundary indicator to a
-                                       // different than the
-                                       // previously set value
-      if (quad->boundary_indicator() != 0)
-       {
-         if (quad->boundary_indicator() != boundary_quad->material_id)
-           {
-             clear_despite_subscriptions ();
-         
-             AssertThrow (false, ExcMessage (
-                            "Duplicate boundary quads are only allowed "
-                            "if they carry the same boundary indicator."));
-           }
-       }
-      quad->set_boundary_indicator (boundary_quad->material_id); 
-    }
 
+                                    /**
+                                     * Distort a 1d triangulation in
+                                     * some random way.
+                                     */
+    template <int spacedim>
+    static
+    void
+    distort_random (const double               factor,
+                   const bool                 keep_boundary,
+                   Triangulation<1,spacedim> &triangulation)
+      {
+                                        // if spacedim>1 we need to
+                                        // make sure that we perturb
+                                        // points but keep them on
+                                        // the manifold
+       Assert (spacedim == 1,
+               ExcNotImplemented());
+
+                                        // this function is mostly
+                                        // equivalent to that for the
+                                        // general dimensional case the
+                                        // only difference being the
+                                        // correction for split faces which
+                                        // is not necessary in 1D
+  
+                                        // find the smallest length of the
+                                        // lines adjacent to the
+                                        // vertex. take the initial value
+                                        // to be larger than anything that
+                                        // might be found: the diameter of
+                                        // the triangulation, here computed
+                                        // by adding up the diameters of
+                                        // the coarse grid cells.
+       double almost_infinite_length = 0;
+       for (cell_iterator cell=triangulation.begin(0); cell!=triangulation.end(0); ++cell)
+         almost_infinite_length += cell->diameter();
+  
+       std::vector<double> minimal_length (triangulation.vertices.size(),
+                                           almost_infinite_length);
+                                        // also note if a vertex is at
+                                        // the boundary
+       std::vector<bool>   at_boundary (triangulation.vertices.size(), false);
+  
+       for (active_line_iterator line=triangulation.begin_active_line();
+            line != triangulation.end_line(); ++line)
+         {
+           if (keep_boundary && line->at_boundary())
+             {
+               at_boundary[line->vertex_index(0)] = true;
+               at_boundary[line->vertex_index(1)] = true;
+             }
+      
+           minimal_length[line->vertex_index(0)]
+             = std::min(line->diameter(),
+                        minimal_length[line->vertex_index(0)]);
+           minimal_length[line->vertex_index(1)]
+             = std::min(line->diameter(),
+                        minimal_length[line->vertex_index(1)]);
+         }
 
-                                  /////////////////////////////////////////
-                                  // finally update neighborship info
-  for (cell_iterator cell=begin(); cell!=end(); ++cell)
-    for (unsigned int face=0; face<6; ++face)
-      if (adjacent_cells[cell->quad(face)->index()][0] == cell)
-                                        // first adjacent cell is
-                                        // this one
-       {
-         if (adjacent_cells[cell->quad(face)->index()].size() == 2)
-                                            // there is another
-                                            // adjacent cell
-           cell->set_neighbor (face,
-                               adjacent_cells[cell->quad(face)->index()][1]);
-       }
-                                  // first adjacent cell is not this
-                                  // one, -> it must be the neighbor
-                                  // we are looking for
-      else
-       cell->set_neighbor (face,
-                           adjacent_cells[cell->quad(face)->index()][0]);
 
+       const unsigned int n_vertices = triangulation.vertices.size();
+       Point<spacedim> shift_vector;
+  
+       for (unsigned int vertex=0; vertex<n_vertices; ++vertex) 
+         {
+                                            // ignore this vertex if we
+                                            // whall keep the boundary and
+                                            // this vertex *is* at the
+                                            // boundary
+           if (keep_boundary && at_boundary[vertex])
+             continue;
+      
+                                            // first compute a random shift
+                                            // vector
+           for (unsigned int d=0; d<spacedim; ++d)
+             shift_vector(d) = std::rand()*1.0/RAND_MAX;
 
-                                  // re-compute numbers of lines, etc
-  update_number_cache ();  
-}
-
-#endif
-
-
-#if deal_II_dimension == 1
-
-template <>
-void Triangulation<1>::distort_random (const double factor,
-                                      const bool   keep_boundary)
-{
-                                  // this function is mostly
-                                  // equivalent to that for the
-                                  // general dimensional case the
-                                  // only difference being the
-                                  // correction for split faces which
-                                  // is not necessary in 1D
-                                  //
-                                  // if you change something here,
-                                  // don't forget to do so there as
-                                  // well
-
-  const unsigned int dim = 1;
-  
-                                  // find the smallest length of the
-                                  // lines adjacent to the
-                                  // vertex. take the initial value
-                                  // to be larger than anything that
-                                  // might be found: the diameter of
-                                  // the triangulation, here computed
-                                  // by adding up the diameters of
-                                  // the coarse grid cells.
-  double almost_infinite_length = 0;
-  for (cell_iterator cell=begin(0); cell!=end(0); ++cell)
-    almost_infinite_length += cell->diameter();
-  
-  std::vector<double> minimal_length (vertices.size(),
-                                     almost_infinite_length);
-                                  // also note if a vertex is at
-                                  // the boundary
-  std::vector<bool>   at_boundary (vertices.size(), false);
-  
-  for (active_line_iterator line=begin_active_line();
-       line != end_line(); ++line)
-    {
-      if (keep_boundary && line->at_boundary())
-       {
-         at_boundary[line->vertex_index(0)] = true;
-         at_boundary[line->vertex_index(1)] = true;
-       }
-      
-      minimal_length[line->vertex_index(0)]
-       = std::min(line->diameter(),
-                  minimal_length[line->vertex_index(0)]);
-      minimal_length[line->vertex_index(1)]
-       = std::min(line->diameter(),
-                  minimal_length[line->vertex_index(1)]);
-    }
-
-
-  const unsigned int n_vertices = vertices.size();
-  Point<dim> shift_vector;
-  
-  for (unsigned int vertex=0; vertex<n_vertices; ++vertex) 
-    {
-                                      // ignore this vertex if we
-                                      // whall keep the boundary and
-                                      // this vertex *is* at the
-                                      // boundary
-      if (keep_boundary && at_boundary[vertex])
-       continue;
-      
-                                      // first compute a random shift
-                                      // vector
-      for (unsigned int d=0; d<dim; ++d)
-       shift_vector(d) = std::rand()*1.0/RAND_MAX;
-
-      shift_vector *= factor * minimal_length[vertex] /
-                     std::sqrt(shift_vector.square());
-
-                                      // finally move the vertex
-      vertices[vertex] += shift_vector;
-    }
-}
-
-#endif
+           shift_vector *= factor * minimal_length[vertex] /
+                           std::sqrt(shift_vector.square());
 
+                                            // finally move the vertex
+           triangulation.vertices[vertex] += shift_vector;
+         }
+      }
+    
 
-template <int dim>
-void Triangulation<dim>::distort_random (const double factor,
-                                        const bool   keep_boundary)
-{
+                                    /**
+                                     * Distort a triangulation in
+                                     * some random way. This is the
+                                     * function taken for the case
+                                     * dim>1.
+                                     */
+    template <int dim, int spacedim>
+    static
+    void
+    distort_random (const double                 factor,
+                   const bool                   keep_boundary,
+                   Triangulation<dim,spacedim> &triangulation)
+      {
 //TODO:[?]Implement the random distortion in Triangulation for hanging nodes as well
 //    Hanging nodes need to be reset to the correct mean value
 //    at the end, which is simple for 2D but difficult for 3D. Maybe take
 //    a look at how we get to the original location of the point in the
 //    execute_refinement function and copy the relevant lines.
   
-                                  // this function is mostly
-                                  // equivalent to that for the
-                                  // general dimensional case the
-                                  // only difference being the
-                                  // correction for split faces which
-                                  // is not necessary in 1D
-                                  //
-                                  // if you change something here,
-                                  // don't forget to do so there as
-                                  // well
+                                        // this function is mostly
+                                        // equivalent to that for the
+                                        // general dimensional case the
+                                        // only difference being the
+                                        // correction for split faces which
+                                        // is not necessary in 1D
+                                        //
+                                        // if you change something here,
+                                        // don't forget to do so there as
+                                        // well
   
-                                  // find the smallest length of the
-                                  // lines adjacent to the
-                                  // vertex. take the initial value
-                                  // to be larger than anything that
-                                  // might be found: the diameter of
-                                  // the triangulation, here
-                                  // estimated by adding up the
-                                  // diameters of the coarse grid
-                                  // cells.
-  double almost_infinite_length = 0;
-  for (cell_iterator cell=begin(0); cell!=end(0); ++cell)
-    almost_infinite_length += cell->diameter();
+                                        // find the smallest length of the
+                                        // lines adjacent to the
+                                        // vertex. take the initial value
+                                        // to be larger than anything that
+                                        // might be found: the diameter of
+                                        // the triangulation, here
+                                        // estimated by adding up the
+                                        // diameters of the coarse grid
+                                        // cells.
+       double almost_infinite_length = 0;
+       for (cell_iterator cell=triangulation.begin(0); cell!=triangulation.end(0); ++cell)
+         almost_infinite_length += cell->diameter();
   
-  std::vector<double> minimal_length (vertices.size(),
-                                     almost_infinite_length);
+       std::vector<double> minimal_length (triangulation.vertices.size(),
+                                           almost_infinite_length);
 
-                                  // also note if a vertex is at the
-                                  // boundary
-  std::vector<bool>   at_boundary (vertices.size(), false);
+                                        // also note if a vertex is at the
+                                        // boundary
+       std::vector<bool>   at_boundary (triangulation.vertices.size(), false);
   
-  for (active_line_iterator line=begin_active_line();
-       line != end_line(); ++line)
-    {
-      if (keep_boundary && line->at_boundary())
-       {
-         at_boundary[line->vertex_index(0)] = true;
-         at_boundary[line->vertex_index(1)] = true;
-       }
+       for (active_line_iterator line=triangulation.begin_active_line();
+            line != triangulation.end_line(); ++line)
+         {
+           if (keep_boundary && line->at_boundary())
+             {
+               at_boundary[line->vertex_index(0)] = true;
+               at_boundary[line->vertex_index(1)] = true;
+             }
       
-      minimal_length[line->vertex_index(0)]
-       = std::min(line->diameter(),
-                  minimal_length[line->vertex_index(0)]);
-      minimal_length[line->vertex_index(1)]
-       = std::min(line->diameter(),
-                  minimal_length[line->vertex_index(1)]);
-    }
+           minimal_length[line->vertex_index(0)]
+             = std::min(line->diameter(),
+                        minimal_length[line->vertex_index(0)]);
+           minimal_length[line->vertex_index(1)]
+             = std::min(line->diameter(),
+                        minimal_length[line->vertex_index(1)]);
+         }
 
 
-  const unsigned int n_vertices = vertices.size();
-  Point<dim> shift_vector;
+       const unsigned int n_vertices = triangulation.vertices.size();
+       Point<spacedim> shift_vector;
   
-  for (unsigned int vertex=0; vertex<n_vertices; ++vertex) 
-    {
-                                      // ignore this vertex if we
-                                      // whall keep the boundary and
-                                      // this vertex *is* at the
-                                      // boundary
-      if (keep_boundary && at_boundary[vertex])
-       continue;
+       for (unsigned int vertex=0; vertex<n_vertices; ++vertex) 
+         {
+                                            // ignore this vertex if we
+                                            // whall keep the boundary and
+                                            // this vertex *is* at the
+                                            // boundary
+           if (keep_boundary && at_boundary[vertex])
+             continue;
       
-                                      // first compute a random shift
-                                      // vector
-      for (unsigned int d=0; d<dim; ++d)
-       shift_vector(d) = std::rand()*1.0/RAND_MAX;
-
-      shift_vector *= factor * minimal_length[vertex] /
-                     std::sqrt(shift_vector.square());
-
-                                      // finally move the vertex
-      vertices[vertex] += shift_vector;
-    }
+                                            // first compute a random shift
+                                            // vector
+           for (unsigned int d=0; d<spacedim; ++d)
+             shift_vector(d) = std::rand()*1.0/RAND_MAX;
 
+           shift_vector *= factor * minimal_length[vertex] /
+                           std::sqrt(shift_vector.square());
 
-                                  // finally correct hanging nodes
-                                  // again. The following is not
-                                  // necessary for 1D
-  active_cell_iterator cell = begin_active(),
-                      endc = end();
-  for (; cell!=endc; ++cell) 
-    for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-      if (cell->face(face)->has_children() &&
-         !cell->face(face)->at_boundary())
-                                        // this lines has children,
-                                        // thus there are restricted
-                                        // nodes
-       {
-                                          // not implemented at
-                                          // present for dim=3 or
-                                          // higher
-         Assert (dim<=2, ExcNotImplemented());
-
-                                          // compute where the common
-                                          // point of the two child
-                                          // lines will lie and reset
-                                          // it to the correct value
-         vertices[cell->face(face)->child(0)->vertex_index(1)]
-           = (cell->face(face)->vertex(0) +
-              cell->face(face)->vertex(1)) / 2;
-       }
-}
-
+                                            // finally move the vertex
+           triangulation.vertices[vertex] += shift_vector;
+         }
 
 
-template <int dim>
-void Triangulation<dim>::set_all_refine_flags ()
-{
-  active_cell_iterator cell = begin_active(),
-                      endc = end();
+                                        // finally correct hanging nodes
+                                        // again. The following is not
+                                        // necessary for 1D
+       active_cell_iterator cell = triangulation.begin_active(),
+                            endc = triangulation.end();
+       for (; cell!=endc; ++cell) 
+         for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+           if (cell->face(face)->has_children() &&
+               !cell->face(face)->at_boundary())
+                                              // this lines has children,
+                                              // thus there are restricted
+                                              // nodes
+             {
+                                                // not implemented at
+                                                // present for dim=3 or
+                                                // higher
+               Assert (dim<=2, ExcNotImplemented());
+
+                                                // compute where the common
+                                                // point of the two child
+                                                // lines will lie and reset
+                                                // it to the correct value
+               triangulation.vertices[cell->face(face)->child(0)->vertex_index(1)]
+                 = (cell->face(face)->vertex(0) +
+                    cell->face(face)->vertex(1)) / 2;
+             }
+      }
 
-  for (; cell != endc; ++cell)
-    {
-      cell->clear_coarsen_flag();
-      cell->set_refine_flag ();
-    }
-}
 
+                                    /**
+                                     * Actually delete a cell, or rather all
+                                     * its children, which is the main step for
+                                     * the coarsening process.  This is the
+                                     * dimension dependent part of @p
+                                     * execute_coarsening. The second argument
+                                     * is a vector which gives for each line
+                                     * index the number of cells containing
+                                     * this line. This information is needed to
+                                     * decide whether a refined line may be
+                                     * coarsened or not in 3D. In 1D and 2D
+                                     * this argument is not needed and thus
+                                     * ignored. The same applies for the last
+                                     * argument and quads instead of lines.
+                                     */
+    template <int spacedim>
+    static
+    void
+    delete_children (Triangulation<1,spacedim> &triangulation,
+                    cell_iterator             &cell,
+                    std::vector<unsigned int> &,
+                    std::vector<unsigned int> &)
+      {
+                                        // first we need to reset the
+                                        // neighbor pointers of the
+                                        // neighbors of this cell's
+                                        // children to this cell. This is
+                                        // different for one dimension,
+                                        // since there neighbors can have a
+                                        // refinement level differing from
+                                        // that of this cell's children by
+                                        // more than one level.
+
+       Assert (!cell->child(0)->has_children() && !cell->child(1)->has_children(),
+               ExcInternalError());
+  
+                                        // first do it for the cells to the
+                                        // left
+       if (cell->neighbor(0).state() == IteratorState::valid)
+         if (cell->neighbor(0)->has_children())
+           {
+             cell_iterator neighbor = cell->neighbor(0);
+             Assert (neighbor->level() == cell->level(), ExcInternalError());
+       
+                                              // right child
+             neighbor = neighbor->child(1);
+             while (1)
+               {
+                 Assert (neighbor->neighbor(1) == cell->child(0),
+                         ExcInternalError());
+                 neighbor->set_neighbor (1, cell);
+           
+                                                  // move on to further
+                                                  // children on the
+                                                  // boundary between this
+                                                  // cell and its neighbor
+                 if (neighbor->has_children())
+                   neighbor = neighbor->child(1);
+                 else
+                   break;
+               }
+           }
 
+                                        // now do it for the cells to the
+                                        // left
+       if (cell->neighbor(1).state() == IteratorState::valid)
+         if (cell->neighbor(1)->has_children())
+           {
+             cell_iterator neighbor = cell->neighbor(1);
+             Assert (neighbor->level() == cell->level(), ExcInternalError());
+       
+                                              // left child
+             neighbor = neighbor->child(0);
+             while (1)
+               {
+                 Assert (neighbor->neighbor(0) == cell->child(1),
+                         ExcInternalError());
+                 neighbor->set_neighbor (0, cell);
+           
+                                                  // move on to further
+                                                  // children on the
+                                                  // boundary between this
+                                                  // cell and its neighbor
+                 if (neighbor->has_children())
+                   neighbor = neighbor->child(0);
+                 else
+                   break;
+               }
+           }
 
-template <int dim>
-void Triangulation<dim>::refine_global (const unsigned int times)
-{
-  for (unsigned int i=0; i<times; ++i)
-    {
-      set_all_refine_flags();
-      execute_coarsening_and_refinement ();
-    }
-}
 
+                                        // delete the vertex which will not
+                                        // be needed anymore. This vertex
+                                        // is the second of the first child
+       triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
 
+                                        // invalidate children.  clear user
+                                        // pointers, to avoid that they may
+                                        // appear at unwanted places later
+                                        // on...
+       for (unsigned int child=0; child<cell->n_children(); ++child)
+         {
+           cell->child(child)->clear_user_data();
+           cell->child(child)->clear_user_flag();
+           cell->child(child)->clear_used_flag();
+         }
 
-template <int dim>
-void Triangulation<dim>::save_refine_flags (std::vector<bool> &v) const
-{
-  v.resize (dim*n_active_cells(), false);
-  std::vector<bool>::iterator  i = v.begin();
-  active_cell_iterator cell = begin_active(),
-                      endc = end();
-  for (; cell!=endc; ++cell)
-    for (unsigned int j=0; j<dim; ++j,++i)
-      if (cell->refine_flag_set() & (1<<j) )
-       *i = true;
-}
 
+                                        // delete pointer to children
+       cell->clear_children ();
+       cell->clear_user_flag();
+      }
 
 
-template <int dim>
-void Triangulation<dim>::save_refine_flags (std::ostream &out) const
-{
-  std::vector<bool> v;
-  save_refine_flags (v);
-  write_bool_vector (mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end,
-                    out);
-}
+    
+    template <int spacedim>
+    static
+    void
+    delete_children (Triangulation<2,spacedim> &triangulation,
+                    cell_iterator             &cell,
+                    std::vector<unsigned int> &,
+                    std::vector<unsigned int> &)
+      {
+       const unsigned int dim=2;
+       const RefinementCase<dim> ref_case=cell->refinement_case();
 
+       for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+         if (!cell->at_boundary(face_no))
+           {
+             if (GeometryInfo<dim>::face_refinement_case(ref_case, face_no)
+                 ==RefinementCase<1>::no_refinement)
+               cell->set_neighbor(face_no,cell->child(face_no%2)->neighbor(face_no));
+       
+             cell_iterator neighbor=cell->neighbor(face_no);
+       
+                                              // it is possible that the neighbor is
+                                              // coarser if it has already been
+                                              // coarsened earlier in this cycle. for
+                                              // anisotropic refinement that can
+                                              // happen, even if the neighbor is on a
+                                              // higher level.
+       
+                                              // it is also possible, that the
+                                              // neighbor information of cell was not
+                                              // the best information currently
+                                              // available. however, the neighbor
+                                              // information now set should be
+                                              // accurate, as we have taken the
+                                              // pointer from one of our children, if
+                                              // that could be mor accurate and these
+                                              // children can't be further refined.
+       
+                                              // if the neighbor is coarser, do
+                                              // nothing: we won't have to reset our
+                                              // pointer of course and the coarser
+                                              // neighbor does not point to this cell
+             if (cell->neighbor_is_coarser(face_no))
+               {
+                 Assert(neighbor->active(),
+                        ExcInternalError());
+                 continue;
+               }
+       
+             const unsigned int nb_nb=cell->neighbor_of_neighbor(face_no);
+             neighbor->set_neighbor(nb_nb, cell);
+                                              // go down the list of children which
+                                              // are not refined along the face (if
+                                              // any)
+             while (neighbor->has_children() &&
+                    (GeometryInfo<dim>::face_refinement_case(neighbor->refinement_case(), nb_nb)
+                     ==RefinementCase<dim-1>::no_refinement))
+               {
+                 neighbor=neighbor->child(GeometryInfo<dim>
+                                          ::child_cell_on_face(neighbor->refinement_case(),
+                                                               nb_nb,
+                                                               0));
+                 neighbor->set_neighbor(nb_nb, cell);
+               }
+               
+                                              // now we can safely set the cells
+                                              // neighbor
+             cell->set_neighbor(face_no,neighbor);
+                          
+                                              // if there are still children, they
+                                              // have to be refined along the face
+                                              // currently under consideration
+             if (neighbor->has_children())
+               {
+                 unsigned int n_subfaces=GeometryInfo<dim-1>::n_children(
+                   GeometryInfo<dim>::face_refinement_case(neighbor->refinement_case(), nb_nb));
+                 Assert (n_subfaces>0, ExcInternalError());
+               
+                 for (unsigned int i=0; i<n_subfaces; ++i)
+                   {
+                     cell_iterator neighbor_child=neighbor->child(
+                       GeometryInfo<dim>::child_cell_on_face(neighbor->refinement_case(),
+                                                             nb_nb, i));
+                     neighbor_child->set_neighbor(nb_nb, cell);
+                                                      // once again, this
+                                                      // neighbor_child can be
+                                                      // refined several times,
+                                                      // as long as this
+                                                      // refinement is not along
+                                                      // the current subface. if
+                                                      // there are children
+                                                      // refined along the
+                                                      // subface they will be
+                                                      // coarsened away later in
+                                                      // this process, so we
+                                                      // don't care about them
+                                                      // here
+                     while (neighbor_child->has_children() &&
+                            (GeometryInfo<dim>::face_refinement_case(neighbor_child->refinement_case(),
+                                                                     nb_nb)
+                             == RefinementCase<dim-1>::no_refinement))
+                       {
+                         neighbor_child=neighbor_child
+                                        ->child(GeometryInfo<dim>
+                                                ::child_cell_on_face(neighbor_child->refinement_case(),
+                                                                     nb_nb,
+                                                                     0));
+                         neighbor_child->set_neighbor(nb_nb, cell);
+                       }
+                   }
+               }
+           }
+                                        // delete the vertex which will not
+                                        // be needed anymore. This vertex
+                                        // is the second of the second line
+                                        // of the first child, if the cell
+                                        // is refined with cut_xy, else there
+                                        // is no inner vertex.
+                                        // additionally delete unneeded inner
+                                        // lines
+       if (ref_case==RefinementCase<dim>::cut_xy)
+         {
+           triangulation.vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
+      
+                                            // clear user pointers, to
+                                            // avoid that they may appear
+                                            // at unwanted places later
+                                            // on...
+           cell->child(0)->line(1)->clear_user_data();
+           cell->child(0)->line(3)->clear_user_data();
+           cell->child(3)->line(0)->clear_user_data();
+           cell->child(3)->line(2)->clear_user_data();
+      
+                                            // same for user flags
+           cell->child(0)->line(1)->clear_user_flag();
+           cell->child(0)->line(3)->clear_user_flag();
+           cell->child(3)->line(0)->clear_user_flag();
+           cell->child(3)->line(2)->clear_user_flag();
+      
+                                            // delete the four interior
+                                            // lines
+           cell->child(0)->line(1)->clear_used_flag();
+           cell->child(0)->line(3)->clear_used_flag();
+           cell->child(3)->line(0)->clear_used_flag();
+           cell->child(3)->line(2)->clear_used_flag();
+         }
+       else
+         {
+           unsigned int inner_face_no=ref_case==RefinementCase<dim>::cut_x ? 1 : 3;
+                                
+                                            // the inner line will not be
+                                            // used any more
+           cell->child(0)->line(inner_face_no)->clear_user_data();
+           cell->child(0)->line(inner_face_no)->clear_user_flag();
+           cell->child(0)->line(inner_face_no)->clear_used_flag();
+         }
+                                  
+                                        // if the neighbor does not need
+                                        // the subfaces, delete them.  in case of
+                                        // anisotropic refinement we can't just
+                                        // ask the neighbor's level here to
+                                        // assure, that he is not refined along
+                                        // the face
+       for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face) 
+         if (((cell->neighbor(face).state() != IteratorState::valid) ||
+              (!cell->neighbor(face)->has_children())) &&
+             (GeometryInfo<dim>::face_refinement_case(ref_case,face)
+              !=RefinementCase<dim-1>::no_refinement))
+           {
+             line_iterator line=cell->face(face);
+                                              // delete middle vertex
+             triangulation.vertices_used[line->child(0)->vertex_index(1)] = false;
+                                              // delete the two subfaces
+             for (unsigned int subface=0;
+                  subface<line->n_children(); ++subface)
+               {
+                 line->child(subface)->clear_user_data ();
+                 line->child(subface)->clear_user_flag ();
+                 line->child(subface)->clear_used_flag ();
+               }
+       
+             line->clear_children();
+           }
+                                        // invalidate children
+       for (unsigned int child=0; child<cell->n_children(); ++child)
+         {
+           cell->child(child)->clear_user_data();
+           cell->child(child)->clear_user_flag();
+           cell->child(child)->clear_used_flag();
+         }
 
 
-template <int dim>
-void Triangulation<dim>::load_refine_flags (std::istream &in)
-{
-  std::vector<bool> v;
-  read_bool_vector (mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end,
-                   in);
-  load_refine_flags (v);
-}
+                                        // delete pointer to children
+       cell->clear_children ();
+       cell->clear_refinement_case();
+       cell->clear_user_flag();
+      }
 
 
 
-template <int dim>
-void Triangulation<dim>::load_refine_flags (const std::vector<bool> &v)
-{
-  AssertThrow (v.size() == dim*n_active_cells(), ExcGridReadError());
+    template <int spacedim>
+    static
+    void
+    delete_children (Triangulation<3,spacedim> &triangulation,
+                    cell_iterator             &cell,
+                    std::vector<unsigned int> &line_cell_count,
+                    std::vector<unsigned int> &quad_cell_count)
+      {
+       const unsigned int dim=3;
   
-  active_cell_iterator cell = begin_active(),
-                      endc = end();
-  std::vector<bool>::const_iterator i = v.begin();
-   for (; cell!=endc; ++cell)
-     {
-       unsigned int ref_case=0;
-       
-       for(unsigned int j=0; j<dim; ++j, ++i)
-        if (*i == true)
-          ref_case+=1<<j;
-       Assert(ref_case<RefinementCase<dim>::isotropic_refinement+1,
-             ExcGridReadError());
-       if (ref_case>0)
-        cell->set_refine_flag(RefinementCase<dim>(ref_case));
-       else
-        cell->clear_refine_flag();
-     }
-}
-
-
-
-template <int dim>
-void Triangulation<dim>::save_coarsen_flags (std::vector<bool> &v) const
-{
-  v.resize (n_active_cells(), false);
-  std::vector<bool>::iterator  i = v.begin();
-  active_cell_iterator cell = begin_active(),
-                      endc = end();
-  for (; cell!=endc; ++cell, ++i)
-    *i = cell->coarsen_flag_set();
-}
-
+       Assert(line_cell_count.size()==triangulation.n_raw_lines(), ExcInternalError());
+       Assert(quad_cell_count.size()==triangulation.n_raw_quads(), ExcInternalError());
+
+                                        // first of all, we store the RefineCase of
+                                        // this cell
+       const RefinementCase<dim> ref_case=cell->refinement_case();
+                                        // vectors to hold all lines and quads which
+                                        // may be deleted
+       std::vector<line_iterator> lines_to_delete(0);
+       std::vector<quad_iterator> quads_to_delete(0);
+       lines_to_delete.reserve(12*2+6*4+6);
+       quads_to_delete.reserve(6*4+12);
+  
+                                        // now we decrease the counters for lines and
+                                        // quads contained in the child cells
+       for (unsigned int c=0; c<cell->n_children(); ++c)
+         {
+           cell_iterator child=cell->child(c);
+           for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+             --line_cell_count[child->line_index(l)];
+           for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+             --quad_cell_count[child->quad_index(f)];
+         }
+  
+                                        // first we need to reset the neighbor
+                                        // pointers of the neighbors from this cell's
+                                        // children to this cell. This is done by a
+                                        // seperate function.
+       update_neighbors<spacedim> (cell, false);
+
+                                        ///////////////////////////////////////
+                                        // delete interior quads and lines and the
+                                        // interior vertex, depending on the
+                                        // refinement case of the cell
+                                        //
+                                        // for append quads and lines: only append
+                                        // them to the list of objects to be deleted
+  
+       switch (ref_case)
+         {
+           case RefinementCase<dim>::cut_x:
+                 quads_to_delete.push_back(cell->child(0)->face(1));
+                 break;
+           case RefinementCase<dim>::cut_y:
+                 quads_to_delete.push_back(cell->child(0)->face(3));
+                 break;
+           case RefinementCase<dim>::cut_z:
+                 quads_to_delete.push_back(cell->child(0)->face(5));
+                 break;
+           case RefinementCase<dim>::cut_xy:
+                 quads_to_delete.push_back(cell->child(0)->face(1));
+                 quads_to_delete.push_back(cell->child(0)->face(3));
+                 quads_to_delete.push_back(cell->child(3)->face(0));
+                 quads_to_delete.push_back(cell->child(3)->face(2));
 
+                 lines_to_delete.push_back(cell->child(0)->line(11));
+                 break;
+           case RefinementCase<dim>::cut_xz:
+                 quads_to_delete.push_back(cell->child(0)->face(1));
+                 quads_to_delete.push_back(cell->child(0)->face(5));
+                 quads_to_delete.push_back(cell->child(3)->face(0));
+                 quads_to_delete.push_back(cell->child(3)->face(4));
 
-template <int dim>
-void Triangulation<dim>::save_coarsen_flags (std::ostream &out) const
-{
-  std::vector<bool> v;
-  save_coarsen_flags (v);
-  write_bool_vector (mn_tria_coarsen_flags_begin, v, mn_tria_coarsen_flags_end,
-                    out);
-}
+                 lines_to_delete.push_back(cell->child(0)->line(5));
+                 break;
+           case RefinementCase<dim>::cut_yz:
+                 quads_to_delete.push_back(cell->child(0)->face(3));
+                 quads_to_delete.push_back(cell->child(0)->face(5));
+                 quads_to_delete.push_back(cell->child(3)->face(2));
+                 quads_to_delete.push_back(cell->child(3)->face(4));
 
+                 lines_to_delete.push_back(cell->child(0)->line(7));
+                 break;
+           case RefinementCase<dim>::cut_xyz:
+                 quads_to_delete.push_back(cell->child(0)->face(1));
+                 quads_to_delete.push_back(cell->child(2)->face(1));
+                 quads_to_delete.push_back(cell->child(4)->face(1));
+                 quads_to_delete.push_back(cell->child(6)->face(1));
+           
+                 quads_to_delete.push_back(cell->child(0)->face(3));
+                 quads_to_delete.push_back(cell->child(1)->face(3));
+                 quads_to_delete.push_back(cell->child(4)->face(3));
+                 quads_to_delete.push_back(cell->child(5)->face(3));
+           
+                 quads_to_delete.push_back(cell->child(0)->face(5));
+                 quads_to_delete.push_back(cell->child(1)->face(5));
+                 quads_to_delete.push_back(cell->child(2)->face(5));
+                 quads_to_delete.push_back(cell->child(3)->face(5)); 
+           
+                 lines_to_delete.push_back(cell->child(0)->line(5));
+                 lines_to_delete.push_back(cell->child(0)->line(7));
+                 lines_to_delete.push_back(cell->child(0)->line(11));
+                 lines_to_delete.push_back(cell->child(7)->line(0));
+                 lines_to_delete.push_back(cell->child(7)->line(2));
+                 lines_to_delete.push_back(cell->child(7)->line(8));
+                                                  // delete the vertex which will not
+                                                  // be needed anymore. This vertex
+                                                  // is the vertex at the heart of
+                                                  // this cell, which is the sixth of
+                                                  // the first child
+                 triangulation.vertices_used[cell->child(0)->vertex_index(7)] = false;
+                 break;
+           default:
+                                                  // only remaining case is
+                                                  // no_refinement, thus an error
+                 Assert(false, ExcInternalError());
+                 break;
+         }
+  
 
+                                        // invalidate children
+       for (unsigned int child=0; child<cell->n_children(); ++child)
+         {
+           cell->child(child)->clear_user_data();
+           cell->child(child)->clear_user_flag();
 
-template <int dim>
-void Triangulation<dim>::load_coarsen_flags (std::istream &in)
-{
-  std::vector<bool> v;
-  read_bool_vector (mn_tria_coarsen_flags_begin, v, mn_tria_coarsen_flags_end,
-                   in);
-  load_coarsen_flags (v);
-}
+           for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+             {
+                                                // set flags denoting deviations from
+                                                // standard orientation of faces back
+                                                // to initialization values
+               cell->child(child)->set_face_orientation (f, true);
+               cell->child(child)->set_face_flip(f,false);
+               cell->child(child)->set_face_rotation(f,false);
+             }
+      
+           cell->child(child)->clear_used_flag();
+         }
 
 
+                                        // delete pointer to children
+       cell->clear_children ();
+       cell->clear_refinement_case ();
+       cell->clear_user_flag();
 
-template <int dim>
-void Triangulation<dim>::load_coarsen_flags (const std::vector<bool> &v)
-{
-  Assert (v.size() == n_active_cells(), ExcGridReadError());
+                                        // so far we only looked at inner quads,
+                                        // lines and vertices. Now we have to
+                                        // consider outer ones as well. here, we have
+                                        // to check, whether there are other cells
+                                        // still needing these objects. oherwise we
+                                        // can delete them. first for quads (and
+                                        // their inner lines).
   
-  active_cell_iterator cell = begin_active(),
-                      endc = end();
-  std::vector<bool>::const_iterator i = v.begin();
-  for (; cell!=endc; ++cell, ++i)
-    if (*i == true)
-      cell->set_coarsen_flag();
-    else
-      cell->clear_coarsen_flag();
-}
+       for (unsigned int quad_no=0; quad_no<GeometryInfo<dim>::faces_per_cell; ++quad_no)
+         {
+           quad_iterator quad=cell->face(quad_no);
 
+           Assert((GeometryInfo<dim>::face_refinement_case(ref_case,quad_no) && quad->has_children()) ||
+                  GeometryInfo<dim>::face_refinement_case(ref_case,quad_no)==RefinementCase<dim-1>::no_refinement,
+                  ExcInternalError());
 
-template <int dim>
-bool Triangulation<dim>::get_anisotropic_refinement_flag() const
-{
-  return anisotropic_refinement;
-}
+           switch (quad->refinement_case())
+             {
+               case RefinementCase<dim-1>::no_refinement:
+                                                      // nothing to do as the quad
+                                                      // is not refined
+                     break;
+               case RefinementCase<dim-1>::cut_x:
+               case RefinementCase<dim-1>::cut_y:
+               {
+                                                  // if one of the cell counters is
+                                                  // zero, the other has to be as
+                                                  // well
+                 Assert((quad_cell_count[quad->child_index(0)] == 0 &&
+                         quad_cell_count[quad->child_index(1)] == 0) ||
+                        (quad_cell_count[quad->child_index(0)] > 0 &&
+                         quad_cell_count[quad->child_index(1)] > 0),
+                        ExcInternalError());
+                                                  // it might be, that the quad is
+                                                  // refined twice anisotropically,
+                                                  // first check, whether we may
+                                                  // delete possible grand_children
+                 unsigned int deleted_grandchildren=0;
+                 unsigned int number_of_child_refinements=0;
+           
+                 for (unsigned int c=0; c<2; ++c)
+                   if (quad->child(c)->has_children())
+                     {
+                       ++number_of_child_refinements;
+                                                        // if one of the cell counters is
+                                                        // zero, the other has to be as
+                                                        // well
+                       Assert((quad_cell_count[quad->child(c)->child_index(0)] == 0 &&
+                               quad_cell_count[quad->child(c)->child_index(1)] == 0) ||
+                              (quad_cell_count[quad->child(c)->child_index(0)] > 0 &&
+                               quad_cell_count[quad->child(c)->child_index(1)] > 0),
+                              ExcInternalError());
+                       if (quad_cell_count[quad->child(c)->child_index(0)]==0)
+                         {
+                                                            // Assert, that the two
+                                                            // anisotropic
+                                                            // refinements add up to
+                                                            // isotropic refinement
+                           Assert(quad->refinement_case()+quad->child(c)->refinement_case()==RefinementCase<dim>::cut_xy,
+                                  ExcInternalError());
+                                                            // we may delete the
+                                                            // quad's children and
+                                                            // the inner line as no
+                                                            // cell references them
+                                                            // anymore
+                           quads_to_delete.push_back(quad->child(c)->child(0));
+                           quads_to_delete.push_back(quad->child(c)->child(1));
+                           if (quad->child(c)->refinement_case()==RefinementCase<2>::cut_x)
+                             lines_to_delete.push_back(quad->child(c)->child(0)->line(1));
+                           else
+                             lines_to_delete.push_back(quad->child(c)->child(0)->line(3));
+                           quad->child(c)->clear_children();
+                           quad->child(c)->clear_refinement_case();
+                           ++deleted_grandchildren;
+                         }
+                     }
+                                                  // if no grandchildren are left, we
+                                                  // may as well delete the
+                                                  // refinement of the inner line
+                                                  // between our children and the
+                                                  // corresponding vertex
+                 if (number_of_child_refinements>0 &&
+                     deleted_grandchildren==number_of_child_refinements)
+                   {
+                     line_iterator middle_line;
+                     if (quad->refinement_case()==RefinementCase<2>::cut_x)
+                       middle_line=quad->child(0)->line(1);
+                     else
+                       middle_line=quad->child(0)->line(3);
 
+                     lines_to_delete.push_back(middle_line->child(0));
+                     lines_to_delete.push_back(middle_line->child(1));
+                     triangulation.vertices_used[middle_vertex_index<dim,spacedim>(middle_line)]
+                       = false;
+                     middle_line->clear_children();
+                   }
 
-#if deal_II_dimension == 1
-
-template <>
-void Triangulation<1>::clear_user_data ()
-{
-  for (unsigned int level=0;level<levels.size();++level)
-    levels[level]->cells.clear_user_data();
-}
-
+                                                  // now consider the direct children
+                                                  // of the given quad
+                 if (quad_cell_count[quad->child_index(0)]==0)
+                   {
+                                                      // we may delete the quad's
+                                                      // children and the inner line
+                                                      // as no cell references them
+                                                      // anymore
+                     quads_to_delete.push_back(quad->child(0));
+                     quads_to_delete.push_back(quad->child(1));
+                     if (quad->refinement_case()==RefinementCase<2>::cut_x)
+                       lines_to_delete.push_back(quad->child(0)->line(1));
+                     else
+                       lines_to_delete.push_back(quad->child(0)->line(3));
+
+                                                      // if the counters just dropped
+                                                      // to zero, otherwise the
+                                                      // children would have been
+                                                      // deleted earlier, then this
+                                                      // cell's children must have
+                                                      // contained the anisotropic
+                                                      // quad children. thus, if
+                                                      // those have again anisotropic
+                                                      // children, which are in
+                                                      // effect isotropic children of
+                                                      // the original quad, those are
+                                                      // still needed by a
+                                                      // neighboring cell and we
+                                                      // cannot delete them. instead,
+                                                      // we have to reset this quad's
+                                                      // refine case to isotropic and
+                                                      // set the children
+                                                      // accordingly.
+                     if (quad->child(0)->has_children())
+                       if (quad->refinement_case()==RefinementCase<2>::cut_x)
+                         {
+                                                            // now evereything is
+                                                            // quite complicated. we
+                                                            // have the children
+                                                            // numbered according to
+                                                            //
+                                                            // *---*---*
+                                                            // |n+1|m+1|
+                                                            // *---*---*
+                                                            // | n | m |
+                                                            // *---*---*
+                                                            //
+                                                            // from the original
+                                                            // anisotropic
+                                                            // refinement. we have to
+                                                            // reorder them as
+                                                            //
+                                                            // *---*---*
+                                                            // | m |m+1|
+                                                            // *---*---*
+                                                            // | n |n+1|
+                                                            // *---*---*
+                                                            //
+                                                            // for isotropic refinement.
+                                                            //
+                                                            // this is a bit ugly, of
+                                                            // course: loop over all
+                                                            // cells on all levels
+                                                            // and look for faces n+1
+                                                            // (switch_1) and m
+                                                            // (switch_2).
+                           const quad_iterator switch_1=quad->child(0)->child(1);
+                           const quad_iterator switch_2=quad->child(1)->child(0);
+
+                           Assert(!switch_1->has_children(), ExcInternalError());
+                           Assert(!switch_2->has_children(), ExcInternalError());
+                     
+                           const int switch_1_index=switch_1->index();
+                           const int switch_2_index=switch_2->index();
+                           for (unsigned int l=0; l<triangulation.levels.size(); ++l)
+                             for (unsigned int h=0; h<triangulation.levels[l]->cells.cells.size(); ++h)
+                               for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
+                                 {
+                                   const int index=triangulation.levels[l]->cells.cells[h].face(q);
+                                   if (index==switch_1_index)
+                                     triangulation.levels[l]->cells.cells[h].set_face(q,switch_2_index);
+                                   else if (index==switch_2_index)
+                                     triangulation.levels[l]->cells.cells[h].set_face(q,switch_1_index);
+                                 }
+                                                            // now we have to copy
+                                                            // all information of the
+                                                            // two quads
+                           const int switch_1_lines[4]=
+                             {switch_1->line_index(0),
+                              switch_1->line_index(1),
+                              switch_1->line_index(2),
+                              switch_1->line_index(3)};
+                           const bool switch_1_line_orientations[4]=
+                             {switch_1->line_orientation(0),
+                              switch_1->line_orientation(1),
+                              switch_1->line_orientation(2),
+                              switch_1->line_orientation(3)};
+                           const unsigned char switch_1_boundary_indicator=switch_1->boundary_indicator();
+                           const unsigned int switch_1_user_index=switch_1->user_index();
+                           const bool switch_1_user_flag=switch_1->user_flag_set();
+
+                           switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
+                                                                                switch_2->line_index(1),
+                                                                                switch_2->line_index(2),
+                                                                                switch_2->line_index(3)));
+                           switch_1->set_line_orientation(0, switch_2->line_orientation(0));
+                           switch_1->set_line_orientation(1, switch_2->line_orientation(1));
+                           switch_1->set_line_orientation(2, switch_2->line_orientation(2));
+                           switch_1->set_line_orientation(3, switch_2->line_orientation(3));
+                           switch_1->set_boundary_indicator(switch_2->boundary_indicator());
+                           switch_1->set_user_index(switch_2->user_index());
+                           if (switch_2->user_flag_set())
+                             switch_1->set_user_flag();
+                           else
+                             switch_1->clear_user_flag();
+
+                           switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
+                                                                                switch_1_lines[1],
+                                                                                switch_1_lines[2],
+                                                                                switch_1_lines[3]));
+                           switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
+                           switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
+                           switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
+                           switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
+                           switch_2->set_boundary_indicator(switch_1_boundary_indicator);
+                           switch_2->set_user_index(switch_1_user_index);
+                           if (switch_1_user_flag)
+                             switch_2->set_user_flag();
+                           else
+                             switch_2->clear_user_flag();
+
+                           const unsigned int child_0=quad->child(0)->child_index(0);
+                           const unsigned int child_2=quad->child(1)->child_index(0);
+                           quad->clear_children();
+                           quad->clear_refinement_case();
+                           quad->set_refinement_case(RefinementCase<2>::cut_xy);
+                           quad->set_children(0,child_0);
+                           quad->set_children(2,child_2);
+                           std::swap(quad_cell_count[child_0+1],quad_cell_count[child_2]);
+                         }
+                       else
+                         {
+                                                            // the face was refined
+                                                            // with cut_y, thus the
+                                                            // children are already
+                                                            // in correct order. we
+                                                            // only have to set them
+                                                            // correctly, deleting
+                                                            // the indirection of two
+                                                            // anisotropic refinement
+                                                            // and going directly
+                                                            // from the quad to
+                                                            // isotropic children
+                           const unsigned int child_0=quad->child(0)->child_index(0);
+                           const unsigned int child_2=quad->child(1)->child_index(0);
+                           quad->clear_children();
+                           quad->clear_refinement_case();
+                           quad->set_refinement_case(RefinementCase<2>::cut_xy);
+                           quad->set_children(0,child_0);
+                           quad->set_children(2,child_2);                   
+                         }
+                     else
+                       {
+                         quad->clear_children();
+                         quad->clear_refinement_case();
+                       }
+               
+               
+                   }
+                 break;
+               }
+               case RefinementCase<dim-1>::cut_xy:
+               {
+                                                  // if one of the cell counters is
+                                                  // zero, the others have to be as
+                                                  // well
 
+                 Assert((quad_cell_count[quad->child_index(0)] == 0 &&
+                         quad_cell_count[quad->child_index(1)] == 0 &&
+                         quad_cell_count[quad->child_index(2)] == 0 &&
+                         quad_cell_count[quad->child_index(3)] == 0) ||
+                        (quad_cell_count[quad->child_index(0)] > 0 &&
+                         quad_cell_count[quad->child_index(1)] > 0 &&
+                         quad_cell_count[quad->child_index(2)] > 0 &&
+                         quad_cell_count[quad->child_index(3)] > 0),
+                        ExcInternalError());
+      
+                 if (quad_cell_count[quad->child_index(0)]==0)
+                   {
+                                                      // we may delete the quad's
+                                                      // children, the inner lines
+                                                      // and the middle vertex as no
+                                                      // cell references them anymore
+                     lines_to_delete.push_back(quad->child(0)->line(1));
+                     lines_to_delete.push_back(quad->child(3)->line(0));
+                     lines_to_delete.push_back(quad->child(0)->line(3));
+                     lines_to_delete.push_back(quad->child(3)->line(2));
+
+                     for (unsigned int child=0; child<quad->n_children(); ++child)
+                       quads_to_delete.push_back(quad->child(child));
+               
+                     triangulation.vertices_used[quad->child(0)->vertex_index(3)] = false;
+               
+                     quad->clear_children();
+                     quad->clear_refinement_case();
+                   }
+               }
+               break;
 
-template <>
-void Triangulation<1>::clear_user_pointers ()
-{
-  clear_user_data ();
-}
+               default:
+                     Assert(false, ExcInternalError());
+                     break;
+             }
+      
+         }
 
+                                        // now we repeat a similar procedure for the
+                                        // outer lines of this cell.
+  
+                                        // if in debug mode: check that each of the
+                                        // lines for which we consider deleting the
+                                        // children in fact has children (the
+                                        // bits/coarsening_3d test tripped over this
+                                        // initially)
+       for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
+         {
+           line_iterator line=cell->line(line_no);
 
+           Assert((GeometryInfo<dim>::line_refinement_case(ref_case,line_no) && line->has_children()) ||
+                  GeometryInfo<dim>::line_refinement_case(ref_case,line_no)==RefinementCase<1>::no_refinement,
+                  ExcInternalError());
+      
+           if (line->has_children())
+             {
+                                                // if one of the cell counters is
+                                                // zero, the other has to be as well
+
+               Assert((line_cell_count[line->child_index(0)] == 0 &&
+                       line_cell_count[line->child_index(1)] == 0) ||
+                      (line_cell_count[line->child_index(0)] > 0 &&
+                       line_cell_count[line->child_index(1)] > 0),
+                      ExcInternalError());
+      
+               if (line_cell_count[line->child_index(0)]==0)
+                 {
+                   for (unsigned int c=0; c<2; ++c)
+                     Assert (!line->child(c)->has_children(),
+                             ExcInternalError());
+             
+                                                    // we may delete the line's
+                                                    // children and the middle vertex
+                                                    // as no cell references them
+                                                    // anymore
+                   triangulation.vertices_used[line->child(0)->vertex_index(1)] = false;
+             
+                   lines_to_delete.push_back(line->child(0));
+                   lines_to_delete.push_back(line->child(1));
+             
+                   line->clear_children();
+                 }
+             }
+         }
 
-template <>
-void Triangulation<1>::clear_user_flags_line ()
-{
-  for (unsigned int level=0; level<levels.size(); ++level)
-    levels[level]->cells.clear_user_flags();
-}
+                                        // finally, delete unneeded quads and lines
+  
+                                        // clear user pointers, to avoid that
+                                        // they may appear at unwanted places
+                                        // later on...
+                                        // same for user flags, then finally
+                                        // delete the quads and lines
+       typename std::vector<line_iterator>::iterator
+         line=lines_to_delete.begin(),
+         endline=lines_to_delete.end();
+       for (; line!=endline; ++line)
+         {
+           (*line)->clear_user_data();
+           (*line)->clear_user_flag();
+           (*line)->clear_used_flag();
+         }
 
+       typename std::vector<quad_iterator>::iterator
+         quad=quads_to_delete.begin(),
+         endquad=quads_to_delete.end();
+       for (; quad!=endquad; ++quad)
+         {
+           (*quad)->clear_user_data();
+           (*quad)->clear_children();
+           (*quad)->clear_refinement_case();
+           (*quad)->clear_user_flag();
+           (*quad)->clear_used_flag();
+         }     
+      }
+    
+    
+                                    /**
+                                     * Create the children of a 2d
+                                     * cell. The arguments indicate
+                                     * the next free spots in the
+                                     * vertices, lines, and cells
+                                     * arrays.
+                                     *
+                                     * The faces of the cell have to
+                                     * be refined already, whereas
+                                     * the inner lines in 2D will be
+                                     * created in this
+                                     * function. Therefore iterator
+                                     * pointers into the vectors of
+                                     * lines, quads and cells have to
+                                     * be passed, which point at (or
+                                     * "before") the reserved space.
+                                     */
+    template <int spacedim>
+    static
+    void
+    create_children (Triangulation<2,spacedim> &triangulation,
+                    unsigned int &next_unused_vertex,
+                    raw_line_iterator &next_unused_line,
+                    raw_cell_iterator &next_unused_cell,
+                    cell_iterator &cell)
+      {
+       const unsigned int dim=2;
+                                        // clear refinement flag
+       const RefinementCase<dim> ref_case=cell->refine_flag_set();
+       cell->clear_refine_flag ();
 
+/* For the refinement process: since we go the levels up from the lowest, there
+   are (unlike above) only two possibilities: a neighbor cell is on the same
+   level or one level up (in both cases, it may or may not be refined later on,
+   but we don't care here).
+   
+   First:
+   Set up an array of the 3x3 vertices, which are distributed on the cell
+   (the array consists of indices into the @p{vertices} std::vector
+   
+   2--7--3
+   |  |  |
+   4--8--5
+   |  |  |
+   0--6--1
 
-template <>
-void Triangulation<1>::clear_user_flags_quad ()
-{}
+   note: in case of cut_x or cut_y not all these vertices are needed for the new
+   cells
+       
+   Second:  
+   Set up an array of the new lines (the array consists of iterator pointers
+   into the lines arrays)
+   
+   .-6-.-7-.         The directions are:  .->-.->-.
+   1   9   3                              ^   ^   ^
+   .-10.11-.                             .->-.->-.
+   0   8   2                              ^   ^   ^
+   .-4-.-5-.                              .->-.->-.
 
+   cut_x:   
+   .-4-.-5-. 
+   |   |   | 
+   0   6   1 
+   |   |   | 
+   .-2-.-3-.
+   
+   cut_y:
+   .---5---. 
+   1       3 
+   .---6---. 
+   0       2 
+   .---4---. 
 
+     
+   Third:
+   Set up an array of neighbors:
+   
+   6  7
+   .--.--.
+   1|  |  |3
+   .--.--.
+   0|  |  |2
+   .--.--.
+   4   5
 
-template <>
-void Triangulation<1>::clear_user_flags_hex ()
-{}
+   We need this array for two reasons: first to get the lines which will
+   bound the four subcells (if the neighboring cell is refined, these
+   lines already exist), and second to update neighborship information.
+   Since if a neighbor is not refined, its neighborship record only
+   points to the present, unrefined, cell rather than the children we
+   are presently creating, we only need the neighborship information
+   if the neighbor cells are refined. In all other cases, we store
+   the unrefined neighbor address
 
+   We also need for every neighbor (if refined) which number among its
+   neighbors the present (unrefined) cell has, since that number is to
+   be replaced and because that also is the number of the subline which
+   will be the interface between that neighbor and the to be created cell.
+   We will store this number (between 0 and 3) in the field
+   @p{neighbors_neighbor}.
 
+   It would be sufficient to use the children of the common line to the
+   neighbor, if we only wanted to get the new sublines and the new vertex,
+   but because we need to update the neighborship information of the
+   two refined subcells of the neighbor, we need to search these anyway.
 
-template <>
-void Triangulation<1>::clear_user_flags ()
-{
-  clear_user_flags_line();
-}
+   Convention:
+   The created children are numbered like this:
 
-#endif
+   .--.--.
+   |2 . 3|
+   .--.--.
+   |0 | 1|
+   .--.--.
+*/
 
+                                        // collect the indices
+                                        // all vertices
+                                        //   2--7--3
+                                        //   |  |  |
+                                        //   4--8--5
+                                        //   |  |  |
+                                        //   0--6--1
+       int new_vertices[9];
+       for (unsigned int vertex_no=0; vertex_no<4; ++vertex_no)
+         new_vertices[vertex_no]=cell->vertex_index(vertex_no);
+       for (unsigned int line_no=0; line_no<4; ++line_no)
+         if (cell->line(line_no)->has_children())
+           new_vertices[4+line_no]=cell->line(line_no)->child(0)->vertex_index(1);
+           
+       if (ref_case==RefinementCase<dim>::cut_xy)
+         {
+                                            // find the next
+                                            // unused vertex and
+                                            // set it
+                                            // appropriately
+           while (triangulation.vertices_used[next_unused_vertex] == true)
+             ++next_unused_vertex;
+           Assert (next_unused_vertex < triangulation.vertices.size(),
+                   ExcTooFewVerticesAllocated());
+           triangulation.vertices_used[next_unused_vertex] = true;
 
-#if deal_II_dimension == 2
+           new_vertices[8]=next_unused_vertex;
 
-template <>
-void Triangulation<2>::clear_user_data ()
-{
-  for (unsigned int level=0;level<levels.size();++level)
-    levels[level]->cells.clear_user_data();
-  faces->lines.clear_user_data();
-}
+           Point<spacedim> new_point;
+           if (dim == spacedim)
+             {
+               for (unsigned int i=0; i<8; ++i)
+                 new_point += triangulation.vertices[new_vertices[i]];
+               new_point /= 8.0;
+             }
+           else
+             {
+                                                // new vertex is
+                                                // placed on the
+                                                // surface according
+                                                // to the information
+                                                // stored in the
+                                                // boundary class
+               new_point = 
+                 triangulation.boundary[cell->material_id()]
+                 ->get_new_point_on_quad (cell);
+             }
+           
+           triangulation.vertices[new_vertices[8]] = new_point;
+    
 
+                                            // if the user_flag is set, i.e. if the
+                                            // cell is at the boundary, use a
+                                            // different calculation of the middle
+                                            // vertex here. this is of advantage, if
+                                            // the boundary is strongly curved and
+                                            // the cell has a high aspect ratio. this
+                                            // can happen for example, if it was
+                                            // refined anisotropically before.
+           if (cell->user_flag_set())
+             {
+                                                // first reset the user_flag
+               cell->clear_user_flag();
+                                                // the user flag indicates: at least
+                                                // one face is at the boundary. if it
+                                                // is only one, set the new middle
+                                                // vertex in a different way to avoid
+                                                // some mis-shaped elements if the
+                                                // new point on the boundary is not
+                                                // where we expect it, especially if
+                                                // it is to far inside the current
+                                                // cell
+               unsigned int bound_face=GeometryInfo<dim>::faces_per_cell;
+               for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+                 if (cell->face(face)->at_boundary())
+                   {
+                     if (bound_face == GeometryInfo<dim>::faces_per_cell)
+                                                        // no boundary face found so
+                                                        // far, so set it now
+                       bound_face=face;
+                     else
+                                                        // there is another boundary
+                                                        // face, so reset bound_face to
+                                                        // invalid value as a flag to
+                                                        // do nothing in the following
+                       bound_face=GeometryInfo<dim>::faces_per_cell+1;
+                   }
+         
+               if (bound_face<GeometryInfo<dim>::faces_per_cell)
+                                                  // reset the cell's middle vertex
+                                                  // to the middle of the straight
+                                                  // connection between the new
+                                                  // points on this face and on the
+                                                  // opposite face
+                 triangulation.vertices[new_vertices[8]]
+                   = 0.5*(cell->face(bound_face)
+                          ->child(0)->vertex(1)+
+                          cell->face(GeometryInfo<dim>
+                                     ::opposite_face[bound_face])
+                          ->child(0)->vertex(1));
+             }
+         }
+  
+  
+                                        // Now the lines:
+       raw_line_iterator new_lines[12];
+       unsigned int lmin=8;
+       unsigned int lmax=12;
+       if (ref_case!=RefinementCase<dim>::cut_xy)
+         {
+           lmin=6;
+           lmax=7;
+         }
+           
+       for (unsigned int l=lmin; l<lmax; ++l)
+         {
+           while (next_unused_line->used() == true)
+             ++next_unused_line;
+           new_lines[l] = next_unused_line;
+           ++next_unused_line;
 
+           Assert (new_lines[l]->used() == false,
+                   ExcCellShouldBeUnused());
+         }
+           
+       if (ref_case==RefinementCase<dim>::cut_xy)
+         {
+                                            //   .-6-.-7-.   
+                                            //   1   9   3 
+                                            //   .-10.11-. 
+                                            //   0   8   2 
+                                            //   .-4-.-5-. 
+
+                                            // lines 0-7 already
+                                            // exist, create only
+                                            // the four interior
+                                            // lines 8-11
+           unsigned int l=0;
+           for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+             for (unsigned int c=0; c<2; ++c, ++l)
+               new_lines[l]=cell->line(face_no)->child(c);
+           Assert(l==8, ExcInternalError());
+
+           new_lines[8] ->set (internal::Triangulation::
+                               TriaObject<1>(new_vertices[6], new_vertices[8]));
+           new_lines[9] ->set (internal::Triangulation::
+                               TriaObject<1>(new_vertices[8], new_vertices[7]));
+           new_lines[10]->set (internal::Triangulation::
+                               TriaObject<1>(new_vertices[4], new_vertices[8]));
+           new_lines[11]->set (internal::Triangulation::
+                               TriaObject<1>(new_vertices[8], new_vertices[5]));
+         }
+       else if (ref_case==RefinementCase<dim>::cut_x)
+         {
+                                            //   .-4-.-5-. 
+                                            //   |   |   | 
+                                            //   0   6   1 
+                                            //   |   |   | 
+                                            //   .-2-.-3-.
+           new_lines[0]=cell->line(0);
+           new_lines[1]=cell->line(1);
+           new_lines[2]=cell->line(2)->child(0);
+           new_lines[3]=cell->line(2)->child(1);
+           new_lines[4]=cell->line(3)->child(0);
+           new_lines[5]=cell->line(3)->child(1);
+           new_lines[6]->set (internal::Triangulation::
+                              TriaObject<1>(new_vertices[6], new_vertices[7]));
+         }
+       else
+         {
+           Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
+                                            //   .---5---. 
+                                            //   1       3 
+                                            //   .---6---. 
+                                            //   0       2 
+                                            //   .---4---.
+           new_lines[0]=cell->line(0)->child(0);
+           new_lines[1]=cell->line(0)->child(1);
+           new_lines[2]=cell->line(1)->child(0);
+           new_lines[3]=cell->line(1)->child(1);
+           new_lines[4]=cell->line(2);
+           new_lines[5]=cell->line(3);
+           new_lines[6]->set (internal::Triangulation::
+                              TriaObject<1>(new_vertices[4], new_vertices[5]));
+         }
 
-template <>
-void Triangulation<2>::clear_user_pointers ()
-{
-  clear_user_data();
-}
+       for (unsigned int l=lmin; l<lmax; ++l)
+         {
+           new_lines[l]->set_used_flag();
+           new_lines[l]->clear_user_flag();
+           new_lines[l]->clear_user_data();
+           new_lines[l]->clear_children();
+                                            // interior line
+           new_lines[l]->set_boundary_indicator(255);
+         }
 
+                                        // Now add the four (two)
+                                        // new cells!
+       raw_cell_iterator subcells[GeometryInfo<dim>::max_children_per_cell];
+       while (next_unused_cell->used() == true)
+         ++next_unused_cell;
+           
+       const unsigned int n_children=
+         GeometryInfo<dim>::n_children(ref_case);
+       for (unsigned int i=0; i<n_children; ++i) 
+         {
+           Assert (next_unused_cell->used() == false,
+                   ExcCellShouldBeUnused());
+           subcells[i] = next_unused_cell;
+           ++next_unused_cell;
+           if (i%2==1 && i<n_children-1)
+             while (next_unused_cell->used() == true)
+               ++next_unused_cell;
+         }
 
+       if (ref_case==RefinementCase<dim>::cut_xy)
+         {
+                                            // children:
+                                            //   .--.--.
+                                            //   |2 . 3|
+                                            //   .--.--.
+                                            //   |0 | 1|
+                                            //   .--.--.
+                                            // lines:
+                                            //   .-6-.-7-.   
+                                            //   1   9   3 
+                                            //   .-10.11-. 
+                                            //   0   8   2 
+                                            //   .-4-.-5-. 
+           subcells[0]->set (internal::Triangulation::
+                             TriaObject<2>(new_lines[0]->index(),
+                                           new_lines[8]->index(),
+                                           new_lines[4]->index(),
+                                           new_lines[10]->index()));
+           subcells[1]->set (internal::Triangulation::
+                             TriaObject<2>(new_lines[8]->index(),
+                                           new_lines[2]->index(),
+                                           new_lines[5]->index(),
+                                           new_lines[11]->index()));
+           subcells[2]->set (internal::Triangulation::
+                             TriaObject<2>(new_lines[1]->index(),
+                                           new_lines[9]->index(),
+                                           new_lines[10]->index(),
+                                           new_lines[6]->index()));
+           subcells[3]->set (internal::Triangulation::
+                             TriaObject<2>(new_lines[9]->index(),
+                                           new_lines[3]->index(),
+                                           new_lines[11]->index(),
+                                           new_lines[7]->index()));
+         }
+       else if (ref_case==RefinementCase<dim>::cut_x)
+         {
+                                            // children:
+                                            //   .--.--.
+                                            //   |  .  |
+                                            //   .0 . 1.
+                                            //   |  |  |
+                                            //   .--.--.
+                                            // lines:
+                                            //   .-4-.-5-. 
+                                            //   |   |   | 
+                                            //   0   6   1 
+                                            //   |   |   | 
+                                            //   .-2-.-3-.
+           subcells[0]->set (internal::Triangulation::
+                             TriaObject<2>(new_lines[0]->index(),
+                                           new_lines[6]->index(),
+                                           new_lines[2]->index(),
+                                           new_lines[4]->index()));
+           subcells[1]->set (internal::Triangulation::
+                             TriaObject<2>(new_lines[6]->index(),
+                                           new_lines[1]->index(),
+                                           new_lines[3]->index(),
+                                           new_lines[5]->index()));
+         }
+       else
+         {
+           Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
+                                            // children:
+                                            //   .-----.
+                                            //   |  1  |
+                                            //   .-----.
+                                            //   |  0  |
+                                            //   .-----.
+                                            // lines:
+                                            //   .---5---. 
+                                            //   1       3 
+                                            //   .---6---. 
+                                            //   0       2 
+                                            //   .---4---.
+           subcells[0]->set (internal::Triangulation::
+                             TriaObject<2>(new_lines[0]->index(),
+                                           new_lines[2]->index(),
+                                           new_lines[4]->index(),
+                                           new_lines[6]->index()));
+           subcells[1]->set (internal::Triangulation::
+                             TriaObject<2>(new_lines[1]->index(),
+                                           new_lines[3]->index(),
+                                           new_lines[6]->index(),
+                                           new_lines[5]->index()));
+         }
+           
 
-template <>
-void Triangulation<2>::clear_user_flags_quad ()
-{
-  for (unsigned int level=0; level<levels.size(); ++level)
-    levels[level]->cells.clear_user_flags();
-}
+       for (unsigned int i=0; i<n_children; ++i)
+         {
+           subcells[i]->set_used_flag();
+           subcells[i]->clear_refine_flag();           
+           subcells[i]->clear_user_flag();
+           subcells[i]->clear_user_data();
+           subcells[i]->clear_children();
+                                            // inherit material
+                                            // properties              
+           subcells[i]->set_material_id (cell->material_id());
+           subcells[i]->set_subdomain_id (cell->subdomain_id());
+         }
+           
+                                        // now the only thing
+                                        // still to be done is
+                                        // setting neighborship
+                                        // information.
+                                        //
+                                        // we have to do that for
+                                        // all children of our
+                                        // current cell. if the
+                                        // neighbor is a refined
+                                        // one or if we use anisotropic
+                                        // refinement and there is only
+                                        // one child of the current cell
+                                        // adjacent to a certain face,
+                                        // we also have to reset the
+                                        // neighbors neighbor pointers.
+                                        // In earlier versions of the
+                                        // library these tasks were done one
+                                        // after the other. here we combine
+                                        // these steps, as otherwise we
+                                        // would have to gather the same
+                                        // information on the refinement
+                                        // situation along a certain face
+                                        // twice. As this is a more
+                                        // complicated task for anisotropic
+                                        // refinement, we prefer to do it
+                                        // only once.
+                                        //
+                                        // note that in case the
+                                        // neighboring cell is
+                                        // not refined along the
+                                        // common face, the
+                                        // neighbor iterators
+                                        // point to the common
+                                        // mother cell. the same
+                                        // applies if there is no
+                                        // neighbor: the
+                                        // iterators are past the
+                                        // end
+       cell_iterator nb_children[GeometryInfo<dim>::max_children_per_face],
+         nb_child,
+         children[GeometryInfo<dim>::faces_per_cell][GeometryInfo<dim>::max_children_per_face];
+
+                                        // first, set up an array of our current
+                                        // children / subcells. for all faces and
+                                        // subfaces store the info, which subcell is
+                                        // adjacent to that subface
+       for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+         for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_face; ++c)
+           children[face][c]=subcells[GeometryInfo<dim>::child_cell_on_face(ref_case,
+                                                                            face,c)];
+
+
+       for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell;
+            ++face)
+         {
+           const cell_iterator neighbor=cell->neighbor(face);
+           const RefinementCase<dim-1> face_ref_case=GeometryInfo<dim>::face_refinement_case(ref_case,face);
+           const unsigned int n_subfaces=std::max(GeometryInfo<dim-1>::n_children(face_ref_case),
+                                                  static_cast<unsigned int>(1));
+               
+                                                     
+                                                     
+                                            // if no neighbor set invalid pointer for
+                                            // all children adjacent to that face
+           if (neighbor.state() != IteratorState::valid)
+             for (unsigned int c=0; c<n_subfaces; ++c)
+               children[face][c]
+                 ->set_neighbor(face,neighbor);
+      
+           else
+                                              // neighbor exists
+             {
+                                                // now there are two possibilities:
+                                                // either the neighbor is not refined
+                                                // along the common face or it is
+                                                // refined along the common face once,
+                                                // this must be terminal then
+                                                // (otherwise something went wrong in
+                                                // prepare_refinement_and_coarsening()).
+                                                // however, if at any time the neighbor
+                                                // has children, which are not refined
+                                                // along the face currently under
+                                                // consideration, one of these children
+                                                // would have been set as the neighbor
+                                                // of our current cell. therefore the
+                                                // question wether the neighbor is
+                                                // refined along the common face is
+                                                // equivalent to the question, wether
+                                                // the neighbor has children.  if our
+                                                // current cell is not refined along
+                                                // the face face_no, then we have to
+                                                // set the current neighbor as the new
+                                                // neighbor, even if the neighbor is
+                                                // further refined
+               if (!neighbor->has_children())
+                 {
+                                                    // if the neighbor has no children,
+                                                    // set the neighbor-pointer of all
+                                                    // children to this neighbor cell
+                   for (unsigned int c=0; c<n_subfaces; ++c)
+                     children[face][c]
+                       ->set_neighbor(face,neighbor);
+                                                    // if the current cell is not
+                                                    // refined along the face we have
+                                                    // to update the neighbors neighbor
+                                                    // pointer. we have to do this only,
+                                                    // if the neighbor is not coarser
+                   if (n_subfaces==1 && !cell->neighbor_is_coarser(face))
+                     {
+                       const unsigned int nb_nb = cell->neighbor_of_neighbor(face);
+                       neighbor->set_neighbor(nb_nb, children[face][0]);
+                     }
+                 }
+               else
+                 {
+                                                    // neighbor has children
+                   const unsigned int nb_nb = cell->neighbor_of_neighbor(face);
+                   const RefinementCase<dim> nb_ref_case = neighbor->refinement_case();
+                   const RefinementCase<dim-1> nb_face_ref_case = GeometryInfo<dim>::face_refinement_case(nb_ref_case,
+                                                                                                          nb_nb);
+                   const unsigned int nb_n_subfaces = std::max(GeometryInfo<dim-1>::
+                                                               n_children(nb_face_ref_case),
+                                                               static_cast<unsigned int>(1));
+                       
+                   for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_face; ++c)
+                     {
+                       nb_child=neighbor->child(GeometryInfo<dim>::
+                                                child_cell_on_face(nb_ref_case,
+                                                                   nb_nb,
+                                                                   c));
+                                                        // there could be an unknown
+                                                        // number of refinements for
+                                                        // nb_child that do
+                                                        // not refine the common
+                                                        // face.
+
+                                                        // consider for example the
+                                                        // following case, where the
+                                                        // lower cell has been refined
+                                                        // in this step into c1 and c2.
+
+                                                        //  ---------------
+                                                        // |       |       |
+                                                        // |       |  n2.1 |
+                                                        // |       |       |
+                                                        // |  n1    -------
+                                                        // |       |       |
+                                                        // |       |  n2.2 |   
+                                                        // |       |       |
+                                                        //  ---------------
+                                                        // |       |       |
+                                                        // |       |       |
+                                                        // |       |       |
+                                                        // |  c1   |  c2   |
+                                                        // |       |       |
+                                                        // |       |       |
+                                                        //  ---------------
+               
+                                                        // the neighbor of cell c was
+                                                        // the whole of cell n. what we
+                                                        // have done so far is setting
+                                                        // the right neighbor
+                                                        // information for cells c1 and
+                                                        // n1 as well as c2 and n2,
+                                                        // where n2 is the mother cell
+                                                        // of n2.1 and n2.2. however,
+                                                        // n2 is further refined and we
+                                                        // would have to set n2.2 as
+                                                        // neighbor of child c2 and
+                                                        // vice versa. this is specific
+                                                        // to anisotropic refinement.
+           
+                                                        // note that n2.2 could be
+                                                        // further refined with cut_y
+                                                        // (if n1 was also refined with
+                                                        // cut_y). 
+                                                   
+                                                        // go down that list to
+                                                        // the end. note, that nb_nb
+                                                        // stays constant, for all
+                                                        // children of a cell have
+                                                        // their faces in the same
+                                                        // direction and orientation as
+                                                        // the mother cell
+                       while(nb_child->has_children()
+                             && (GeometryInfo<dim>::face_refinement_case(nb_child->refinement_case(),
+                                                                         nb_nb)
+                                 == RefinementCase<dim-1>::no_refinement))
+                                                          // nb_child has children
+                                                          // which are not refined at
+                                                          // the current (sub)face,
+                                                          // therefore one of these
+                                                          // children is the true
+                                                          // neighbor of our cell
+                         nb_child = nb_child
+                                    ->child(GeometryInfo<dim>::
+                                            child_cell_on_face(nb_child->refinement_case(),
+                                                               nb_nb,
+                                                               0));
+                                                        // there's one more possibility
+                                                        // here, if the current cell is
+                                                        // refined along the face: the
+                                                        // last child found above could
+                                                        // still be refined once along
+                                                        // the common face, e.g. n1 or
+                                                        // n2.2 in the above picture
+                                                        // could be refined with
+                                                        // cut_x. this refinement leeds
+                                                        // to an inreased number of
+                                                        // hanging nodes. therefore it
+                                                        // was introduced in this
+                                                        // refinement cycle and the
+                                                        // additional hanging nodes
+                                                        // will be removed now, as the
+                                                        // current cell is also
+                                                        // refined. this temporaray
+                                                        // effect can occur during
+                                                        // anisotropic refinement, as
+                                                        // it is possible there, that a
+                                                        // coarser cell (along the face
+                                                        // between the cells) is on a
+                                                        // higher level and therefore
+                                                        // refined after the already
+                                                        // refined neighbor.
+                       if (nb_child->has_children())
+                         {
+                                                            // This is only valid, if
+                                                            // the current cell is
+                                                            // refined along the face
+                                                            // considered here
+                           Assert(n_subfaces > 1, ExcInternalError());
+                           for (unsigned int sub=0;
+                                sub<GeometryInfo<dim>::max_children_per_face; ++sub)
+                             {
+                                                                // collect all the
+                                                                // children of nb_child
+                                                                // and set their
+                                                                // neighbor
+                                                                // pointers. we will
+                                                                // care for our own
+                                                                // children later on
+                               nb_children[sub]=nb_child->
+                                                child(GeometryInfo<dim>::
+                                                      child_cell_on_face(nb_child->refinement_case(),
+                                                                         nb_nb, sub));
+                               nb_children[sub]->set_neighbor(nb_nb, children[face][c]);
+                             }
+                         }
+                           
+                           
+                                                        // now set the neighbor
+                                                        // pointers of the neighbor's
+                                                        // children.
+                       nb_child->set_neighbor(nb_nb, children[face][c]);
+                                                        // if this cell is as refined
+                                                        // as the neighbor, set the
+                                                        // neighbor pointers of the
+                                                        // subcells to the
+                                                        // corresponting
+                                                        // neighbor_child. else, set
+                                                        // the neighbor pointers to the
+                                                        // common neighbor mother cell
+                       if (nb_n_subfaces==n_subfaces)
+                         children[face][c]->set_neighbor(face,nb_child);
+                       else
+                         children[face][c]->set_neighbor(face,neighbor);
+                     }
+                 }
+             }     
+         }
+                                        // by now, all the outer neighbors have been
+                                        // set, the inner neighbors have to be
+                                        // considered in the following
 
+       if (ref_case==RefinementCase<dim>::cut_xy)
+         {
+                                            // children:
+                                            //   .--.--.
+                                            //   |2 . 3|
+                                            //   .--.--.
+                                            //   |0 | 1|
+                                            //   .--.--.
+           subcells[0]->set_neighbor (1, subcells[1]);
+           subcells[0]->set_neighbor (3, subcells[2]);
+               
+           subcells[1]->set_neighbor (0, subcells[0]);
+           subcells[1]->set_neighbor (3, subcells[3]);
+               
+           subcells[2]->set_neighbor (1, subcells[3]);
+           subcells[2]->set_neighbor (2, subcells[0]);
+               
+           subcells[3]->set_neighbor (0, subcells[2]);
+           subcells[3]->set_neighbor (2, subcells[1]);
+         }
+       else if (ref_case==RefinementCase<dim>::cut_x)
+         {
+                                            // children:
+                                            //   .--.--.
+                                            //   |  .  |
+                                            //   .0 . 1.
+                                            //   |  |  |
+                                            //   .--.--.
+           subcells[0]->set_neighbor (1, subcells[1]);
+               
+           subcells[1]->set_neighbor (0, subcells[0]);
+         }
+       else
+         {
+           Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
+                                            // children:
+                                            //   .-----.
+                                            //   |  1  |
+                                            //   .-----.
+                                            //   |  0  |
+                                            //   .-----.
+           subcells[0]->set_neighbor (3, subcells[1]);
+               
+           subcells[1]->set_neighbor (2, subcells[0]);
+         }
+           
+           
 
+                                        // set child index for
+                                        // even children children
+                                        // i=0,2 (0)
+       for (unsigned int i=0; i<n_children/2; ++i)
+         cell->set_children (2*i, subcells[2*i]->index());
+                                        // set the refine case
+       cell->set_refinement_case(ref_case);        
+
+                                        // note that the
+                                        // refinement flag was
+                                        // already cleared at the
+                                        // beginning of this function      
+      }
+    
+    
 
-template <>
-void Triangulation<2>::clear_user_flags_hex ()
-{}
+                                    /**
+                                     * A function that performs the
+                                     * refinement of a triangulation in 1d.
+                                     */
+    template <int spacedim>
+    static
+    void
+    execute_refinement (Triangulation<1,spacedim> &triangulation)
+      {
+       const unsigned int dim = 1;
+  
+                                        // check whether a new level is
+                                        // needed we have to check for this
+                                        // on the highest level only (on
+                                        // this, all used cells are also
+                                        // active, so we only have to check
+                                        // for this)
+       {
+         raw_cell_iterator
+           cell = triangulation.begin_active (triangulation.levels.size()-1),
+           endc = triangulation.end();
+         for (; cell != endc; ++cell)
+           if (cell->used())
+             if (cell->refine_flag_set()) 
+               {
+                 triangulation.levels
+                   .push_back (new internal::Triangulation::TriaLevel<dim>);
+                 break;
+               }
+       }
 
 
+                                        // check how much space is needed
+                                        // on every level we need not check
+                                        // the highest level since either -
+                                        // on the highest level no cells
+                                        // are flagged for refinement -
+                                        // there are, but
+                                        // prepare_refinement added another
+                                        // empty level
+       unsigned int needed_vertices = 0;
+       for (int level=triangulation.levels.size()-2; level>=0; --level)
+         {
+                                            // count number of flagged
+                                            // cells on this level
+           unsigned int flagged_cells = 0;
+           active_cell_iterator
+             acell = triangulation.begin_active(level),
+             aendc = triangulation.begin_active(level+1);
+           for (; acell!=aendc; ++acell) 
+             if (acell->refine_flag_set())
+               ++flagged_cells;
+
+                                            // count number of used cells
+                                            // on the next higher level
+           const unsigned int used_cells
+             =  std::count_if (triangulation.levels[level+1]->cells.used.begin(),
+                               triangulation.levels[level+1]->cells.used.end(),
+                               std::bind2nd (std::equal_to<bool>(), true));
+
+                                            // reserve space for the
+                                            // used_cells cells already
+                                            // existing on the next higher
+                                            // level as well as for the
+                                            // 2*flagged_cells that will be
+                                            // created on that level
+           triangulation.levels[level+1]
+             ->reserve_space(used_cells+
+                             GeometryInfo<1>::max_children_per_cell *
+                             flagged_cells,
+                             1);
+                                            // reserve space for
+                                            // 2*flagged_cells new lines on
+                                            // the next higher level
+           triangulation.levels[level+1]->cells
+             .reserve_space (GeometryInfo<1>::max_children_per_cell *
+                             flagged_cells,
+                             0);
+      
+           needed_vertices += flagged_cells;
+         }
 
-template <>
-void Triangulation<2>::clear_user_flags ()
-{
-  clear_user_flags_line ();
-  clear_user_flags_quad ();  
-}
+                                        // add to needed vertices how many
+                                        // vertices are already in use
+       needed_vertices += std::count_if (triangulation.vertices_used.begin(),
+                                         triangulation.vertices_used.end(),
+                                         std::bind2nd (std::equal_to<bool>(),
+                                                       true));
+                                        // if we need more vertices: create
+                                        // them, if not: leave the array as
+                                        // is, since shrinking is not
+                                        // really possible because some of
+                                        // the vertices at the end may be
+                                        // in use
+       if (needed_vertices > triangulation.vertices.size())
+         {
+           triangulation.vertices.resize (needed_vertices,
+                                          Point<spacedim>());
+           triangulation.vertices_used.resize (needed_vertices, false);
+         }
 
-#endif
 
+                                        // Do REFINEMENT
+                                        // on every level; exclude highest
+                                        // level as above
 
-#if deal_II_dimension == 3
+                                        // index of next unused vertex
+       unsigned int next_unused_vertex = 0;
+  
+       for (int level=triangulation.levels.size()-2; level>=0; --level) 
+         {
+           active_cell_iterator
+             cell = triangulation.begin_active(level),
+             endc = triangulation.begin_active(level+1);
+      
+           raw_cell_iterator
+             next_unused_cell = triangulation.begin_raw (level+1);
 
-template <>
-void Triangulation<3>::clear_user_data ()
-{
-  for (unsigned int level=0;level<levels.size();++level)
-    levels[level]->cells.clear_user_data();
-  faces->quads.clear_user_data();
-  faces->lines.clear_user_data();
-}
+           for (; (cell!=endc) && (cell->level()==level); ++cell) 
+             if (cell->refine_flag_set()) 
+               {
+                                                  // clear refinement flag
+                 cell->clear_refine_flag ();
 
+                                                  // search for next unused
+                                                  // vertex
+                 while (triangulation.vertices_used[next_unused_vertex] == true)
+                   ++next_unused_vertex;
+                 Assert (next_unused_vertex < triangulation.vertices.size(),
+                         ExcTooFewVerticesAllocated());
+           
+                                                  // first insert new
+                                                  // vertex. if dim==spacedim
+                                                  // then simply use the
+                                                  // midpoint; otherwise we
+                                                  // have to ask the manifold
+                                                  // object
+                 if (dim == spacedim)
+                   triangulation.vertices[next_unused_vertex] =
+                     (cell->vertex(0) + cell->vertex(1)) / 2;
+                 else
+                   triangulation.vertices[next_unused_vertex] = 
+                     triangulation.boundary[cell->material_id()]
+                     ->get_new_point_on_line(cell);
+                 triangulation.vertices_used[next_unused_vertex] = true;
+
+                                                  // search for next two
+                                                  // unused cell (++ takes
+                                                  // care of the end of the
+                                                  // vector)
+                 raw_cell_iterator first_child, second_child;
+                 while (next_unused_cell->used() == true)
+                   ++next_unused_cell;
+                 first_child = next_unused_cell;
+                 first_child->set_used_flag ();
+                 first_child->clear_user_data ();
+                 ++next_unused_cell;
+                 Assert (next_unused_cell->used() == false,
+                         ExcCellShouldBeUnused());
+                 second_child = next_unused_cell;
+                 second_child->set_used_flag ();
+                 second_child->clear_user_data ();
+
+                                                  // insert first child
+                 cell->set_children (0, first_child->index());
+                 first_child->clear_children ();
+                 first_child->set (internal::Triangulation
+                                   ::TriaObject<1> (cell->vertex_index(0),
+                                                    next_unused_vertex));
+                 first_child->set_material_id (cell->material_id());
+                 first_child->set_subdomain_id (cell->subdomain_id());     
+           
+                                                  // reset neighborship info (refer
+                                                  // to
+                                                  // internal::Triangulation::TriaLevel<0>
+                                                  // for details)
+                 first_child->set_neighbor (1, second_child);
+                 if (cell->neighbor(0).state() != IteratorState::valid)
+                   first_child->set_neighbor (0, cell->neighbor(0));
+                 else
+                   if (cell->neighbor(0)->active())
+                     {
+                                                        // since the
+                                                        // neighbors level
+                                                        // is always
+                                                        // <=level, if the
+                                                        // cell is active,
+                                                        // then there are
+                                                        // no cells to the
+                                                        // left which may
+                                                        // want to know
+                                                        // about this new
+                                                        // child cell.
+                       Assert (cell->neighbor(0)->level() <= cell->level(),
+                               ExcInternalError());
+                       first_child->set_neighbor (0, cell->neighbor(0));
+                     }
+                   else
+                                                      // left neighbor is
+                                                      // refined
+                     {
+                                                        // set neighbor to
+                                                        // cell on same
+                                                        // level
+                       first_child->set_neighbor (0, cell->neighbor(0)->child(1));
+
+                                                        // reset neighbor
+                                                        // info of all
+                                                        // right descendant
+                                                        // of the left
+                                                        // neighbor of cell
+                       cell_iterator left_neighbor = cell->neighbor(0);
+                       while (left_neighbor->has_children())
+                         {
+                           left_neighbor = left_neighbor->child(1);
+                           left_neighbor->set_neighbor (1, first_child);
+                         }
+                     }
+           
+                                                  // insert second child
+                 second_child->clear_children ();
+                 second_child->set (internal::Triangulation
+                                    ::TriaObject<1>(next_unused_vertex,
+                                                    cell->vertex_index(1)));
+                 second_child->set_neighbor (0, first_child);
+                 second_child->set_material_id (cell->material_id());
+                 second_child->set_subdomain_id (cell->subdomain_id());            
+                 if (cell->neighbor(1).state() != IteratorState::valid)
+                   second_child->set_neighbor (1, cell->neighbor(1));
+                 else
+                   if (cell->neighbor(1)->active())
+                     {
+                       Assert (cell->neighbor(1)->level() <= cell->level(),
+                               ExcInternalError());
+                       second_child->set_neighbor (1, cell->neighbor(1));
+                     }
+                   else
+                                                      // right neighbor is
+                                                      // refined same as
+                                                      // above
+                     {
+                       second_child->set_neighbor (1, cell->neighbor(1)->child(0));
+                 
+                       cell_iterator right_neighbor = cell->neighbor(1);
+                       while (right_neighbor->has_children())
+                         {
+                           right_neighbor = right_neighbor->child(0);
+                           right_neighbor->set_neighbor (0, second_child);
+                         }
+                     }
+               }      
+         }
+      }
 
 
-template <>
-void Triangulation<3>::clear_user_pointers ()
-{
-  clear_user_data();
-}
+                                    /**
+                                     * A function that performs the
+                                     * refinement of a triangulation in 2d.
+                                     */
+    template <int spacedim>
+    static
+    void
+    execute_refinement (Triangulation<2,spacedim> &triangulation)
+      {
+       const unsigned int dim = 2;
+  
+                                        // check whether a new level is
+                                        // needed we have to check for this
+                                        // on the highest level only (on
+                                        // this, all used cells are also
+                                        // active, so we only have to check
+                                        // for this)
+       if (true)
+         {
+           raw_cell_iterator cell = triangulation.begin_active (triangulation.levels.size()-1),
+                             endc = triangulation.end();
+           for (; cell != endc; ++cell)
+             if (cell->used())
+               if (cell->refine_flag_set()) 
+                 {
+                   triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+                   break;
+                 }
+         }
 
 
+                                        // first clear user flags and
+                                        // pointers of lines; we're going
+                                        // to use them to flag which lines
+                                        // need refinement
+       for (line_iterator line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+         {
+           line->clear_user_flag();
+           line->clear_user_data();
+         }
+                                        // running over all cells and lines
+                                        // count the number
+                                        // n_single_lines of lines
+                                        // which can be stored as
+                                        // single lines, e.g. inner lines
+       unsigned int n_single_lines=0;
+                                        // New lines to be created:
+                                        // number lines which are
+                                        // stored in pairs (the
+                                        // children of lines must be
+                                        // stored in pairs)
+       unsigned int n_lines_in_pairs = 0;
+
+                                        // check how much space is needed
+                                        // on every level we need not check
+                                        // the highest level since either
+                                        // - on the highest level no cells
+                                        //   are flagged for refinement
+                                        // - there are, but prepare_refinement
+                                        //   added another empty level
+       unsigned int needed_vertices = 0;
+       for (int level=triangulation.levels.size()-2; level>=0; --level)
+         {
+                                            // count number of flagged
+                                            // cells on this level and
+                                            // compute how many new
+                                            // vertices and new lines will
+                                            // be needed
+           unsigned int needed_cells = 0;
+
+           active_cell_iterator cell = triangulation.begin_active(level),
+                                endc = triangulation.begin_active(level+1);
+           for (; cell!=endc; ++cell) 
+             if (cell->refine_flag_set()) 
+               {
+                 if (cell->refine_flag_set()==RefinementCase<dim>::cut_xy)
+                   {
+                     needed_cells += 4;
+               
+                                                      // new vertex at
+                                                      // center of cell is
+                                                      // needed in any case
+                     ++needed_vertices;
+                                                      // the four inner
+                                                      // lines can be
+                                                      // stored as singles
+                     n_single_lines += 4;
+                   }
+                 else // cut_x || cut_y
+                   {
+                                                      // set the flag showing that
+                                                      // anisotropic refinement is
+                                                      // used for at least one cell
+                     triangulation.anisotropic_refinement = true;
+               
+                     needed_cells += 2;
+                                                      // no vertex at center
+               
+                                                      // the inner line can
+                                                      // be stored as
+                                                      // single
+                     n_single_lines += 1;
 
-template <>
-void Triangulation<3>::clear_user_flags_quad ()
-{
-  faces->quads.clear_user_flags();
-}
+                   }
+           
+                                                  // mark all faces
+                                                  // (lines) for
+                                                  // refinement;
+                                                  // checking locally
+                                                  // whether the
+                                                  // neighbor would
+                                                  // also like to
+                                                  // refine them is
+                                                  // rather difficult
+                                                  // for lines so we
+                                                  // only flag them and
+                                                  // after visiting all
+                                                  // cells, we decide
+                                                  // which lines need
+                                                  // refinement;
+                 for (unsigned int line_no=0; line_no<GeometryInfo<dim>::faces_per_cell;
+                      ++line_no)
+                   {
+                     if (GeometryInfo<dim>::face_refinement_case(
+                           cell->refine_flag_set(), line_no)==RefinementCase<1>::cut_x)
+                       {
+                         line_iterator line = cell->line(line_no);
+                         if (line->has_children() == false) {
+                           line->set_user_flag ();
+//TODO[WB]: we overwrite the user_index here because we later on need to find
+// out which boundary object we have to ask to refine this line. find a better
+// way to do that                    
+                           if (spacedim > dim)
+                             line->set_user_index(cell->material_id());
+                         }
+                       }
+                   }
+               }
 
+      
+                                            // count number of used cells
+                                            // on the next higher level
+           const unsigned int used_cells
+             = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
+                              triangulation.levels[level+1]->cells.used.end(),
+                              std::bind2nd (std::equal_to<bool>(), true));
+      
 
+                                            // reserve space for the
+                                            // used_cells cells already
+                                            // existing on the next higher
+                                            // level as well as for the
+                                            // needed_cells that will be
+                                            // created on that level
+           triangulation.levels[level+1]->reserve_space (used_cells+needed_cells, 2);
+
+                                            // reserve space for
+                                            // needed_cells
+                                            // new quads on the next higher
+                                            // level
+           triangulation.levels[level+1]->cells.
+             reserve_space (needed_cells,0);
+         }
 
-template <>
-void Triangulation<3>::clear_user_flags_hex ()
-{
-  for (unsigned int level=0; level<levels.size(); ++level)
-    levels[level]->cells.clear_user_flags();
-}
+                                        // now count the lines which
+                                        // were flagged for refinement
+       for (line_iterator line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+         if (line->user_flag_set())
+           {
+             Assert (line->has_children() == false, ExcInternalError());
+             n_lines_in_pairs += 2;
+             needed_vertices  += 1;
+           }
+                                        // reserve space for
+                                        // n_lines_in_pairs new lines.
+                                        // note, that we can't reserve space
+                                        // for the single lines here as well,
+                                        // as all the space reserved for lines
+                                        // in pairs would be counted as unused
+                                        // and we would end up with too little
+                                        // space to store all lines. memory
+                                        // reservation for n_single_lines can
+                                        // only be done AFTER we refined the lines
+                                        // of the current cells
+       triangulation.faces->lines.
+         reserve_space (n_lines_in_pairs, 0);
+  
+                                        // add to needed vertices how many
+                                        // vertices are already in use
+       needed_vertices += std::count_if (triangulation.vertices_used.begin(), triangulation.vertices_used.end(),
+                                         std::bind2nd (std::equal_to<bool>(), true));
+                                        // if we need more vertices: create
+                                        // them, if not: leave the array as
+                                        // is, since shrinking is not
+                                        // really possible because some of
+                                        // the vertices at the end may be
+                                        // in use
+       if (needed_vertices > triangulation.vertices.size())
+         {
+           triangulation.vertices.resize (needed_vertices, Point<spacedim>());
+           triangulation.vertices_used.resize (needed_vertices, false);
+         }
 
 
+                                        // Do REFINEMENT  
+                                        // on every level; exclude highest
+                                        // level as above
 
-template <>
-void Triangulation<3>::clear_user_flags ()
-{
-  clear_user_flags_line ();
-  clear_user_flags_quad ();
-  clear_user_flags_hex ();
-}
+                                        //  index of next unused vertex
+       unsigned int next_unused_vertex = 0;
 
-#endif
+                                        // first the refinement of lines.
+                                        // children are stored pairwise
+       if (true)
+         {
+                                            // only active objects can be
+                                            // refined further
+           active_line_iterator line = triangulation.begin_active_line(),
+                                endl = triangulation.end_line();
+           raw_line_iterator next_unused_line = triangulation.begin_raw_line ();
+
+           for (; line!=endl; ++line)
+             if (line->user_flag_set())
+               {
+                                                  // this line needs to be
+                                                  // refined
 
+                                                  // find the next unused
+                                                  // vertex and set it
+                                                  // appropriately
+                 while (triangulation.vertices_used[next_unused_vertex] == true)
+                   ++next_unused_vertex;
+                 Assert (next_unused_vertex < triangulation.vertices.size(),
+                         ExcTooFewVerticesAllocated());
+                 triangulation.vertices_used[next_unused_vertex] = true;
 
-#if deal_II_dimension > 1
+                 if (spacedim == dim)
+                   {
+                                                      // for the case of a domain
+                                                      // in an equal-dimensional
+                                                      // space we only have to
+                                                      // treat boundary lines
+                                                      // differently; for interior
+                                                      // lines we can compute the
+                                                      // midpoint as the mean of
+                                                      // the two vertices:
+                     if (line->at_boundary())
+                       triangulation.vertices[next_unused_vertex]
+                         = triangulation.boundary[line->boundary_indicator()]->get_new_point_on_line (line);
+                     else
+                       triangulation.vertices[next_unused_vertex]
+                         = (line->vertex(0) + line->vertex(1)) / 2;
+                   }
+                 else
+                                                    // however, if spacedim>dim, we
+                                                    // always have to ask the
+                                                    // boundary object for its
+                                                    // answer
+                   triangulation.vertices[next_unused_vertex]
+                     = triangulation.boundary[line->user_index()]->get_new_point_on_line (line);
+         
+                                                  // now that we created
+                                                  // the right point, make
+                                                  // up the two child
+                                                  // lines.  To this end,
+                                                  // find a pair of unused
+                                                  // lines
+                 bool pair_found=false;
+                 for (; next_unused_line!=endl; ++next_unused_line)
+                   if (!next_unused_line->used() &&
+                       !(++next_unused_line)->used())
+                     {
+                                                        // go back to the
+                                                        // first of the two
+                                                        // unused lines
+                       --next_unused_line;
+                       pair_found=true;
+                       break;
+                     }
+                 Assert (pair_found, ExcInternalError());
+
+                                                  // there are now two
+                                                  // consecutive unused
+                                                  // lines, such that the
+                                                  // children of a line
+                                                  // will be consecutive.
+                                                  // then set the child
+                                                  // pointer of the present
+                                                  // line
+                 line->set_children (0, next_unused_line->index());
+         
+                                                  // set the two new lines
+                 const raw_line_iterator children[2] = { next_unused_line,
+                                                         ++next_unused_line };
+                                                  // some tests; if any of
+                                                  // the iterators should
+                                                  // be invalid, then
+                                                  // already dereferencing
+                                                  // will fail
+                 Assert (children[0]->used() == false, ExcCellShouldBeUnused());
+                 Assert (children[1]->used() == false, ExcCellShouldBeUnused());
+         
+                 children[0]->set (internal::Triangulation
+                                   ::TriaObject<1>(line->vertex_index(0),
+                                                   next_unused_vertex));
+                 children[1]->set (internal::Triangulation
+                                   ::TriaObject<1>(next_unused_vertex,
+                                                   line->vertex_index(1)));
+    
+                 children[0]->set_used_flag();
+                 children[1]->set_used_flag();
+                 children[0]->clear_children();
+                 children[1]->clear_children();
+                 children[0]->clear_user_data();
+                 children[1]->clear_user_data();
+                 children[0]->clear_user_flag();
+                 children[1]->clear_user_flag();
+
+                 children[0]->set_boundary_indicator (line->boundary_indicator());
+                 children[1]->set_boundary_indicator (line->boundary_indicator());
+           
+                                                  // finally clear flag
+                                                  // indicating the need
+                                                  // for refinement
+                 line->clear_user_flag ();
+               }
+         }
 
-template <int dim>
-void Triangulation<dim>::clear_user_flags_line ()
-{
-  faces->lines.clear_user_flags();
-}
+  
+                                        // Now set up the new cells
+
+                                        // reserve space for inner
+                                        // lines (can be stored as
+                                        // single lines)
+       triangulation.faces->lines.
+         reserve_space (0,n_single_lines);
+
+                                        // reset next_unused_line, as
+                                        // now also single empty places
+                                        // in the vector can be used
+       raw_line_iterator next_unused_line = triangulation.begin_raw_line ();
+  
+       for (int level=0; level<static_cast<int>(triangulation.levels.size())-1; ++level) 
+         {
+      
+                                            // Remember: as we don't operate
+                                            // on the finest level, begin_*(level+1)
+                                            // is allowed
+           active_cell_iterator cell = triangulation.begin_active(level),
+                                endc = triangulation.begin_active(level+1);
+      
+           raw_cell_iterator next_unused_cell = triangulation.begin_raw (level+1);
 
-#endif
+           for (; cell!=endc; ++cell) 
+             if (cell->refine_flag_set()) 
+               {
+                                                  // set the user flag to
+                                                  // indicate, that at least one
+                                                  // line is at the boundary
+           
+                                                  // TODO[Tobias Leicht] find a
+                                                  // better place to set this flag,
+                                                  // so that we do not need so much
+                                                  // time to check each cell here
+                 if (cell->at_boundary())
+                   cell->set_user_flag();
+                                                  // actually set up the children and
+                                                  // update neighbor information
+                 create_children (triangulation,
+                                  next_unused_vertex,
+                                  next_unused_line,
+                                  next_unused_cell,
+                                  cell);
+               }
+         }
+      }
 
 
+                                    /**
+                                     * A function that performs the
+                                     * refinement of a triangulation in 3d.
+                                     */
+    template <int spacedim>
+    static
+    void
+    execute_refinement (Triangulation<3,spacedim> &triangulation)
+      {
+       const unsigned int dim = 3;
+
+                                        // this function probably
+                                        // also works for spacedim>3
+                                        // but it isn't tested. it
+                                        // will probably be necessary
+                                        // to pull new vertices onto
+                                        // the manifold just as we do
+                                        // for the other functions
+                                        // above.
+       Assert (spacedim == 3, ExcNotImplemented());
+
+                                        // check whether a new level is
+                                        // needed we have to check for this
+                                        // on the highest level only (on
+                                        // this, all used cells are also
+                                        // active, so we only have to check
+                                        // for this)
+       if (true)
+         {
+           raw_cell_iterator cell = triangulation.begin_active (triangulation.levels.size()-1),
+                             endc = triangulation.end();
+           for (; cell != endc; ++cell)
+             if (cell->used())
+               if (cell->refine_flag_set()) 
+                 {
+                   triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+                   break;
+                 }
+         }
 
 
-template <int dim>
-void Triangulation<dim>::save_user_flags (std::ostream &out) const
-{
-  save_user_flags_line (out);
+                                        // first clear user flags for quads
+                                        // and lines; we're going to use them
+                                        // to flag which lines and quads
+                                        // need refinement
+       triangulation.faces->quads.clear_user_data();
   
-  if (dim>=2)
-    save_user_flags_quad (out);
+       for (line_iterator line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+         line->clear_user_flag();
+       for (quad_iterator quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
+         {
+           quad->clear_user_flag();
+         }
+                                        // create an array of face refine cases. User
+                                        // indices of faces will be set to values
+                                        // corresponding with indices in this array.
+       const RefinementCase<dim-1>  face_refinement_cases[4]=
+         {RefinementCase<dim-1>::no_refinement,
+          RefinementCase<dim-1>::cut_x,
+          RefinementCase<dim-1>::cut_y,
+          RefinementCase<dim-1>::cut_xy};
   
-  if (dim>=3)
-    save_user_flags_hex (out);
+                                        // check how much space is needed
+                                        // on every level
+                                        // we need not check the highest
+                                        // level since either
+                                        // - on the highest level no cells
+                                        //   are flagged for refinement
+                                        // - there are, but prepare_refinement
+                                        //   added another empty level which
+                                        //   then is the highest level
+
+                                        // variables to hold the number of newly to
+                                        // be created vertices, lines and quads. as
+                                        // these are stored globally, declare them
+                                        // outside the loop over al levels. we need
+                                        // lines and quads in pairs for refinement of
+                                        // old ones and lines and quads, that can be
+                                        // stored as single ones, as they are newly
+                                        // created in the inside of an existing cell
+       unsigned int needed_vertices = 0;
+       unsigned int needed_lines_single  = 0;
+       unsigned int needed_quads_single  = 0;
+       unsigned int needed_lines_pair  = 0;
+       unsigned int needed_quads_pair  = 0;
+       for (int level=triangulation.levels.size()-2; level>=0; --level)
+         {
+                                            // count number of flagged
+                                            // cells on this level and
+                                            // compute how many new
+                                            // vertices and new lines will
+                                            // be needed
+           unsigned int new_cells = 0;
+      
+           active_cell_iterator acell = triangulation.begin_active(level),
+                                aendc = triangulation.begin_active(level+1);
+           for (; acell!=aendc; ++acell) 
+             if (acell->refine_flag_set()) 
+               {
+                 RefinementCase<dim> ref_case=acell->refine_flag_set();
+           
+                                                  // now for interior vertices, lines
+                                                  // and quads, which are needed in
+                                                  // any case
+                 if (ref_case==RefinementCase<dim>::cut_x ||
+                     ref_case==RefinementCase<dim>::cut_y ||
+                     ref_case==RefinementCase<dim>::cut_z)
+                   {
+                     ++needed_quads_single;
+                     new_cells+=2;
+                     triangulation.anisotropic_refinement=true;
+                   }
+                 else if (ref_case==RefinementCase<dim>::cut_xy ||
+                          ref_case==RefinementCase<dim>::cut_xz ||
+                          ref_case==RefinementCase<dim>::cut_yz)
+                   {
+                     ++needed_lines_single;
+                     needed_quads_single += 4;
+                     new_cells+=4;
+                     triangulation.anisotropic_refinement=true;
+                   }
+                 else if  (ref_case==RefinementCase<dim>::cut_xyz)
+                   {
+                     ++needed_vertices;
+                     needed_lines_single += 6;
+                     needed_quads_single += 12;
+                     new_cells+=8;
+                   }
+                 else
+                   {
+                                                      // we should never get here
+                     Assert(false, ExcInternalError());
+                   }
+           
+                                                  // mark all faces for refinement;
+                                                  // checking locally
+                                                  // if and how the neighbor
+                                                  // would like to
+                                                  // refine these is
+                                                  // difficult so
+                                                  // we only flag them and
+                                                  // after visiting all
+                                                  // cells, we decide which
+                                                  // faces need which refinement;
+                 for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell;
+                      ++face)
+                   {
+                     face_iterator aface = acell->face(face);
+                                                      // get the RefineCase this
+                                                      // faces has for the given
+                                                      // RefineCase of the cell
+                     RefinementCase<dim-1> face_ref_case=
+                       GeometryInfo<dim>::face_refinement_case(ref_case,
+                                                               face,
+                                                               acell->face_orientation(face),
+                                                               acell->face_flip(face),
+                                                               acell->face_rotation(face));
+                                                      // only do something, if this
+                                                      // face has to be refined
+                     if (face_ref_case)
+                       {
+                         if (face_ref_case==RefinementCase<dim-1>::isotropic_refinement)
+                           {
+                             if (aface->number_of_children()<4)
+                                                                // we use user_flags to
+                                                                // denote needed isotropic
+                                                                // refinement
+                               aface->set_user_flag();
+                           }
+                         else if (aface->refinement_case()!=face_ref_case)
+                                                            // we use user_indices
+                                                            // to denote needed
+                                                            // anisotropic
+                                                            // refinement. note, that
+                                                            // we can have at most
+                                                            // one anisotropic
+                                                            // refinement case for
+                                                            // this face, as
+                                                            // otherwise
+                                                            // prepare_refinement()
+                                                            // would have changed one
+                                                            // of the cells to yield
+                                                            // isotropic refinement
+                                                            // at this
+                                                            // face. therefore we set
+                                                            // the user_index
+                                                            // uniquely
+                           {
+                             Assert(aface->refinement_case()==RefinementCase<dim-1>::isotropic_refinement ||
+                                    aface->refinement_case()==RefinementCase<dim-1>::no_refinement,
+                                    ExcInternalError());
+                             aface->set_user_index(face_ref_case);
+                           }
+                       }
+                   }// for all faces
+           
+                                                  // flag all lines, that have to be
+                                                  // refined
+                 for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+                   if (GeometryInfo<dim>::line_refinement_case(ref_case,line) &&
+                       !acell->line(line)->has_children())
+                     acell->line(line)->set_user_flag();
+               
+               }// if refine_flag set and for all cells on this level
+      
 
-  if (dim >= 4)
-    Assert (false, ExcNotImplemented());
-}
+                                            // count number of used cells on
+                                            // the next higher level
+           const unsigned int used_cells
+             = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
+                              triangulation.levels[level+1]->cells.used.end(),
+                              std::bind2nd (std::equal_to<bool>(), true));
+
+
+                                            // reserve space for the
+                                            // used_cells cells already
+                                            // existing on the next higher
+                                            // level as well as for the
+                                            // 8*flagged_cells that will be
+                                            // created on that level
+           triangulation.levels[level+1]->reserve_space (used_cells+new_cells, 3);
+                                            // reserve space for
+                                            // 8*flagged_cells
+                                            // new hexes on the next higher
+                                            // level
+           triangulation.levels[level+1]->cells.reserve_space (new_cells);
+         }// for all levels
+                                        // now count the quads and
+                                        // lines which were flagged for
+                                        // refinement
+       for (quad_iterator quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
+         {
+           if (quad->user_flag_set())
+             {
+                                                // isotropic refinement: 1 interior
+                                                // vertex, 4 quads and 4 interior
+                                                // lines. we store the interior lines
+                                                // in pairs in case the face is
+                                                // already or will be refined
+                                                // anisotropically
+               needed_quads_pair += 4;
+               needed_lines_pair += 4;
+               needed_vertices += 1;
+             }
+           if (quad->user_index())
+             {
+                                                // anisotropic refinement: 1 interior
+                                                // line and two quads
+               needed_quads_pair += 2;
+               needed_lines_single += 1;
+                                                // there is a kind of complicated
+                                                // situation here which requires our
+                                                // attention. if the quad is refined
+                                                // isotropcally, two of the interior
+                                                // lines will get a new mother line -
+                                                // the interior line of our
+                                                // anisotropically refined quad. if
+                                                // those two lines are not
+                                                // consecutive, we cannot do so and
+                                                // have to replace them by two lines
+                                                // that are consecutive. we try to
+                                                // avoid that situation, but it may
+                                                // happen nevertheless throug
+                                                // repeated refinement and
+                                                // coarsening. thus we have to check
+                                                // here, as we will need some
+                                                // additional space to store those
+                                                // new lines in case we need them...
+               if (quad->has_children())
+                 {
+                   Assert(quad->refinement_case()==RefinementCase<dim-1>::isotropic_refinement, ExcInternalError());
+                   if ((face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_x
+                        && (quad->child(0)->line_index(1)+1!=quad->child(2)->line_index(1))) ||
+                       (face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_y
+                        && (quad->child(0)->line_index(3)+1!=quad->child(1)->line_index(3))))
+                     needed_lines_pair +=2;
+                 }
+             }
+         }
+  
+       for (line_iterator line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+         if (line->user_flag_set())
+           {
+             needed_lines_pair += 2;
+             needed_vertices += 1;
+           }
 
+                                        // reserve space for
+                                        // needed_lines new lines
+                                        // stored in pairs
+       triangulation.faces->lines.
+         reserve_space (needed_lines_pair,needed_lines_single);
+                                        // reserve space for
+                                        // needed_quads new quads
+                                        // stored in pairs
+       triangulation.faces->quads.
+         reserve_space (needed_quads_pair,needed_quads_single);
+
+
+                                        // add to needed vertices how many
+                                        // vertices are already in use
+       needed_vertices += std::count_if (triangulation.vertices_used.begin(), triangulation.vertices_used.end(),
+                                         std::bind2nd (std::equal_to<bool>(), true));
+                                        // if we need more vertices: create
+                                        // them, if not: leave the array as
+                                        // is, since shrinking is not
+                                        // really possible because some of
+                                        // the vertices at the end may be
+                                        // in use
+       if (needed_vertices > triangulation.vertices.size())
+         {
+           triangulation.vertices.resize (needed_vertices, Point<spacedim>());
+           triangulation.vertices_used.resize (needed_vertices, false);
+         }
 
 
-template <int dim>
-void Triangulation<dim>::save_user_flags (std::vector<bool> &v) const
-{
-                                  // clear vector and append
-                                  // all the stuff later on
-  v.clear ();
+                                        ///////////////////////////////////////////
+                                        // Before we start with the actual
+                                        // refinement, we do some sanity
+                                        // checks if in debug
+                                        // mode. especially, we try to
+                                        // catch the notorious problem with
+                                        // lines being twice refined,
+                                        // i.e. there are cells adjacent at
+                                        // one line ("around the edge", but
+                                        // not at a face), with two cells
+                                        // differing by more than one
+                                        // refinement level
+                                        //
+                                        // this check is very simple to
+                                        // implement here, since we have
+                                        // all lines flagged if they shall
+                                        // be refined
+#ifdef DEBUG
+       for (active_cell_iterator cell=triangulation.begin_active(); cell!=triangulation.end(); ++cell)
+         if (!cell->refine_flag_set())
+           for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+             if (cell->line(line)->has_children())
+               for (unsigned int c=0; c<2; ++c)
+                 Assert (cell->line(line)->child(c)->user_flag_set() == false,
+                         ExcInternalError());
+#endif
 
-  std::vector<bool> tmp;
+                                        ///////////////////////////////////////////
+                                        // Do refinement on every level
+                                        //
+                                        // To make life a bit easier, we
+                                        // first refine those lines and
+                                        // quads that were flagged for
+                                        // refinement and then compose the
+                                        // newly to be created cells.
+                                        //
+                                        // index of next unused vertex
+       unsigned int next_unused_vertex = 0;
+
+                                        // first for lines
+       if (true)
+         {
+                                            // only active objects can be
+                                            // refined further
+           active_line_iterator line = triangulation.begin_active_line(),
+                                endl = triangulation.end_line();
+           raw_line_iterator next_unused_line = triangulation.begin_raw_line ();
+
+           for (; line!=endl; ++line)
+             if (line->user_flag_set())
+               {
+                                                  // this line needs to be
+                                                  // refined
 
-  save_user_flags_line (tmp);
-  v.insert (v.end(), tmp.begin(), tmp.end());
+                                                  // find the next unused
+                                                  // vertex and set it
+                                                  // appropriately
+                 while (triangulation.vertices_used[next_unused_vertex] == true)
+                   ++next_unused_vertex;
+                 Assert (next_unused_vertex < triangulation.vertices.size(),
+                         ExcTooFewVerticesAllocated());
+                 triangulation.vertices_used[next_unused_vertex] = true;
 
-  if (dim >= 2)
-    {
-      save_user_flags_quad (tmp);
-      v.insert (v.end(), tmp.begin(), tmp.end());
-    }
-  
-  if (dim >= 3)
-    {
-      save_user_flags_hex (tmp);
-      v.insert (v.end(), tmp.begin(), tmp.end());
-    }      
+                 if (line->at_boundary())
+                   triangulation.vertices[next_unused_vertex]
+                     = triangulation.boundary[line->boundary_indicator()]->get_new_point_on_line (line);
+                 else
+                   triangulation.vertices[next_unused_vertex]
+                     = (line->vertex(0) + line->vertex(1)) / 2;
+         
+                                                  // now that we created
+                                                  // the right point, make
+                                                  // up the two child lines
+                                                  // (++ takes care of the
+                                                  // end of the vector)
+                 next_unused_line=triangulation.faces->lines.next_free_pair_line(triangulation);
+                 Assert(next_unused_line.state() == IteratorState::valid,
+                        ExcInternalError());
+           
+                                                  // now we found
+                                                  // two consecutive unused
+                                                  // lines, such that the
+                                                  // children of a line
+                                                  // will be consecutive.
+                                                  // then set the child
+                                                  // pointer of the present
+                                                  // line
+                 line->set_children (0, next_unused_line->index());
+         
+                                                  // set the two new lines
+                 const raw_line_iterator children[2] = { next_unused_line,
+                                                         ++next_unused_line };
+                                                  // some tests; if any of
+                                                  // the iterators should
+                                                  // be invalid, then
+                                                  // already dereferencing
+                                                  // will fail
+                 Assert (children[0]->used() == false, ExcCellShouldBeUnused());
+                 Assert (children[1]->used() == false, ExcCellShouldBeUnused());
+         
+                 children[0]->set (internal::Triangulation
+                                   ::TriaObject<1>(line->vertex_index(0),
+                                                   next_unused_vertex));
+                 children[1]->set (internal::Triangulation
+                                   ::TriaObject<1>(next_unused_vertex,
+                                                   line->vertex_index(1)));
+    
+                 children[0]->set_used_flag();
+                 children[1]->set_used_flag();
+                 children[0]->clear_children();
+                 children[1]->clear_children();
+                 children[0]->clear_user_data();
+                 children[1]->clear_user_data();
+                 children[0]->clear_user_flag();
+                 children[1]->clear_user_flag();
+
+                 children[0]->set_boundary_indicator (line->boundary_indicator());
+                 children[1]->set_boundary_indicator (line->boundary_indicator());
+           
+                                                  // finally clear flag
+                                                  // indicating the need
+                                                  // for refinement
+                 line->clear_user_flag ();
+               }
+         }
 
-  if (dim >= 4)
-    Assert (false, ExcNotImplemented());
-}
 
+                                        ///////////////////////////////////////
+                                        // now refine marked quads
+                                        ///////////////////////////////////////
 
+                                        // here we encounter several cases:
 
-template <int dim>
-void Triangulation<dim>::load_user_flags (std::istream &in)
-{
-  load_user_flags_line (in);
-  
-  if (dim>=2)
-    load_user_flags_quad (in);
-  
-  if (dim>=3)
-    load_user_flags_hex (in);
+                                        // a) the quad is unrefined and shall be
+                                        // refined isotropically
 
-  if (dim >= 4)
-    Assert (false, ExcNotImplemented());
-}
+                                        // b) the quad is unrefined and shall be
+                                        // refined anisotropically
 
+                                        // c) the quad is unrefined and shall be
+                                        // refined both anisotropically and
+                                        // isotropically (this is reduced to case b)
+                                        // and then case b) for the children again)
 
+                                        // d) the quad is refined anisotropically and
+                                        // shall be refined isotropically (this is
+                                        // reduced to case b) for the anisotropic
+                                        // children)
 
-template <int dim>
-void Triangulation<dim>::load_user_flags (const std::vector<bool> &v)
-{
-  Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
-  std::vector<bool> tmp;
+                                        // e) the quad is refined isotropically and
+                                        // shall be refined anisotropically (this is
+                                        // transformed to case c), however we might
+                                        // have to renumber/rename children...)
 
-                                  // first extract the flags
-                                  // belonging to lines
-  tmp.insert (tmp.end(),
-             v.begin(), v.begin()+n_lines());
-                                  // and set the lines
-  load_user_flags_line (tmp);
+                                        // we need a loop in cases c) and d), as the
+                                        // anisotropic children migt have a lower
+                                        // index than the mother quad
+       for (unsigned int loop=0; loop<2; ++loop)
+         {
+                                            // usually, only active objects can be
+                                            // refined further. however, in cases d)
+                                            // and e) that is not true, so we have to
+                                            // use 'normal' iterators here
+           quad_iterator quad = triangulation.begin_quad(),
+                         endq = triangulation.end_quad();
+           raw_line_iterator next_unused_line = triangulation.begin_raw_line (),
+                                         endl = triangulation.end_line();
+           raw_quad_iterator next_unused_quad = triangulation.begin_raw_quad ();
+
+           for (; quad!=endq; ++quad)
+             {
+               if (quad->user_index())
+                 {
+                   RefinementCase<dim-1> aniso_quad_ref_case=face_refinement_cases[quad->user_index()];
+                                                    // there is one unlikely event
+                                                    // here, where we already have
+                                                    // refind the face: if the face
+                                                    // was refined anisotropically
+                                                    // and we want to refine it
+                                                    // isotropically, both children
+                                                    // are flagged for anisotropic
+                                                    // refinement. however, if those
+                                                    // children were already flagged
+                                                    // for anisotropic refinement,
+                                                    // they might already be
+                                                    // processed and refined.
+                   if (aniso_quad_ref_case == quad->refinement_case())
+                     continue;
+             
+                   Assert(quad->refinement_case()==RefinementCase<dim-1>::cut_xy ||
+                          quad->refinement_case()==RefinementCase<dim-1>::no_refinement,
+                          ExcInternalError());
+             
+                                                    // this quad needs to be refined
+                                                    // anisotropically
+                   Assert(quad->user_index() == RefinementCase<dim-1>::cut_x ||
+                          quad->user_index() == RefinementCase<dim-1>::cut_y,
+                          ExcInternalError());
+
+                                                    // make the new line interior to
+                                                    // the quad
+                   raw_line_iterator new_line;
+             
+                   new_line=triangulation.faces->lines.next_free_single_line(triangulation);
+                   Assert (new_line->used() == false,
+                           ExcCellShouldBeUnused());
+
+                                                    // first collect the
+                                                    // indices of the vertices:
+                                                    // *--1--*
+                                                    // |  |  |
+                                                    // |  |  |    cut_x
+                                                    // |  |  |
+                                                    // *--0--*
+                                                    //
+                                                    // *-----*
+                                                    // |     |
+                                                    // 0-----1    cut_y
+                                                    // |     |
+                                                    // *-----*
+                   unsigned int vertex_indices[2];
+                   if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+                     {
+                       vertex_indices[0]=quad->line(2)->child(0)->vertex_index(1);
+                       vertex_indices[1]=quad->line(3)->child(0)->vertex_index(1);
+                     }
+                   else
+                     {
+                       vertex_indices[0]=quad->line(0)->child(0)->vertex_index(1);
+                       vertex_indices[1]=quad->line(1)->child(0)->vertex_index(1);
+                     }
 
-  if (dim >= 2)
-    {
-      tmp.clear ();
-      tmp.insert (tmp.end(),
-                 v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
-      load_user_flags_quad (tmp);
-    }
-  
-  if (dim >= 3)
-    {
-      tmp.clear();
-      tmp.insert (tmp.end(),
-                 v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
-      load_user_flags_hex (tmp);
-    }      
+                   new_line->set (internal::Triangulation::
+                                  TriaObject<1>(vertex_indices[0], vertex_indices[1]));
+                   new_line->set_used_flag();
+                   new_line->clear_user_flag();
+                   new_line->clear_user_data();
+                   new_line->clear_children();
+                   new_line->set_boundary_indicator(quad->boundary_indicator());
+
+                                                    // child 0 and 1 of a line are
+                                                    // switched if the line
+                                                    // orientation is false. set up a
+                                                    // miniature table, indicating
+                                                    // which child to take for line
+                                                    // orientations false and
+                                                    // true. first index: child index
+                                                    // in standard orientation,
+                                                    // second index: line orientation
+                   const unsigned int index[2][2]=
+                     {{1,0},   // child 0, line_orientation=false and true
+                      {0,1}};  // child 1, line_orientation=false and true
+             
+                                                    // find some space (consecutive)
+                                                    // for the two newly to be
+                                                    // created quads.
+                   raw_quad_iterator new_quads[2];
+             
+                   next_unused_quad=triangulation.faces->quads.next_free_pair_quad(triangulation);
+                   new_quads[0] = next_unused_quad;
+                   Assert (new_quads[0]->used() == false, ExcCellShouldBeUnused());
+             
+                   ++next_unused_quad;
+                   new_quads[1] = next_unused_quad;
+                   Assert (new_quads[1]->used() == false, ExcCellShouldBeUnused());
 
-  if (dim >= 4)
-    Assert (false, ExcNotImplemented());
-}
 
+                   if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+                     {
+                       new_quads[0]->set (internal::Triangulation
+                                          ::TriaObject<2>(quad->line_index(0),
+                                                          new_line->index(),
+                                                          quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
+                                                          quad->line(3)->child(index[0][quad->line_orientation(3)])->index()));
+                       new_quads[1]->set (internal::Triangulation
+                                          ::TriaObject<2>(new_line->index(),
+                                                          quad->line_index(1),
+                                                          quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
+                                                          quad->line(3)->child(index[1][quad->line_orientation(3)])->index()));
+                     }
+                   else
+                     {
+                       new_quads[0]->set (internal::Triangulation
+                                          ::TriaObject<2>(quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
+                                                          quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
+                                                          quad->line_index(2),
+                                                          new_line->index()));
+                       new_quads[1]->set (internal::Triangulation
+                                          ::TriaObject<2>(quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
+                                                          quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
+                                                          new_line->index(),
+                                                          quad->line_index(3)));
+                     }
+             
+                   for (unsigned int i=0; i<2; ++i)
+                     {
+                       new_quads[i]->set_used_flag();
+                       new_quads[i]->clear_user_flag();
+                       new_quads[i]->clear_user_data();
+                       new_quads[i]->clear_children();
+                       new_quads[i]->set_boundary_indicator (quad->boundary_indicator());
+                                                        // set all line orientations to
+                                                        // true, change this after the
+                                                        // loop, as we have to consider
+                                                        // different lines for each
+                                                        // child
+                       for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
+                         new_quads[i]->set_line_orientation(j,true);
+                     }
+                                                    // now set the line orientation of
+                                                    // children of outer lines
+                                                    // correctly, the lines in the
+                                                    // interior of the refined quad are
+                                                    // automatically oriented
+                                                    // conforming to the standard
+                   new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
+                   new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
+                   new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
+                   new_quads[1]->set_line_orientation(2,quad->line_orientation(3));
+                   if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+                     {
+                       new_quads[0]->set_line_orientation(3,quad->line_orientation(3));
+                       new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
+                     }
+                   else
+                     {
+                       new_quads[0]->set_line_orientation(1,quad->line_orientation(1));
+                       new_quads[1]->set_line_orientation(0,quad->line_orientation(0));
+                     }
 
+                                                    // test, whether this face is
+                                                    // refined isotropically
+                                                    // already. if so, set the
+                                                    // correct children pointers.
+                   if (quad->refinement_case()==RefinementCase<dim-1>::cut_xy)
+                     {
+                                                        // we will put a new
+                                                        // refinemnt level of
+                                                        // anisotropic refinement
+                                                        // between the unrefined and
+                                                        // isotropically refined quad
+                                                        // ending up with the same
+                                                        // fine quads but introducing
+                                                        // anisotropically refined
+                                                        // ones as children of the
+                                                        // unrefined quad and mother
+                                                        // cells of the original fine
+                                                        // ones.
+
+                                                        // this process includes the
+                                                        // creation of a new middle
+                                                        // line which we will assign
+                                                        // as the mother line of two
+                                                        // of the existing inner
+                                                        // lines. If those inner
+                                                        // lines are not consecutive
+                                                        // in memory, we won't find
+                                                        // them later on, so we have
+                                                        // to create new ones instead
+                                                        // and replace all occurances
+                                                        // of the old ones with those
+                                                        // new ones. As this is kind
+                                                        // of ugly, we hope we don't
+                                                        // have to do it often...
+                       line_iterator old_child[2];
+                       if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+                         {
+                           old_child[0]=quad->child(0)->line(1);
+                           old_child[1]=quad->child(2)->line(1);
+                         }
+                       else
+                         {
+                           Assert(aniso_quad_ref_case==RefinementCase<dim-1>::cut_y, ExcInternalError());
+                     
+                           old_child[0]=quad->child(0)->line(3);
+                           old_child[1]=quad->child(1)->line(3);
+                         }
+                 
+                       if (old_child[0]->index()+1 != old_child[1]->index())
+                         {
+                                                            // this is exactly the
+                                                            // ugly case we taked
+                                                            // about. so, no
+                                                            // coimplaining, lets get
+                                                            // two new lines and copy
+                                                            // all info
+                           raw_line_iterator new_child[2];
+                     
+                           new_child[0]=new_child[1]=triangulation.faces->lines.next_free_pair_line(triangulation);
+                           ++new_child[1];
 
-template <int dim>
-void Triangulation<dim>::save_user_flags_line (std::vector<bool> &v) const
-{
-  v.resize (n_lines(), false);
-  std::vector<bool>::iterator  i = v.begin();
-  line_iterator line = begin_line(),
-               endl = end_line();
-  for (; line!=endl; ++line, ++i)
-    *i = line->user_flag_set();
-}
+                           new_child[0]->set_used_flag();
+                           new_child[1]->set_used_flag();
+                     
+                           const int old_index_0=old_child[0]->index(),
+                                     old_index_1=old_child[1]->index(),
+                                     new_index_0=new_child[0]->index(),
+                                     new_index_1=new_child[1]->index();
+
+                                                            // loop over all quads
+                                                            // and replace the old
+                                                            // lines
+                           for (unsigned int q=0; q<triangulation.faces->quads.cells.size(); ++q)
+                             for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+                               {
+                                 const int index=triangulation.faces->quads.cells[q].face(l);
+                                 if (index==old_index_0)
+                                   triangulation.faces->quads.cells[q].set_face(l,new_index_0);
+                                 else if (index==old_index_1)
+                                   triangulation.faces->quads.cells[q].set_face(l,new_index_1);
+                               }
+                                                            // now we have to copy
+                                                            // all information of the
+                                                            // two lines
+                           for (unsigned int i=0; i<2; ++i)
+                             {
+                               Assert(!old_child[i]->has_children(), ExcInternalError());
+                         
+                               new_child[i]->set(internal::Triangulation::TriaObject<1>(old_child[i]->vertex_index(0),
+                                                                                        old_child[i]->vertex_index(1)));
+                               new_child[i]->set_boundary_indicator(old_child[i]->boundary_indicator());
+                               new_child[i]->set_user_index(old_child[i]->user_index());
+                               if (old_child[i]->user_flag_set())
+                                 new_child[i]->set_user_flag();
+                               else
+                                 new_child[i]->clear_user_flag();
+                         
+                               new_child[i]->clear_children();
+                         
+                               old_child[i]->clear_user_flag();
+                               old_child[i]->clear_user_index();
+                               old_child[i]->clear_used_flag();
+                             }
+                         }
+                                                        // now that we cared
+                                                        // about the lines, go on
+                                                        // with the quads
+                                                        // themselves, where we
+                                                        // might encounter
+                                                        // similar situations...
+                       if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+                         {
+                           new_line->set_children(0, quad->child(0)->line_index(1));
+                           Assert(new_line->child(1)==quad->child(2)->line(1),
+                                  ExcInternalError());
+                                                            // now evereything is
+                                                            // quite complicated. we
+                                                            // have the children
+                                                            // numbered according to
+                                                            //
+                                                            // *---*---*
+                                                            // |n+2|n+3|
+                                                            // *---*---*
+                                                            // | n |n+1|
+                                                            // *---*---*
+                                                            //
+                                                            // from the original
+                                                            // isotropic
+                                                            // refinement. we have to
+                                                            // reorder them as
+                                                            //
+                                                            // *---*---*
+                                                            // |n+1|n+3|
+                                                            // *---*---*
+                                                            // | n |n+2|
+                                                            // *---*---*
+                                                            //
+                                                            // such that n and n+1
+                                                            // are consecutive
+                                                            // children of m and n+2
+                                                            // and n+3 are
+                                                            // consecutive children
+                                                            // of m+1, where m and
+                                                            // m+1 are given as in
+                                                            //
+                                                            // *---*---*
+                                                            // |   |   |
+                                                            // | m |m+1|
+                                                            // |   |   |
+                                                            // *---*---*
+                                                            //
+                                                            // this is a bit ugly, of
+                                                            // course: loop over all
+                                                            // cells on all levels
+                                                            // and look for faces n+1
+                                                            // (switch_1) and n+2
+                                                            // (switch_2).
+                           const quad_iterator switch_1=quad->child(1);
+                           const quad_iterator switch_2=quad->child(2);
+                           const int switch_1_index=switch_1->index();
+                           const int switch_2_index=switch_2->index();
+                           for (unsigned int l=0; l<triangulation.levels.size(); ++l)
+                             for (unsigned int h=0; h<triangulation.levels[l]->cells.cells.size(); ++h)
+                               for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
+                                 {
+                                   const int index=triangulation.levels[l]->cells.cells[h].face(q);
+                                   if (index==switch_1_index)
+                                     triangulation.levels[l]->cells.cells[h].set_face(q,switch_2_index);
+                                   else if (index==switch_2_index)
+                                     triangulation.levels[l]->cells.cells[h].set_face(q,switch_1_index);
+                                 }
+                                                            // now we have to copy
+                                                            // all information of the
+                                                            // two quads
+                           const int switch_1_lines[4]=
+                             {switch_1->line_index(0),
+                              switch_1->line_index(1),
+                              switch_1->line_index(2),
+                              switch_1->line_index(3)};
+                           const bool switch_1_line_orientations[4]=
+                             {switch_1->line_orientation(0),
+                              switch_1->line_orientation(1),
+                              switch_1->line_orientation(2),
+                              switch_1->line_orientation(3)};
+                           const unsigned char switch_1_boundary_indicator=switch_1->boundary_indicator();
+                           const unsigned int switch_1_user_index=switch_1->user_index();
+                           const bool switch_1_user_flag=switch_1->user_flag_set();
+                           const RefinementCase<dim-1> switch_1_refinement_case=switch_1->refinement_case();
+                           const int switch_1_first_child_pair=(switch_1_refinement_case ? switch_1->child_index(0) : -1);
+                           const int switch_1_second_child_pair=(switch_1_refinement_case==RefinementCase<dim-1>::cut_xy ? switch_1->child_index(2) : -1);
+
+                           switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
+                                                                                switch_2->line_index(1),
+                                                                                switch_2->line_index(2),
+                                                                                switch_2->line_index(3)));
+                           switch_1->set_line_orientation(0, switch_2->line_orientation(0));
+                           switch_1->set_line_orientation(1, switch_2->line_orientation(1));
+                           switch_1->set_line_orientation(2, switch_2->line_orientation(2));
+                           switch_1->set_line_orientation(3, switch_2->line_orientation(3));
+                           switch_1->set_boundary_indicator(switch_2->boundary_indicator());
+                           switch_1->set_user_index(switch_2->user_index());
+                           if (switch_2->user_flag_set())
+                             switch_1->set_user_flag();
+                           else
+                             switch_1->clear_user_flag();
+                           switch_1->clear_refinement_case();
+                           switch_1->set_refinement_case(switch_2->refinement_case());
+                           switch_1->clear_children();
+                           if (switch_2->refinement_case())
+                             switch_1->set_children(0, switch_2->child_index(0));
+                           if (switch_2->refinement_case()==RefinementCase<dim-1>::cut_xy)
+                             switch_1->set_children(2, switch_2->child_index(2));
+                       
+                           switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
+                                                                                switch_1_lines[1],
+                                                                                switch_1_lines[2],
+                                                                                switch_1_lines[3]));
+                           switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
+                           switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
+                           switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
+                           switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
+                           switch_2->set_boundary_indicator(switch_1_boundary_indicator);
+                           switch_2->set_user_index(switch_1_user_index);
+                           if (switch_1_user_flag)
+                             switch_2->set_user_flag();
+                           else
+                             switch_2->clear_user_flag();
+                           switch_2->clear_refinement_case();
+                           switch_2->set_refinement_case(switch_1_refinement_case);
+                           switch_2->clear_children();
+                           switch_2->set_children(0, switch_1_first_child_pair);
+                           switch_2->set_children(2, switch_1_second_child_pair);
+
+                           new_quads[0]->set_refinement_case(RefinementCase<2>::cut_y);
+                           new_quads[0]->set_children(0, quad->child_index(0));
+                           new_quads[1]->set_refinement_case(RefinementCase<2>::cut_y);
+                           new_quads[1]->set_children(0, quad->child_index(2));
+                         }
+                       else
+                         {
+                           new_quads[0]->set_refinement_case(RefinementCase<2>::cut_x);
+                           new_quads[0]->set_children(0, quad->child_index(0));
+                           new_quads[1]->set_refinement_case(RefinementCase<2>::cut_x);
+                           new_quads[1]->set_children(0, quad->child_index(2));
+                           new_line->set_children(0, quad->child(0)->line_index(3));
+                           Assert(new_line->child(1)==quad->child(1)->line(3),
+                                  ExcInternalError());
+                         }
+                       quad->clear_children();
+                     }
+             
+                                                    // note these quads as children
+                                                    // to the present one
+                   quad->set_children (0, new_quads[0]->index());
 
+                   quad->set_refinement_case(aniso_quad_ref_case);
+             
+                                                    // finally clear flag
+                                                    // indicating the need
+                                                    // for refinement
+                   quad->clear_user_data ();
+                 } // if (anisotropic refinement)
 
+               if (quad->user_flag_set())
+                 {
+                                                    // this quad needs to be
+                                                    // refined isotropically
+
+                                                    // first of all: we only get here
+                                                    // in the first run of the loop
+                   Assert(loop==0,ExcInternalError());
+
+                                                    // find the next unused
+                                                    // vertex. we'll need this in any
+                                                    // case
+                   while (triangulation.vertices_used[next_unused_vertex] == true)
+                     ++next_unused_vertex;
+                   Assert (next_unused_vertex < triangulation.vertices.size(),
+                           ExcTooFewVerticesAllocated());
+           
+                                                    // now: if the quad is refined
+                                                    // anisotropically already, set
+                                                    // the anisotropic refinement
+                                                    // flag for both
+                                                    // children. Additionally, we
+                                                    // have to refine the inner line,
+                                                    // as it is an outer line of the
+                                                    // two (anisotropic) children
+                   const RefinementCase<dim-1> quad_ref_case=quad->refinement_case();
+           
+                   if (quad_ref_case==RefinementCase<dim-1>::cut_x ||
+                       quad_ref_case==RefinementCase<dim-1>::cut_y)
+                     {
+                                                        // set the 'opposite' refine case for children
+                       quad->child(0)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
+                       quad->child(1)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
+                                                        // refine the inner line
+                       line_iterator middle_line;
+                       if (quad_ref_case==RefinementCase<dim-1>::cut_x)
+                         middle_line=quad->child(0)->line(1);
+                       else
+                         middle_line=quad->child(0)->line(3);
+
+                                                        // if the face has been
+                                                        // refined anisotropically in
+                                                        // the last refinement step
+                                                        // it might be, that it is
+                                                        // flagged already and that
+                                                        // the middle line is thus
+                                                        // refined already. if not
+                                                        // create children.
+                       if (!middle_line->has_children())
+                         {
+                                                            // set the middle vertex
+                                                            // appropriately. double
+                                                            // refinement of quads can only
+                                                            // happen in the interior of
+                                                            // the domain, so we need not
+                                                            // care about boundary quads
+                                                            // here
+                           triangulation.vertices[next_unused_vertex]
+                             = (middle_line->vertex(0) + middle_line->vertex(1)) / 2;
+                           triangulation.vertices_used[next_unused_vertex] = true;
+                     
+                                                            // now search a slot for the two
+                                                            // child lines
+                           next_unused_line=triangulation.faces->lines.next_free_pair_line(triangulation);
+                     
+                                                            // set the child
+                                                            // pointer of the present
+                                                            // line
+                           middle_line->set_children (0, next_unused_line->index());
+                     
+                                                            // set the two new lines
+                           const raw_line_iterator children[2] = { next_unused_line,
+                                                                   ++next_unused_line };
+                                                            // some tests; if any of
+                                                            // the iterators should
+                                                            // be invalid, then
+                                                            // already dereferencing
+                                                            // will fail
+                           Assert (children[0]->used() == false, ExcCellShouldBeUnused());
+                           Assert (children[1]->used() == false, ExcCellShouldBeUnused());
+                     
+                           children[0]->set (internal::Triangulation::
+                                             TriaObject<1>(middle_line->vertex_index(0),
+                                                           next_unused_vertex));
+                           children[1]->set (internal::Triangulation::
+                                             TriaObject<1>(next_unused_vertex,
+                                                           middle_line->vertex_index(1)));
+                     
+                           children[0]->set_used_flag();
+                           children[1]->set_used_flag();
+                           children[0]->clear_children();
+                           children[1]->clear_children();
+                           children[0]->clear_user_data();
+                           children[1]->clear_user_data();
+                           children[0]->clear_user_flag();
+                           children[1]->clear_user_flag();
+                     
+                           children[0]->set_boundary_indicator (middle_line->boundary_indicator());
+                           children[1]->set_boundary_indicator (middle_line->boundary_indicator());
+                         }
+                                                        // now remove the flag from the
+                                                        // quad and go to the next
+                                                        // quad, the actual refinement
+                                                        // of the quad takes place
+                                                        // later on in this pass of the
+                                                        // loop or in the next one
+                       quad->clear_user_flag();
+                       continue;
+                     } // if (several refinement cases)
+
+                                                    // if we got here, we have an
+                                                    // unrefined quad and have to do
+                                                    // the usual work like in an purely
+                                                    // isotropic refinement
+                   Assert(quad_ref_case==RefinementCase<dim-1>::no_refinement, ExcInternalError());
+
+                                                    // set the middle vertex
+                                                    // appropriately
+                   if (quad->at_boundary()) 
+                     triangulation.vertices[next_unused_vertex]
+                       = triangulation.boundary[quad->boundary_indicator()]->get_new_point_on_quad (quad);
+                   else
+                                                      // it might be that the
+                                                      // quad itself is not
+                                                      // at the boundary, but
+                                                      // that one of its lines
+                                                      // actually is. in this
+                                                      // case, the newly
+                                                      // created vertices at
+                                                      // the centers of the
+                                                      // lines are not
+                                                      // necessarily the mean
+                                                      // values of the
+                                                      // adjacent vertices,
+                                                      // so do not compute
+                                                      // the new vertex as
+                                                      // the mean value of
+                                                      // the 4 vertices of
+                                                      // the face, but rather
+                                                      // as a weighted mean
+                                                      // value of the 8
+                                                      // vertices which we
+                                                      // already have (the
+                                                      // four old ones, and
+                                                      // the four ones
+                                                      // inserted as middle
+                                                      // points for the four
+                                                      // lines). summing up
+                                                      // some more points is
+                                                      // generally cheaper
+                                                      // than first asking
+                                                      // whether one of the
+                                                      // lines is at the
+                                                      // boundary
+                                                      //
+                                                      // note that the exact
+                                                      // weights are chosen
+                                                      // such as to minimize
+                                                      // the distortion of
+                                                      // the four new quads
+                                                      // from the optimal
+                                                      // shape; their
+                                                      // derivation and
+                                                      // values is copied
+                                                      // over from the
+                                                      // @p{MappingQ::set_laplace_on_vector}
+                                                      // function
+                     triangulation.vertices[next_unused_vertex]
+                       = (quad->vertex(0) + quad->vertex(1) +
+                          quad->vertex(2) + quad->vertex(3) +
+                          3*(quad->line(0)->child(0)->vertex(1) +
+                             quad->line(1)->child(0)->vertex(1) +
+                             quad->line(2)->child(0)->vertex(1) +
+                             quad->line(3)->child(0)->vertex(1))   ) / 16;
+
+                   triangulation.vertices_used[next_unused_vertex] = true;
+
+                                                    // now that we created
+                                                    // the right point, make
+                                                    // up the four lines
+                                                    // interior to the quad
+                                                    // (++ takes care of the
+                                                    // end of the vector)
+                   raw_line_iterator new_lines[4];
+
+                   for (unsigned int i=0; i<4; ++i)
+                     {
+                       if (i%2==0)
+                                                          // search a free pair of
+                                                          // lines for 0. and 2. line,
+                                                          // so that two of them end up
+                                                          // together, which is
+                                                          // necessary if later on we
+                                                          // want to refine the quad
+                                                          // anisotropically and the
+                                                          // two lines end up as
+                                                          // children of new line
+                         next_unused_line=triangulation.faces->lines.next_free_pair_line(triangulation);
+
+                       new_lines[i] = next_unused_line;
+                       ++next_unused_line;
+
+                       Assert (new_lines[i]->used() == false,
+                               ExcCellShouldBeUnused());
+                     }
 
-template <int dim>
-void Triangulation<dim>::save_user_flags_line (std::ostream &out) const
-{
-  std::vector<bool> v;
-  save_user_flags_line (v);
-  write_bool_vector (mn_tria_line_user_flags_begin, v, mn_tria_line_user_flags_end,
-                    out);
-}
+                                                    // set the data of the
+                                                    // four lines.
+                                                    // first collect the
+                                                    // indices of the five
+                                                    // vertices:
+                                                    // *--3--*
+                                                    // |  |  |
+                                                    // 0--4--1
+                                                    // |  |  |
+                                                    // *--2--*
+                                                    // the lines are numbered
+                                                    // as follows:
+                                                    // *--*--*
+                                                    // |  1  |
+                                                    // *2-*-3*
+                                                    // |  0  |
+                                                    // *--*--*
+           
+                   const unsigned int vertex_indices[5]
+                     = { quad->line(0)->child(0)->vertex_index(1),
+                         quad->line(1)->child(0)->vertex_index(1),
+                         quad->line(2)->child(0)->vertex_index(1),
+                         quad->line(3)->child(0)->vertex_index(1),
+                         next_unused_vertex 
+                   };
+             
+                   new_lines[0]->set (internal::Triangulation::
+                                      TriaObject<1>(vertex_indices[2], vertex_indices[4]));
+                   new_lines[1]->set (internal::Triangulation::
+                                      TriaObject<1>(vertex_indices[4], vertex_indices[3]));
+                   new_lines[2]->set (internal::Triangulation::
+                                      TriaObject<1>(vertex_indices[0], vertex_indices[4]));
+                   new_lines[3]->set (internal::Triangulation::
+                                      TriaObject<1>(vertex_indices[4], vertex_indices[1]));
+
+                   for (unsigned int i=0; i<4; ++i)
+                     {
+                       new_lines[i]->set_used_flag();
+                       new_lines[i]->clear_user_flag();
+                       new_lines[i]->clear_user_data();
+                       new_lines[i]->clear_children();
+                       new_lines[i]->set_boundary_indicator(quad->boundary_indicator());
+                     }
+             
+                                                    // now for the
+                                                    // quads. again, first
+                                                    // collect some data
+                                                    // about the indices of
+                                                    // the lines, with the
+                                                    // following numbering:
+                                                    //   .-6-.-7-.
+                                                    //   1   9   3
+                                                    //   .-10.11-.
+                                                    //   0   8   2
+                                                    //   .-4-.-5-.
+
+                                                    // child 0 and 1 of a line are
+                                                    // switched if the line orientation
+                                                    // is false. set up a miniature
+                                                    // table, indicating which child to
+                                                    // take for line orientations false
+                                                    // and true. first index: child
+                                                    // index in standard orientation,
+                                                    // second index: line orientation
+                   const unsigned int index[2][2]=
+                     {{1,0},   // child 0, line_orientation=false and true
+                      {0,1}};  // child 1, line_orientation=false and true
+                   
+                   const unsigned int line_indices[12]
+                     = { quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
+                         quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
+                         quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
+                         quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
+                         quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
+                         quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
+                         quad->line(3)->child(index[0][quad->line_orientation(3)])->index(),
+                         quad->line(3)->child(index[1][quad->line_orientation(3)])->index(),
+                         new_lines[0]->index(),
+                         new_lines[1]->index(),
+                         new_lines[2]->index(),
+                         new_lines[3]->index() 
+                   };
+           
+                                                    // find some space (consecutive)
+                                                    // for the first two newly to be
+                                                    // created quads.
+                   raw_quad_iterator new_quads[4];
 
+                   next_unused_quad=triangulation.faces->quads.next_free_pair_quad(triangulation);
+           
+                   new_quads[0] = next_unused_quad;
+                   Assert (new_quads[0]->used() == false, ExcCellShouldBeUnused());
+
+                   ++next_unused_quad;
+                   new_quads[1] = next_unused_quad;
+                   Assert (new_quads[1]->used() == false, ExcCellShouldBeUnused());
+
+                   next_unused_quad=triangulation.faces->quads.next_free_pair_quad(triangulation);
+                   new_quads[2] = next_unused_quad;
+                   Assert (new_quads[2]->used() == false, ExcCellShouldBeUnused());
+
+                   ++next_unused_quad;
+                   new_quads[3] = next_unused_quad;
+                   Assert (new_quads[3]->used() == false, ExcCellShouldBeUnused());
+
+                                                    // note these quads as
+                                                    // children to the
+                                                    // present one
+                   quad->set_children (0, new_quads[0]->index());
+                   quad->set_children (2, new_quads[2]->index());
+                   new_quads[0]->set (internal::Triangulation
+                                      ::TriaObject<2>(line_indices[0],
+                                                      line_indices[8],
+                                                      line_indices[4],
+                                                      line_indices[10]));
+             
+                   quad->set_refinement_case(RefinementCase<2>::cut_xy);
+
+                   new_quads[0]->set (internal::Triangulation
+                                      ::TriaObject<2>(line_indices[0],
+                                                      line_indices[8],
+                                                      line_indices[4],
+                                                      line_indices[10]));
+                   new_quads[1]->set (internal::Triangulation
+                                      ::TriaObject<2>(line_indices[8],
+                                                      line_indices[2],
+                                                      line_indices[5],
+                                                      line_indices[11]));
+                   new_quads[2]->set (internal::Triangulation
+                                      ::TriaObject<2>(line_indices[1],
+                                                      line_indices[9],
+                                                      line_indices[10],
+                                                      line_indices[6]));
+                   new_quads[3]->set (internal::Triangulation
+                                      ::TriaObject<2>(line_indices[9],
+                                                      line_indices[3],
+                                                      line_indices[11],
+                                                      line_indices[7]));
+                   for (unsigned int i=0; i<4; ++i)
+                     {
+                       new_quads[i]->set_used_flag();
+                       new_quads[i]->clear_user_flag();
+                       new_quads[i]->clear_user_data();
+                       new_quads[i]->clear_children();
+                       new_quads[i]->set_boundary_indicator (quad->boundary_indicator());
+                                                        // set all line orientations to
+                                                        // true, change this after the
+                                                        // loop, as we have to consider
+                                                        // different lines for each
+                                                        // child
+                       for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
+                         new_quads[i]->set_line_orientation(j,true);
+                     }
+                                                    // now set the line orientation of
+                                                    // children of outer lines
+                                                    // correctly, the lines in the
+                                                    // interior of the refined quad are
+                                                    // automatically oriented
+                                                    // conforming to the standard
+                   new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
+                   new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
+                   new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
+                   new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
+                   new_quads[2]->set_line_orientation(0,quad->line_orientation(0));
+                   new_quads[2]->set_line_orientation(3,quad->line_orientation(3));
+                   new_quads[3]->set_line_orientation(1,quad->line_orientation(1));
+                   new_quads[3]->set_line_orientation(3,quad->line_orientation(3));
+                                      
+                                                    // finally clear flag
+                                                    // indicating the need
+                                                    // for refinement
+                   quad->clear_user_flag ();
+                 } // if (isotropic refinement)
+             } // for all quads
+         } // looped two times over all quads, all quads refined now
+
+                                        ///////////////////////////////////
+                                        // Now, finally, set up the new
+                                        // cells
+                                        ///////////////////////////////////
+       for (unsigned int level=0; level!=triangulation.levels.size()-1; ++level)
+         {
+                                            // only active objects can be
+                                            // refined further; remember
+                                            // that we won't operate on the
+                                            // finest level, so
+                                            // triangulation.begin_*(level+1) is allowed
+           active_hex_iterator hex  = triangulation.begin_active_hex(level),
+                               endh = triangulation.begin_active_hex(level+1);
+           raw_line_iterator next_unused_line = triangulation.begin_raw_line ();
+           raw_quad_iterator next_unused_quad = triangulation.begin_raw_quad ();
+           raw_hex_iterator  next_unused_hex  = triangulation.begin_raw_hex (level+1);
+
+           for (; hex!=endh; ++hex)
+             if (hex->refine_flag_set())
+               {
+                                                  // this hex needs to be
+                                                  // refined
+           
+                                                  // clear flag indicating
+                                                  // the need for
+                                                  // refinement. do it here
+                                                  // already, since we
+                                                  // can't do it anymore
+                                                  // once the cell has
+                                                  // children
+                 const RefinementCase<dim> ref_case=hex->refine_flag_set();
+                 hex->clear_refine_flag ();
+                 hex->set_refinement_case(ref_case);
+
+                                                  // depending on the refine case we
+                                                  // might have to create additional
+                                                  // vertices, lines and quads
+                                                  // interior of the hex before the
+                                                  // actual children can be set up.
+
+                                                  // in a first step: reserve the
+                                                  // needed space for lines, quads
+                                                  // and hexes and initialize them
+                                                  // correctly
+
+                 unsigned int n_new_lines=0;
+                 unsigned int n_new_quads=0;
+                 unsigned int n_new_hexes=0;
+                 switch (ref_case)
+                   {
+                     case RefinementCase<dim>::cut_x:
+                     case RefinementCase<dim>::cut_y:
+                     case RefinementCase<dim>::cut_z:
+                           n_new_lines=0;
+                           n_new_quads=1;
+                           n_new_hexes=2;
+                           break;
+                     case RefinementCase<dim>::cut_xy:
+                     case RefinementCase<dim>::cut_xz:
+                     case RefinementCase<dim>::cut_yz:
+                           n_new_lines=1;
+                           n_new_quads=4;
+                           n_new_hexes=4;
+                           break;
+                     case RefinementCase<dim>::cut_xyz:
+                           n_new_lines=6;
+                           n_new_quads=12;
+                           n_new_hexes=8;
+                           break;
+                     default:
+                           Assert(false, ExcInternalError());
+                           break;
+                   }
+           
+                                                  // find some space for the newly to
+                                                  // be created interior lines and
+                                                  // initialize them.
+                 std::vector<raw_line_iterator> new_lines(n_new_lines);
+                 for (unsigned int i=0; i<n_new_lines; ++i)
+                   {
+                     new_lines[i] = triangulation.faces->lines.next_free_single_line(triangulation);
+               
+                     Assert (new_lines[i]->used() == false,
+                             ExcCellShouldBeUnused());
+                     new_lines[i]->set_used_flag();
+                     new_lines[i]->clear_user_flag();
+                     new_lines[i]->clear_user_data();
+                     new_lines[i]->clear_children();
+                                                      // interior line
+                     new_lines[i]->set_boundary_indicator(255);
+                   }
 
+                                                  // find some space for the newly to
+                                                  // be created interior quads and
+                                                  // initialize them.
+                 std::vector<raw_quad_iterator> new_quads(n_new_quads);
+                 for (unsigned int i=0; i<n_new_quads; ++i)
+                   {
+                     new_quads[i] = triangulation.faces->quads.next_free_single_quad(triangulation);
+               
+                     Assert (new_quads[i]->used() == false,
+                             ExcCellShouldBeUnused());
+                     new_quads[i]->set_used_flag();
+                     new_quads[i]->clear_user_flag();
+                     new_quads[i]->clear_user_data();
+                     new_quads[i]->clear_children();
+                                                      // interior quad
+                     new_quads[i]->set_boundary_indicator (255);
+                                                      // set all line orientation
+                                                      // flags to true by default,
+                                                      // change this afterwards, if
+                                                      // necessary
+                     for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
+                       new_quads[i]->set_line_orientation(j,true);
+                   }
 
-template <int dim>
-void Triangulation<dim>::load_user_flags_line (std::istream &in)
-{
-  std::vector<bool> v;
-  read_bool_vector (mn_tria_line_user_flags_begin, v, mn_tria_line_user_flags_end,
-                   in);
-  load_user_flags_line (v);
-}
+                                                  // find some space for the newly to
+                                                  // be created hexes and initialize
+                                                  // them.
+                 std::vector<raw_hex_iterator> new_hexes(n_new_hexes);
+                 for (unsigned int i=0; i<n_new_hexes; ++i)
+                   {
+                     if (i%2==0)
+                       next_unused_hex=triangulation.levels[level+1]->cells.next_free_hex(triangulation,level+1);
+                     else
+                       ++next_unused_hex;
+               
+                     new_hexes[i]=next_unused_hex;
+               
+                     Assert (new_hexes[i]->used() == false,
+                             ExcCellShouldBeUnused());
+                     new_hexes[i]->set_used_flag();
+                     new_hexes[i]->clear_user_flag();
+                     new_hexes[i]->clear_user_data();
+                     new_hexes[i]->clear_children();
+                                                      // inherit material
+                                                      // properties
+                     new_hexes[i]->set_material_id (hex->material_id());
+                     new_hexes[i]->set_subdomain_id (hex->subdomain_id());
+                                                      // set the face_orientation
+                                                      // flag to true for all faces
+                                                      // initially, as this is the
+                                                      // default value which is true
+                                                      // for all faces interior to
+                                                      // the hex. later on go the
+                                                      // other way round and reset
+                                                      // faces that are at the
+                                                      // boundary of the mother cube
+                                                      //
+                                                      // the same is true for the
+                                                      // face_flip and face_rotation
+                                                      // flags. however, the latter
+                                                      // two are set to false by
+                                                      // default as this is the
+                                                      // standard value
+                     for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+                       {
+                         new_hexes[i]->set_face_orientation(f, true);
+                         new_hexes[i]->set_face_flip(f, false);
+                         new_hexes[i]->set_face_rotation(f, false);
+                       }
+                   }
+                                                  // note these hexes as
+                                                  // children to the
+                                                  // present cell
+                 for (unsigned int i=0; i<n_new_hexes/2; ++i) 
+                   hex->set_children (2*i, new_hexes[2*i]->index());
+
+                                                  // we have to take into account
+                                                  // whether the different faces are
+                                                  // oriented correctly or in the
+                                                  // opposite direction, so store
+                                                  // that up front
+
+                                                  // face_orientation
+                 const bool f_or[6]
+                   = { hex->face_orientation (0),
+                       hex->face_orientation (1),
+                       hex->face_orientation (2),
+                       hex->face_orientation (3),
+                       hex->face_orientation (4),
+                       hex->face_orientation (5) };
+                    
+                                                  // face_flip
+                 const bool f_fl[6]
+                   = { hex->face_flip (0),
+                       hex->face_flip (1),
+                       hex->face_flip (2),
+                       hex->face_flip (3),
+                       hex->face_flip (4),
+                       hex->face_flip (5) };
+                    
+                                                  // face_rotation
+                 const bool f_ro[6]
+                   = { hex->face_rotation (0),
+                       hex->face_rotation (1),
+                       hex->face_rotation (2),
+                       hex->face_rotation (3),
+                       hex->face_rotation (4),
+                       hex->face_rotation (5) };
+
+                                                  // some commonly used fields which
+                                                  // have varying size
+                 const unsigned int *vertex_indices=0;
+                 const raw_line_iterator *lines=0;
+                 const unsigned int *line_indices=0;
+                 const bool *line_orientation=0;
+                 const unsigned int *quad_indices=0;
+
+                                                  // little helper table, indicating,
+                                                  // whether the child with index 0
+                                                  // or with index 1 can be found at
+                                                  // the standard origin of an
+                                                  // anisotropically refined quads in
+                                                  // real orientation
+                                                  // index 1: (RefineCase - 1)
+                                                  // index 2: face_flip
+
+                                                  // index 3: face rotation
+                                                  // note: face orientation has no influence
+                 const unsigned int child_at_origin[2][2][2]=
+                   { { { 0, 0 },  // RefinementCase<dim>::cut_x, face_flip=false, face_rotation=false and true
+                       { 1, 1 }}, // RefinementCase<dim>::cut_x, face_flip=true,  face_rotation=false and true
+                     { { 0, 1 },  // RefinementCase<dim>::cut_y, face_flip=false, face_rotation=false and true
+                       { 1, 0 }}};// RefinementCase<dim>::cut_y, face_flip=true,  face_rotation=false and true
+            
+                                                  ///////////////////////////////////////
+                                                  //
+                                                  // in the following we will do the
+                                                  // same thing for each refinement
+                                                  // case: create a new vertex (if
+                                                  // needed), create new interior
+                                                  // lines (if needed), create new
+                                                  // interior quads and afterwards
+                                                  // build the children hexes out of
+                                                  // these and the existing subfaces
+                                                  // of the outer quads (which have
+                                                  // been created above). However,
+                                                  // even if the steps are quite
+                                                  // similar, the actual work
+                                                  // strongly depends on the actual
+                                                  // refinement case. therefore, we
+                                                  // use seperate blocks of code for
+                                                  // each of these cases, which
+                                                  // hopefully increases the
+                                                  // readability to some extend.
+
+                 switch (ref_case)
+                   {
+                     case RefinementCase<dim>::cut_x:
+                     {
+                                                        //////////////////////////////
+                                                        //
+                                                        //     RefinementCase<dim>::cut_x
+                                                        //
+                                                        // the refined cube will look
+                                                        // like this:
+                                                        //
+                                                        //        *----*----*
+                                                        //       /    /    /|
+                                                        //      /    /    / |
+                                                        //     /    /    /  |
+                                                        //    *----*----*   |
+                                                        //    |    |    |   |
+                                                        //    |    |    |   *
+                                                        //    |    |    |  /
+                                                        //    |    |    | /
+                                                        //    |    |    |/
+                                                        //    *----*----*
+                                                        // 
+                                                        // again, first
+                                                        // collect some data
+                                                        // about the indices of
+                                                        // the lines, with the
+                                                        // following numbering:
+           
+                                                        // face 2: front plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *---*---*
+                                                        //   |   |   |
+                                                        //   |   0   |
+                                                        //   |   |   |
+                                                        //   *---*---*
+                                                        //       m0
+                                                        // face 3: back plane
+                                                        //   (note: x,y exchanged)
+                                                        //       m1
+                                                        //   *---*---*
+                                                        //   |   |   | 
+                                                        //   |   1   |
+                                                        //   |   |   | 
+                                                        //   *---*---*
+                                                        // face 4: bottom plane
+                                                        //       *---*---*
+                                                        //      /   /   /
+                                                        //     /   2   /
+                                                        //    /   /   /
+                                                        //   *---*---*
+                                                        //       m0
+                                                        // face 5: top plane
+                                                        //           m1
+                                                        //       *---*---*
+                                                        //      /   /   /
+                                                        //     /   3   /
+                                                        //    /   /   /
+                                                        //   *---*---*
+
+                                                        // set up a list of line iterators
+                                                        // first. from this, construct
+                                                        // lists of line_indices and
+                                                        // line orientations later on
+                       const raw_line_iterator lines_x[4]
+                         = {
+                             hex->face(2)->child(0)
+                             ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
+                             hex->face(3)->child(0)
+                             ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
+                             hex->face(4)->child(0)
+                             ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
+                             hex->face(5)->child(0)
+                             ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3)         //3
+                       };
+                 
+                       lines=&lines_x[0];
+                 
+                       unsigned int line_indices_x[4];
+                     
+                       for (unsigned int i=0; i<4; ++i)
+                         line_indices_x[i]=lines[i]->index();
+                       line_indices=&line_indices_x[0];
+
+                                                        // the orientation of lines for the
+                                                        // inner quads is quite tricky. as
+                                                        // these lines are newly created
+                                                        // ones and thus have no parents,
+                                                        // they cannot inherit this
+                                                        // property. set up an array and
+                                                        // fill it with the respective
+                                                        // values
+                       bool line_orientation_x[4];
+
+                                                        // the middle vertice marked
+                                                        // as m0 above is the start
+                                                        // vertex for lines 0 and 2
+                                                        // in standard orientation,
+                                                        // whereas m1 is the end
+                                                        // vertex of lines 1 and 3 in
+                                                        // standard orientation
+                       const unsigned int middle_vertices[2]=
+                         {
+                               hex->line(2)->child(0)->vertex_index(1),
+                               hex->line(7)->child(0)->vertex_index(1)
+                         };
 
+                       for (unsigned int i=0; i<4; ++i)
+                         if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
+                           line_orientation_x[i]=true;
+                         else
+                           {
+                                                              // it must be the other
+                                                              // way round then
+                             Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
+                                    ExcInternalError());
+                             line_orientation_x[i]=false;
+                           }
+                 
+                       line_orientation=&line_orientation_x[0];
+
+                                                        // set up the new quad, line
+                                                        // numbering is as indicated
+                                                        // above
+                       new_quads[0]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[0],
+                                                          line_indices[1],
+                                                          line_indices[2],
+                                                          line_indices[3]));
+
+                       new_quads[0]->set_line_orientation(0,line_orientation[0]);
+                       new_quads[0]->set_line_orientation(1,line_orientation[1]);
+                       new_quads[0]->set_line_orientation(2,line_orientation[2]);
+                       new_quads[0]->set_line_orientation(3,line_orientation[3]);
+                 
+                                                        // the quads are
+                                                        // numbered as follows:
+                                                        //
+                                                        // planes in the interior
+                                                        // of the old hex:
+                                                        //      *
+                                                        //     /|
+                                                        //    / | x         
+                                                        //   /  | *-------*      *---------*
+                                                        //  *   | |       |     /         /
+                                                        //  | 0 | |       |    /         /
+                                                        //  |   * |       |   /         /
+                                                        //  |  /  *-------*y *---------*x
+                                                        //  | /
+                                                        //  |/
+                                                        //  *
+                                                        //
+                                                        // children of the faces
+                                                        // of the old hex
+                                                        //      *---*---*        *---*---*
+                                                        //     /|   |   |       /   /   /|
+                                                        //    / |   |   |      / 9 / 10/ |
+                                                        //   /  | 5 | 6 |     /   /   /  |
+                                                        //  *   |   |   |    *---*---*   |
+                                                        //  | 1 *---*---*    |   |   | 2 *
+                                                        //  |  /   /   /     |   |   |  /
+                                                        //  | / 7 / 8 /      | 3 | 4 | /
+                                                        //  |/   /   /       |   |   |/
+                                                        //  *---*---*        *---*---*
+                                                        //
+                                                        // note that we have to
+                                                        // take care of the
+                                                        // orientation of
+                                                        // faces.
+                       const unsigned int quad_indices_x[11]
+                         = {
+                             new_quads[0]->index(),     //0
+                             
+                             hex->face(0)->index(),     //1
+                         
+                             hex->face(1)->index(),     //2
 
+                             hex->face(2)->child_index(  child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),  //3
+                             hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
+                             
+                             hex->face(3)->child_index(  child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),  //5
+                             hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
+                             
+                             hex->face(4)->child_index(  child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),  //7
+                             hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
+                             
+                             hex->face(5)->child_index(  child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]),  //9
+                             hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
+                             
+                       };
+                       quad_indices=&quad_indices_x[0];
+
+                       new_hexes[0]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[1],
+                                                          quad_indices[0],
+                                                          quad_indices[3],
+                                                          quad_indices[5],
+                                                          quad_indices[7],
+                                                          quad_indices[9]));
+                       new_hexes[1]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[0],
+                                                          quad_indices[2],
+                                                          quad_indices[4],
+                                                          quad_indices[6],
+                                                          quad_indices[8],
+                                                          quad_indices[10]));
+                       break;
+                     }
+                     case RefinementCase<dim>::cut_y:
+                     {
+                                                        //////////////////////////////
+                                                        //
+                                                        //     RefinementCase<dim>::cut_y
+                                                        //
+                                                        // the refined cube will look
+                                                        // like this:
+                                                        //
+                                                        //        *---------*
+                                                        //       /         /|
+                                                        //      *---------* |
+                                                        //     /         /| |
+                                                        //    *---------* | |
+                                                        //    |         | | |
+                                                        //    |         | | *
+                                                        //    |         | |/
+                                                        //    |         | *
+                                                        //    |         |/
+                                                        //    *---------*
+                                                        // 
+                                                        // again, first
+                                                        // collect some data
+                                                        // about the indices of
+                                                        // the lines, with the
+                                                        // following numbering:
+           
+                                                        // face 0: left plane
+                                                        //       *
+                                                        //      /| 
+                                                        //     * |
+                                                        //    /| |
+                                                        //   * | |
+                                                        //   | 0 |
+                                                        //   | | *
+                                                        //   | |/ 
+                                                        //   | *m0
+                                                        //   |/   
+                                                        //   *    
+                                                        // face 1: right plane
+                                                        //       *
+                                                        //      /| 
+                                                        //   m1* |
+                                                        //    /| |
+                                                        //   * | |
+                                                        //   | 1 |
+                                                        //   | | *
+                                                        //   | |/ 
+                                                        //   | *  
+                                                        //   |/   
+                                                        //   *    
+                                                        // face 4: bottom plane
+                                                        //       *-------*
+                                                        //      /       /
+                                                        //   m0*---2---*
+                                                        //    /       /
+                                                        //   *-------*
+                                                        // face 5: top plane
+                                                        //       *-------*
+                                                        //      /       /
+                                                        //     *---3---*m1
+                                                        //    /       /
+                                                        //   *-------*
+
+                                                        // set up a list of line iterators
+                                                        // first. from this, construct
+                                                        // lists of line_indices and
+                                                        // line orientations later on
+                       const raw_line_iterator lines_y[4]
+                         = {
+                             hex->face(0)->child(0)
+                             ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
+                             hex->face(1)->child(0)
+                             ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
+                             hex->face(4)->child(0)
+                             ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
+                             hex->face(5)->child(0)
+                             ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3)         //3
+                       };
+                 
+                       lines=&lines_y[0];
+                 
+                       unsigned int line_indices_y[4];
+                     
+                       for (unsigned int i=0; i<4; ++i)
+                         line_indices_y[i]=lines[i]->index();
+                       line_indices=&line_indices_y[0];
+
+                                                        // the orientation of lines for the
+                                                        // inner quads is quite tricky. as
+                                                        // these lines are newly created
+                                                        // ones and thus have no parents,
+                                                        // they cannot inherit this
+                                                        // property. set up an array and
+                                                        // fill it with the respective
+                                                        // values
+                       bool line_orientation_y[4];
+
+                                                        // the middle vertice marked
+                                                        // as m0 above is the start
+                                                        // vertex for lines 0 and 2
+                                                        // in standard orientation,
+                                                        // whereas m1 is the end
+                                                        // vertex of lines 1 and 3 in
+                                                        // standard orientation
+                       const unsigned int middle_vertices[2]=
+                         {
+                               hex->line(0)->child(0)->vertex_index(1),
+                               hex->line(5)->child(0)->vertex_index(1)
+                         };
 
-template <int dim>
-void Triangulation<dim>::load_user_flags_line (const std::vector<bool> &v)
-{
-  Assert (v.size() == n_lines(), ExcGridReadError());
-  
-  line_iterator line = begin_line(),
-               endl = end_line();
-  std::vector<bool>::const_iterator i = v.begin();
-  for (; line!=endl; ++line, ++i)
-    if (*i == true)
-      line->set_user_flag();
-    else
-      line->clear_user_flag();
-}
+                       for (unsigned int i=0; i<4; ++i)
+                         if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
+                           line_orientation_y[i]=true;
+                         else
+                           {
+                                                              // it must be the other way round then
+                             Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
+                                    ExcInternalError());
+                             line_orientation_y[i]=false;
+                           }
+                 
+                       line_orientation=&line_orientation_y[0];
+
+                                                        // set up the new quad, line
+                                                        // numbering is as indicated
+                                                        // above
+                       new_quads[0]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[2],
+                                                          line_indices[3],
+                                                          line_indices[0],
+                                                          line_indices[1]));
+
+                       new_quads[0]->set_line_orientation(0,line_orientation[2]);
+                       new_quads[0]->set_line_orientation(1,line_orientation[3]);
+                       new_quads[0]->set_line_orientation(2,line_orientation[0]);
+                       new_quads[0]->set_line_orientation(3,line_orientation[1]);
+
+                                                        // the quads are
+                                                        // numbered as follows:
+                                                        //
+                                                        // planes in the interior
+                                                        // of the old hex:
+                                                        //      *
+                                                        //     /|
+                                                        //    / | x         
+                                                        //   /  | *-------*      *---------*
+                                                        //  *   | |       |     /         /
+                                                        //  |   | |   0   |    /         /
+                                                        //  |   * |       |   /         /
+                                                        //  |  /  *-------*y *---------*x
+                                                        //  | /
+                                                        //  |/
+                                                        //  *
+                                                        //
+                                                        // children of the faces
+                                                        // of the old hex
+                                                        //      *-------*        *-------*
+                                                        //     /|       |       /   10  /|
+                                                        //    * |       |      *-------* |
+                                                        //   /| |   6   |     /   9   /| |
+                                                        //  * |2|       |    *-------* |4|
+                                                        //  | | *-------*    |       | | *
+                                                        //  |1|/   8   /     |       |3|/
+                                                        //  | *-------*      |   5   | *
+                                                        //  |/   7   /       |       |/
+                                                        //  *-------*        *-------*
+                                                        //
+                                                        // note that we have to
+                                                        // take care of the
+                                                        // orientation of
+                                                        // faces.
+                       const unsigned int quad_indices_y[11]
+                         = {
+                             new_quads[0]->index(),     //0
+                             
+                             hex->face(0)->child_index(  child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),  //1
+                             hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
+                             
+                             hex->face(1)->child_index(  child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),  //3
+                             hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
+                             
+                             hex->face(2)->index(),     //5
+                         
+                             hex->face(3)->index(),     //6
 
+                             hex->face(4)->child_index(  child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),  //7
+                             hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
+                             
+                             hex->face(5)->child_index(  child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]),  //9
+                             hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
+                             
+                       };
+                       quad_indices=&quad_indices_y[0];
+
+                       new_hexes[0]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[1],
+                                                          quad_indices[3],
+                                                          quad_indices[5],
+                                                          quad_indices[0],
+                                                          quad_indices[7],
+                                                          quad_indices[9]));
+                       new_hexes[1]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[2],
+                                                          quad_indices[4],
+                                                          quad_indices[0],
+                                                          quad_indices[6],
+                                                          quad_indices[8],
+                                                          quad_indices[10]));
+                       break;
+                     }
+                     case RefinementCase<dim>::cut_z:
+                     {
+                                                        //////////////////////////////
+                                                        //
+                                                        //     RefinementCase<dim>::cut_z
+                                                        //
+                                                        // the refined cube will look
+                                                        // like this:
+                                                        //
+                                                        //        *---------*
+                                                        //       /         /|
+                                                        //      /         / |
+                                                        //     /         /  *
+                                                        //    *---------*  /|
+                                                        //    |         | / |
+                                                        //    |         |/  *
+                                                        //    *---------*  /
+                                                        //    |         | /
+                                                        //    |         |/
+                                                        //    *---------*
+                                                        // 
+                                                        // again, first
+                                                        // collect some data
+                                                        // about the indices of
+                                                        // the lines, with the
+                                                        // following numbering:
+           
+                                                        // face 0: left plane
+                                                        //       *
+                                                        //      /| 
+                                                        //     / |
+                                                        //    /  *
+                                                        //   *  /|
+                                                        //   | 0 |
+                                                        //   |/  *
+                                                        // m0*  / 
+                                                        //   | /  
+                                                        //   |/   
+                                                        //   *    
+                                                        // face 1: right plane
+                                                        //       *
+                                                        //      /| 
+                                                        //     / |
+                                                        //    /  *m1
+                                                        //   *  /|
+                                                        //   | 1 |
+                                                        //   |/  *
+                                                        //   *  / 
+                                                        //   | /  
+                                                        //   |/   
+                                                        //   *    
+                                                        // face 2: front plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *-------*
+                                                        //   |       |
+                                                        // m0*---2---*
+                                                        //   |       |
+                                                        //   *-------*
+                                                        // face 3: back plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *-------*
+                                                        //   |       | 
+                                                        //   *---3---*m1
+                                                        //   |       | 
+                                                        //   *-------*
+
+                                                        // set up a list of line iterators
+                                                        // first. from this, construct
+                                                        // lists of line_indices and
+                                                        // line orientations later on
+                       const raw_line_iterator lines_z[4]
+                         = {
+                             hex->face(0)->child(0)
+                             ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
+                             hex->face(1)->child(0)
+                             ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
+                             hex->face(2)->child(0)
+                             ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
+                             hex->face(3)->child(0)
+                             ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3)         //3
+                       };
+                 
+                       lines=&lines_z[0];
+                 
+                       unsigned int line_indices_z[4];
+                     
+                       for (unsigned int i=0; i<4; ++i)
+                         line_indices_z[i]=lines[i]->index();
+                       line_indices=&line_indices_z[0];
+
+                                                        // the orientation of lines for the
+                                                        // inner quads is quite tricky. as
+                                                        // these lines are newly created
+                                                        // ones and thus have no parents,
+                                                        // they cannot inherit this
+                                                        // property. set up an array and
+                                                        // fill it with the respective
+                                                        // values
+                       bool line_orientation_z[4];
+
+                                                        // the middle vertex marked
+                                                        // as m0 above is the start
+                                                        // vertex for lines 0 and 2
+                                                        // in standard orientation,
+                                                        // whereas m1 is the end
+                                                        // vertex of lines 1 and 3 in
+                                                        // standard orientation
+                       const unsigned int middle_vertices[2]=
+                         {
+                               middle_vertex_index<dim,spacedim>(hex->line(8)),
+                               middle_vertex_index<dim,spacedim>(hex->line(11))
+                         };
 
-#if deal_II_dimension == 1
+                       for (unsigned int i=0; i<4; ++i)
+                         if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
+                           line_orientation_z[i]=true;
+                         else
+                           {
+                                                              // it must be the other way round then
+                             Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
+                                    ExcInternalError());
+                             line_orientation_z[i]=false;
+                           }
+                 
+                       line_orientation=&line_orientation_z[0];
+
+                                                        // set up the new quad, line
+                                                        // numbering is as indicated
+                                                        // above
+                       new_quads[0]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[0],
+                                                          line_indices[1],
+                                                          line_indices[2],
+                                                          line_indices[3]));
+                 
+                       new_quads[0]->set_line_orientation(0,line_orientation[0]);
+                       new_quads[0]->set_line_orientation(1,line_orientation[1]);
+                       new_quads[0]->set_line_orientation(2,line_orientation[2]);
+                       new_quads[0]->set_line_orientation(3,line_orientation[3]);
+
+                                                        // the quads are
+                                                        // numbered as follows:
+                                                        //
+                                                        // planes in the interior
+                                                        // of the old hex:
+                                                        //      *
+                                                        //     /|
+                                                        //    / | x         
+                                                        //   /  | *-------*      *---------*
+                                                        //  *   | |       |     /         /
+                                                        //  |   | |       |    /    0    /
+                                                        //  |   * |       |   /         /
+                                                        //  |  /  *-------*y *---------*x
+                                                        //  | /
+                                                        //  |/
+                                                        //  *
+                                                        //
+                                                        // children of the faces
+                                                        // of the old hex
+                                                        //      *---*---*        *-------*
+                                                        //     /|   8   |       /       /|
+                                                        //    / |       |      /   10  / |
+                                                        //   /  *-------*     /       /  *
+                                                        //  * 2/|       |    *-------* 4/|
+                                                        //  | / |   7   |    |   6   | / |
+                                                        //  |/1 *-------*    |       |/3 *
+                                                        //  *  /       /     *-------*  /
+                                                        //  | /   9   /      |       | /
+                                                        //  |/       /       |   5   |/
+                                                        //  *-------*        *---*---*
+                                                        //
+                                                        // note that we have to
+                                                        // take care of the
+                                                        // orientation of
+                                                        // faces.
+                       const unsigned int quad_indices_z[11]
+                         = {
+                             new_quads[0]->index(),     //0
+                             
+                             hex->face(0)->child_index(  child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),  //1
+                             hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
+                             
+                             hex->face(1)->child_index(  child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),  //3
+                             hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
+                             
+                             hex->face(2)->child_index(  child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),  //5
+                             hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
+                             
+                             hex->face(3)->child_index(  child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),  //7
+                             hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
+                             
+                             hex->face(4)->index(),     //9
+                         
+                             hex->face(5)->index()      //10
+                       };
+                       quad_indices=&quad_indices_z[0];
+
+                       new_hexes[0]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[1],
+                                                          quad_indices[3],
+                                                          quad_indices[5],
+                                                          quad_indices[7],
+                                                          quad_indices[9],
+                                                          quad_indices[0]));
+                       new_hexes[1]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[2],
+                                                          quad_indices[4],
+                                                          quad_indices[6],
+                                                          quad_indices[8],
+                                                          quad_indices[0],
+                                                          quad_indices[10]));
+                       break;
+                     }
+                     case RefinementCase<dim>::cut_xy:
+                     {
+                                                        //////////////////////////////
+                                                        //
+                                                        //     RefinementCase<dim>::cut_xy
+                                                        //
+                                                        // the refined cube will look
+                                                        // like this:
+                                                        //
+                                                        //        *----*----*
+                                                        //       /    /    /|
+                                                        //      *----*----* |
+                                                        //     /    /    /| |
+                                                        //    *----*----* | |
+                                                        //    |    |    | | |
+                                                        //    |    |    | | *
+                                                        //    |    |    | |/
+                                                        //    |    |    | *
+                                                        //    |    |    |/
+                                                        //    *----*----*
+                                                        // 
+
+                                                        // first, create the new
+                                                        // internal line
+                       new_lines[0]->set (internal::Triangulation::
+                                          TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(4)),
+                                                        middle_vertex_index<dim,spacedim>(hex->face(5))));
+
+                                                        // again, first
+                                                        // collect some data
+                                                        // about the indices of
+                                                        // the lines, with the
+                                                        // following numbering:
+           
+                                                        // face 0: left plane
+                                                        //       *
+                                                        //      /| 
+                                                        //     * |
+                                                        //    /| |
+                                                        //   * | |
+                                                        //   | 0 |
+                                                        //   | | *
+                                                        //   | |/ 
+                                                        //   | *  
+                                                        //   |/   
+                                                        //   *    
+                                                        // face 1: right plane
+                                                        //       *
+                                                        //      /| 
+                                                        //     * |
+                                                        //    /| |
+                                                        //   * | |
+                                                        //   | 1 |
+                                                        //   | | *
+                                                        //   | |/ 
+                                                        //   | *  
+                                                        //   |/   
+                                                        //   *    
+                                                        // face 2: front plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *---*---*
+                                                        //   |   |   |
+                                                        //   |   2   |
+                                                        //   |   |   |
+                                                        //   *-------*
+                                                        // face 3: back plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *---*---*
+                                                        //   |   |   | 
+                                                        //   |   3   |
+                                                        //   |   |   | 
+                                                        //   *---*---*
+                                                        // face 4: bottom plane
+                                                        //       *---*---*
+                                                        //      /   5   /
+                                                        //     *-6-*-7-*
+                                                        //    /   4   /
+                                                        //   *---*---*
+                                                        // face 5: top plane
+                                                        //       *---*---*
+                                                        //      /   9   /
+                                                        //     *10-*-11*
+                                                        //    /   8   /
+                                                        //   *---*---*
+                                                        // middle planes
+                                                        //     *-------*   *---*---*
+                                                        //    /       /    |   |   |
+                                                        //   /       /     |   12  |
+                                                        //  /       /      |   |   |
+                                                        // *-------*       *---*---*
+
+                                                        // set up a list of line iterators
+                                                        // first. from this, construct
+                                                        // lists of line_indices and
+                                                        // line orientations later on
+                       const raw_line_iterator lines_xy[13]
+                         = {
+                             hex->face(0)->child(0)
+                             ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
+                             hex->face(1)->child(0)
+                             ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
+                             hex->face(2)->child(0)
+                             ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
+                             hex->face(3)->child(0)
+                             ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //3
+
+                             hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])),        //4
+                             hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])),        //5
+                             hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])),        //6
+                             hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])),        //7
+                         
+                             hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])),        //8
+                             hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])),        //9
+                             hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])),        //10
+                             hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])),        //11
+
+                             new_lines[0]                        //12
+                       };
+                 
+                       lines=&lines_xy[0];
+                 
+                       unsigned int line_indices_xy[13];
+                     
+                       for (unsigned int i=0; i<13; ++i)
+                         line_indices_xy[i]=lines[i]->index();
+                       line_indices=&line_indices_xy[0];
+
+                                                        // the orientation of lines for the
+                                                        // inner quads is quite tricky. as
+                                                        // these lines are newly created
+                                                        // ones and thus have no parents,
+                                                        // they cannot inherit this
+                                                        // property. set up an array and
+                                                        // fill it with the respective
+                                                        // values
+                       bool line_orientation_xy[13];
+
+                                                        // the middle vertices of the
+                                                        // lines of our bottom face
+                       const unsigned int middle_vertices[4]=
+                         {
+                               hex->line(0)->child(0)->vertex_index(1),
+                               hex->line(1)->child(0)->vertex_index(1),
+                               hex->line(2)->child(0)->vertex_index(1),
+                               hex->line(3)->child(0)->vertex_index(1),
+                         };
+
+                                                        // note: for lines 0 to 3 the
+                                                        // orientation of the line
+                                                        // is 'true', if vertex 0 is
+                                                        // on the bottom face
+                       for (unsigned int i=0; i<4; ++i)
+                         if (lines[i]->vertex_index(0)==middle_vertices[i])
+                           line_orientation_xy[i]=true;
+                         else
+                           {
+                                                              // it must be the other way round then
+                             Assert(lines[i]->vertex_index(1)==middle_vertices[i],
+                                    ExcInternalError());
+                             line_orientation_xy[i]=false;
+                           }
+                 
+                                                        // note: for lines 4 to 11
+                                                        // (inner lines of the outer quads)
+                                                        // the following holds: the second
+                                                        // vertex of the even lines in
+                                                        // standard orientation is the
+                                                        // vertex in the middle of the
+                                                        // quad, whereas for odd lines the
+                                                        // first vertex is the same middle
+                                                        // vertex.
+                       for (unsigned int i=4; i<12; ++i)
+                         if (lines[i]->vertex_index((i+1)%2) ==
+                             middle_vertex_index<dim,spacedim>(hex->face(3+i/4)))
+                           line_orientation_xy[i]=true;
+                         else
+                           {
+                                                              // it must be the other way
+                                                              // round then
+                             Assert(lines[i]->vertex_index(i%2) ==
+                                    (middle_vertex_index<dim,spacedim>(hex->face(3+i/4))),
+                                    ExcInternalError());
+                             line_orientation_xy[i]=false;
+                           }
+                                                        // for the last line the line
+                                                        // orientation is always true,
+                                                        // since it was just constructed
+                                                        // that way
+
+                       line_orientation_xy[12]=true;
+                       line_orientation=&line_orientation_xy[0];
+
+                                                        // set up the 4 quads,
+                                                        // numbered as follows
+                                                        // (left quad numbering,
+                                                        // right line numbering
+                                                        // extracted from above)
+                                                        //
+                                                        //      *          *
+                                                        //     /|         9|
+                                                        //    * |        * |
+                                                        //  y/| |       8| 3  
+                                                        //  * |1|      * | | 
+                                                        //  | | |x     | 12|
+                                                        //  |0| *      | | * 
+                                                        //  | |/       2 |5 
+                                                        //  | *        | *
+                                                        //  |/         |4
+                                                        //  *          *
+                                                        //
+                                                        //  x
+                                                        //  *---*---*      *10-*-11*
+                                                        //  |   |   |      |   |   |
+                                                        //  | 2 | 3 |      0   12  1 
+                                                        //  |   |   |      |   |   |
+                                                        //  *---*---*y     *-6-*-7-*
+                 
+                       new_quads[0]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[2],
+                                                          line_indices[12],
+                                                          line_indices[4],
+                                                          line_indices[8]));
+                       new_quads[1]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[12],
+                                                          line_indices[3],
+                                                          line_indices[5],
+                                                          line_indices[9]));
+                       new_quads[2]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[6],
+                                                          line_indices[10],
+                                                          line_indices[0],
+                                                          line_indices[12]));
+                       new_quads[3]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[7],
+                                                          line_indices[11],
+                                                          line_indices[12],
+                                                          line_indices[1]));
+
+                       new_quads[0]->set_line_orientation(0,line_orientation[2]);
+                       new_quads[0]->set_line_orientation(2,line_orientation[4]);
+                       new_quads[0]->set_line_orientation(3,line_orientation[8]);
+                     
+                       new_quads[1]->set_line_orientation(1,line_orientation[3]);
+                       new_quads[1]->set_line_orientation(2,line_orientation[5]);
+                       new_quads[1]->set_line_orientation(3,line_orientation[9]);
+                     
+                       new_quads[2]->set_line_orientation(0,line_orientation[6]);
+                       new_quads[2]->set_line_orientation(1,line_orientation[10]);
+                       new_quads[2]->set_line_orientation(2,line_orientation[0]);
+
+                       new_quads[3]->set_line_orientation(0,line_orientation[7]);
+                       new_quads[3]->set_line_orientation(1,line_orientation[11]);
+                       new_quads[3]->set_line_orientation(3,line_orientation[1]);
+
+                                                        // the quads are
+                                                        // numbered as follows:
+                                                        //
+                                                        // planes in the interior
+                                                        // of the old hex:
+                                                        //      *
+                                                        //     /|
+                                                        //    * | x         
+                                                        //   /| | *---*---*      *---------*
+                                                        //  * |1| |   |   |     /         /
+                                                        //  | | | | 2 | 3 |    /         /
+                                                        //  |0| * |   |   |   /         /
+                                                        //  | |/  *---*---*y *---------*x
+                                                        //  | *
+                                                        //  |/
+                                                        //  *
+                                                        //
+                                                        // children of the faces
+                                                        // of the old hex
+                                                        //      *---*---*        *---*---*
+                                                        //     /|   |   |       /18 / 19/|
+                                                        //    * |10 | 11|      /---/---* |
+                                                        //   /| |   |   |     /16 / 17/| |
+                                                        //  * |5|   |   |    *---*---* |7|
+                                                        //  | | *---*---*    |   |   | | *
+                                                        //  |4|/14 / 15/     |   |   |6|/
+                                                        //  | *---/---/      | 8 | 9 | *
+                                                        //  |/12 / 13/       |   |   |/
+                                                        //  *---*---*        *---*---*
+                                                        //
+                                                        // note that we have to
+                                                        // take care of the
+                                                        // orientation of
+                                                        // faces.
+                       const unsigned int quad_indices_xy[20]
+                         = {
+                             new_quads[0]->index(),     //0
+                             new_quads[1]->index(),
+                             new_quads[2]->index(),
+                             new_quads[3]->index(),
+                             
+                             hex->face(0)->child_index(  child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),  //4
+                             hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
 
-template <>
-void Triangulation<1>::save_user_flags_quad (std::ostream &) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-}
+                             hex->face(1)->child_index(  child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),  //6
+                             hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
+                             
+                             hex->face(2)->child_index(  child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),  //8
+                             hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
+                             
+                             hex->face(3)->child_index(  child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),  //10
+                             hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
+                             
+                             hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])),  //12
+                             hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
+                             hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
+                             hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
+                             
+                             hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])),  //16
+                             hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
+                             hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
+                             hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+                       };
+                       quad_indices=&quad_indices_xy[0];
+
+                       new_hexes[0]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[4],
+                                                          quad_indices[0],
+                                                          quad_indices[8],
+                                                          quad_indices[2],
+                                                          quad_indices[12],
+                                                          quad_indices[16]));
+                       new_hexes[1]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[0],
+                                                          quad_indices[6],
+                                                          quad_indices[9],
+                                                          quad_indices[3],
+                                                          quad_indices[13],
+                                                          quad_indices[17]));
+                       new_hexes[2]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[5],
+                                                          quad_indices[1],
+                                                          quad_indices[2],
+                                                          quad_indices[10],
+                                                          quad_indices[14],
+                                                          quad_indices[18]));
+                       new_hexes[3]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[1],
+                                                          quad_indices[7],
+                                                          quad_indices[3],
+                                                          quad_indices[11],
+                                                          quad_indices[15],
+                                                          quad_indices[19]));
+                       break;
+                     }
+                     case RefinementCase<dim>::cut_xz:
+                     {
+                                                        //////////////////////////////
+                                                        //
+                                                        //     RefinementCase<dim>::cut_xz
+                                                        //
+                                                        // the refined cube will look
+                                                        // like this:
+                                                        //
+                                                        //        *----*----*
+                                                        //       /    /    /|
+                                                        //      /    /    / |
+                                                        //     /    /    /  *
+                                                        //    *----*----*  /|
+                                                        //    |    |    | / |
+                                                        //    |    |    |/  *
+                                                        //    *----*----*  /
+                                                        //    |    |    | /
+                                                        //    |    |    |/
+                                                        //    *----*----*
+                                                        // 
+
+                                                        // first, create the new
+                                                        // internal line
+                       new_lines[0]->set (internal::Triangulation::
+                                          TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(2)),
+                                                        middle_vertex_index<dim,spacedim>(hex->face(3))));
+
+                                                        // again, first
+                                                        // collect some data
+                                                        // about the indices of
+                                                        // the lines, with the
+                                                        // following numbering:
+           
+                                                        // face 0: left plane
+                                                        //       *
+                                                        //      /| 
+                                                        //     / |
+                                                        //    /  *
+                                                        //   *  /|
+                                                        //   | 0 |
+                                                        //   |/  *
+                                                        //   *  / 
+                                                        //   | /  
+                                                        //   |/   
+                                                        //   *    
+                                                        // face 1: right plane
+                                                        //       *
+                                                        //      /| 
+                                                        //     / |
+                                                        //    /  *
+                                                        //   *  /|
+                                                        //   | 1 |
+                                                        //   |/  *
+                                                        //   *  / 
+                                                        //   | /  
+                                                        //   |/   
+                                                        //   *    
+                                                        // face 2: front plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *---*---*
+                                                        //   |   5   |
+                                                        //   *-6-*-7-*
+                                                        //   |   4   |
+                                                        //   *---*---*
+                                                        // face 3: back plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *---*---*
+                                                        //   |   9   | 
+                                                        //   *10-*-11*
+                                                        //   |   8   | 
+                                                        //   *---*---*
+                                                        // face 4: bottom plane
+                                                        //       *---*---*
+                                                        //      /   /   /
+                                                        //     /   2   /
+                                                        //    /   /   /
+                                                        //   *---*---*
+                                                        // face 5: top plane
+                                                        //       *---*---*
+                                                        //      /   /   /
+                                                        //     /   3   /
+                                                        //    /   /   /
+                                                        //   *---*---*
+                                                        // middle planes
+                                                        //     *---*---*   *-------*
+                                                        //    /   /   /    |       |
+                                                        //   /   12  /     |       |
+                                                        //  /   /   /      |       |
+                                                        // *---*---*       *-------*
+
+                                                        // set up a list of line iterators
+                                                        // first. from this, construct
+                                                        // lists of line_indices and
+                                                        // line orientations later on
+                       const raw_line_iterator lines_xz[13]
+                         = {
+                             hex->face(0)->child(0)
+                             ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
+                             hex->face(1)->child(0)
+                             ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
+                             hex->face(4)->child(0)
+                             ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
+                             hex->face(5)->child(0)
+                             ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //3
+
+                             hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])),        //4
+                             hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])),        //5
+                             hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])),        //6
+                             hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])),        //7
+                         
+                             hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])),        //8
+                             hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])),        //9
+                             hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])),        //10
+                             hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])),        //11
+
+                             new_lines[0]                        //12
+                       };
+                 
+                       lines=&lines_xz[0];
+                 
+                       unsigned int line_indices_xz[13];
+                     
+                       for (unsigned int i=0; i<13; ++i)
+                         line_indices_xz[i]=lines[i]->index();
+                       line_indices=&line_indices_xz[0];
+
+                                                        // the orientation of lines for the
+                                                        // inner quads is quite tricky. as
+                                                        // these lines are newly created
+                                                        // ones and thus have no parents,
+                                                        // they cannot inherit this
+                                                        // property. set up an array and
+                                                        // fill it with the respective
+                                                        // values
+                       bool line_orientation_xz[13];
+
+                                                        // the middle vertices of the
+                                                        // lines of our front face
+                       const unsigned int middle_vertices[4]=
+                         {
+                               hex->line(8)->child(0)->vertex_index(1),
+                               hex->line(9)->child(0)->vertex_index(1),
+                               hex->line(2)->child(0)->vertex_index(1),
+                               hex->line(6)->child(0)->vertex_index(1),
+                         };
+
+                                                        // note: for lines 0 to 3 the
+                                                        // orientation of the line
+                                                        // is 'true', if vertex 0 is
+                                                        // on the front
+                       for (unsigned int i=0; i<4; ++i)
+                         if (lines[i]->vertex_index(0)==middle_vertices[i])
+                           line_orientation_xz[i]=true;
+                         else
+                           {
+                                                              // it must be the other way round then
+                             Assert(lines[i]->vertex_index(1)==middle_vertices[i],
+                                    ExcInternalError());
+                             line_orientation_xz[i]=false;
+                           }
+                 
+                                                        // note: for lines 4 to 11
+                                                        // (inner lines of the outer quads)
+                                                        // the following holds: the second
+                                                        // vertex of the even lines in
+                                                        // standard orientation is the
+                                                        // vertex in the middle of the
+                                                        // quad, whereas for odd lines the
+                                                        // first vertex is the same middle
+                                                        // vertex.
+                       for (unsigned int i=4; i<12; ++i)
+                         if (lines[i]->vertex_index((i+1)%2) ==
+                             middle_vertex_index<dim,spacedim>(hex->face(1+i/4)))
+                           line_orientation_xz[i]=true;
+                         else
+                           {
+                                                              // it must be the other way
+                                                              // round then
+                             Assert(lines[i]->vertex_index(i%2) ==
+                                    (middle_vertex_index<dim,spacedim>(hex->face(1+i/4))),
+                                    ExcInternalError());
+                             line_orientation_xz[i]=false;
+                           }
+                                                        // for the last line the line
+                                                        // orientation is always true,
+                                                        // since it was just constructed
+                                                        // that way
+
+                       line_orientation_xz[12]=true;
+                       line_orientation=&line_orientation_xz[0];
+
+                                                        // set up the 4 quads,
+                                                        // numbered as follows
+                                                        // (left quad numbering,
+                                                        // right line numbering
+                                                        // extracted from above),
+                                                        // the drawings denote
+                                                        // middle planes
+                                                        //
+                                                        //      *          *
+                                                        //     /|         /|
+                                                        //    / |        3 9 
+                                                        //  y/  *       /  *  
+                                                        //  * 3/|      *  /|
+                                                        //  | / |x     5 12|8
+                                                        //  |/  *      |/  * 
+                                                        //  * 2/       *  /  
+                                                        //  | /        4 2
+                                                        //  |/         |/ 
+                                                        //  *          *
+                                                        //
+                                                        //       y
+                                                        //      *----*----*      *-10-*-11-*
+                                                        //     /    /    /      /    /    /
+                                                        //    / 0  /  1 /      0    12   1
+                                                        //   /    /    /      /    /    /
+                                                        //  *----*----*x     *--6-*--7-*
+           
+                       new_quads[0]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[0],
+                                                          line_indices[12],
+                                                          line_indices[6],
+                                                          line_indices[10]));
+                       new_quads[1]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[12],
+                                                          line_indices[1],
+                                                          line_indices[7],
+                                                          line_indices[11]));
+                       new_quads[2]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[4],
+                                                          line_indices[8],
+                                                          line_indices[2],
+                                                          line_indices[12]));
+                       new_quads[3]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[5],
+                                                          line_indices[9],
+                                                          line_indices[12],
+                                                          line_indices[3]));
+
+                       new_quads[0]->set_line_orientation(0,line_orientation[0]);
+                       new_quads[0]->set_line_orientation(2,line_orientation[6]);
+                       new_quads[0]->set_line_orientation(3,line_orientation[10]);
+                     
+                       new_quads[1]->set_line_orientation(1,line_orientation[1]);
+                       new_quads[1]->set_line_orientation(2,line_orientation[7]);
+                       new_quads[1]->set_line_orientation(3,line_orientation[11]);
+                     
+                       new_quads[2]->set_line_orientation(0,line_orientation[4]);
+                       new_quads[2]->set_line_orientation(1,line_orientation[8]);
+                       new_quads[2]->set_line_orientation(2,line_orientation[2]);
+
+                       new_quads[3]->set_line_orientation(0,line_orientation[5]);
+                       new_quads[3]->set_line_orientation(1,line_orientation[9]);
+                       new_quads[3]->set_line_orientation(3,line_orientation[3]);
+
+                                                        // the quads are
+                                                        // numbered as follows:
+                                                        //
+                                                        // planes in the interior
+                                                        // of the old hex:
+                                                        //      *
+                                                        //     /|
+                                                        //    / | x         
+                                                        //   /3 * *-------*      *----*----*
+                                                        //  *  /| |       |     /    /    /
+                                                        //  | / | |       |    /  0 /  1 /
+                                                        //  |/  * |       |   /    /    /
+                                                        //  * 2/  *-------*y *----*----*x
+                                                        //  | /
+                                                        //  |/
+                                                        //  *
+                                                        //
+                                                        // children of the faces
+                                                        // of the old hex
+                                                        //      *---*---*        *---*---*
+                                                        //     /|13 | 15|       /   /   /|
+                                                        //    / |   |   |      /18 / 19/ |
+                                                        //   /  *---*---*     /   /   /  *
+                                                        //  * 5/|   |   |    *---*---* 7/|
+                                                        //  | / |12 | 14|    | 9 | 11| / |
+                                                        //  |/4 *---*---*    |   |   |/6 *
+                                                        //  *  /   /   /     *---*---*  /
+                                                        //  | /16 / 17/      |   |   | /
+                                                        //  |/   /   /       | 8 | 10|/
+                                                        //  *---*---*        *---*---*
+                                                        //
+                                                        // note that we have to
+                                                        // take care of the
+                                                        // orientation of
+                                                        // faces.
+                       const unsigned int quad_indices_xz[20]
+                         = {
+                             new_quads[0]->index(),     //0
+                             new_quads[1]->index(),
+                             new_quads[2]->index(),
+                             new_quads[3]->index(),
+                             
+                             hex->face(0)->child_index(  child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),  //4
+                             hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
 
+                             hex->face(1)->child_index(  child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),  //6
+                             hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
+                             
+                             hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])),  //8 
+                             hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
+                             hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
+                             hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
+                             
+                             hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])),  //12
+                             hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
+                             hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
+                             hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
 
+                             hex->face(4)->child_index(  child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),  //16
+                             hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
+                             
+                             hex->face(5)->child_index(  child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]),  //18
+                             hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
+                       };
+                       quad_indices=&quad_indices_xz[0];
+
+                                                        // due to the exchange of x
+                                                        // and y for the front and
+                                                        // back face, we order the
+                                                        // children according to
+                                                        //
+                                                        // *---*---*
+                                                        // | 1 | 3 |
+                                                        // *---*---*
+                                                        // | 0 | 2 |
+                                                        // *---*---*
+                       new_hexes[0]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[4],
+                                                          quad_indices[2],
+                                                          quad_indices[8],
+                                                          quad_indices[12],
+                                                          quad_indices[16],
+                                                          quad_indices[0]));
+                       new_hexes[1]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[5],
+                                                          quad_indices[3],
+                                                          quad_indices[9],
+                                                          quad_indices[13],
+                                                          quad_indices[0],
+                                                          quad_indices[18]));
+                       new_hexes[2]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[2],
+                                                          quad_indices[6],
+                                                          quad_indices[10],
+                                                          quad_indices[14],
+                                                          quad_indices[17],
+                                                          quad_indices[1]));
+                       new_hexes[3]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[3],
+                                                          quad_indices[7],
+                                                          quad_indices[11],
+                                                          quad_indices[15],
+                                                          quad_indices[1],
+                                                          quad_indices[19]));
+                       break;
+                     }
+                     case RefinementCase<dim>::cut_yz:
+                     {
+                                                        //////////////////////////////
+                                                        //
+                                                        //     RefinementCase<dim>::cut_yz
+                                                        //
+                                                        // the refined cube will look
+                                                        // like this:
+                                                        //
+                                                        //        *---------*
+                                                        //       /         /|
+                                                        //      *---------* |
+                                                        //     /         /| |
+                                                        //    *---------* |/|
+                                                        //    |         | * |
+                                                        //    |         |/| *
+                                                        //    *---------* |/
+                                                        //    |         | *
+                                                        //    |         |/
+                                                        //    *---------*
+                                                        // 
+
+                                                        // first, create the new
+                                                        // internal line
+                       new_lines[0]->set (internal::Triangulation::
+                                          TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(0)),
+                                                        middle_vertex_index<dim,spacedim>(hex->face(1))));
+
+                                                        // again, first
+                                                        // collect some data
+                                                        // about the indices of
+                                                        // the lines, with the
+                                                        // following numbering:
+                                                        // (note that face 0 and
+                                                        // 1 each are shown twice
+                                                        // for better
+                                                        // readability)
+                 
+                                                        // face 0: left plane
+                                                        //       *            *
+                                                        //      /|           /| 
+                                                        //     * |          * |
+                                                        //    /| *         /| *
+                                                        //   * 5/|        * |7|
+                                                        //   | * |        | * |
+                                                        //   |/| *        |6| *
+                                                        //   * 4/         * |/
+                                                        //   | *          | *
+                                                        //   |/           |/ 
+                                                        //   *            *
+                                                        // face 1: right plane
+                                                        //       *            *
+                                                        //      /|           /| 
+                                                        //     * |          * |
+                                                        //    /| *         /| *
+                                                        //   * 9/|        * |11
+                                                        //   | * |        | * |
+                                                        //   |/| *        |10 *
+                                                        //   * 8/         * |/
+                                                        //   | *          | *
+                                                        //   |/           |/
+                                                        //   *            *
+                                                        // face 2: front plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *-------*
+                                                        //   |       |
+                                                        //   *---0---*
+                                                        //   |       |
+                                                        //   *-------*
+                                                        // face 3: back plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *-------*
+                                                        //   |       | 
+                                                        //   *---1---*
+                                                        //   |       | 
+                                                        //   *-------*
+                                                        // face 4: bottom plane
+                                                        //       *-------*
+                                                        //      /       /
+                                                        //     *---2---*
+                                                        //    /       /
+                                                        //   *-------*
+                                                        // face 5: top plane
+                                                        //       *-------*
+                                                        //      /       /
+                                                        //     *---3---*
+                                                        //    /       /
+                                                        //   *-------*
+                                                        // middle planes
+                                                        //     *-------*   *-------*
+                                                        //    /       /    |       |
+                                                        //   *---12--*     |       |
+                                                        //  /       /      |       |
+                                                        // *-------*       *-------*
+
+                                                        // set up a list of line iterators
+                                                        // first. from this, construct
+                                                        // lists of line_indices and
+                                                        // line orientations later on
+                       const raw_line_iterator lines_yz[13]
+                         = {
+                             hex->face(2)->child(0)
+                             ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
+                             hex->face(3)->child(0)
+                             ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
+                             hex->face(4)->child(0)
+                             ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
+                             hex->face(5)->child(0)
+                             ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //3
+
+                             hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])),        //4
+                             hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])),        //5
+                             hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])),        //6
+                             hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])),        //7
+                         
+                             hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])),        //8
+                             hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])),        //9
+                             hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])),        //10
+                             hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])),        //11
+
+                             new_lines[0]                        //12
+                       };
+                 
+                       lines=&lines_yz[0];
+                 
+                       unsigned int line_indices_yz[13];
+                     
+                       for (unsigned int i=0; i<13; ++i)
+                         line_indices_yz[i]=lines[i]->index();
+                       line_indices=&line_indices_yz[0];
+
+                                                        // the orientation of lines for the
+                                                        // inner quads is quite tricky. as
+                                                        // these lines are newly created
+                                                        // ones and thus have no parents,
+                                                        // they cannot inherit this
+                                                        // property. set up an array and
+                                                        // fill it with the respective
+                                                        // values
+                       bool line_orientation_yz[13];
+
+                                                        // the middle vertices of the
+                                                        // lines of our front face
+                       const unsigned int middle_vertices[4]=
+                         {
+                               hex->line(8)->child(0)->vertex_index(1),
+                               hex->line(10)->child(0)->vertex_index(1),
+                               hex->line(0)->child(0)->vertex_index(1),
+                               hex->line(4)->child(0)->vertex_index(1),
+                         };
+
+                                                        // note: for lines 0 to 3 the
+                                                        // orientation of the line
+                                                        // is 'true', if vertex 0 is
+                                                        // on the front
+                       for (unsigned int i=0; i<4; ++i)
+                         if (lines[i]->vertex_index(0)==middle_vertices[i])
+                           line_orientation_yz[i]=true;
+                         else
+                           {
+                                                              // it must be the other way round then
+                             Assert(lines[i]->vertex_index(1)==middle_vertices[i],
+                                    ExcInternalError());
+                             line_orientation_yz[i]=false;
+                           }
+                 
+                                                        // note: for lines 4 to 11
+                                                        // (inner lines of the outer quads)
+                                                        // the following holds: the second
+                                                        // vertex of the even lines in
+                                                        // standard orientation is the
+                                                        // vertex in the middle of the
+                                                        // quad, whereas for odd lines the
+                                                        // first vertex is the same middle
+                                                        // vertex.
+                       for (unsigned int i=4; i<12; ++i)
+                         if (lines[i]->vertex_index((i+1)%2) ==
+                             middle_vertex_index<dim,spacedim>(hex->face(i/4-1)))
+                           line_orientation_yz[i]=true;
+                         else
+                           {
+                                                              // it must be the other way
+                                                              // round then
+                             Assert(lines[i]->vertex_index(i%2) ==
+                                    (middle_vertex_index<dim,spacedim>(hex->face(i/4-1))),
+                                    ExcInternalError());
+                             line_orientation_yz[i]=false;
+                           }
+                                                        // for the last line the line
+                                                        // orientation is always true,
+                                                        // since it was just constructed
+                                                        // that way
+
+                       line_orientation_yz[12]=true;
+                       line_orientation=&line_orientation_yz[0];
+
+                                                        // set up the 4 quads,
+                                                        // numbered as follows (left
+                                                        // quad numbering, right line
+                                                        // numbering extracted from
+                                                        // above)
+                                                        //
+                                                        //  x
+                                                        //  *-------*      *---3---*
+                                                        //  |   3   |      5       9
+                                                        //  *-------*      *---12--*
+                                                        //  |   2   |      4       8
+                                                        //  *-------*y     *---2---*
+                                                        //
+                                                        //       y
+                                                        //      *---------*      *----1----*
+                                                        //     /    1    /      7         11
+                                                        //    *---------*      *----12---*
+                                                        //   /    0    /      6         10
+                                                        //  *---------*x     *----0----*
+           
+                       new_quads[0]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[6],
+                                                          line_indices[10],
+                                                          line_indices[0],
+                                                          line_indices[12]));
+                       new_quads[1]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[7],
+                                                          line_indices[11],
+                                                          line_indices[12],
+                                                          line_indices[1]));
+                       new_quads[2]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[2],
+                                                          line_indices[12],
+                                                          line_indices[4],
+                                                          line_indices[8]));
+                       new_quads[3]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[12],
+                                                          line_indices[3],
+                                                          line_indices[5],
+                                                          line_indices[9]));
+
+                       new_quads[0]->set_line_orientation(0,line_orientation[6]);
+                       new_quads[0]->set_line_orientation(1,line_orientation[10]);
+                       new_quads[0]->set_line_orientation(2,line_orientation[0]);
+                     
+                       new_quads[1]->set_line_orientation(0,line_orientation[7]);
+                       new_quads[1]->set_line_orientation(1,line_orientation[11]);
+                       new_quads[1]->set_line_orientation(3,line_orientation[1]);
+                     
+                       new_quads[2]->set_line_orientation(0,line_orientation[2]);
+                       new_quads[2]->set_line_orientation(2,line_orientation[4]);
+                       new_quads[2]->set_line_orientation(3,line_orientation[8]);
+
+                       new_quads[3]->set_line_orientation(1,line_orientation[3]);
+                       new_quads[3]->set_line_orientation(2,line_orientation[5]);
+                       new_quads[3]->set_line_orientation(3,line_orientation[9]);
+
+                                                        // the quads are
+                                                        // numbered as follows:
+                                                        //
+                                                        // planes in the interior
+                                                        // of the old hex:
+                                                        //      *
+                                                        //     /|
+                                                        //    / | x         
+                                                        //   /  | *-------*      *---------*
+                                                        //  *   | |   3   |     /    1    /
+                                                        //  |   | *-------*    *---------*
+                                                        //  |   * |   2   |   /    0    /
+                                                        //  |  /  *-------*y *---------*x
+                                                        //  | /
+                                                        //  |/
+                                                        //  *
+                                                        //
+                                                        // children of the faces
+                                                        // of the old hex
+                                                        //      *-------*        *-------*
+                                                        //     /|       |       /  19   /|
+                                                        //    * |  15   |      *-------* |
+                                                        //   /|7*-------*     /  18   /|11
+                                                        //  * |/|       |    *-------* |/|
+                                                        //  |6* |  14   |    |       10* |
+                                                        //  |/|5*-------*    |  13   |/|9*
+                                                        //  * |/  17   /     *-------* |/
+                                                        //  |4*-------*      |       |8*
+                                                        //  |/  16   /       |  12   |/
+                                                        //  *-------*        *-------*
+                                                        //
+                                                        // note that we have to
+                                                        // take care of the
+                                                        // orientation of
+                                                        // faces.
+                       const unsigned int quad_indices_yz[20]
+                         = {
+                             new_quads[0]->index(),     //0
+                             new_quads[1]->index(),
+                             new_quads[2]->index(),
+                             new_quads[3]->index(),
+                             
+                             hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])),  //4 
+                             hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
+                             hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
+                             hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
+                             
+                             hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])),  //8 
+                             hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
+                             hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
+                             hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
 
-template <>
-void Triangulation<1>::save_user_flags_quad (std::vector<bool> &) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-}
+                             hex->face(2)->child_index(  child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),  //12
+                             hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
 
+                             hex->face(3)->child_index(  child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),  //14
+                             hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
+                             
+                             hex->face(4)->child_index(  child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),  //16
+                             hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
+                             
+                             hex->face(5)->child_index(  child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]),  //18
+                             hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
+                       };
+                       quad_indices=&quad_indices_yz[0];
+
+                       new_hexes[0]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[4],
+                                                          quad_indices[8],
+                                                          quad_indices[12],
+                                                          quad_indices[2],
+                                                          quad_indices[16],
+                                                          quad_indices[0]));
+                       new_hexes[1]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[5],
+                                                          quad_indices[9],
+                                                          quad_indices[2],
+                                                          quad_indices[14],
+                                                          quad_indices[17],
+                                                          quad_indices[1]));
+                       new_hexes[2]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[6],
+                                                          quad_indices[10],
+                                                          quad_indices[13],
+                                                          quad_indices[3],
+                                                          quad_indices[0],
+                                                          quad_indices[18]));
+                       new_hexes[3]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[7],
+                                                          quad_indices[11],
+                                                          quad_indices[3],
+                                                          quad_indices[15],
+                                                          quad_indices[1],
+                                                          quad_indices[19]));
+                       break;
+                     }
+                     case RefinementCase<dim>::cut_xyz:
+                     {
+                                                        //////////////////////////////
+                                                        //
+                                                        //     RefinementCase<dim>::cut_xyz
+                                                        //     isotropic refinement
+                                                        //
+                                                        // the refined cube will look
+                                                        // like this:
+                                                        //
+                                                        //        *----*----*
+                                                        //       /    /    /|
+                                                        //      *----*----* |
+                                                        //     /    /    /| *
+                                                        //    *----*----* |/|
+                                                        //    |    |    | * |
+                                                        //    |    |    |/| *
+                                                        //    *----*----* |/
+                                                        //    |    |    | *
+                                                        //    |    |    |/
+                                                        //    *----*----*
+                                                        // 
+
+                                                        // find the next unused
+                                                        // vertex and set it
+                                                        // appropriately
+                       while (triangulation.vertices_used[next_unused_vertex] == true)
+                         ++next_unused_vertex;
+                       Assert (next_unused_vertex < triangulation.vertices.size(),
+                               ExcTooFewVerticesAllocated());
+                       triangulation.vertices_used[next_unused_vertex] = true;
+                 
+                                                        // the new vertex is
+                                                        // definitely in the
+                                                        // interior, so we need not
+                                                        // worry about the boundary.
+                                                        // let it be the average of
+                                                        // the 26 vertices
+                                                        // surrounding it. weight
+                                                        // these vertices in the same
+                                                        // way as they are weighted
+                                                        // in the
+                                                        // @p{MappingQ::set_laplace_on_hex_vector}
+                                                        // function, and like the new
+                                                        // vertex at the center of
+                                                        // the quad is weighted (see
+                                                        // above)
+                       triangulation.vertices[next_unused_vertex] = Point<dim>();
+                                                        // first add corners of hex
+                       for (unsigned int vertex=0;
+                            vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+                         triangulation.vertices[next_unused_vertex] += hex->vertex(vertex) / 128;
+                                                        // now add center of lines
+                       for (unsigned int line=0;
+                            line<GeometryInfo<dim>::lines_per_cell; ++line)
+                         triangulation.vertices[next_unused_vertex] += hex->line(line)->child(0)->vertex(1) *
+                                                         7./192.;
+                                                        // finally add centers of
+                                                        // faces. note that vertex 3
+                                                        // of child 0 is an invariant
+                                                        // with respect to the face
+                                                        // orientation, flip and
+                                                        // rotation
+                       for (unsigned int face=0;
+                            face<GeometryInfo<dim>::faces_per_cell; ++face)
+                         triangulation.vertices[next_unused_vertex] += hex->face(face)->isotropic_child(0)->vertex(3) *
+                                                         1./12.;
+
+                                                        // set the data of the
+                                                        // six lines.  first
+                                                        // collect the indices of
+                                                        // the seven vertices
+                                                        // (consider the two
+                                                        // planes to be crossed
+                                                        // to form the planes
+                                                        // cutting the hex in two
+                                                        // vertically and
+                                                        // horizontally)
+                                                        //     *--3--*   *--5--*
+                                                        //    /  /  /    |  |  |
+                                                        //   0--6--1     0--6--1
+                                                        //  /  /  /      |  |  |
+                                                        // *--2--*       *--4--*
+                                                        // the lines are numbered
+                                                        // as follows:
+                                                        //     *--*--*   *--*--*
+                                                        //    /  1  /    |  5  |
+                                                        //   *2-*-3*     *2-*-3*
+                                                        //  /  0  /      |  4  |
+                                                        // *--*--*       *--*--*
+                                                        //
+                       const unsigned int vertex_indices_xyz[7]
+                         = { middle_vertex_index<dim,spacedim>(hex->face(0)),
+                             middle_vertex_index<dim,spacedim>(hex->face(1)),
+                             middle_vertex_index<dim,spacedim>(hex->face(2)),
+                             middle_vertex_index<dim,spacedim>(hex->face(3)),
+                             middle_vertex_index<dim,spacedim>(hex->face(4)),
+                             middle_vertex_index<dim,spacedim>(hex->face(5)),
+                             next_unused_vertex 
+                       };
+                       vertex_indices=&vertex_indices_xyz[0];
+                     
+                       new_lines[0]->set (internal::Triangulation::
+                                          TriaObject<1>(vertex_indices[2], vertex_indices[6]));
+                       new_lines[1]->set (internal::Triangulation::
+                                          TriaObject<1>(vertex_indices[6], vertex_indices[3]));
+                       new_lines[2]->set (internal::Triangulation::
+                                          TriaObject<1>(vertex_indices[0], vertex_indices[6]));
+                       new_lines[3]->set (internal::Triangulation::
+                                          TriaObject<1>(vertex_indices[6], vertex_indices[1]));
+                       new_lines[4]->set (internal::Triangulation::
+                                          TriaObject<1>(vertex_indices[4], vertex_indices[6]));
+                       new_lines[5]->set (internal::Triangulation::
+                                          TriaObject<1>(vertex_indices[6], vertex_indices[5]));
+
+                                                        // again, first
+                                                        // collect some data
+                                                        // about the indices of
+                                                        // the lines, with the
+                                                        // following numbering:
+                                                        // (note that face 0 and
+                                                        // 1 each are shown twice
+                                                        // for better
+                                                        // readability)
+                 
+                                                        // face 0: left plane
+                                                        //       *            *
+                                                        //      /|           /| 
+                                                        //     * |          * |
+                                                        //    /| *         /| *
+                                                        //   * 1/|        * |3|
+                                                        //   | * |        | * |
+                                                        //   |/| *        |2| *
+                                                        //   * 0/         * |/
+                                                        //   | *          | *
+                                                        //   |/           |/ 
+                                                        //   *            *
+                                                        // face 1: right plane
+                                                        //       *            *
+                                                        //      /|           /| 
+                                                        //     * |          * |
+                                                        //    /| *         /| *
+                                                        //   * 5/|        * |7|
+                                                        //   | * |        | * |
+                                                        //   |/| *        |6| *
+                                                        //   * 4/         * |/
+                                                        //   | *          | *
+                                                        //   |/           |/
+                                                        //   *            *
+                                                        // face 2: front plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *---*---*
+                                                        //   |   11  |
+                                                        //   *-8-*-9-*
+                                                        //   |   10  |
+                                                        //   *---*---*
+                                                        // face 3: back plane
+                                                        //   (note: x,y exchanged)
+                                                        //   *---*---*
+                                                        //   |   15  | 
+                                                        //   *12-*-13*
+                                                        //   |   14  | 
+                                                        //   *---*---*
+                                                        // face 4: bottom plane
+                                                        //       *---*---*
+                                                        //      /  17   /
+                                                        //     *18-*-19*
+                                                        //    /   16  /
+                                                        //   *---*---*
+                                                        // face 5: top plane
+                                                        //       *---*---*
+                                                        //      /  21   /
+                                                        //     *22-*-23*
+                                                        //    /   20  /
+                                                        //   *---*---*
+                                                        // middle planes
+                                                        //     *---*---*   *---*---*
+                                                        //    /  25   /    |   29  |
+                                                        //   *26-*-27*     *26-*-27*
+                                                        //  /   24  /      |   28  |
+                                                        // *---*---*       *---*---*
+                 
+                                                        // set up a list of line iterators
+                                                        // first. from this, construct
+                                                        // lists of line_indices and
+                                                        // line orientations later on
+                       const raw_line_iterator lines_xyz[30]
+                         = {
+                             hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])),        //0
+                             hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])),        //1
+                             hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])),        //2
+                             hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])),        //3
+                         
+                             hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])),        //4
+                             hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])),        //5
+                             hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])),        //6
+                             hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])),        //7
+                         
+                             hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])),        //8
+                             hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])),        //9
+                             hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])),        //10
+                             hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])),        //11
+                         
+                             hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])),        //12
+                             hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])),        //13
+                             hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])),        //14
+                             hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])),        //15
+                         
+                             hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])),        //16
+                             hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])),        //17
+                             hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])),        //18
+                             hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])),        //19
+                         
+                             hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])),        //20
+                             hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])),        //21
+                             hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])),        //22
+                             hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+                             ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])),        //23
+                         
+                             new_lines[0],                       //24
+                             new_lines[1],                       //25
+                             new_lines[2],                       //26
+                             new_lines[3],                       //27
+                             new_lines[4],                       //28
+                             new_lines[5]                        //29
+                       };
+                 
+                       lines=&lines_xyz[0];
+                 
+                       unsigned int line_indices_xyz[30];
+                       for (unsigned int i=0; i<30; ++i)
+                         line_indices_xyz[i]=lines[i]->index();
+                       line_indices=&line_indices_xyz[0];
+                 
+                                                        // the orientation of lines for the
+                                                        // inner quads is quite tricky. as
+                                                        // these lines are newly created
+                                                        // ones and thus have no parents,
+                                                        // they cannot inherit this
+                                                        // property. set up an array and
+                                                        // fill it with the respective
+                                                        // values
+                       bool line_orientation_xyz[30];
+                 
+                                                        // note: for the first 24 lines
+                                                        // (inner lines of the outer quads)
+                                                        // the following holds: the second
+                                                        // vertex of the even lines in
+                                                        // standard orientation is the
+                                                        // vertex in the middle of the
+                                                        // quad, whereas for odd lines the
+                                                        // first vertex is the same middle
+                                                        // vertex.
+                                                        // DEBUG
+                       face_iterator face_0=hex->face(0);
+                       face_iterator face_0_child_0=face_0->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]));
+                       line_iterator face_0_child_0_line_1=face_0_child_0
+                                                           ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0]));
+                                                        // END DEBUG
+                       for (unsigned int i=0; i<24; ++i)
+                         if (lines[i]->vertex_index((i+1)%2)==vertex_indices[i/4])
+                           line_orientation_xyz[i]=true;
+                         else
+                           {
+                                                              // it must be the other way
+                                                              // round then
+                             Assert(lines[i]->vertex_index(i%2)==vertex_indices[i/4],
+                                    ExcInternalError());
+                             line_orientation_xyz[i]=false;
+                           }
+                                                        // for the last 6 lines the line
+                                                        // orientation is always true,
+                                                        // since they were just constructed
+                                                        // that way
+                       for (unsigned int i=24; i<30; ++i)
+                         line_orientation_xyz[i]=true;
+                       line_orientation=&line_orientation_xyz[0];
+
+                                                        // set up the 12 quads,
+                                                        // numbered as follows
+                                                        // (left quad numbering,
+                                                        // right line numbering
+                                                        // extracted from above)
+                                                        //
+                                                        //      *          *
+                                                        //     /|        21|
+                                                        //    * |        * 15
+                                                        //  y/|3*      20| *  
+                                                        //  * |/|      * |/| 
+                                                        //  |2* |x    11 * 14
+                                                        //  |/|1*      |/| * 
+                                                        //  * |/       * |17 
+                                                        //  |0*       10 *
+                                                        //  |/         |16
+                                                        //  *          *
+                                                        //
+                                                        //  x
+                                                        //  *---*---*      *22-*-23*
+                                                        //  | 5 | 7 |      1  29   5
+                                                        //  *---*---*      *26-*-27*
+                                                        //  | 4 | 6 |      0  28   4
+                                                        //  *---*---*y     *18-*-19*
+                                                        //
+                                                        //       y
+                                                        //      *----*----*      *-12-*-13-*
+                                                        //     / 10 / 11 /      3   25    7
+                                                        //    *----*----*      *-26-*-27-*
+                                                        //   / 8  / 9  /      2   24    6
+                                                        //  *----*----*x     *--8-*--9-*
+           
+                       new_quads[0]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[10],
+                                                          line_indices[28],
+                                                          line_indices[16],
+                                                          line_indices[24]));
+                       new_quads[1]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[28],
+                                                          line_indices[14],
+                                                          line_indices[17],
+                                                          line_indices[25]));
+                       new_quads[2]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[11],
+                                                          line_indices[29],
+                                                          line_indices[24],
+                                                          line_indices[20]));
+                       new_quads[3]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[29],
+                                                          line_indices[15],
+                                                          line_indices[25],
+                                                          line_indices[21]));
+                       new_quads[4]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[18],
+                                                          line_indices[26],
+                                                          line_indices[0],
+                                                          line_indices[28]));
+                       new_quads[5]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[26],
+                                                          line_indices[22],
+                                                          line_indices[1],
+                                                          line_indices[29]));
+                       new_quads[6]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[19],
+                                                          line_indices[27],
+                                                          line_indices[28],
+                                                          line_indices[4]));
+                       new_quads[7]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[27],
+                                                          line_indices[23],
+                                                          line_indices[29],
+                                                          line_indices[5]));
+                       new_quads[8]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[2],
+                                                          line_indices[24],
+                                                          line_indices[8],
+                                                          line_indices[26]));
+                       new_quads[9]->set (internal::Triangulation
+                                          ::TriaObject<2>(line_indices[24],
+                                                          line_indices[6],
+                                                          line_indices[9],
+                                                          line_indices[27]));
+                       new_quads[10]->set (internal::Triangulation
+                                           ::TriaObject<2>(line_indices[3],
+                                                           line_indices[25],
+                                                           line_indices[26],
+                                                           line_indices[12]));
+                       new_quads[11]->set (internal::Triangulation
+                                           ::TriaObject<2>(line_indices[25],
+                                                           line_indices[7],
+                                                           line_indices[27],
+                                                           line_indices[13]));
+           
+                                                        // now reset the line_orientation
+                                                        // flags of outer lines as they
+                                                        // cannot be set in a loop (at
+                                                        // least not easily)
+                       new_quads[0]->set_line_orientation(0,line_orientation[10]);
+                       new_quads[0]->set_line_orientation(2,line_orientation[16]);
+                     
+                       new_quads[1]->set_line_orientation(1,line_orientation[14]);
+                       new_quads[1]->set_line_orientation(2,line_orientation[17]);
+                     
+                       new_quads[2]->set_line_orientation(0,line_orientation[11]);
+                       new_quads[2]->set_line_orientation(3,line_orientation[20]);
 
+                       new_quads[3]->set_line_orientation(1,line_orientation[15]);
+                       new_quads[3]->set_line_orientation(3,line_orientation[21]);
+                     
+                       new_quads[4]->set_line_orientation(0,line_orientation[18]);
+                       new_quads[4]->set_line_orientation(2,line_orientation[0]);
+                     
+                       new_quads[5]->set_line_orientation(1,line_orientation[22]);
+                       new_quads[5]->set_line_orientation(2,line_orientation[1]);
+                     
+                       new_quads[6]->set_line_orientation(0,line_orientation[19]);
+                       new_quads[6]->set_line_orientation(3,line_orientation[4]);
+                     
+                       new_quads[7]->set_line_orientation(1,line_orientation[23]);
+                       new_quads[7]->set_line_orientation(3,line_orientation[5]);
+                     
+                       new_quads[8]->set_line_orientation(0,line_orientation[2]);
+                       new_quads[8]->set_line_orientation(2,line_orientation[8]);
+                     
+                       new_quads[9]->set_line_orientation(1,line_orientation[6]);
+                       new_quads[9]->set_line_orientation(2,line_orientation[9]);
+                     
+                       new_quads[10]->set_line_orientation(0,line_orientation[3]);
+                       new_quads[10]->set_line_orientation(3,line_orientation[12]);
+                     
+                       new_quads[11]->set_line_orientation(1,line_orientation[7]);
+                       new_quads[11]->set_line_orientation(3,line_orientation[13]);
+
+                                                        /////////////////////////////////
+                                                        // create the eight new hexes
+                                                        //
+                                                        // again first collect
+                                                        // some data.  here, we
+                                                        // need the indices of a
+                                                        // whole lotta
+                                                        // quads.
+           
+                                                        // the quads are
+                                                        // numbered as follows:
+                                                        //
+                                                        // planes in the interior
+                                                        // of the old hex:
+                                                        //      *
+                                                        //     /|
+                                                        //    * |
+                                                        //   /|3*  *---*---*      *----*----*
+                                                        //  * |/|  | 5 | 7 |     / 10 / 11 /
+                                                        //  |2* |  *---*---*    *----*----*
+                                                        //  |/|1*  | 4 | 6 |   / 8  / 9  /
+                                                        //  * |/   *---*---*y *----*----*x
+                                                        //  |0*
+                                                        //  |/
+                                                        //  *
+                                                        //
+                                                        // children of the faces
+                                                        // of the old hex
+                                                        //      *-------*        *-------*
+                                                        //     /|25   27|       /34   35/|
+                                                        //    15|       |      /       /19
+                                                        //   /  |       |     /32   33/  |
+                                                        //  *   |24   26|    *-------*18 |
+                                                        //  1413*-------*    |21   23| 17*
+                                                        //  |  /30   31/     |       |  /
+                                                        //  12/       /      |       |16
+                                                        //  |/28   29/       |20   22|/
+                                                        //  *-------*        *-------*
+                                                        //
+                                                        // note that we have to
+                                                        // take care of the
+                                                        // orientation of
+                                                        // faces.
+                       const unsigned int quad_indices_xyz[36]
+                         = {
+                             new_quads[0]->index(),     //0
+                             new_quads[1]->index(),
+                             new_quads[2]->index(),
+                             new_quads[3]->index(),
+                             new_quads[4]->index(),
+                             new_quads[5]->index(),
+                             new_quads[6]->index(),
+                             new_quads[7]->index(),
+                             new_quads[8]->index(),
+                             new_quads[9]->index(),
+                             new_quads[10]->index(),
+                             new_quads[11]->index(),    //11
+                             
+                             hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])),  //12
+                             hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
+                             hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
+                             hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
+
+                             hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])),  //16
+                             hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
+                             hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
+                             hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
+                             
+                             hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])),  //20
+                             hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
+                             hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
+                             hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
+                             
+                             hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])),  //24
+                             hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
+                             hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
+                             hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
+                             
+                             hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])),  //28
+                             hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
+                             hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
+                             hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
+                             
+                             hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])),  //32
+                             hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
+                             hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
+                             hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+                       };
+                       quad_indices=&quad_indices_xyz[0];
+
+                                                        // bottom children
+                       new_hexes[0]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[12],
+                                                          quad_indices[0],
+                                                          quad_indices[20],
+                                                          quad_indices[4],
+                                                          quad_indices[28],
+                                                          quad_indices[8]));
+                       new_hexes[1]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[0],
+                                                          quad_indices[16],
+                                                          quad_indices[22],
+                                                          quad_indices[6],
+                                                          quad_indices[29],
+                                                          quad_indices[9]));
+                       new_hexes[2]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[13],
+                                                          quad_indices[1],
+                                                          quad_indices[4],
+                                                          quad_indices[24],
+                                                          quad_indices[30],
+                                                          quad_indices[10]));
+                       new_hexes[3]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[1],
+                                                          quad_indices[17],
+                                                          quad_indices[6],
+                                                          quad_indices[26],
+                                                          quad_indices[31],
+                                                          quad_indices[11]));
+           
+                                                        // top children
+                       new_hexes[4]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[14],
+                                                          quad_indices[2],
+                                                          quad_indices[21],
+                                                          quad_indices[5],
+                                                          quad_indices[8],
+                                                          quad_indices[32]));
+                       new_hexes[5]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[2],
+                                                          quad_indices[18],
+                                                          quad_indices[23],
+                                                          quad_indices[7],
+                                                          quad_indices[9],
+                                                          quad_indices[33]));
+                       new_hexes[6]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[15],
+                                                          quad_indices[3],
+                                                          quad_indices[5],
+                                                          quad_indices[25],
+                                                          quad_indices[10],
+                                                          quad_indices[34]));
+                       new_hexes[7]->set (internal::Triangulation
+                                          ::TriaObject<3>(quad_indices[3],
+                                                          quad_indices[19],
+                                                          quad_indices[7],
+                                                          quad_indices[27],
+                                                          quad_indices[11],
+                                                          quad_indices[35]));
+                       break;
+                     }
+                     default:
+                                                            // all refinement cases
+                                                            // have been treated,
+                                                            // there only remains
+                                                            // RefinementCase<dim>::no_refinement
+                                                            // as untreated
+                                                            // enumeration
+                                                            // value. However, in
+                                                            // that case we should
+                                                            // have aborted much
+                                                            // earlier. thus we
+                                                            // should never get here
+                           Assert(false, ExcInternalError());
+                           break;
+                   }//switch (ref_case)
+           
+                                                  // and set face orientation
+                                                  // flags. note that new faces in
+                                                  // the interior of the mother cell
+                                                  // always have a correctly oriented
+                                                  // face, but the ones on the outer
+                                                  // faces will inherit this flag
+                                                  //
+                                                  // the flag have been set to true
+                                                  // for all faces initially, now go
+                                                  // the other way round and reset
+                                                  // faces that are at the boundary
+                                                  // of the mother cube
+                                                  //
+                                                  // the same is true for the
+                                                  // face_flip and face_rotation
+                                                  // flags. however, the latter two
+                                                  // are set to false by default as
+                                                  // this is the standard value
+           
+                                                  // loop over all faces and all
+                                                  // (relevant) subfaces of that in
+                                                  // order to set the correct values
+                                                  // for face_orientation, face_flip
+                                                  // and face_rotation, which are
+                                                  // inherited from the corresponding
+                                                  // face of the mother cube
+                 for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+                   for (unsigned int s=0;
+                        s<std::max(GeometryInfo<dim-1>::n_children(GeometryInfo<dim>::face_refinement_case(ref_case,f)),
+                                   1U);
+                        ++s)
+                     {
+                       const unsigned int current_child
+                         =GeometryInfo<dim>::child_cell_on_face(ref_case,
+                                                                f,
+                                                                s,
+                                                                f_or[f],
+                                                                f_fl[f],
+                                                                f_ro[f],
+                                                                GeometryInfo<dim>::face_refinement_case(ref_case,
+                                                                                                        f,
+                                                                                                        f_or[f],
+                                                                                                        f_fl[f],
+                                                                                                        f_ro[f]));
+                       new_hexes[current_child]->set_face_orientation (f, f_or[f]);
+                       new_hexes[current_child]->set_face_flip        (f, f_fl[f]);
+                       new_hexes[current_child]->set_face_rotation    (f, f_ro[f]);
+                     }
 
-template <>
-void Triangulation<1>::load_user_flags_quad (std::istream &)
-{
-  Assert (false, ExcImpossibleInDim(1));
-}
+                                                  /////////////////////////////////
+                                                  // now the only thing still
+                                                  // to be done is setting
+                                                  // neighborship
+                                                  // information.
+                                                  //
+                                                  // the easiest part is setting the
+                                                  // inner neighbors, i.e. children
+                                                  // neighboring other children of
+                                                  // the same mother cube.
+                 switch (ref_case)
+                   {
+                     case RefinementCase<dim>::cut_x:
+                           new_hexes[0]->set_neighbor(1, new_hexes[1]);
+                     
+                           new_hexes[1]->set_neighbor(0, new_hexes[0]);
+                           break;
+                     case RefinementCase<dim>::cut_y:
+                           new_hexes[0]->set_neighbor(3, new_hexes[1]);
+
+                           new_hexes[1]->set_neighbor(2, new_hexes[0]);
+                           break;
+                     case RefinementCase<dim>::cut_z:
+                           new_hexes[0]->set_neighbor(5, new_hexes[1]);
+
+                           new_hexes[1]->set_neighbor(4, new_hexes[0]);
+                           break;
+                     case RefinementCase<dim>::cut_xy:
+                           new_hexes[0]->set_neighbor(1, new_hexes[1]);
+                           new_hexes[0]->set_neighbor(3, new_hexes[2]);
+
+                           new_hexes[1]->set_neighbor(0, new_hexes[0]);
+                           new_hexes[1]->set_neighbor(3, new_hexes[3]);
+
+                           new_hexes[2]->set_neighbor(1, new_hexes[3]);
+                           new_hexes[2]->set_neighbor(2, new_hexes[0]);
+
+                           new_hexes[3]->set_neighbor(0, new_hexes[2]);
+                           new_hexes[3]->set_neighbor(2, new_hexes[1]);
+                           break;
+                     case RefinementCase<dim>::cut_xz:
+                           new_hexes[0]->set_neighbor(1, new_hexes[2]);
+                           new_hexes[0]->set_neighbor(5, new_hexes[1]);
+
+                           new_hexes[1]->set_neighbor(1, new_hexes[3]);
+                           new_hexes[1]->set_neighbor(4, new_hexes[0]);
+
+                           new_hexes[2]->set_neighbor(0, new_hexes[0]);
+                           new_hexes[2]->set_neighbor(5, new_hexes[3]);
+
+                           new_hexes[3]->set_neighbor(0, new_hexes[1]);
+                           new_hexes[3]->set_neighbor(4, new_hexes[2]);
+                           break;
+                     case RefinementCase<dim>::cut_yz:
+                           new_hexes[0]->set_neighbor(3, new_hexes[1]);
+                           new_hexes[0]->set_neighbor(5, new_hexes[2]);
+
+                           new_hexes[1]->set_neighbor(2, new_hexes[0]);
+                           new_hexes[1]->set_neighbor(5, new_hexes[3]);
+
+                           new_hexes[2]->set_neighbor(3, new_hexes[3]);
+                           new_hexes[2]->set_neighbor(4, new_hexes[0]);
+
+                           new_hexes[3]->set_neighbor(2, new_hexes[2]);
+                           new_hexes[3]->set_neighbor(4, new_hexes[1]);
+                           break;
+                     case RefinementCase<dim>::cut_xyz:
+                           new_hexes[0]->set_neighbor(1, new_hexes[1]);
+                           new_hexes[0]->set_neighbor(3, new_hexes[2]);
+                           new_hexes[0]->set_neighbor(5, new_hexes[4]);
+
+                           new_hexes[1]->set_neighbor(0, new_hexes[0]);
+                           new_hexes[1]->set_neighbor(3, new_hexes[3]);
+                           new_hexes[1]->set_neighbor(5, new_hexes[5]);
+
+                           new_hexes[2]->set_neighbor(1, new_hexes[3]);
+                           new_hexes[2]->set_neighbor(2, new_hexes[0]);
+                           new_hexes[2]->set_neighbor(5, new_hexes[6]);
+
+                           new_hexes[3]->set_neighbor(0, new_hexes[2]);
+                           new_hexes[3]->set_neighbor(2, new_hexes[1]);
+                           new_hexes[3]->set_neighbor(5, new_hexes[7]);
+
+                           new_hexes[4]->set_neighbor(1, new_hexes[5]);
+                           new_hexes[4]->set_neighbor(3, new_hexes[6]);
+                           new_hexes[4]->set_neighbor(4, new_hexes[0]);
+
+                           new_hexes[5]->set_neighbor(0, new_hexes[4]);
+                           new_hexes[5]->set_neighbor(3, new_hexes[7]);
+                           new_hexes[5]->set_neighbor(4, new_hexes[1]);
+
+                           new_hexes[6]->set_neighbor(1, new_hexes[7]);
+                           new_hexes[6]->set_neighbor(2, new_hexes[4]);
+                           new_hexes[6]->set_neighbor(4, new_hexes[2]);
+
+                           new_hexes[7]->set_neighbor(0, new_hexes[6]);
+                           new_hexes[7]->set_neighbor(2, new_hexes[5]);
+                           new_hexes[7]->set_neighbor(4, new_hexes[3]);
+                           break;
+                     default:
+                           Assert (false, ExcInternalError());
+                           break;
+                   }
+           
+                                                  // it's a bit more complicated for
+                                                  // outer neighbors. Leave this to a
+                                                  // separate function
+                 update_neighbors<spacedim> (hex, true);
+
+                                                  // note that the
+                                                  // refinement flag was
+                                                  // already cleared at the
+                                                  // beginning of this loop
+               }
+         }
 
+                                        // clear user data on quads. we used some of
+                                        // this data to indicate anisotropic
+                                        // refinemnt cases on faces. all data should
+                                        // be cleared by now, but the information
+                                        // whether we used indices or pointers is
+                                        // still present. reset it now to enable the
+                                        // user to use whichever he likes later on.
+       triangulation.faces->quads.clear_user_data();   
+      }
 
 
-template <>
-void Triangulation<1>::load_user_flags_quad (const std::vector<bool> &)
-{
-  Assert (false, ExcImpossibleInDim(1));
-}
+                                    /**
+                                     * At the boundary of the domain, the new
+                                     * point on the face may be far inside the
+                                     * current cell, if the boundary has a
+                                     * strong curvature. If we allow anisotropic
+                                     * refinement here, the resulting cell may
+                                     * be strongly distorted. To prevent this,
+                                     * this function flags such cells for
+                                     * isotropic refinement. It is called
+                                     * automatically from
+                                     * prepare_coarsening_and_refinement().
+                                     *
+                                     * This function does nothing in
+                                     * 1d (therefore the
+                                     * specialization).
+                                     */
+    template <int spacedim>
+    static
+    void
+    prevent_distorted_boundary_cells (const Triangulation<1,spacedim> &);
+
+    template <int dim, int spacedim>
+    static
+    void
+    prevent_distorted_boundary_cells (Triangulation<dim,spacedim> &triangulation)
+      {
+       for (cell_iterator cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
+         if (cell->at_boundary() &&
+             cell->refine_flag_set() &&
+             cell->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
+           {
+                                              // The cell is at the boundary
+                                              // and it is flagged for
+                                              // anisotropic
+                                              // refinement. Therefore, we have
+                                              // a closer look
+             const RefinementCase<dim> ref_case=cell->refine_flag_set();
+             for (unsigned int face_no=0;
+                  face_no<GeometryInfo<dim>::faces_per_cell;
+                  ++face_no)
+               if (cell->face(face_no)->at_boundary())
+                 {
+                                                    // this is the critical
+                                                    // face at the boundary.
+                   if (GeometryInfo<dim>::face_refinement_case(ref_case,face_no)
+                       !=RefinementCase<dim-1>::isotropic_refinement)
+                     {
+                                                        // up to now, we do not
+                                                        // want to refine this
+                                                        // cell along the face
+                                                        // under consideration
+                                                        // here.
+                       const face_iterator face = cell->face(face_no);
+                                                        // the new point on the
+                                                        // boundary would be
+                                                        // this one.
+                       const Point<spacedim> new_bound
+                         = triangulation.boundary[face->boundary_indicator()]
+                         ->get_new_point_on_face (face);
+                                                        // to check it,
+                                                        // transform to the
+                                                        // unit cell with
+                                                        // Q1Mapping
+                       const Point<dim> new_unit
+                         = StaticMappingQ1<dim,spacedim>::mapping.
+                         transform_real_to_unit_cell(cell,
+                                                     new_bound);
+                       
+                                                        // Now, we have to
+                                                        // calculate the
+                                                        // distance from the
+                                                        // face in the unit
+                                                        // cell.
+                       
+                                                        // take the correct
+                                                        // coordinate direction (0
+                                                        // for faces 0 and 1, 1 for
+                                                        // faces 2 and 3, 2 for faces
+                                                        // 4 and 5) and substract the
+                                                        // correct boundary value of
+                                                        // the face (0 for faces 0,
+                                                        // 2, and 4; 1 for faces 1, 3
+                                                        // and 5)
+                       const double dist = fabs(new_unit[face_no/2] - face_no%2);
+                                                        // compare this with
+                                                        // the empirical value
+                                                        // allowed. if it is
+                                                        // too big, flag the
+                                                        // cell for isotropic
+                                                        // refinement
+                       const double allowed=0.25;
+                       
+                       if (dist>allowed)
+                         cell->flag_for_face_refinement(face_no);
+                     }//if flagged for anistropic refinement
+                 }//if (cell->face(face)->at_boundary())
+           }//for all cells
+      }
+    
 
+                                    /**
+                                     * Some dimension dependent stuff for
+                                     * mesh smoothing.
+                                     *
+                                     * At present, this function does nothing
+                                     * in 1d and 2D, but makes sure no two
+                                     * cells with a level difference greater
+                                     * than one share one line in 3D. This
+                                     * is a requirement needed for the
+                                     * interpolation of hanging nodes, since
+                                     * otherwise to steps of interpolation
+                                     * would be necessary. This would make
+                                     * the processes implemented in the
+                                     * @p ConstraintMatrix class much more
+                                     * complex, since these two steps of
+                                     * interpolation do not commute.
+                                     */
+    template <int dim, int spacedim>
+    static
+    void
+    prepare_refinement_dim_dependent (const Triangulation<dim,spacedim> &)
+      {
+       Assert (dim < 3,
+               ExcMessage ("Wrong function called -- there should "
+                           "be a specialization."));
+      }
 
 
-template <>
-void Triangulation<1>::save_user_flags_hex (std::ostream &) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-}
+    template <int spacedim>
+    static
+    void
+    prepare_refinement_dim_dependent (Triangulation<3,spacedim> &triangulation)
+      {
+       const unsigned int dim = 3;
+  
+                                        // first clear flags on lines,
+                                        // since we need them to determine
+                                        // which lines will be refined
+       triangulation.clear_user_flags_line();
+
+                                        // also clear flags on hexes, since we need
+                                        // them to mark those cells which are to be
+                                        // coarsened
+       triangulation.clear_user_flags_hex();
+
+                                        // variable to store whether the
+                                        // mesh was changed in the present
+                                        // loop and in the whole process
+       bool mesh_changed      = false;
+
+       do
+         {
+           mesh_changed = false;
 
+                                            // for this following, we need to know
+                                            // which cells are going to be
+                                            // coarsened, if we had to make a
+                                            // decision. the following function
+                                            // sets these flags:
+           triangulation.fix_coarsen_flags ();
 
+      
+                                            // flag those lines that are refined and
+                                            // will not be coarsened and those that
+                                            // will be refined
+           for (cell_iterator cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
+             if (cell->refine_flag_set())
+               {
+                 for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+                   if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
+                       ==RefinementCase<1>::cut_x)
+                                                      // flag a line, that will be
+                                                      // refined
+                     cell->line(line)->set_user_flag();
+               }
+             else if(cell->has_children() && !cell->child(0)->coarsen_flag_set())
+               {
+                 for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+                   if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), line)
+                       ==RefinementCase<1>::cut_x)
+                                                      // flag a line, that is refined
+                                                      // and will stay so
+                     cell->line(line)->set_user_flag();
+               }
+             else if(cell->has_children() && cell->child(0)->coarsen_flag_set())
+               cell->set_user_flag();
+
+
+                                            // now check whether there are
+                                            // cells with lines that are
+                                            // more than once refined or
+                                            // that will be more than once
+                                            // refined. The first thing
+                                            // should never be the case, in
+                                            // the second case we flag the
+                                            // cell for refinement
+           for (active_cell_iterator cell=triangulation.last_active(); cell!=triangulation.end(); --cell)
+             for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+               {
+                 if (cell->line(line)->has_children())
+                   {
+                                                      // if this line is
+                                                      // refined, its
+                                                      // children should
+                                                      // not have further
+                                                      // children
+                                                      //
+                                                      // however, if any of
+                                                      // the children is
+                                                      // flagged for
+                                                      // further
+                                                      // refinement, we
+                                                      // need to refine
+                                                      // this cell also (at
+                                                      // least, if the cell
+                                                      // is not already
+                                                      // flagged)
+                     bool offending_line_found = false;
+               
+                     for (unsigned int c=0; c<2; ++c)
+                       {
+                         Assert (cell->line(line)->child(c)->has_children() == false,
+                                 ExcInternalError());
+                   
+                         if (cell->line(line)->child(c)->user_flag_set () &&
+                             (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
+                                                                      line)
+                              ==RefinementCase<1>::no_refinement))
+                           {
+                                                              // tag this
+                                                              // cell for
+                                                              // refinement
+                             cell->clear_coarsen_flag ();
+                                                              // if anisotropic
+                                                              // coarsening is
+                                                              // allowed: extend the
+                                                              // refine_flag in the
+                                                              // needed direction,
+                                                              // else set refine_flag
+                                                              // (isotropic)
+                             if (triangulation.smooth_grid & allow_anisotropic_smoothing)
+                               cell->flag_for_line_refinement(line);
+                             else
+                               cell->set_refine_flag();
+                       
+                             for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+                               if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
+                                   ==RefinementCase<1>::cut_x)
+                                                                  // flag a line,
+                                                                  // that will be
+                                                                  // refined
+                                 cell->line(l)->set_user_flag();
+                                                              // note that
+                                                              // we have
+                                                              // changed
+                                                              // the grid
+                             offending_line_found = true;
+                       
+                                                              // it may save us several
+                                                              // loop iterations if we
+                                                              // flag all lines of
+                                                              // this cell now (and not
+                                                              // at the outset of the
+                                                              // next iteration) for
+                                                              // refinement
+                             for (unsigned int line=0;
+                                  line<GeometryInfo<dim>::lines_per_cell; ++line)
+                               if (!cell->line(line)->has_children() &&
+                                   (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
+                                                                            line)
+                                    !=RefinementCase<1>::no_refinement))
+                                 cell->line(line)->set_user_flag();
+                       
+                             break;
+                           }
+                       }
 
-template <>
-void Triangulation<1>::save_user_flags_hex (std::vector<bool> &) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-}
+                     if (offending_line_found)
+                       {
+                         mesh_changed = true;
+                         break;
+                       }
+                   }
+               }
+       
 
+                                            // there is another thing here:
+                                            // if any of the lines will be
+                                            // refined, then we may not
+                                            // coarsen the present cell
+                                            // similarly, if any of the lines
+                                            // *is* already refined, we may
+                                            // not coarsen the current
+                                            // cell. however, there's a
+                                            // catch: if the line is refined,
+                                            // but the cell behind it is
+                                            // going to be coarsened, then
+                                            // the situation changes. if we
+                                            // forget this second condition,
+                                            // the refine_and_coarsen_3d test
+                                            // will start to fail. note that
+                                            // to know which cells are going
+                                            // to be coarsened, the call for
+                                            // fix_coarsen_flags above is
+                                            // necessary
+           for (cell_iterator cell=triangulation.last(); cell!=triangulation.end(); --cell)
+             {
+               if (cell->user_flag_set())
+                 for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+                   if (cell->line(line)->has_children() &&
+                       (cell->line(line)->child(0)->user_flag_set() ||
+                        cell->line(line)->child(1)->user_flag_set()))
+                     {
+                       for (unsigned int c=0; c<cell->n_children(); ++c)
+                         cell->child(c)->clear_coarsen_flag ();
+                       cell->clear_user_flag();
+                       for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+                         if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), l)
+                             ==RefinementCase<1>::cut_x)
+                                                            // flag a line, that is refined
+                                                            // and will stay so
+                           cell->line(l)->set_user_flag();
+                       mesh_changed = true;
+                       break;
+                     }
+             }
+         }
+       while (mesh_changed == true);
+      }
 
 
-template <>
-void Triangulation<1>::load_user_flags_hex (std::istream &)
-{
-  Assert (false, ExcImpossibleInDim(1));
-}
 
+                                    /**
+                                     * Helper function for
+                                     * @p fix_coarsen_flags. Return wether 
+                                     * coarsening of this cell is allowed.
+                                     * Coarsening can be forbidden if the
+                                     * neighboring cells are or will be
+                                     * refined twice along the common face. 
+                                     */
+    template <int dim, int spacedim>
+    static
+    bool
+    coarsening_allowed (const cell_iterator& cell)
+      {
+                                        // in 1d, coarsening is
+                                        // always allowed since we
+                                        // don't enforce the 2:1
+                                        // constraint there
+       if (dim == 1)
+         return true;
+       
+       const RefinementCase<dim> ref_case = cell->refinement_case();
+       for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
+         {
+                                            // if the cell is not refined
+                                            // along that face, coarsening
+                                            // will not change anything, so
+                                            // do nothing. the same applies,
+                                            // if the face is at the boandary 
+           const RefinementCase<dim-1> face_ref_case =
+             GeometryInfo<dim>::face_refinement_case(cell->refinement_case(), n);
+               
+           const unsigned int n_subfaces
+             = GeometryInfo<dim-1>::n_children(face_ref_case);
+                                     
+           if (n_subfaces == 0 || cell->at_boundary(n))
+             continue;
+           for (unsigned int c=0; c<n_subfaces; ++c)
+             {
+               const cell_iterator child = cell->child(GeometryInfo<dim>::
+                                                       child_cell_on_face(ref_case,
+                                                                          n,c));
+                 
+               const cell_iterator child_neighbor = child->neighbor(n);
+               if (!child->neighbor_is_coarser(n))
+                                                  // in 2d, if the child's neighbor
+                                                  // is coarser, then it has no
+                                                  // children. however, in 3d it
+                                                  // might be otherwise. consider
+                                                  // for example, that our face
+                                                  // might be refined with cut_x,
+                                                  // but the neighbor is refined
+                                                  // with cut_xy at that face. then
+                                                  // the neighbor pointers of the
+                                                  // children of our cell will point
+                                                  // to the common neighbor cell,
+                                                  // not to its children. what we
+                                                  // really want to know in the
+                                                  // following is, wether the
+                                                  // neighbor cell is refined twice
+                                                  // with reference to our cell.
+                                                  // that only has to be asked, if
+                                                  // the child's neighbor is not a
+                                                  // coarser one.
+                 if ((child_neighbor->has_children() &&
+                      !child_neighbor->user_flag_set())||
+                                                      // neighbor has children, which
+                                                      // are further refined along
+                                                      // the face, otherwise
+                                                      // something went wrong in the
+                                                      // contruction of neighbor
+                                                      // pointers.  then only allow
+                                                      // coarsening if this neighbor
+                                                      // will be coarsened as well
+                                                      // (user_pointer is set).  the
+                                                      // same applies, if the
+                                                      // neighbors children are not
+                                                      // refined but will be after
+                                                      // refinement
+                     child_neighbor->refine_flag_set())
+                   return false;
+             }
+         }
+       return true;
+      }
+};
 
 
-template <>
-void Triangulation<1>::load_user_flags_hex (const std::vector<bool> &)
-{
-  Assert (false, ExcImpossibleInDim(1));
-}
+template <int dim, int spacedim>
+const StraightBoundary<dim,spacedim>
+Triangulation<dim, spacedim>::straight_boundary = StraightBoundary<dim,spacedim>();
 
-#endif
 
 
-template <int dim>
-void Triangulation<dim>::save_user_flags_quad (std::vector<bool> &v) const
-{
-  v.resize (n_quads(), false);
-  std::vector<bool>::iterator  i = v.begin();
-  quad_iterator quad = begin_quad(),
-               endq = end_quad();
-  for (; quad!=endq; ++quad, ++i)
-    *i = quad->user_flag_set();
-}
+template <int dim, int spacedim>
+const unsigned int
+Triangulation<dim, spacedim>::dimension;
 
 
 
-template <int dim>
-void Triangulation<dim>::save_user_flags_quad (std::ostream &out) const
+template <int dim, int spacedim>
+Triangulation<dim, spacedim>::Triangulation (const MeshSmoothing smooth_grid)
+               :
+               Subscriptor (),
+               faces(NULL),
+               anisotropic_refinement(false),
+               smooth_grid(smooth_grid)
 {
-  std::vector<bool> v;
-  save_user_flags_quad (v);
-  write_bool_vector (mn_tria_quad_user_flags_begin, v, mn_tria_quad_user_flags_end,
-                    out);
+                                  // set default boundary for all
+                                  // possible components
+  for (unsigned int i=0;i<255;++i)
+    boundary[i] = &straight_boundary;
 }
 
 
-
-template <int dim>
-void Triangulation<dim>::load_user_flags_quad (std::istream &in)
+template <int dim, int spacedim>
+Triangulation<dim, spacedim>::Triangulation (const Triangulation<dim, spacedim> &) 
+               :
+               Subscriptor ()
+                                  // do not set any subscriptors;
+                                  // anyway, calling this constructor
+                                  // is an error!
 {
-  std::vector<bool> v;
-  read_bool_vector (mn_tria_quad_user_flags_begin, v, mn_tria_quad_user_flags_end,
-                   in);
-  load_user_flags_quad (v);
+  Assert (false, ExcInternalError());
 }
 
 
-
-template <int dim>
-void Triangulation<dim>::load_user_flags_quad (const std::vector<bool> &v)
+template <int dim, int spacedim>
+Triangulation<dim, spacedim>::~Triangulation ()
 {
-  Assert (v.size() == n_quads(), ExcGridReadError());
-  
-  quad_iterator quad = begin_quad(),
-               endq = end_quad();
-  std::vector<bool>::const_iterator i = v.begin();
-  for (; quad!=endq; ++quad, ++i)
-    if (*i == true)
-      quad->set_user_flag();
-    else
-      quad->clear_user_flag();
+  for (unsigned int i=0; i<levels.size(); ++i)
+    delete levels[i];
+  levels.clear ();
+  delete faces;
 }
 
 
-#if deal_II_dimension == 2
-
-template <>
-void Triangulation<2>::save_user_flags_hex (std::ostream &) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::clear () 
 {
-  Assert (false, ExcImpossibleInDim(2));
+  clear_despite_subscriptions();
 }
 
 
-
-template <>
-void Triangulation<2>::save_user_flags_hex (std::vector<bool> &) const
+template <int dim, int spacedim>
+void
+Triangulation<dim, spacedim>::set_boundary (const unsigned int number,
+                                           const Boundary<dim, spacedim>& boundary_object)
 {
-  Assert (false, ExcImpossibleInDim(2));
+  Assert(number<255, ExcIndexRange(number,0,255));
+  
+  boundary[number] = &boundary_object;
 }
 
 
 
-template <>
-void Triangulation<2>::load_user_flags_hex (std::istream &)
+template <int dim, int spacedim>
+void
+Triangulation<dim, spacedim>::set_boundary (const unsigned int number)
 {
-  Assert (false, ExcImpossibleInDim(2));
+  set_boundary (number, straight_boundary);
 }
 
 
 
-template <>
-void Triangulation<2>::load_user_flags_hex (const std::vector<bool> &)
+template <int dim, int spacedim>
+const Boundary<dim, spacedim> &
+Triangulation<dim, spacedim>::get_boundary (const unsigned int number) const 
 {
-  Assert (false, ExcImpossibleInDim(2));
+  Assert(number<255, ExcIndexRange(number,0,255));
+  
+  return *(boundary[number]);
 }
 
 
-#endif
-
-
-template <int dim>
-void Triangulation<dim>::save_user_flags_hex (std::vector<bool> &v) const
+template <int dim, int spacedim>
+std::vector<unsigned char>
+Triangulation<dim, spacedim>::get_boundary_indicators () const 
 {
-  v.resize (n_hexs(), false);
-  std::vector<bool>::iterator  i = v.begin();
-  hex_iterator hex = begin_hex(),
-             endh = end_hex();
-  for (; hex!=endh; ++hex, ++i)
-    *i = hex->user_flag_set();
-}
+                                  // in 1d, the situation is simpler:
+  if (dim == 1)
+    return std::vector<unsigned char> (0);;
+  
+  std::vector<bool> bi_exists(255, false);
+  active_cell_iterator cell=begin_active();
+  for (; cell!=end(); ++cell)
+    for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+      if (cell->at_boundary(face))
+       bi_exists[cell->face(face)->boundary_indicator()]=true;
 
+  const unsigned int n_bi=
+    std::count(bi_exists.begin(), bi_exists.end(), true);
 
+  std::vector<unsigned char> boundary_indicators(n_bi);
+  unsigned int bi_counter=0;
+  for (unsigned int i=0; i<bi_exists.size(); ++i)
+    if (bi_exists[i]==true)
+      boundary_indicators[bi_counter++]=i;
 
-template <int dim>
-void Triangulation<dim>::save_user_flags_hex (std::ostream &out) const
-{
-  std::vector<bool> v;
-  save_user_flags_hex (v);
-  write_bool_vector (mn_tria_hex_user_flags_begin, v, mn_tria_hex_user_flags_end,
-                    out);
+  return boundary_indicators;
 }
 
 
 
-template <int dim>
-void Triangulation<dim>::load_user_flags_hex (std::istream &in)
+/*-----------------------------------------------------------------*/
+
+
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::copy_triangulation (const Triangulation<dim, spacedim> &old_tria)
 {
-  std::vector<bool> v;
-  read_bool_vector (mn_tria_hex_user_flags_begin, v, mn_tria_hex_user_flags_end,
-                   in);
-  load_user_flags_hex (v);
-}
+  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;
+  anisotropic_refinement = old_tria.anisotropic_refinement;
+  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];
 
+  levels.reserve (old_tria.levels.size());
+  for (unsigned int level=0; level<old_tria.levels.size(); ++level)
+    levels.push_back (new internal::Triangulation::TriaLevel<dim>(*old_tria.levels[level]));
 
-template <int dim>
-void Triangulation<dim>::load_user_flags_hex (const std::vector<bool> &v)
-{
-  Assert (v.size() == n_hexs(), ExcGridReadError());
+  number_cache = old_tria.number_cache;
   
-  hex_iterator hex = begin_hex(),
-             endh = end_hex();
-  std::vector<bool>::const_iterator i = v.begin();
-  for (; hex!=endh; ++hex, ++i)
-    if (*i == true)
-      hex->set_user_flag();
-    else
-      hex->clear_user_flag();
+                                  // inform RefinementListeners of old_tria of
+                                  // the copy operation
+  typename std::list<RefinementListener *>::iterator ref_listener =
+    old_tria.refinement_listeners.begin (),
+    end_listener = old_tria.refinement_listeners.end ();
+  for (; ref_listener != end_listener; ++ref_listener)
+    (*ref_listener)->copy_notification (old_tria, *this);
+  
+                                  // note that we need not copy the
+                                  // subscriptor!
 }
 
 
 
-template <int dim>
-void Triangulation<dim>::save_user_indices (std::vector<unsigned int> &v) const
+template <int dim, int spacedim>
+void
+Triangulation<dim,spacedim>::
+create_triangulation_compatibility (const std::vector<Point<spacedim> > &v,
+                                   const std::vector<CellData<dim> >   &cells,
+                                   const SubCellData                   &subcelldata)
 {
-                                  // clear vector and append all the
-                                  // stuff later on
-  v.clear ();
+  std::vector<CellData<dim> > reordered_cells (cells);
+  SubCellData                 reordered_subcelldata (subcelldata);
 
-  std::vector<unsigned int> tmp;
+                                  // in-place reordering of data
+  reorder_compatibility (reordered_cells, reordered_subcelldata);
 
-  save_user_indices_line (tmp);
-  v.insert (v.end(), tmp.begin(), tmp.end());
+                                  // now create triangulation from
+                                  // reordered data
+  create_triangulation(v, reordered_cells, reordered_subcelldata);
+}
 
-  if (dim >= 2)
+
+template <int dim, int spacedim>
+void
+Triangulation<dim,spacedim>::
+create_triangulation (const std::vector<Point<spacedim> >    &v,
+                     const std::vector<CellData<dim> > &cells,
+                     const SubCellData &subcelldata)
+{
+  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());
+  
+                                  // try to create a triangulation;
+                                  // if this fails, we still want to
+                                  // throw an exception but if we
+                                  // just do so we'll get into
+                                  // trouble because sometimes other
+                                  // objects are already attached to
+                                  // it:
+  try
     {
-      save_user_indices_quad (tmp);
-      v.insert (v.end(), tmp.begin(), tmp.end());
+      Implementation::create_triangulation (v, cells, subcelldata, *this);
     }
-  
-  if (dim >= 3)
+  catch (...)
     {
-      save_user_indices_hex (tmp);
-      v.insert (v.end(), tmp.begin(), tmp.end());
-    }      
-
-  if (dim >= 4)
-    Assert (false, ExcNotImplemented());
+      clear_despite_subscriptions();
+      throw;
+    }
+  
+  compute_number_cache (*this, number_cache);
 }
 
 
 
-template <int dim>
-void Triangulation<dim>::load_user_indices (const std::vector<unsigned int> &v)
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::distort_random (const double factor,
+                                                  const bool   keep_boundary)
 {
-  Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
-  std::vector<unsigned int> tmp;
+  Implementation::distort_random (factor, keep_boundary, *this);
+}
 
-                                  // first extract the indices
-                                  // belonging to lines
-  tmp.insert (tmp.end(),
-             v.begin(), v.begin()+n_lines());
-                                  // and set the lines
-  load_user_indices_line (tmp);
 
-  if (dim >= 2)
+
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::set_all_refine_flags ()
+{
+  active_cell_iterator cell = begin_active(),
+                      endc = end();
+
+  for (; cell != endc; ++cell)
     {
-      tmp.clear ();
-      tmp.insert (tmp.end(),
-                 v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
-      load_user_indices_quad (tmp);
+      cell->clear_coarsen_flag();
+      cell->set_refine_flag ();
     }
-  
-  if (dim >= 3)
-    {
-      tmp.clear ();
-      tmp.insert (tmp.end(),
-                 v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
-      load_user_indices_hex (tmp);
-    }      
-
-  if (dim >= 4)
-    Assert (false, ExcNotImplemented());
 }
 
 
 
-template <int dim>
-void Triangulation<dim>::save_user_indices_line (std::vector<unsigned int> &v) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::refine_global (const unsigned int times)
 {
-  v.resize (n_lines(), 0);
-  std::vector<unsigned int>::iterator  i = v.begin();
-  line_iterator line = begin_line(),
-               endl = end_line();
-  for (; line!=endl; ++line, ++i)
-    *i = line->user_index();
+  for (unsigned int i=0; i<times; ++i)
+    {
+      set_all_refine_flags();
+      execute_coarsening_and_refinement ();
+    }
 }
 
 
 
-template <int dim>
-void Triangulation<dim>::load_user_indices_line (const std::vector<unsigned int> &v)
-{
-  Assert (v.size() == n_lines(), ExcGridReadError());
-  
-  line_iterator line = begin_line(),
-               endl = end_line();
-  std::vector<unsigned int>::const_iterator i = v.begin();
-  for (; line!=endl; ++line, ++i)
-    line->set_user_index(*i);
-}
+/*-------------------- refine/coarsen flags -------------------------*/
 
-#if deal_II_dimension == 1
 
 
-template <>
-void Triangulation<1>::save_user_indices_quad (std::vector<unsigned int> &) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_refine_flags (std::vector<bool> &v) const
 {
-  Assert (false, ExcImpossibleInDim(1));
+  v.resize (dim*n_active_cells(), false);
+  std::vector<bool>::iterator  i = v.begin();
+  active_cell_iterator cell = begin_active(),
+                      endc = end();
+  for (; cell!=endc; ++cell)
+    for (unsigned int j=0; j<dim; ++j,++i)
+      if (cell->refine_flag_set() & (1<<j) )
+       *i = true;
+
+  Assert (i == v.end(), ExcInternalError());
 }
 
 
 
-template <>
-void Triangulation<1>::load_user_indices_quad (const std::vector<unsigned int> &)
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_refine_flags (std::ostream &out) const
 {
-  Assert (false, ExcImpossibleInDim(1));
+  std::vector<bool> v;
+  save_refine_flags (v);
+  write_bool_vector (mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end,
+                    out);
 }
 
 
 
-template <>
-void Triangulation<1>::save_user_indices_hex (std::vector<unsigned int> &) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_refine_flags (std::istream &in)
 {
-  Assert (false, ExcImpossibleInDim(1));
+  std::vector<bool> v;
+  read_bool_vector (mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end,
+                   in);
+  load_refine_flags (v);
 }
 
 
 
-template <>
-void Triangulation<1>::load_user_indices_hex (const std::vector<unsigned int> &)
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_refine_flags (const std::vector<bool> &v)
 {
-  Assert (false, ExcImpossibleInDim(1));
+  AssertThrow (v.size() == dim*n_active_cells(), ExcGridReadError());
+  
+  active_cell_iterator cell = begin_active(),
+                      endc = end();
+  std::vector<bool>::const_iterator i = v.begin();
+  for (; cell!=endc; ++cell)
+    {
+      unsigned int ref_case=0;
+      
+      for(unsigned int j=0; j<dim; ++j, ++i)
+       if (*i == true)
+         ref_case+=1<<j;
+      Assert(ref_case<RefinementCase<dim>::isotropic_refinement+1,
+            ExcGridReadError());
+      if (ref_case>0)
+       cell->set_refine_flag(RefinementCase<dim>(ref_case));
+      else
+       cell->clear_refine_flag();
+
+      Assert (i == v.end(), ExcInternalError());      
+    }
 }
 
-#endif
 
 
-template <int dim>
-void Triangulation<dim>::save_user_indices_quad (std::vector<unsigned int> &v) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_coarsen_flags (std::vector<bool> &v) const
 {
-  v.resize (n_quads(), 0);
-  std::vector<unsigned int>::iterator  i = v.begin();
-  quad_iterator quad = begin_quad(),
-               endq = end_quad();
-  for (; quad!=endq; ++quad, ++i)
-    *i = quad->user_index();
+  v.resize (n_active_cells(), false);
+  std::vector<bool>::iterator  i = v.begin();
+  active_cell_iterator cell = begin_active(),
+                      endc = end();
+  for (; cell!=endc; ++cell, ++i)
+    *i = cell->coarsen_flag_set();
+
+  Assert (i == v.end(), ExcInternalError());
 }
 
 
 
-template <int dim>
-void Triangulation<dim>::load_user_indices_quad (const std::vector<unsigned int> &v)
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_coarsen_flags (std::ostream &out) const
 {
-  Assert (v.size() == n_quads(), ExcGridReadError());
-  
-  quad_iterator quad = begin_quad(),
-               endq = end_quad();
-  std::vector<unsigned int>::const_iterator i = v.begin();
-  for (; quad!=endq; ++quad, ++i)
-    quad->set_user_index(*i);
+  std::vector<bool> v;
+  save_coarsen_flags (v);
+  write_bool_vector (mn_tria_coarsen_flags_begin, v, mn_tria_coarsen_flags_end,
+                    out);
 }
 
 
-#if deal_II_dimension == 2
+
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_coarsen_flags (std::istream &in)
+{
+  std::vector<bool> v;
+  read_bool_vector (mn_tria_coarsen_flags_begin, v, mn_tria_coarsen_flags_end,
+                   in);
+  load_coarsen_flags (v);
+}
 
 
 
-template <>
-void Triangulation<2>::save_user_indices_hex (std::vector<unsigned int> &) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_coarsen_flags (const std::vector<bool> &v)
 {
-  Assert (false, ExcImpossibleInDim(2));
-}
+  Assert (v.size() == n_active_cells(), ExcGridReadError());
+  
+  active_cell_iterator cell = begin_active(),
+                      endc = end();
+  std::vector<bool>::const_iterator i = v.begin();
+  for (; cell!=endc; ++cell, ++i)
+    if (*i == true)
+      cell->set_coarsen_flag();
+    else
+      cell->clear_coarsen_flag();
 
+  Assert (i == v.end(), ExcInternalError());
+}
 
 
-template <>
-void Triangulation<2>::load_user_indices_hex (const std::vector<unsigned int> &)
+template <int dim, int spacedim>
+bool Triangulation<dim,spacedim>::get_anisotropic_refinement_flag() const
 {
-  Assert (false, ExcImpossibleInDim(2));
+  return anisotropic_refinement;
 }
 
 
-#endif
+
+/*-------------------- user data/flags -------------------------*/
 
 
-template <int dim>
-void Triangulation<dim>::save_user_indices_hex (std::vector<unsigned int> &v) const
+namespace 
 {
-  v.resize (n_hexs(), 0);
-  std::vector<unsigned int>::iterator  i = v.begin();
-  hex_iterator hex = begin_hex(),
-             endh = end_hex();
-  for (; hex!=endh; ++hex, ++i)
-    *i = hex->user_index();
-}
+                                  // clear user data of cells
+  template <int dim>
+  void clear_user_data (std::vector<internal::Triangulation::TriaLevel<dim>*> &levels)
+  {
+    for (unsigned int level=0;level<levels.size();++level)
+      levels[level]->cells.clear_user_data();
+  }
 
 
+                                  // clear user data of faces
+  void clear_user_data (internal::Triangulation::TriaFaces<1> *)
+  {
+                                    // nothing to do in 1d
+  }  
 
-template <int dim>
-void Triangulation<dim>::load_user_indices_hex (const std::vector<unsigned int> &v)
-{
-  Assert (v.size() == n_hexs(), ExcGridReadError());
-  
-  hex_iterator hex = begin_hex(),
-             endh = end_hex();
-  std::vector<unsigned int>::const_iterator i = v.begin();
-  for (; hex!=endh; ++hex, ++i)
-    hex->set_user_index(*i);
-}
 
+  void clear_user_data (internal::Triangulation::TriaFaces<2> *faces)
+  {
+    faces->lines.clear_user_data();
+  }
+  
 
+  void clear_user_data (internal::Triangulation::TriaFaces<3> *faces)
+  {
+    faces->lines.clear_user_data();
+    faces->quads.clear_user_data();
+  }  
+}
 
-//----------------------------------------------------------------------//
 
-template <int dim>
-void Triangulation<dim>::save_user_pointers (std::vector<void *> &v) const
+template <int dim, int spacedim>
+void Triangulation<dim,spacedim>::clear_user_data ()
 {
-                                  // clear vector and append all the
-                                  // stuff later on
-  v.clear ();
+                                  // let functions in anonymous namespace do their work
+  dealii::clear_user_data (levels);
+  dealii::clear_user_data (faces);
+}
 
-  std::vector<void *> tmp;
 
-  save_user_pointers_line (tmp);
-  v.insert (v.end(), tmp.begin(), tmp.end());
 
-  if (dim >= 2)
-    {
-      save_user_pointers_quad (tmp);
+namespace
+{
+  void clear_user_flags_line (std::vector<internal::Triangulation::TriaLevel<1>*> &levels,
+                             internal::Triangulation::TriaFaces<1> *)
+  {
+    for (unsigned int level=0; level<levels.size(); ++level)
+      levels[level]->cells.clear_user_flags();    
+  }
+
+  template <int dim>
+  void clear_user_flags_line (std::vector<internal::Triangulation::TriaLevel<dim>*> &,
+                             internal::Triangulation::TriaFaces<dim> *faces)
+  {
+    faces->lines.clear_user_flags();
+  }
+}
+
+
+template <int dim, int spacedim>
+void Triangulation<dim,spacedim>::clear_user_flags_line ()
+{
+  dealii::clear_user_flags_line (levels, faces);
+}
+
+
+
+namespace
+{
+  void clear_user_flags_quad (std::vector<internal::Triangulation::TriaLevel<1>*> &,
+                             internal::Triangulation::TriaFaces<1> *)
+  {
+                                    // nothing to do in 1d
+  }
+
+  void clear_user_flags_quad (std::vector<internal::Triangulation::TriaLevel<2>*> &levels,
+                             internal::Triangulation::TriaFaces<2> *)
+  {
+    for (unsigned int level=0; level<levels.size(); ++level)
+      levels[level]->cells.clear_user_flags();    
+  }
+  
+  template <int dim>
+  void clear_user_flags_quad (std::vector<internal::Triangulation::TriaLevel<dim>*> &,
+                             internal::Triangulation::TriaFaces<dim> *faces)
+  {
+    faces->quads.clear_user_flags();
+  }
+}
+
+
+template <int dim, int spacedim>
+void Triangulation<dim,spacedim>::clear_user_flags_quad ()
+{
+  dealii::clear_user_flags_quad (levels, faces);
+}
+
+
+
+namespace
+{
+  void clear_user_flags_hex (std::vector<internal::Triangulation::TriaLevel<1>*> &,
+                             internal::Triangulation::TriaFaces<1> *)
+  {
+                                    // nothing to do in 1d
+  }
+
+
+  void clear_user_flags_hex (std::vector<internal::Triangulation::TriaLevel<2>*> &,
+                             internal::Triangulation::TriaFaces<2> *)
+  {
+                                    // nothing to do in 2d
+  }
+  
+  void clear_user_flags_hex (std::vector<internal::Triangulation::TriaLevel<3>*> &levels,
+                             internal::Triangulation::TriaFaces<3> *)
+  {
+    for (unsigned int level=0; level<levels.size(); ++level)
+      levels[level]->cells.clear_user_flags();    
+  }
+}
+
+
+template <int dim, int spacedim>
+void Triangulation<dim,spacedim>::clear_user_flags_hex ()
+{
+  dealii::clear_user_flags_hex (levels, faces);
+}
+
+
+
+template <int dim, int spacedim>
+void Triangulation<dim,spacedim>::clear_user_flags ()
+{
+  clear_user_flags_line ();
+  clear_user_flags_quad ();
+  clear_user_flags_hex ();
+}
+
+
+
+template <int dim, int spacedim>
+void Triangulation<dim,spacedim>::clear_user_pointers ()
+{
+  clear_user_data();
+}
+
+
+
+
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_flags (std::ostream &out) const
+{
+  save_user_flags_line (out);
+  
+  if (dim>=2)
+    save_user_flags_quad (out);
+  
+  if (dim>=3)
+    save_user_flags_hex (out);
+
+  if (dim >= 4)
+    Assert (false, ExcNotImplemented());
+}
+
+
+
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_flags (std::vector<bool> &v) const
+{
+                                  // clear vector and append
+                                  // all the stuff later on
+  v.clear ();
+
+  std::vector<bool> tmp;
+
+  save_user_flags_line (tmp);
+  v.insert (v.end(), tmp.begin(), tmp.end());
+
+  if (dim >= 2)
+    {
+      save_user_flags_quad (tmp);
       v.insert (v.end(), tmp.begin(), tmp.end());
     }
   
   if (dim >= 3)
     {
-      save_user_pointers_hex (tmp);
+      save_user_flags_hex (tmp);
       v.insert (v.end(), tmp.begin(), tmp.end());
     }      
 
@@ -3167,33 +9977,50 @@ void Triangulation<dim>::save_user_pointers (std::vector<void *> &v) const
 
 
 
-template <int dim>
-void Triangulation<dim>::load_user_pointers (const std::vector<void *> &v)
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_flags (std::istream &in)
+{
+  load_user_flags_line (in);
+  
+  if (dim>=2)
+    load_user_flags_quad (in);
+  
+  if (dim>=3)
+    load_user_flags_hex (in);
+
+  if (dim >= 4)
+    Assert (false, ExcNotImplemented());
+}
+
+
+
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_flags (const std::vector<bool> &v)
 {
   Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
-  std::vector<void *> tmp;
+  std::vector<bool> tmp;
 
-                                  // first extract the pointers
+                                  // first extract the flags
                                   // belonging to lines
   tmp.insert (tmp.end(),
              v.begin(), v.begin()+n_lines());
                                   // and set the lines
-  load_user_pointers_line (tmp);
+  load_user_flags_line (tmp);
 
   if (dim >= 2)
     {
       tmp.clear ();
       tmp.insert (tmp.end(),
                  v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
-      load_user_pointers_quad (tmp);
+      load_user_flags_quad (tmp);
     }
   
   if (dim >= 3)
     {
-      tmp.clear ();
+      tmp.clear();
       tmp.insert (tmp.end(),
                  v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
-      load_user_pointers_hex (tmp);
+      load_user_flags_hex (tmp);
     }      
 
   if (dim >= 4)
@@ -3202,967 +10029,1283 @@ void Triangulation<dim>::load_user_pointers (const std::vector<void *> &v)
 
 
 
-template <int dim>
-void Triangulation<dim>::save_user_pointers_line (std::vector<void *> &v) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_flags_line (std::vector<bool> &v) const
 {
-  v.resize (n_lines(), 0);
-  std::vector<void *>::iterator  i = v.begin();
+  v.resize (n_lines(), false);
+  std::vector<bool>::iterator  i = v.begin();
   line_iterator line = begin_line(),
                endl = end_line();
   for (; line!=endl; ++line, ++i)
-    *i = line->user_pointer();
+    *i = line->user_flag_set();
+
+  Assert (i == v.end(), ExcInternalError());
 }
 
 
 
-template <int dim>
-void Triangulation<dim>::load_user_pointers_line (const std::vector<void *> &v)
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_flags_line (std::ostream &out) const
 {
-  Assert (v.size() == n_lines(), ExcGridReadError());
-  
-  line_iterator line = begin_line(),
-               endl = end_line();
-  std::vector<void *>::const_iterator i = v.begin();
-  for (; line!=endl; ++line, ++i)
-    line->set_user_pointer(*i);
+  std::vector<bool> v;
+  save_user_flags_line (v);
+  write_bool_vector (mn_tria_line_user_flags_begin, v, mn_tria_line_user_flags_end,
+                    out);
 }
 
 
-#if deal_II_dimension == 1
-
 
-template <>
-void Triangulation<1>::save_user_pointers_quad (std::vector<void *> &) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_flags_line (std::istream &in)
 {
-  Assert (false, ExcImpossibleInDim(1));
+  std::vector<bool> v;
+  read_bool_vector (mn_tria_line_user_flags_begin, v, mn_tria_line_user_flags_end,
+                   in);
+  load_user_flags_line (v);
 }
 
 
 
-template <>
-void Triangulation<1>::load_user_pointers_quad (const std::vector<void *> &)
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_flags_line (const std::vector<bool> &v)
 {
-  Assert (false, ExcImpossibleInDim(1));
-}
+  Assert (v.size() == n_lines(), ExcGridReadError());
+  
+  line_iterator line = begin_line(),
+               endl = end_line();
+  std::vector<bool>::const_iterator i = v.begin();
+  for (; line!=endl; ++line, ++i)
+    if (*i == true)
+      line->set_user_flag();
+    else
+      line->clear_user_flag();
 
+  Assert (i == v.end(), ExcInternalError());
+}
 
 
-template <>
-void Triangulation<1>::save_user_pointers_hex (std::vector<void *> &) const
+namespace
 {
-  Assert (false, ExcImpossibleInDim(1));
-}
+  template <typename Iterator>
+  bool get_user_flag (const Iterator &i)
+  {
+    return i->user_flag_set();
+  }
 
 
 
-template <>
-void Triangulation<1>::load_user_pointers_hex (const std::vector<void *> &)
-{
-  Assert (false, ExcImpossibleInDim(1));
-}
+  template <int structdim, int dim, int spacedim>
+  bool get_user_flag (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
+  {
+    Assert (false, ExcInternalError());
+    return false;
+  }
 
-#endif
 
 
-template <int dim>
-void Triangulation<dim>::save_user_pointers_quad (std::vector<void *> &v) const
-{
-  v.resize (n_quads(), 0);
-  std::vector<void *>::iterator  i = v.begin();
-  quad_iterator quad = begin_quad(),
-               endq = end_quad();
-  for (; quad!=endq; ++quad, ++i)
-    *i = quad->user_pointer();
-}
+  template <typename Iterator>
+  void set_user_flag (const Iterator &i)
+  {
+    i->set_user_flag();
+  }
 
 
 
-template <int dim>
-void Triangulation<dim>::load_user_pointers_quad (const std::vector<void *> &v)
-{
-  Assert (v.size() == n_quads(), ExcGridReadError());
-  
-  quad_iterator quad = begin_quad(),
-               endq = end_quad();
-  std::vector<void *>::const_iterator i = v.begin();
-  for (; quad!=endq; ++quad, ++i)
-    quad->set_user_pointer(*i);
-}
+  template <int structdim, int dim, int spacedim>
+  void set_user_flag (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
+  {
+    Assert (false, ExcInternalError());
+  }
 
 
-#if deal_II_dimension == 2
+
+  template <typename Iterator>
+  void clear_user_flag (const Iterator &i)
+  {
+    i->clear_user_flag();
+  }
 
 
 
-template <>
-void Triangulation<2>::save_user_pointers_hex (std::vector<void *> &) const
-{
-  Assert (false, ExcImpossibleInDim(2));
+  template <int structdim, int dim, int spacedim>
+  void clear_user_flag (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
+  {
+    Assert (false, ExcInternalError());
+  }
 }
 
 
-
-template <>
-void Triangulation<2>::load_user_pointers_hex (const std::vector<void *> &)
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_flags_quad (std::vector<bool> &v) const
 {
-  Assert (false, ExcImpossibleInDim(2));
-}
+  v.resize (n_quads(), false);
 
+  if (dim >= 2)
+    {
+      std::vector<bool>::iterator  i = v.begin();
+      quad_iterator quad = begin_quad(),
+                   endq = end_quad();
+      for (; quad!=endq; ++quad, ++i)
+       *i = get_user_flag (quad);
+
+      Assert (i == v.end(), ExcInternalError());
+    }
+}
 
-#endif
 
 
-template <int dim>
-void Triangulation<dim>::save_user_pointers_hex (std::vector<void *> &v) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_flags_quad (std::ostream &out) const
 {
-  v.resize (n_hexs(), 0);
-  std::vector<void *>::iterator  i = v.begin();
-  hex_iterator hex = begin_hex(),
-             endh = end_hex();
-  for (; hex!=endh; ++hex, ++i)
-    *i = hex->user_pointer();
+  std::vector<bool> v;
+  save_user_flags_quad (v);
+  write_bool_vector (mn_tria_quad_user_flags_begin, v, mn_tria_quad_user_flags_end,
+                    out);
 }
 
 
 
-template <int dim>
-void Triangulation<dim>::load_user_pointers_hex (const std::vector<void *> &v)
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_flags_quad (std::istream &in)
 {
-  Assert (v.size() == n_hexs(), ExcGridReadError());
-  
-  hex_iterator hex = begin_hex(),
-             endh = end_hex();
-  std::vector<void *>::const_iterator i = v.begin();
-  for (; hex!=endh; ++hex, ++i)
-    hex->set_user_pointer(*i);
+  std::vector<bool> v;
+  read_bool_vector (mn_tria_quad_user_flags_begin, v, mn_tria_quad_user_flags_end,
+                   in);
+  load_user_flags_quad (v);
 }
 
 
 
-/*------------------------ Iterator functions ------------------------*/
-
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_flags_quad (const std::vector<bool> &v)
+{
+  Assert (v.size() == n_quads(), ExcGridReadError());
 
-#if deal_II_dimension == 1
+  if (dim >= 2)
+    {  
+      quad_iterator quad = begin_quad(),
+                   endq = end_quad();
+      std::vector<bool>::const_iterator i = v.begin();
+      for (; quad!=endq; ++quad, ++i)
+       if (*i == true)
+         set_user_flag(quad);
+       else
+         clear_user_flag(quad);
 
-template <>
-Triangulation<1>::raw_cell_iterator
-Triangulation<1>::begin_raw (const unsigned int level) const
-{
-  return begin_raw_line (level);
+      Assert (i == v.end(), ExcInternalError());
+    }
 }
 
 
 
-template <>
-Triangulation<1>::active_cell_iterator
-Triangulation<1>::begin_active (const unsigned int level) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_flags_hex (std::vector<bool> &v) const
 {
-  return begin_active_line (level);
+  v.resize (n_hexs(), false);
+
+  if (dim >= 3)
+    {  
+      std::vector<bool>::iterator  i = v.begin();
+      hex_iterator hex = begin_hex(),
+                 endh = end_hex();
+      for (; hex!=endh; ++hex, ++i)
+       *i = get_user_flag (hex);
+
+      Assert (i == v.end(), ExcInternalError());
+    }
 }
 
 
 
-template <>
-Triangulation<1>::raw_cell_iterator
-Triangulation<1>::last_raw () const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_flags_hex (std::ostream &out) const
 {
-  return last_raw_line ();
+  std::vector<bool> v;
+  save_user_flags_hex (v);
+  write_bool_vector (mn_tria_hex_user_flags_begin, v, mn_tria_hex_user_flags_end,
+                    out);
 }
 
 
 
-template <>
-Triangulation<1>::raw_cell_iterator
-Triangulation<1>::last_raw (const unsigned int level) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_flags_hex (std::istream &in)
 {
-  return last_raw_line (level);
+  std::vector<bool> v;
+  read_bool_vector (mn_tria_hex_user_flags_begin, v, mn_tria_hex_user_flags_end,
+                   in);
+  load_user_flags_hex (v);
 }
 
 
 
-template <>
-Triangulation<1>::cell_iterator
-Triangulation<1>::last () const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_flags_hex (const std::vector<bool> &v)
 {
-  return last_line ();
+  Assert (v.size() == n_hexs(), ExcGridReadError());
+  
+  if (dim >= 3)
+    {  
+      hex_iterator hex = begin_hex(),
+                 endh = end_hex();
+      std::vector<bool>::const_iterator i = v.begin();
+      for (; hex!=endh; ++hex, ++i)
+       if (*i == true)
+         set_user_flag(hex);
+       else
+         clear_user_flag(hex);
+
+      Assert (i == v.end(), ExcInternalError());      
+    }
 }
 
 
 
-template <>
-Triangulation<1>::cell_iterator
-Triangulation<1>::last (const unsigned int level) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_indices (std::vector<unsigned int> &v) const
 {
-  return last_line (level);
-}
+                                  // clear vector and append all the
+                                  // stuff later on
+  v.clear ();
 
+  std::vector<unsigned int> tmp;
 
+  save_user_indices_line (tmp);
+  v.insert (v.end(), tmp.begin(), tmp.end());
 
-template <>
-Triangulation<1>::active_cell_iterator
-Triangulation<1>::last_active () const
-{
-  return last_active_line ();
+  if (dim >= 2)
+    {
+      save_user_indices_quad (tmp);
+      v.insert (v.end(), tmp.begin(), tmp.end());
+    }
+  
+  if (dim >= 3)
+    {
+      save_user_indices_hex (tmp);
+      v.insert (v.end(), tmp.begin(), tmp.end());
+    }      
+
+  if (dim >= 4)
+    Assert (false, ExcNotImplemented());
 }
 
 
 
-template <>
-Triangulation<1>::active_cell_iterator
-Triangulation<1>::last_active (const unsigned int level) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_indices (const std::vector<unsigned int> &v)
 {
-  return last_active_line (level);
-}
+  Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
+  std::vector<unsigned int> tmp;
 
+                                  // first extract the indices
+                                  // belonging to lines
+  tmp.insert (tmp.end(),
+             v.begin(), v.begin()+n_lines());
+                                  // and set the lines
+  load_user_indices_line (tmp);
 
+  if (dim >= 2)
+    {
+      tmp.clear ();
+      tmp.insert (tmp.end(),
+                 v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
+      load_user_indices_quad (tmp);
+    }
+  
+  if (dim >= 3)
+    {
+      tmp.clear ();
+      tmp.insert (tmp.end(),
+                 v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
+      load_user_indices_hex (tmp);
+    }      
 
-template <>
-Triangulation<1>::raw_face_iterator
-Triangulation<1>::begin_raw_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  if (dim >= 4)
+    Assert (false, ExcNotImplemented());
 }
 
 
 
-template <>
-Triangulation<1>::face_iterator
-Triangulation<1>::begin_face () const
+namespace
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
+  template <typename Iterator>
+  unsigned int get_user_index (const Iterator &i)
+  {
+    return i->user_index();
+  }
 
 
 
-template <>
-Triangulation<1>::active_face_iterator
-Triangulation<1>::begin_active_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
+  template <int structdim, int dim, int spacedim>
+  unsigned int get_user_index (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
+  {
+    Assert (false, ExcInternalError());
+    return numbers::invalid_unsigned_int;
+  }
 
 
 
-template <>
-Triangulation<1>::raw_face_iterator
-Triangulation<1>::end_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
+  template <typename Iterator>
+  void set_user_index (const Iterator &i,
+                      const unsigned int x)
+  {
+    i->set_user_index(x);
+  }
 
 
 
-template <>
-Triangulation<1>::raw_face_iterator
-Triangulation<1>::last_raw_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  template <int structdim, int dim, int spacedim>
+  void set_user_index (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &,
+                      const unsigned int)
+  {
+    Assert (false, ExcInternalError());
+  }
 }
 
 
-
-template <>
-Triangulation<1>::face_iterator
-Triangulation<1>::last_face () const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_indices_line (std::vector<unsigned int> &v) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  v.resize (n_lines(), 0);
+  std::vector<unsigned int>::iterator  i = v.begin();
+  line_iterator line = begin_line(),
+               endl = end_line();
+  for (; line!=endl; ++line, ++i)
+    *i = line->user_index();
 }
 
 
 
-template <>
-Triangulation<1>::active_face_iterator
-Triangulation<1>::last_active_face () const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_indices_line (const std::vector<unsigned int> &v)
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  Assert (v.size() == n_lines(), ExcGridReadError());
+  
+  line_iterator line = begin_line(),
+               endl = end_line();
+  std::vector<unsigned int>::const_iterator i = v.begin();
+  for (; line!=endl; ++line, ++i)
+    line->set_user_index(*i);
 }
 
 
-
-template <>
-Triangulation<1>::raw_quad_iterator
-Triangulation<1>::begin_raw_quad (const unsigned int) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_indices_quad (std::vector<unsigned int> &v) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  v.resize (n_quads(), 0);
+
+  if (dim >= 2)
+    {  
+      std::vector<unsigned int>::iterator  i = v.begin();
+      quad_iterator quad = begin_quad(),
+                   endq = end_quad();
+      for (; quad!=endq; ++quad, ++i)
+       *i = get_user_index(quad);
+    }
 }
 
 
 
-template <>
-Triangulation<1>::quad_iterator
-Triangulation<1>::begin_quad (const unsigned int) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_indices_quad (const std::vector<unsigned int> &v)
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  Assert (v.size() == n_quads(), ExcGridReadError());
+  
+  if (dim >= 2)
+    {  
+      quad_iterator quad = begin_quad(),
+                   endq = end_quad();
+      std::vector<unsigned int>::const_iterator i = v.begin();
+      for (; quad!=endq; ++quad, ++i)
+       set_user_index(quad, *i);
+    }
 }
 
 
-
-template <>
-Triangulation<1>::active_quad_iterator
-Triangulation<1>::begin_active_quad (const unsigned int) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_indices_hex (std::vector<unsigned int> &v) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  v.resize (n_hexs(), 0);
+
+  if (dim >= 3)
+    {  
+      std::vector<unsigned int>::iterator  i = v.begin();
+      hex_iterator hex = begin_hex(),
+                 endh = end_hex();
+      for (; hex!=endh; ++hex, ++i)
+       *i = get_user_index(hex);
+    }
 }
 
 
 
-template <>
-Triangulation<1>::raw_quad_iterator
-Triangulation<1>::end_quad () const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_indices_hex (const std::vector<unsigned int> &v)
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  Assert (v.size() == n_hexs(), ExcGridReadError());
+  
+  if (dim >= 3)
+    {  
+      hex_iterator hex = begin_hex(),
+                 endh = end_hex();
+      std::vector<unsigned int>::const_iterator i = v.begin();
+      for (; hex!=endh; ++hex, ++i)
+       set_user_index(hex, *i);
+    }
 }
 
 
 
-template <>
-Triangulation<1>::raw_quad_iterator
-Triangulation<1>::last_raw_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
+//---------------- user pointers ----------------------------------------//
 
 
-template <>
-Triangulation<1>::raw_quad_iterator
-Triangulation<1>::last_raw_quad () const
+namespace
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
+  template <typename Iterator>
+  void * get_user_pointer (const Iterator &i)
+  {
+    return i->user_pointer();
+  }
 
 
 
-template <>
-Triangulation<1>::quad_iterator
-Triangulation<1>::last_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
+  template <int structdim, int dim, int spacedim>
+  void * get_user_pointer (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
+  {
+    Assert (false, ExcInternalError());
+    return 0;
+  }
 
 
 
-template <>
-Triangulation<1>::quad_iterator
-Triangulation<1>::last_quad () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
+  template <typename Iterator>
+  void set_user_pointer (const Iterator &i,
+                        void * x)
+  {
+    i->set_user_pointer(x);
+  }
 
 
 
-template <>
-Triangulation<1>::active_quad_iterator
-Triangulation<1>::last_active_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  template <int structdim, int dim, int spacedim>
+  void set_user_pointer (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &,
+                        void *)
+  {
+    Assert (false, ExcInternalError());
+  }
 }
 
 
-
-template <>
-Triangulation<1>::active_quad_iterator
-Triangulation<1>::last_active_quad () const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_pointers (std::vector<void *> &v) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
+                                  // clear vector and append all the
+                                  // stuff later on
+  v.clear ();
 
+  std::vector<void *> tmp;
 
+  save_user_pointers_line (tmp);
+  v.insert (v.end(), tmp.begin(), tmp.end());
 
-template <>
-Triangulation<1>::raw_hex_iterator
-Triangulation<1>::begin_raw_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  if (dim >= 2)
+    {
+      save_user_pointers_quad (tmp);
+      v.insert (v.end(), tmp.begin(), tmp.end());
+    }
+  
+  if (dim >= 3)
+    {
+      save_user_pointers_hex (tmp);
+      v.insert (v.end(), tmp.begin(), tmp.end());
+    }      
+
+  if (dim >= 4)
+    Assert (false, ExcNotImplemented());
 }
 
 
 
-template <>
-Triangulation<1>::hex_iterator
-Triangulation<1>::begin_hex (const unsigned int) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_pointers (const std::vector<void *> &v)
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
+  Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
+  std::vector<void *> tmp;
 
+                                  // first extract the pointers
+                                  // belonging to lines
+  tmp.insert (tmp.end(),
+             v.begin(), v.begin()+n_lines());
+                                  // and set the lines
+  load_user_pointers_line (tmp);
 
+  if (dim >= 2)
+    {
+      tmp.clear ();
+      tmp.insert (tmp.end(),
+                 v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
+      load_user_pointers_quad (tmp);
+    }
+  
+  if (dim >= 3)
+    {
+      tmp.clear ();
+      tmp.insert (tmp.end(),
+                 v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
+      load_user_pointers_hex (tmp);
+    }      
 
-template <>
-Triangulation<1>::active_hex_iterator
-Triangulation<1>::begin_active_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  if (dim >= 4)
+    Assert (false, ExcNotImplemented());
 }
 
 
 
-template <>
-Triangulation<1>::raw_hex_iterator
-Triangulation<1>::end_hex () const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_pointers_line (std::vector<void *> &v) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  v.resize (n_lines(), 0);
+  std::vector<void *>::iterator  i = v.begin();
+  line_iterator line = begin_line(),
+               endl = end_line();
+  for (; line!=endl; ++line, ++i)
+    *i = line->user_pointer();
 }
 
 
 
-template <>
-Triangulation<1>::raw_hex_iterator
-Triangulation<1>::last_raw_hex (const unsigned int) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_pointers_line (const std::vector<void *> &v)
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  Assert (v.size() == n_lines(), ExcGridReadError());
+  
+  line_iterator line = begin_line(),
+               endl = end_line();
+  std::vector<void *>::const_iterator i = v.begin();
+  for (; line!=endl; ++line, ++i)
+    line->set_user_pointer(*i);
 }
 
 
 
-template <>
-Triangulation<1>::raw_hex_iterator
-Triangulation<1>::last_raw_hex () const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_pointers_quad (std::vector<void *> &v) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  v.resize (n_quads(), 0);
+
+  if (dim >= 2)
+    {      
+      std::vector<void *>::iterator  i = v.begin();
+      quad_iterator quad = begin_quad(),
+                   endq = end_quad();
+      for (; quad!=endq; ++quad, ++i)
+       *i = get_user_pointer(quad);
+    }
 }
 
 
 
-template <>
-Triangulation<1>::hex_iterator
-Triangulation<1>::last_hex (const unsigned int) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_pointers_quad (const std::vector<void *> &v)
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  Assert (v.size() == n_quads(), ExcGridReadError());
+  
+  if (dim >= 2)
+    {
+      quad_iterator quad = begin_quad(),
+                   endq = end_quad();
+      std::vector<void *>::const_iterator i = v.begin();
+      for (; quad!=endq; ++quad, ++i)
+       set_user_pointer(quad, *i);
+    }
 }
 
 
-
-template <>
-Triangulation<1>::hex_iterator
-Triangulation<1>::last_hex () const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::save_user_pointers_hex (std::vector<void *> &v) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  v.resize (n_hexs(), 0);
+
+  if (dim >= 3)
+    {
+      std::vector<void *>::iterator  i = v.begin();
+      hex_iterator hex = begin_hex(),
+                 endh = end_hex();
+      for (; hex!=endh; ++hex, ++i)
+       *i = get_user_pointer(hex);
+    }
 }
 
 
 
-template <>
-Triangulation<1>::active_hex_iterator
-Triangulation<1>::last_active_hex (const unsigned int) const
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::load_user_pointers_hex (const std::vector<void *> &v)
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  Assert (v.size() == n_hexs(), ExcGridReadError());
+  
+  if (dim >= 3)
+    {
+      hex_iterator hex = begin_hex(),
+                 endh = end_hex();
+      std::vector<void *>::const_iterator i = v.begin();
+      for (; hex!=endh; ++hex, ++i)
+       set_user_pointer(hex, *i);
+    }
 }
 
 
 
-template <>
-Triangulation<1>::active_hex_iterator
-Triangulation<1>::last_active_hex () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-#endif
-
+/*------------------------ Cell iterator functions ------------------------*/
 
-#if deal_II_dimension == 2
 
-template <>
-Triangulation<2>::raw_cell_iterator
-Triangulation<2>::begin_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_cell_iterator
+Triangulation<dim,spacedim>::begin_raw (const unsigned int level) const
 {
-  return begin_raw_quad (level);
+  switch (dim)
+    {
+      case 1:
+           return begin_raw_line (level);
+      case 2:
+           return begin_raw_quad (level);
+      case 3:
+           return begin_raw_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_cell_iterator();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::active_cell_iterator
-Triangulation<2>::begin_active (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::cell_iterator
+Triangulation<dim,spacedim>::begin (const unsigned int level) const
 {
-  return begin_active_quad (level);
+  switch (dim)
+    {
+      case 1:
+           return begin_line (level);
+      case 2:
+           return begin_quad (level);
+      case 3:
+           return begin_hex (level);
+      default:
+           Assert (false, ExcImpossibleInDim(dim));
+           return cell_iterator();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::raw_cell_iterator
-Triangulation<2>::last_raw () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::active_cell_iterator
+Triangulation<dim,spacedim>::begin_active (const unsigned int level) const
 {
-  return last_raw_quad ();
+  switch (dim)
+    {
+      case 1:
+           return begin_active_line (level);
+      case 2:
+           return begin_active_quad (level);
+      case 3:
+           return begin_active_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_cell_iterator();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::raw_cell_iterator
-Triangulation<2>::last_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_cell_iterator
+Triangulation<dim,spacedim>::last_raw () const
 {
-  return last_raw_quad (level);
+  switch (dim)
+    {
+      case 1:
+           return last_raw_line ();
+      case 2:
+           return last_raw_quad ();
+      case 3:
+           return last_raw_hex ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_cell_iterator();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::cell_iterator
-Triangulation<2>::last () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_cell_iterator
+Triangulation<dim,spacedim>::last_raw (const unsigned int level) const
 {
-  return last_quad ();
+  switch (dim)
+    {
+      case 1:
+           return last_raw_line (level);
+      case 2:
+           return last_raw_quad (level);
+      case 3:
+           return last_raw_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_cell_iterator();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::cell_iterator
-Triangulation<2>::last (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::cell_iterator
+Triangulation<dim,spacedim>::last () const
 {
-  return last_quad (level);
+  switch (dim)
+    {
+      case 1:
+           return last_line ();
+      case 2:
+           return last_quad ();
+      case 3:
+           return last_hex ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return cell_iterator();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::active_cell_iterator
-Triangulation<2>::last_active () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::cell_iterator
+Triangulation<dim,spacedim>::last (const unsigned int level) const
 {
-  return last_active_quad ();
+  switch (dim)
+    {
+      case 1:
+           return last_line (level);
+      case 2:
+           return last_quad (level);
+      case 3:
+           return last_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return cell_iterator();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::active_cell_iterator
-Triangulation<2>::last_active (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::active_cell_iterator
+Triangulation<dim,spacedim>::last_active () const
 {
-  return last_active_quad (level);
+  switch (dim)
+    {
+      case 1:
+           return last_active_line ();
+      case 2:
+           return last_active_quad ();
+      case 3:
+           return last_active_hex ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_cell_iterator();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::raw_face_iterator
-Triangulation<2>::begin_raw_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::active_cell_iterator
+Triangulation<dim,spacedim>::last_active (const unsigned int level) const
 {
-  return begin_raw_line ();
+  switch (dim)
+    {
+      case 1:
+           return last_active_line (level);
+      case 2:
+           return last_active_quad (level);
+      case 3:
+           return last_active_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_cell_iterator();
+    }
 }
 
 
-
-template <>
-Triangulation<2>::face_iterator
-Triangulation<2>::begin_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_cell_iterator
+Triangulation<dim,spacedim>::end () const
 {
-  return begin_line ();
+  switch (dim)
+    {
+      case 1:
+           return end_line();
+      case 2:
+           return end_quad();
+      case 3:
+           return end_hex();
+      default:
+           Assert (false, ExcImpossibleInDim(dim));
+           return raw_cell_iterator();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::active_face_iterator
-Triangulation<2>::begin_active_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_cell_iterator
+Triangulation<dim, spacedim>::end_raw (const unsigned int level) const
 {
-  return begin_active_line ();
+  return (level == levels.size()-1 ?
+         end() :
+         begin_raw (level+1));
 }
 
 
-
-template <>
-Triangulation<2>::raw_face_iterator
-Triangulation<2>::end_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::cell_iterator
+Triangulation<dim, spacedim>::end (const unsigned int level) const
 {
-  return end_line ();
+  return (level == levels.size()-1 ?
+         cell_iterator(end()) :
+         begin (level+1));
 }
 
 
-
-template <>
-Triangulation<2>::raw_face_iterator
-Triangulation<2>::last_raw_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_cell_iterator
+Triangulation<dim, spacedim>::end_active (const unsigned int level) const
 {
-  return last_raw_line ();
+  return (level == levels.size()-1 ?
+         active_cell_iterator(end()) :
+         begin_active (level+1));
 }
 
 
-
-template <>
-Triangulation<2>::face_iterator
-Triangulation<2>::last_face () const
-{
-  return last_line ();
-}
-
+/*------------------------ Face iterator functions ------------------------*/
 
 
-template <>
-Triangulation<2>::active_face_iterator
-Triangulation<2>::last_active_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_face_iterator
+Triangulation<dim,spacedim>::begin_raw_face () const
 {
-  return last_active_line ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return begin_raw_line ();
+      case 3:
+           return begin_raw_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::raw_hex_iterator
-Triangulation<2>::begin_raw_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::face_iterator
+Triangulation<dim,spacedim>::begin_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return begin_line ();
+      case 3:
+           return begin_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return face_iterator ();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::hex_iterator
-Triangulation<2>::begin_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::active_face_iterator
+Triangulation<dim,spacedim>::begin_active_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return begin_active_line ();
+      case 3:
+           return begin_active_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_face_iterator ();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::active_hex_iterator
-Triangulation<2>::begin_active_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_face_iterator
+Triangulation<dim, spacedim>::end_raw_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  return end_face();
 }
 
 
 
-template <>
-Triangulation<2>::raw_hex_iterator
-Triangulation<2>::end_hex () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_face_iterator
+Triangulation<dim,spacedim>::end_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return end_line ();
+      case 3:
+           return end_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::raw_hex_iterator
-Triangulation<2>::last_raw_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_face_iterator
+Triangulation<dim, spacedim>::end_active_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  return active_face_iterator(end_face());
 }
 
 
 
-template <>
-Triangulation<2>::raw_hex_iterator
-Triangulation<2>::last_raw_hex () const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
-
 
 
-template <>
-Triangulation<2>::hex_iterator
-Triangulation<2>::last_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_face_iterator
+Triangulation<dim,spacedim>::last_raw_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return last_raw_line ();
+      case 3:
+           return last_raw_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::hex_iterator
-Triangulation<2>::last_hex () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::face_iterator
+Triangulation<dim,spacedim>::last_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return last_line ();
+      case 3:
+           return last_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
 
-template <>
-Triangulation<2>::active_hex_iterator
-Triangulation<2>::last_active_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::active_face_iterator
+Triangulation<dim,spacedim>::last_active_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return last_active_line ();
+      case 3:
+           return last_active_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-
-template <>
-Triangulation<2>::active_hex_iterator
-Triangulation<2>::last_active_hex () const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
-
-#endif
+/*------------------------ Line iterator functions ------------------------*/
 
 
-#if deal_II_dimension == 3
 
-template <>
-Triangulation<3>::raw_cell_iterator
-Triangulation<3>::begin_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_line_iterator
+Triangulation<dim, spacedim>::begin_raw_line (const unsigned int level) const
 {
-  return begin_raw_hex (level);
-}
+  switch (dim)
+    {
+      case 1:
+           Assert (level<levels.size(), ExcInvalidLevel(level));
 
+           if (levels[level]->cells.cells.size() == 0)
+             return end_line ();
 
+           return raw_line_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+                                     level,
+                                     0);
 
-template <>
-Triangulation<3>::active_cell_iterator
-Triangulation<3>::begin_active (const unsigned int level) const
-{
-  return begin_active_hex (level);
+      default:
+           Assert (level == 0, ExcFacesHaveNoLevel());
+           return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
+                                     0,
+                                     0);
+    }
 }
 
 
-
-template <>
-Triangulation<3>::raw_cell_iterator
-Triangulation<3>::last_raw () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::line_iterator
+Triangulation<dim, spacedim>::begin_line (const unsigned int level) const
 {
-  return last_raw_hex ();
+                                  // level is checked in begin_raw
+  raw_line_iterator ri = begin_raw_line (level);
+  if (ri.state() != IteratorState::valid)
+    return ri;
+  while (ri->used() == false)
+    if ((++ri).state() != IteratorState::valid)
+      return ri;
+  return ri;
 }
 
 
 
-template <>
-Triangulation<3>::raw_cell_iterator
-Triangulation<3>::last_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_line_iterator
+Triangulation<dim, spacedim>::begin_active_line (const unsigned int level) const
 {
-  return last_raw_hex (level);
+                                  // level is checked in begin_raw
+  line_iterator i = begin_line (level);
+  if (i.state() != IteratorState::valid)
+    return i;
+  while (i->has_children())
+    if ((++i).state() != IteratorState::valid)
+      return i;
+  return i;
 }
 
 
 
-template <>
-Triangulation<3>::cell_iterator
-Triangulation<3>::last () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_line_iterator
+Triangulation<dim, spacedim>::end_line () const
 {
-  return last_hex ();
+  return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
+                           -1,
+                           -1);
 }
 
 
 
-template <>
-Triangulation<3>::cell_iterator
-Triangulation<3>::last (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_line_iterator
+Triangulation<dim, spacedim>::last_raw_line (const unsigned int level) const
 {
-  return last_hex (level);
-}
-
+  switch (dim)
+    {
+      case 1:
+           Assert (level<levels.size(), ExcInvalidLevel(level));
+           Assert (levels[level]->cells.cells.size() != 0,
+                   ExcEmptyLevel (level));
 
+           return raw_line_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+                                     level,
+                                     levels[level]->cells.cells.size()-1);
 
-template <>
-Triangulation<3>::active_cell_iterator
-Triangulation<3>::last_active () const
-{
-  return last_active_hex ();
+      default:
+           Assert (level == 0, ExcFacesHaveNoLevel());
+           return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
+                                     0,
+                                     n_raw_lines()-1);
+    }
 }
 
 
 
-template <>
-Triangulation<3>::active_cell_iterator
-Triangulation<3>::last_active (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_line_iterator
+Triangulation<dim, spacedim>::last_raw_line () const
 {
-  return last_active_hex (level);
+  if (dim == 1)
+    return last_raw_line (levels.size()-1);
+  else
+    return last_raw_line (0);
 }
 
 
-
-template <>
-Triangulation<3>::raw_face_iterator
-Triangulation<3>::begin_raw_face () const
-{
-  return begin_raw_quad ();
-}
-
-
-
-template <>
-Triangulation<3>::face_iterator
-Triangulation<3>::begin_face () const
-{
-  return begin_quad ();
-}
-
-
-
-template <>
-Triangulation<3>::active_face_iterator
-Triangulation<3>::begin_active_face () const
-{
-  return begin_active_quad ();
-}
-
-
-
-template <>
-Triangulation<3>::raw_face_iterator
-Triangulation<3>::end_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::line_iterator
+Triangulation<dim, spacedim>::last_line (const unsigned int level) const
 {
-  return end_quad ();
+                                  // level is checked in last_raw
+  raw_line_iterator ri = last_raw_line(level);
+  if (ri->used()==true)
+    return ri;
+  while ((--ri).state() == IteratorState::valid)
+    if (ri->used()==true)
+      return ri;
+  return ri;
 }
 
 
-
-template <>
-Triangulation<3>::raw_face_iterator
-Triangulation<3>::last_raw_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::line_iterator
+Triangulation<dim, spacedim>::last_line () const
 {
-  return last_raw_quad ();
+  if (dim == 1)
+    return last_line (levels.size()-1);
+  else
+    return last_line (0);
 }
 
 
-
-template <>
-Triangulation<3>::face_iterator
-Triangulation<3>::last_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_line_iterator
+Triangulation<dim, spacedim>::last_active_line (const unsigned int level) const
 {
-  return last_quad ();
+                                  // level is checked in last_raw
+  line_iterator i = last_line(level);
+  if (i->has_children()==false)
+    return i;
+  while ((--i).state() == IteratorState::valid)
+    if (i->has_children()==false)
+      return i;
+  return i;
 }
 
 
-
-template <>
-Triangulation<3>::active_face_iterator
-Triangulation<3>::last_active_face () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_line_iterator
+Triangulation<dim, spacedim>::last_active_line () const
 {
-  return last_active_quad ();
+  if (dim == 1)
+    return last_active_line (levels.size()-1);
+  else
+    return last_active_line (0);
 }
 
 
-#endif
-
-
-template <int dim>
-typename Triangulation<dim>::raw_line_iterator
-Triangulation<dim>::begin_raw_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_line_iterator
+Triangulation<dim, spacedim>::end_raw_line (const unsigned int level) const
 {
-  Assert (level == 0, ExcFacesHaveNoLevel());
-  return raw_line_iterator (const_cast<Triangulation<dim>*>(this),
-                           0,
-                           0);
+  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();
 }
 
-#if deal_II_dimension == 1
 
-template <>
-Triangulation<1>::raw_line_iterator
-Triangulation<1>::begin_raw_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::line_iterator
+Triangulation<dim, spacedim>::end_line (const unsigned int level) const
 {
-  Assert (level<levels.size(), ExcInvalidLevel(level));
-
-  if (levels[level]->cells.cells.size() == 0)
-    return end_line ();
-
-  return raw_line_iterator (const_cast<Triangulation<1>*>(this),
-                           level,
-                           0);
+  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());
 }
 
-#endif
-
-#if deal_II_dimension == 3
 
-template <>
-Triangulation<3>::raw_quad_iterator
-Triangulation<3>::begin_raw_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_line_iterator
+Triangulation<dim, spacedim>::end_active_line (const unsigned int level) const
 {
-  Assert (level == 0, ExcFacesHaveNoLevel())
-
-                return raw_quad_iterator (const_cast<Triangulation<3>*>(this),
-                                          0,
-                                          0);
+  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());
 }
 
-#endif
-
-#if deal_II_dimension == 2
-
-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]->cells.cells.size() == 0)
-    return end_quad();
-  
-  return raw_quad_iterator (const_cast<Triangulation<2>*>(this),
-                           level,
-                           0);
-}
 
-#endif
+/*------------------------ Quad iterator functions ------------------------*/
 
 
-template <int dim>
-typename Triangulation<dim>::raw_hex_iterator
-Triangulation<dim>::begin_raw_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_quad_iterator
+Triangulation<dim,spacedim>::begin_raw_quad (const unsigned int level) const
 {
-  Assert (level<levels.size(), ExcInvalidLevel(level));
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_hex_iterator();
+      case 2:
+      {
+       Assert (level<levels.size(), ExcInvalidLevel(level));
 
-  if (levels[level]->cells.cells.size() == 0)
-    return end_hex();
+       if (levels[level]->cells.cells.size() == 0)
+         return end_quad();
   
-  return raw_hex_iterator (const_cast<Triangulation<dim>*>(this),
-                          level,
-                          0);
-}
-
+       return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+                                 level,
+                                 0);
+      }
 
+      case 3:
+      {
+       Assert (level == 0, ExcFacesHaveNoLevel());
 
-template <int dim>
-typename Triangulation<dim>::line_iterator
-Triangulation<dim>::begin_line (const unsigned int level) const
-{
-                                  // level is checked in begin_raw
-  raw_line_iterator ri = begin_raw_line (level);
-  if (ri.state() != IteratorState::valid)
-    return ri;
-  while (ri->used() == false)
-    if ((++ri).state() != IteratorState::valid)
-      return ri;
-  return ri;
+       return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+                                 0,
+                                 0);
+      }
+      
+      
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_hex_iterator();      
+    }
 }
 
 
 
-template <int dim>
-typename Triangulation<dim>::quad_iterator
-Triangulation<dim>::begin_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::quad_iterator
+Triangulation<dim,spacedim>::begin_quad (const unsigned int level) const
 {
-                                  // level is checked in begin_raw
+                                  // level is checked in begin_raw
   raw_quad_iterator ri = begin_raw_quad (level);
   if (ri.state() != IteratorState::valid)
     return ri;
@@ -4174,28 +11317,12 @@ Triangulation<dim>::begin_quad (const unsigned int level) const
 
 
 
-template <int dim>
-typename Triangulation<dim>::hex_iterator
-Triangulation<dim>::begin_hex (const unsigned int level) const
-{
-                                  // level is checked in begin_raw
-  raw_hex_iterator ri = begin_raw_hex (level);
-  if (ri.state() != IteratorState::valid)
-    return ri;
-  while (ri->used() == false)
-    if ((++ri).state() != IteratorState::valid)
-      return ri;
-  return ri;
-}
-
-
-
-template <int dim>
-typename Triangulation<dim>::active_line_iterator
-Triangulation<dim>::begin_active_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::active_quad_iterator
+Triangulation<dim,spacedim>::begin_active_quad (const unsigned int level) const
 {
-                                  // level is checked in begin_raw
-  line_iterator i = begin_line (level);
+                                  // level is checked in begin_raw
+  quad_iterator i = begin_quad (level);
   if (i.state() != IteratorState::valid)
     return i;
   while (i->has_children())
@@ -4206,509 +11333,376 @@ Triangulation<dim>::begin_active_line (const unsigned int level) const
 
 
 
-template <int dim>
-typename Triangulation<dim>::active_quad_iterator
-Triangulation<dim>::begin_active_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_quad_iterator
+Triangulation<dim, spacedim>::end_raw_quad (const unsigned int level) const
 {
-                                  // level is checked in begin_raw
-  quad_iterator i = begin_quad (level);
-  if (i.state() != IteratorState::valid)
-    return i;
-  while (i->has_children())
-    if ((++i).state() != IteratorState::valid)
-      return i;
-  return i;
+  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();
 }
 
 
 
-template <int dim>
-typename Triangulation<dim>::active_hex_iterator
-Triangulation<dim>::begin_active_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::quad_iterator
+Triangulation<dim, spacedim>::end_quad (const unsigned int level) const
 {
-                                  // level is checked in begin_raw
-  hex_iterator i = begin_hex (level);
-  if (i.state() != IteratorState::valid)
-    return i;
-  while (i->has_children())
-    if ((++i).state() != IteratorState::valid)
-      return i;
-  return i;
+  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());  
 }
 
 
-
-template <int dim>
-typename Triangulation<dim>::raw_line_iterator
-Triangulation<dim>::end_line () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_quad_iterator
+Triangulation<dim, spacedim>::end_active_quad (const unsigned int level) const
 {
-  return raw_line_iterator (const_cast<Triangulation<dim>*>(this),
-                           -1,
-                           -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());
 }
 
 
 
-template <int dim>
-typename Triangulation<dim>::raw_quad_iterator
-Triangulation<dim>::end_quad () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_quad_iterator
+Triangulation<dim,spacedim>::end_quad () const
 {
-  return raw_quad_iterator (const_cast<Triangulation<dim>*>(this),
+  return raw_quad_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
                            -1,
                            -1);
 }
 
 
 
-template <int dim>
-typename Triangulation<dim>::raw_hex_iterator
-Triangulation<dim>::end_hex () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_quad_iterator
+Triangulation<dim,spacedim>::last_raw_quad (const unsigned int level) const
 {
-  return raw_hex_iterator (const_cast<Triangulation<dim>*>(this),
-                          -1,
-                          -1);
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_quad_iterator();
+      case 2:
+           Assert (level<levels.size(),
+                   ExcInvalidLevel(level));
+           Assert (levels[level]->cells.cells.size() != 0,
+                   ExcEmptyLevel (level));
+           return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+                                     level,
+                                     levels[level]->cells.cells.size()-1);
+      case 3:
+           Assert (level == 0, ExcFacesHaveNoLevel());
+           return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+                                     0,
+                                     n_raw_quads()-1);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_quad_iterator();
+    }      
 }
 
 
 
-template <int dim>
-typename Triangulation<dim>::raw_line_iterator
-Triangulation<dim>::last_raw_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_quad_iterator
+Triangulation<dim,spacedim>::last_raw_quad () const
 {
-  Assert (level == 0, ExcFacesHaveNoLevel());
-
-  return raw_line_iterator (const_cast<Triangulation<dim>*>(this),
-                           0,
-                           faces->lines.cells.size()-1);
-  
+  if (dim == 2)
+    return last_raw_quad (levels.size()-1);
+  else
+    return last_raw_quad (0);
 }
 
 
-#if deal_II_dimension == 1
 
-template <>
-Triangulation<1>::raw_line_iterator
-Triangulation<1>::last_raw_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::quad_iterator
+Triangulation<dim,spacedim>::last_quad (const unsigned int level) const
 {
-  Assert (level<levels.size(), ExcInvalidLevel(level));
-  Assert (levels[level]->cells.cells.size() != 0,
-         ExcEmptyLevel (level));
-
-  return raw_line_iterator (const_cast<Triangulation<1>*>(this),
-                           level,
-                           levels[level]->cells.cells.size()-1);
+                                  // level is checked in last_raw
+  raw_quad_iterator ri = last_raw_quad(level);
+  if (ri->used()==true)
+    return ri;
+  while ((--ri).state() == IteratorState::valid)
+    if (ri->used()==true)
+      return ri;
+  return ri;
 }
 
-#endif
 
 
-template <int dim>
-typename Triangulation<dim>::raw_quad_iterator
-Triangulation<dim>::last_raw_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::quad_iterator
+Triangulation<dim,spacedim>::last_quad () const
 {
-  Assert (level == 0, ExcFacesHaveNoLevel());
-  return raw_quad_iterator (const_cast<Triangulation<dim>*>(this),
-                           0,
-                           faces->quads.cells.size()-1);
+  if (dim == 2)
+    return last_quad (levels.size()-1);
+  else
+    return last_quad (0);
 }
 
 
-#if deal_II_dimension == 2
 
-template <>
-Triangulation<2>::raw_quad_iterator
-Triangulation<2>::last_raw_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::active_quad_iterator
+Triangulation<dim,spacedim>::last_active_quad (const unsigned int level) const
 {
-  Assert (level<levels.size(),
-         ExcInvalidLevel(level));
-  Assert (levels[level]->cells.cells.size() != 0,
-         ExcEmptyLevel (level));
-  return raw_quad_iterator (const_cast<Triangulation<2>*>(this),
-                           level,
-                           levels[level]->cells.cells.size()-1);
+                                  // level is checked in last_raw
+  quad_iterator i = last_quad(level);
+  if (i->has_children()==false)
+    return i;
+  while ((--i).state() == IteratorState::valid)
+    if (i->has_children()==false)
+      return i;
+  return i;
 }
 
-#endif
 
 
-template <int dim>
-typename Triangulation<dim>::raw_hex_iterator
-Triangulation<dim>::last_raw_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::active_quad_iterator
+Triangulation<dim,spacedim>::last_active_quad () const
 {
-  Assert (level<levels.size(),
-         ExcInvalidLevel(level));
-  Assert (levels[level]->cells.cells.size() != 0,
-         ExcEmptyLevel (level));
-
-  return raw_hex_iterator (const_cast<Triangulation<dim>*>(this),
-                          level,
-                          levels[level]->cells.cells.size()-1);
+  if (dim == 2)
+    return last_active_quad (levels.size()-1);
+  else
+    return last_active_quad (0);
 }
 
 
-template <int dim>
-typename Triangulation<dim>::raw_line_iterator
-Triangulation<dim>::last_raw_line () const
-{
-  if (dim == 1)
-    return last_raw_line (levels.size()-1);
-  else
-    return last_raw_line (0);
-}
+/*------------------------ Hex iterator functions ------------------------*/
 
 
-template <int dim>
-typename Triangulation<dim>::raw_quad_iterator
-Triangulation<dim>::last_raw_quad () const
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::raw_hex_iterator
+Triangulation<dim,spacedim>::begin_raw_hex (const unsigned int level) const
 {
-  if (dim == 2)
-    return last_raw_quad (levels.size()-1);
-  else
-    return last_raw_quad (0);
+  switch (dim)
+    {
+      case 1:
+      case 2:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_hex_iterator();
+      case 3:
+      {
+       Assert (level<levels.size(), ExcInvalidLevel(level));
+
+       if (levels[level]->cells.cells.size() == 0)
+         return end_hex();
+  
+       return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+                                level,
+                                0);
+      }
+      
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_hex_iterator();      
+    }
 }
 
 
-template <int dim>
-typename Triangulation<dim>::raw_hex_iterator
-Triangulation<dim>::last_raw_hex () const
+
+template <int dim, int spacedim>
+typename Triangulation<dim,spacedim>::hex_iterator
+Triangulation<dim,spacedim>::begin_hex (const unsigned int level) const
 {
-  return last_raw_hex (levels.size()-1);
+                                  // level is checked in begin_raw
+  raw_hex_iterator ri = begin_raw_hex (level);
+  if (ri.state() != IteratorState::valid)
+    return ri;
+  while (ri->used() == false)
+    if ((++ri).state() != IteratorState::valid)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename Triangulation<dim>::line_iterator
-Triangulation<dim>::last_line (const unsigned int level) const
+
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_hex_iterator
+Triangulation<dim, spacedim>::begin_active_hex (const unsigned int level) const
 {
-                                  // level is checked in last_raw
-  raw_line_iterator ri = last_raw_line(level);
-  if (ri->used()==true)
-    return ri;
-  while ((--ri).state() == IteratorState::valid)
-    if (ri->used()==true)
-      return ri;
-  return ri;
-}
-
-
-template <int dim>
-typename Triangulation<dim>::quad_iterator
-Triangulation<dim>::last_quad (const unsigned int level) const
-{
-                                  // level is checked in last_raw
-  raw_quad_iterator ri = last_raw_quad(level);
-  if (ri->used()==true)
-    return ri;
-  while ((--ri).state() == IteratorState::valid)
-    if (ri->used()==true)
-      return ri;
-  return ri;
-}
-
-
-template <int dim>
-typename Triangulation<dim>::hex_iterator
-Triangulation<dim>::last_hex (const unsigned int level) const
-{
-                                  // level is checked in last_raw
-  raw_hex_iterator ri = last_raw_hex(level);
-  if (ri->used()==true)
-    return ri;
-  while ((--ri).state() == IteratorState::valid)
-    if (ri->used()==true)
-      return ri;
-  return ri;
-}
-
-
-template <int dim>
-typename Triangulation<dim>::line_iterator
-Triangulation<dim>::last_line () const
-{
-  if (dim == 1)
-    return last_line (levels.size()-1);
-  else
-    return last_line (0);
-}
-
-
-template <int dim>
-typename Triangulation<dim>::quad_iterator
-Triangulation<dim>::last_quad () const
-{
-  if (dim == 2)
-    return last_quad (levels.size()-1);
-  else
-    return last_quad (0);
-}
-
-
-template <int dim>
-typename Triangulation<dim>::hex_iterator
-Triangulation<dim>::last_hex () const
-{
-  return last_hex (levels.size()-1);
-}
-
-
-template <int dim>
-typename Triangulation<dim>::active_line_iterator
-Triangulation<dim>::last_active_line (const unsigned int level) const
-{
-                                  // level is checked in last_raw
-  line_iterator i = last_line(level);
-  if (i->has_children()==false)
+                                  // level is checked in begin_raw
+  hex_iterator i = begin_hex (level);
+  if (i.state() != IteratorState::valid)
     return i;
-  while ((--i).state() == IteratorState::valid)
-    if (i->has_children()==false)
+  while (i->has_children())
+    if ((++i).state() != IteratorState::valid)
       return i;
   return i;
 }
 
 
-template <int dim>
-typename Triangulation<dim>::active_quad_iterator
-Triangulation<dim>::last_active_quad (const unsigned int level) const
-{
-                                  // level is checked in last_raw
-  quad_iterator i = last_quad(level);
-  if (i->has_children()==false)
-    return i;
-  while ((--i).state() == IteratorState::valid)
-    if (i->has_children()==false)
-      return i;
-  return i;
-}
 
-
-template <int dim>
-typename Triangulation<dim>::active_hex_iterator
-Triangulation<dim>::last_active_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_hex_iterator
+Triangulation<dim, spacedim>::end_raw_hex (const unsigned int level) const
 {
-                                  // level is checked in last_raw
-  hex_iterator i = last_hex(level);
-  if (i->has_children()==false)
-    return i;
-  while ((--i).state() == IteratorState::valid)
-    if (i->has_children()==false)
-      return i;
-  return i;
+  return (level == levels.size()-1 ?
+         end_hex() :
+         begin_raw_hex (level+1));
 }
 
 
-template <int dim>
-typename Triangulation<dim>::active_line_iterator
-Triangulation<dim>::last_active_line () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::hex_iterator
+Triangulation<dim, spacedim>::end_hex (const unsigned int level) const
 {
-  if (dim == 1)
-    return last_active_line (levels.size()-1);
-  else
-    return last_active_line (0);
+  return (level == levels.size()-1 ?
+         hex_iterator(end_hex()) :
+         begin_hex (level+1));
 }
 
 
-template <int dim>
-typename Triangulation<dim>::active_quad_iterator
-Triangulation<dim>::last_active_quad () const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_hex_iterator
+Triangulation<dim, spacedim>::end_active_hex (const unsigned int level) const
 {
-  if (dim == 2)
-    return last_active_quad (levels.size()-1);
-  else
-    return last_active_quad (0);
+  return (level == levels.size()-1 ?
+         active_hex_iterator(end_hex()) :
+         begin_active_hex (level+1));
 }
 
 
-template <int dim>
-typename Triangulation<dim>::active_hex_iterator
-Triangulation<dim>::last_active_hex () const
-{
-  return last_active_hex (levels.size()-1);
-}
-
 
-template <int dim>
-typename Triangulation<dim>::raw_cell_iterator
-Triangulation<dim>::end_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_hex_iterator
+Triangulation<dim, spacedim>::end_hex () const
 {
-  return (level == levels.size()-1 ?
-         end() :
-         begin_raw (level+1));
+  return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+                          -1,
+                          -1);
 }
 
 
-template <int dim>
-typename Triangulation<dim>::cell_iterator
-Triangulation<dim>::end (const unsigned int level) const
-{
-  return (level == levels.size()-1 ?
-         cell_iterator(end()) :
-         begin (level+1));
-}
-
 
-template <int dim>
-typename Triangulation<dim>::active_cell_iterator
-Triangulation<dim>::end_active (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_hex_iterator
+Triangulation<dim, spacedim>::last_raw_hex (const unsigned int level) const
 {
-  return (level == levels.size()-1 ?
-         active_cell_iterator(end()) :
-         begin_active (level+1));
-}
-
+  switch (dim)
+    {
+      case 1:
+      case 2:
+           Assert (false, ExcImpossibleInDim(dim));
+           return raw_hex_iterator();
 
-template <int dim>
-typename Triangulation<dim>::raw_face_iterator
-Triangulation<dim>::end_raw_face () const
-{
-  return end_face();
+      case 3:
+           Assert (level<levels.size(),
+                   ExcInvalidLevel(level));
+           Assert (levels[level]->cells.cells.size() != 0,
+                   ExcEmptyLevel (level));
+
+           return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+                                    level,
+                                    levels[level]->cells.cells.size()-1);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_hex_iterator();
+    }
 }
 
 
-template <int dim>
-typename Triangulation<dim>::active_face_iterator
-Triangulation<dim>::end_active_face () const
-{
-  return active_face_iterator(end_face());
-}
-
 
-template <int dim>
-typename Triangulation<dim>::raw_line_iterator
-Triangulation<dim>::end_raw_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::raw_hex_iterator
+Triangulation<dim, spacedim>::last_raw_hex () const
 {
-  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();
+  return last_raw_hex (levels.size()-1);
 }
 
 
-template <int dim>
-typename Triangulation<dim>::line_iterator
-Triangulation<dim>::end_line (const unsigned int level) const
-{
-  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());
-}
-
 
-template <int dim>
-typename Triangulation<dim>::active_line_iterator
-Triangulation<dim>::end_active_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::hex_iterator
+Triangulation<dim, spacedim>::last_hex (const unsigned int level) const
 {
-  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());
+                                  // level is checked in last_raw
+  raw_hex_iterator ri = last_raw_hex(level);
+  if (ri->used()==true)
+    return ri;
+  while ((--ri).state() == IteratorState::valid)
+    if (ri->used()==true)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename Triangulation<dim>::raw_quad_iterator
-Triangulation<dim>::end_raw_quad (const unsigned int level) const
-{
-  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();
-}
-
 
-template <int dim>
-typename Triangulation<dim>::quad_iterator
-Triangulation<dim>::end_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::hex_iterator
+Triangulation<dim, spacedim>::last_hex () const
 {
-  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());
-  
+  return last_hex (levels.size()-1);
 }
 
 
-template <int dim>
-typename Triangulation<dim>::active_quad_iterator
-Triangulation<dim>::end_active_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_hex_iterator
+Triangulation<dim, spacedim>::last_active_hex (const unsigned int level) const
 {
-  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());
+                                  // level is checked in last_raw
+  hex_iterator i = last_hex(level);
+  if (i->has_children()==false)
+    return i;
+  while ((--i).state() == IteratorState::valid)
+    if (i->has_children()==false)
+      return i;
+  return i;
 }
 
 
-template <int dim>
-typename Triangulation<dim>::raw_hex_iterator
-Triangulation<dim>::end_raw_hex (const unsigned int level) const
-{
-  return (level == levels.size()-1 ?
-         end_hex() :
-         begin_raw_hex (level+1));
-}
-
 
-template <int dim>
-typename Triangulation<dim>::hex_iterator
-Triangulation<dim>::end_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename Triangulation<dim, spacedim>::active_hex_iterator
+Triangulation<dim, spacedim>::last_active_hex () const
 {
-  return (level == levels.size()-1 ?
-         hex_iterator(end_hex()) :
-         begin_hex (level+1));
+  return last_active_hex (levels.size()-1);
 }
 
 
-template <int dim>
-typename Triangulation<dim>::active_hex_iterator
-Triangulation<dim>::end_active_hex (const unsigned int level) const
-{
-  return (level == levels.size()-1 ?
-         active_hex_iterator(end_hex()) :
-         begin_active_hex (level+1));
-}
 
+// -------------------------------- number of cells etc ---------------
 
-template <int dim>
-unsigned int Triangulation<dim>::n_cells () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_cells () const
 {
   unsigned int n=0;
-  for (unsigned int l=0; l<levels.size(); ++l)
+  for (unsigned int l=0; l<n_levels(); ++l)
     n += n_cells (l);
   return n;
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_cells () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_active_cells () const
 {
   unsigned int n=0;
-  for (unsigned int l=0; l<levels.size(); ++l)
+  for (unsigned int l=0; l<n_levels(); ++l)
     n += n_active_cells (l);
   return n;
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_faces () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_faces () const
 {
   switch (dim)
     {
@@ -4725,8 +11719,8 @@ unsigned int Triangulation<dim>::n_faces () const
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_faces () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_active_faces () const
 {
   switch (dim)
     {
@@ -4743,8 +11737,8 @@ unsigned int Triangulation<dim>::n_active_faces () const
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_raw_cells (const unsigned int level) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_raw_cells (const unsigned int level) const
 {
   switch (dim)
     {
@@ -4762,8 +11756,8 @@ unsigned int Triangulation<dim>::n_raw_cells (const unsigned int level) const
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_cells (const unsigned int level) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_cells (const unsigned int level) const
 {
   switch (dim)
     {
@@ -4781,8 +11775,8 @@ unsigned int Triangulation<dim>::n_cells (const unsigned int level) const
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_cells (const unsigned int level) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_active_cells (const unsigned int level) const
 {
   switch (dim)
     {
@@ -4800,8 +11794,8 @@ unsigned int Triangulation<dim>::n_active_cells (const unsigned int level) const
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_lines () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_lines () const
 {
   return number_cache.n_lines;
 }
@@ -4810,7 +11804,24 @@ unsigned int Triangulation<dim>::n_lines () const
 #if deal_II_dimension == 1
 
 template <>
-unsigned int Triangulation<1>::n_raw_lines (const unsigned int level) const
+unsigned int Triangulation<1,1>::n_raw_lines (const unsigned int level) const
+{
+  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
+  return levels[level]->cells.cells.size();
+}
+
+
+template <>
+unsigned int Triangulation<1,1>::n_raw_lines () const
+{
+  Assert(false, ExcNotImplemented());
+  return 0;
+}
+
+
+
+template <>
+unsigned int Triangulation<1,2>::n_raw_lines (const unsigned int level) const
 {
   Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
   return levels[level]->cells.cells.size();
@@ -4818,7 +11829,7 @@ unsigned int Triangulation<1>::n_raw_lines (const unsigned int level) const
 
 
 template <>
-unsigned int Triangulation<1>::n_raw_lines () const
+unsigned int Triangulation<1,2>::n_raw_lines () const
 {
   Assert(false, ExcNotImplemented());
   return 0;
@@ -4827,23 +11838,23 @@ unsigned int Triangulation<1>::n_raw_lines () const
 #endif
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_raw_lines (const unsigned int) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_raw_lines (const unsigned int) const
 {
   Assert(false, ExcFacesHaveNoLevel());
   return 0;
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_raw_lines () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_raw_lines () const
 {
   return faces->lines.cells.size();
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_lines (const unsigned int level) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_lines (const unsigned int level) const
 {
   Assert (level < number_cache.n_lines_level.size(),
          ExcIndexRange (level, 0, number_cache.n_lines_level.size()));
@@ -4852,15 +11863,15 @@ unsigned int Triangulation<dim>::n_lines (const unsigned int level) const
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_lines () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_active_lines () const
 {
   return number_cache.n_active_lines;
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_lines (const unsigned int level) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::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()));
@@ -4873,94 +11884,145 @@ unsigned int Triangulation<dim>::n_active_lines (const unsigned int level) const
 #if deal_II_dimension == 1
 
 template <>
-unsigned int Triangulation<1>::n_quads () const
+unsigned int Triangulation<1,1>::n_quads () const
 {
   return 0;
 }
 
 
 template <>
-unsigned int Triangulation<1>::n_quads (const unsigned int) const
+unsigned int Triangulation<1,1>::n_quads (const unsigned int) const
 {
   return 0;
 }
 
 
 template <>
-unsigned int Triangulation<1>::n_raw_quads (const unsigned int) const
+unsigned int Triangulation<1,1>::n_raw_quads (const unsigned int) const
 {
   return 0;
 }
 
 
 template <>
-unsigned int Triangulation<1>::n_raw_hexs (const unsigned int) const
+unsigned int Triangulation<1,1>::n_raw_hexs (const unsigned int) const
 {
   return 0;
 }
 
 
 template <>
-unsigned int Triangulation<1>::n_active_quads (const unsigned int) const
+unsigned int Triangulation<1,1>::n_active_quads (const unsigned int) const
 {
   return 0;
 }
 
 
 template <>
-unsigned int Triangulation<1>::n_active_quads () const
+unsigned int Triangulation<1,1>::n_active_quads () const
 {
   return 0;
 }
 
 
-#endif
+template <>
+unsigned int Triangulation<1,2>::n_quads () const
+{
+  return 0;
+}
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_quads () const
+template <>
+unsigned int Triangulation<1,2>::n_quads (const unsigned int) const
 {
-  return number_cache.n_quads;
+  return 0;
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_quads (const unsigned int level) const
+template <>
+unsigned int Triangulation<1,2>::n_raw_quads (const unsigned int) const
 {
-  Assert (dim == 2, ExcFacesHaveNoLevel());
-  Assert (level < number_cache.n_quads_level.size(),
-         ExcIndexRange (level, 0, number_cache.n_quads_level.size()));  
-  return number_cache.n_quads_level[level];
+  return 0;
 }
 
-#if deal_II_dimension == 2
-
 
 template <>
-unsigned int Triangulation<2>::n_raw_quads (const unsigned int level) const
+unsigned int Triangulation<1,2>::n_raw_hexs (const unsigned int) const
 {
-  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
-  return levels[level]->cells.cells.size();
+  return 0;
 }
 
-#endif
-
-#if deal_II_dimension == 3
 
 template <>
-unsigned int Triangulation<3>::n_raw_quads (const unsigned int) const
+unsigned int Triangulation<1,2>::n_active_quads (const unsigned int) const
 {
-  Assert(false, ExcFacesHaveNoLevel());
   return 0;
 }
 
-#endif
-
+
+template <>
+unsigned int Triangulation<1,2>::n_active_quads () const
+{
+  return 0;
+}
+
+
+#endif
+
+
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_quads () const
+{
+  return number_cache.n_quads;
+}
+
+
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_quads (const unsigned int level) const
+{
+  Assert (dim == 2, ExcFacesHaveNoLevel());
+  Assert (level < number_cache.n_quads_level.size(),
+         ExcIndexRange (level, 0, number_cache.n_quads_level.size()));  
+  return number_cache.n_quads_level[level];
+}
+
+#if deal_II_dimension == 2
+
+
+template <>
+unsigned int Triangulation<2,2>::n_raw_quads (const unsigned int level) const
+{
+  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
+  return levels[level]->cells.cells.size();
+}
+
+
+
+template <>
+unsigned int Triangulation<2,3>::n_raw_quads (const unsigned int level) const
+{
+  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
+  return levels[level]->cells.cells.size();
+}
+
+#endif
+
+#if deal_II_dimension == 3
+
+template <>
+unsigned int Triangulation<3,3>::n_raw_quads (const unsigned int) const
+{
+  Assert(false, ExcFacesHaveNoLevel());
+  return 0;
+}
+
+#endif
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_raw_quads () const
+
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_raw_quads () const
 {
   Assert (false, ExcNotImplemented());
   return 0;
@@ -4970,22 +12032,22 @@ unsigned int Triangulation<dim>::n_raw_quads () const
 #if deal_II_dimension == 3
 
 template <>
-unsigned int Triangulation<3>::n_raw_quads () const
+unsigned int Triangulation<3,3>::n_raw_quads () const
 {
   return faces->quads.cells.size();
 }
 
 #endif
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_quads () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_active_quads () const
 {
   return number_cache.n_active_quads;
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_quads (const unsigned int level) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::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()));
@@ -4997,39 +12059,39 @@ unsigned int Triangulation<dim>::n_active_quads (const unsigned int level) const
 
 #if deal_II_dimension < 3
 
-template <int dim>
-unsigned int Triangulation<dim>::n_hexs () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_hexs () const
 {
   return 0;
 }
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_hexs (const unsigned int) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_hexs (const unsigned int) const
 {
   return 0;
 }
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_raw_hexs (const unsigned int) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_raw_hexs (const unsigned int) const
 {
   return 0;
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_hexs () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_active_hexs () const
 {
   return 0;
 }
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_hexs (const unsigned int) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_active_hexs (const unsigned int) const
 {
   return 0;
 }
@@ -5038,16 +12100,16 @@ unsigned int Triangulation<dim>::n_active_hexs (const unsigned int) const
 #else
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_hexs () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_hexs () const
 {
   return number_cache.n_hexes;
 }
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_hexs (const unsigned int level) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_hexs (const unsigned int level) const
 {
   Assert (level < number_cache.n_hexes_level.size(),
          ExcIndexRange (level, 0, number_cache.n_hexes_level.size()));
@@ -5057,24 +12119,24 @@ unsigned int Triangulation<dim>::n_hexs (const unsigned int level) const
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_raw_hexs (const unsigned int level) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_raw_hexs (const unsigned int level) const
 {
   Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
   return levels[level]->cells.cells.size();
 }
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_hexs () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_active_hexs () const
 {
   return number_cache.n_active_hexes;
 }
 
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_active_hexs (const unsigned int level) const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_active_hexs (const unsigned int level) const
 {
   Assert (level < number_cache.n_hexes_level.size(),
          ExcIndexRange (level, 0, number_cache.n_hexes_level.size()));
@@ -5086,8 +12148,8 @@ unsigned int Triangulation<dim>::n_active_hexs (const unsigned int level) const
 #endif
 
 
-template <int dim>
-unsigned int Triangulation<dim>::n_levels () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::n_levels () const
 {
   if (levels.size() == 0)
     return 0;
@@ -5112,27 +12174,27 @@ unsigned int Triangulation<dim>::n_levels () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-Triangulation<dim>::n_vertices () const 
+Triangulation<dim, spacedim>::n_vertices () const 
 {
   return vertices.size();
 }
 
 
 
-template <int dim>
-const std::vector<Point<dim> > &
-Triangulation<dim>::get_vertices () const 
+template <int dim, int spacedim>
+const std::vector<Point<spacedim> > &
+Triangulation<dim, spacedim>::get_vertices () const 
 {
   return vertices;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-Triangulation<dim>::n_used_vertices () const 
+Triangulation<dim, spacedim>::n_used_vertices () const 
 {
   return std::count_if (vertices_used.begin(), vertices_used.end(),
                        std::bind2nd (std::equal_to<bool>(), true));
@@ -5140,9 +12202,9 @@ Triangulation<dim>::n_used_vertices () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 const std::vector<bool> &
-Triangulation<dim>::get_used_vertices () const 
+Triangulation<dim, spacedim>::get_used_vertices () const 
 {
   return vertices_used;
 }
@@ -5151,7 +12213,7 @@ Triangulation<dim>::get_used_vertices () const
 #if deal_II_dimension == 1
 
 template <>
-unsigned int Triangulation<1>::max_adjacent_cells () const
+unsigned int Triangulation<1,1>::max_adjacent_cells () const
 {
   return 2;
 }
@@ -5159,11 +12221,11 @@ unsigned int Triangulation<1>::max_adjacent_cells () const
 #endif
 
 
-template <int dim>
-unsigned int Triangulation<dim>::max_adjacent_cells () const
+template <int dim, int spacedim>
+unsigned int Triangulation<dim, spacedim>::max_adjacent_cells () const
 {
   cell_iterator cell = begin(0),
-               endc = (levels.size() > 1 ? begin(1) : cell_iterator(end()));
+               endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
                                   // store the largest index of the
                                   // vertices used on level 0
   unsigned int max_vertex_index = 0;
@@ -5191,9 +12253,9 @@ unsigned int Triangulation<dim>::max_adjacent_cells () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-Triangulation<dim>::execute_coarsening_and_refinement ()
+Triangulation<dim, spacedim>::execute_coarsening_and_refinement ()
 {
   prepare_coarsening_and_refinement ();
 
@@ -5223,9 +12285,9 @@ Triangulation<dim>::execute_coarsening_and_refinement ()
 }
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
-Triangulation<dim>::clear_despite_subscriptions()
+Triangulation<dim, spacedim>::clear_despite_subscriptions()
 {
                                   // This is the former function
                                   // clear without the assertion in
@@ -5247,248 +12309,20 @@ Triangulation<dim>::clear_despite_subscriptions()
 }
 
 
-#if deal_II_dimension == 1
-
-template <>
+template <int dim, int spacedim>
 void
-Triangulation<1>::execute_refinement ()
+Triangulation<dim,spacedim>::execute_refinement ()
 {
-  const unsigned int dim = 1;
-  
-                                  // check whether a new level is
-                                  // needed we have to check for this
-                                  // on the highest level only (on
-                                  // this, all used cells are also
-                                  // active, so we only have to check
-                                  // for this)
-  if (true)
-    {
-      raw_cell_iterator cell = begin_active (levels.size()-1),
-                       endc = end();
-      for (; cell != endc; ++cell)
-       if (cell->used())
-         if (cell->refine_flag_set()) 
-           {
-             levels.push_back (new internal::Triangulation::TriaLevel<dim>);
-             break;
-           }
-    }
-
-
-                                  // check how much space is needed
-                                  // on every level we need not check
-                                  // the highest level since either -
-                                  // on the highest level no cells
-                                  // are flagged for refinement -
-                                  // there are, but
-                                  // prepare_refinement added another
-                                  // empty level
-  unsigned int needed_vertices = 0;
-  for (int level=levels.size()-2; level>=0; --level)
-    {
-                                      // count number of flagged
-                                      // cells on this level
-      unsigned int flagged_cells = 0;
-      active_cell_iterator acell = begin_active(level),
-                          aendc = begin_active(level+1);
-      for (; acell!=aendc; ++acell) 
-       if (acell->refine_flag_set())
-         ++flagged_cells;
-
-                                      // count number of used cells
-                                      // on the next higher level
-      const unsigned int used_cells
-       =  std::count_if (levels[level+1]->cells.used.begin(),
-                         levels[level+1]->cells.used.end(),
-                         std::bind2nd (std::equal_to<bool>(), true));
-
-                                      // reserve space for the
-                                      // used_cells cells already
-                                      // existing on the next higher
-                                      // level as well as for the
-                                      // 2*flagged_cells that will be
-                                      // created on that level
-      levels[level+1]->reserve_space(
-       used_cells+
-       GeometryInfo<1>::max_children_per_cell * flagged_cells, 1);
-                                      // reserve space for
-                                      // 2*flagged_cells new lines on
-                                      // the next higher level to be
-                                      // stored in pairs
-                                      // the next higher level
-      levels[level+1]->cells.
-       reserve_space (GeometryInfo<1>::max_children_per_cell*flagged_cells, 0);
-      
-      needed_vertices += flagged_cells;
-    }
-
-                                  // add to needed vertices how many
-                                  // vertices are already in use
-  needed_vertices += std::count_if (vertices_used.begin(), vertices_used.end(),
-                                   std::bind2nd (std::equal_to<bool>(), true));
-                                  // if we need more vertices: create
-                                  // them, if not: leave the array as
-                                  // is, since shrinking is not
-                                  // really possible because some of
-                                  // the vertices at the end may be
-                                  // in use
-  if (needed_vertices > vertices.size())
-    {
-      vertices.resize (needed_vertices, Point<1>());
-      vertices_used.resize (needed_vertices, false);
-    }
-
-
-                                  // Do REFINEMENT
-                                  // on every level; exclude highest
-                                  // level as above
-
-                                  // index of next unused vertex
-  unsigned int next_unused_vertex = 0;
-  
-  for (int level=levels.size()-2; level>=0; --level) 
-    {
-      
-      active_cell_iterator cell = begin_active(level),
-                          endc = begin_active(level+1);
-      
-      raw_cell_iterator next_unused_cell = begin_raw (level+1);
-
-      for (; (cell!=endc) && (cell->level()==level); ++cell) 
-       if (cell->refine_flag_set()) 
-         {
-                                            // clear refinement flag
-           cell->clear_refine_flag ();
+  Implementation::execute_refinement (*this);
 
-                                            // search for next unused
-                                            // vertex
-           while (vertices_used[next_unused_vertex] == true)
-             ++next_unused_vertex;
-           Assert (next_unused_vertex < vertices.size(),
-                   ExcTooFewVerticesAllocated());
-           
-                                            // first insert new vertex
-           Point<1> new_point = cell->vertex(0);
-           new_point += cell->vertex(1);
-           new_point /= 2.0;
-           
-           vertices[next_unused_vertex] = new_point;
-           vertices_used[next_unused_vertex] = true;
-
-                                            // search for next two
-                                            // unused cell (++ takes
-                                            // care of the end of the
-                                            // vector)
-           raw_cell_iterator first_child, second_child;
-           while (next_unused_cell->used() == true)
-             ++next_unused_cell;
-           first_child = next_unused_cell;
-           first_child->set_used_flag ();
-           first_child->clear_user_data ();
-           ++next_unused_cell;
-           Assert (next_unused_cell->used() == false,
-                   ExcCellShouldBeUnused());
-           second_child = next_unused_cell;
-           second_child->set_used_flag ();
-           second_child->clear_user_data ();
-
-                                            // insert first child
-           cell->set_children (0, first_child->index());
-           first_child->clear_children ();
-           first_child->set (internal::Triangulation
-                              ::TriaObject<1> (cell->vertex_index(0),
-                                              next_unused_vertex));
-           first_child->set_material_id (cell->material_id());
-           first_child->set_subdomain_id (cell->subdomain_id());           
-           
-                                            // reset neighborship info (refer
-                                            // to
-                                            // internal::Triangulation::TriaLevel<0>
-                                            // for details)
-           first_child->set_neighbor (1, second_child);
-           if (cell->neighbor(0).state() != IteratorState::valid)
-             first_child->set_neighbor (0, cell->neighbor(0));
-           else
-             if (cell->neighbor(0)->active())
-               {
-                                                  // since the
-                                                  // neighbors level
-                                                  // is always
-                                                  // <=level, if the
-                                                  // cell is active,
-                                                  // then there are
-                                                  // no cells to the
-                                                  // left which may
-                                                  // want to know
-                                                  // about this new
-                                                  // child cell.
-                 Assert (cell->neighbor(0)->level() <= cell->level(),
-                         ExcInternalError());
-                 first_child->set_neighbor (0, cell->neighbor(0));
-               }
-             else
-                                                // left neighbor is
-                                                // refined
-               {
-                                                  // set neighbor to
-                                                  // cell on same
-                                                  // level
-                 first_child->set_neighbor (0, cell->neighbor(0)->child(1));
-
-                                                  // reset neighbor
-                                                  // info of all
-                                                  // right descendant
-                                                  // of the left
-                                                  // neighbor of cell
-                 cell_iterator left_neighbor = cell->neighbor(0);
-                 while (left_neighbor->has_children())
-                   {
-                     left_neighbor = left_neighbor->child(1);
-                     left_neighbor->set_neighbor (1, first_child);
-                   }
-               }
-           
-                                            // insert second child
-           second_child->clear_children ();
-           second_child->set (internal::Triangulation
-                               ::TriaObject<1>(next_unused_vertex,
-                                              cell->vertex_index(1)));
-           second_child->set_neighbor (0, first_child);
-           second_child->set_material_id (cell->material_id());
-           second_child->set_subdomain_id (cell->subdomain_id());          
-           if (cell->neighbor(1).state() != IteratorState::valid)
-             second_child->set_neighbor (1, cell->neighbor(1));
-           else
-             if (cell->neighbor(1)->active())
-               {
-                 Assert (cell->neighbor(1)->level() <= cell->level(),
-                         ExcInternalError());
-                 second_child->set_neighbor (1, cell->neighbor(1));
-               }
-             else
-                                                // right neighbor is
-                                                // refined same as
-                                                // above
-               {
-                 second_child->set_neighbor (1, cell->neighbor(1)->child(0));
-                 
-                 cell_iterator right_neighbor = cell->neighbor(1);
-                 while (right_neighbor->has_children())
-                   {
-                     right_neighbor = right_neighbor->child(0);
-                     right_neighbor->set_neighbor (0, second_child);
-                   }
-               }
-         }      
-    }
 
 
                                   // re-compute number of lines
-  update_number_cache ();
+  compute_number_cache (*this, number_cache);
   
 #ifdef DEBUG
   for (unsigned int level=0; level<levels.size(); ++level) 
-    levels[level]->cells.monitor_memory (1);
+    levels[level]->cells.monitor_memory (dim);
 
                                   // check whether really all
                                   // refinement flags are reset (also
@@ -5503,8173 +12337,1734 @@ Triangulation<1>::execute_refinement ()
                endc = end();
   while (cell != endc)
     Assert (!(cell++)->refine_flag_set(), ExcInternalError ());  
-#endif
+#endif  
 }
 
-#endif
-
 
-#if deal_II_dimension == 2
 
-template <>
-void
-Triangulation<2>::execute_refinement ()
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::execute_coarsening ()
 {
-  const unsigned int dim = 2;
+                                  // create a vector counting for each line how
+                                  // many cells contain this line. in 3D, this
+                                  // is used later on to decide which lines can
+                                  // be deleted after coarsening a cell. in
+                                  // other dimensions it will be ignored
+  std::vector<unsigned int> line_cell_count = count_cells_bounded_by_line (*this);
+  std::vector<unsigned int> quad_cell_count = count_cells_bounded_by_quad (*this);
   
-                                  // check whether a new level is
-                                  // needed we have to check for this
-                                  // on the highest level only (on
-                                  // this, all used cells are also
-                                  // active, so we only have to check
-                                  // for this)
-  if (true)
-    {
-      raw_cell_iterator cell = begin_active (levels.size()-1),
-                       endc = end();
-      for (; cell != endc; ++cell)
-       if (cell->used())
-         if (cell->refine_flag_set()) 
+                                  // loop over all cells. Flag all
+                                  // cells of which all children are
+                                  // flagged for
+                                  // coarsening and delete the childrens'
+                                  // flags. In effect, only those
+                                  // cells are flagged of which originally
+                                  // all children were flagged and for which
+                                  // all children are on the same refinement
+                                  // level. For flagging, the user flags are
+                                  // used, to avoid confusion and because
+                                  // non-active cells can't be flagged for
+                                  // coarsening. Note that because of the
+                                  // effects of @p{fix_coarsen_flags}, of a
+                                  // cell either all or no children must
+                                  // be flagged for coarsening, so it is
+                                  // ok to only check the first child
+  clear_user_flags ();
+
+  cell_iterator cell = begin(),
+               endc = end();
+  for (; cell!=endc; ++cell) 
+    if (!cell->active())
+      if (cell->child(0)->coarsen_flag_set())
+       {
+         cell->set_user_flag();
+         for (unsigned int child=0; child<cell->n_children(); ++child)
            {
-             levels.push_back (new internal::Triangulation::TriaLevel<dim>);
-             break;
+             Assert (cell->child(child)->coarsen_flag_set(),
+                     ExcInternalError());
+             cell->child(child)->clear_coarsen_flag();
            }
-    }
-
-
-                                  // first clear user flags and
-                                  // pointers of lines; we're going
-                                  // to use them to flag which lines
-                                  // need refinement
-  for (line_iterator line=begin_line(); line!=end_line(); ++line)
-    {
-      line->clear_user_flag();
-      line->clear_user_data();
-    }
-                                  // running over all cells and lines
-                                  // count the number
-                                  // n_single_lines of lines
-                                  // which can be stored as
-                                  // single lines, e.g. inner lines
-  unsigned int n_single_lines=0;
-                                  // New lines to be created:
-                                  // number lines which are
-                                  // stored in pairs (the
-                                  // children of lines must be
-                                  // stored in pairs)
-  unsigned int n_lines_in_pairs = 0;
-
-                                  // check how much space is needed
-                                  // on every level we need not check
-                                  // the highest level since either
-                                  // - on the highest level no cells
-                                  //   are flagged for refinement
-                                  // - there are, but prepare_refinement
-                                  //   added another empty level
-  unsigned int needed_vertices = 0;
-  for (int level=levels.size()-2; level>=0; --level)
-    {
-                                      // count number of flagged
-                                      // cells on this level and
-                                      // compute how many new
-                                      // vertices and new lines will
-                                      // be needed
-      unsigned int needed_cells = 0;
-
-      active_cell_iterator cell = begin_active(level),
-                          endc = begin_active(level+1);
-      for (; cell!=endc; ++cell) 
-       if (cell->refine_flag_set()) 
-         {
-           if (cell->refine_flag_set()==RefinementCase<dim>::cut_xy)
-             {
-               needed_cells += 4;
-               
-                                                // new vertex at
-                                                // center of cell is
-                                                // needed in any case
-               ++needed_vertices;
-                                                // the four inner
-                                                // lines can be
-                                                // stored as singles
-               n_single_lines += 4;
-             }
-           else // cut_x || cut_y
-             {
-                                                // set the flag showing that
-                                                // anisotropic refinement is
-                                                // used for at least one cell
-               anisotropic_refinement=true;
-               
-               needed_cells += 2;
-                                                // no vertex at center
-               
-                                                // the inner line can
-                                                // be stored as
-                                                // single
-               n_single_lines += 1;
+       }
 
-             }
-           
-                                                // mark all faces
-                                                // (lines) for
-                                                // refinement;
-                                                // checking locally
-                                                // whether the
-                                                // neighbor would
-                                                // also like to
-                                                // refine them is
-                                                // rather difficult
-                                                // for lines so we
-                                                // only flag them and
-                                                // after visiting all
-                                                // cells, we decide
-                                                // which lines need
-                                                // refinement;
-           for (unsigned int line_no=0; line_no<GeometryInfo<dim>::faces_per_cell;
-                ++line_no)
-             {
-               if (GeometryInfo<dim>::face_refinement_case(
-                     cell->refine_flag_set(), line_no)==RefinementCase<1>::cut_x)
-                 {
-                   line_iterator line = cell->line(line_no);
-                   if (line->has_children() == false) 
-                     line->set_user_flag ();
-                 }
-             }
-         }
 
-      
-                                      // count number of used cells
-                                      // on the next higher level
-      const unsigned int used_cells
-       = std::count_if (levels[level+1]->cells.used.begin(),
-                        levels[level+1]->cells.used.end(),
-                        std::bind2nd (std::equal_to<bool>(), true));
-      
+                                  // now do the actual coarsening
+                                  // step. Since the loop goes over
+                                  // used cells we only need not
+                                  // worry about deleting some cells
+                                  // since the ++operator will then
+                                  // just hop over them if we should
+                                  // hit one. Do the loop in the
+                                  // reverse way since we may only
+                                  // delete some cells if their
+                                  // neighbors have already been
+                                  // deleted (if the latter are on a
+                                  // higher level for example)
+                                  //
+                                  // if there is only one level,
+                                  // there can not be anything to do
+  if (levels.size() >= 2)
+    for (cell = last(levels.size()-2); cell!=endc; --cell)
+      if (cell->user_flag_set())
+                                        // use a separate function,
+                                        // since this is dimension
+                                        // specific
+       Implementation::delete_children (*this, cell,
+                                        line_cell_count, quad_cell_count);
 
-                                      // reserve space for the
-                                      // used_cells cells already
-                                      // existing on the next higher
-                                      // level as well as for the
-                                      // needed_cells that will be
-                                      // created on that level
-      levels[level+1]->reserve_space (used_cells+needed_cells, 2);
-
-                                      // reserve space for
-                                      // needed_cells
-                                      // new quads on the next higher
-                                      // level
-      levels[level+1]->cells.
-        reserve_space (needed_cells,0);
-    }
+                                  // re-compute number of lines and
+                                  // quads
+  compute_number_cache (*this, number_cache);
 
-                                  // 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());
-       n_lines_in_pairs += 2;
-       needed_vertices  += 1;
-      }
-                                  // reserve space for
-                                  // n_lines_in_pairs new lines.
-                                  // note, that we can't reserve space
-                                  // for the single lines here as well,
-                                  // as all the space reserved for lines
-                                  // in pairs would be counted as unused
-                                  // and we would end up with too little
-                                  // space to store all lines. memory
-                                  // reservation for n_single_lines can
-                                  // only be done AFTER we refined the lines
-                                  // of the current cells
-  faces->lines.
-    reserve_space (n_lines_in_pairs, 0);
-  
-                                  // add to needed vertices how many
-                                  // vertices are already in use
-  needed_vertices += std::count_if (vertices_used.begin(), vertices_used.end(),
-                                   std::bind2nd (std::equal_to<bool>(), true));
-                                  // if we need more vertices: create
-                                  // them, if not: leave the array as
-                                  // is, since shrinking is not
-                                  // really possible because some of
-                                  // the vertices at the end may be
-                                  // in use
-  if (needed_vertices > vertices.size())
-    {
-      vertices.resize (needed_vertices, Point<dim>());
-      vertices_used.resize (needed_vertices, false);
-    }
+                                  // in principle no user flags
+                                  // should be
+                                  // set any more at this point
+#if DEBUG
+  for (cell=begin(); cell!=endc; ++cell)
+    Assert (cell->user_flag_set() == false, ExcInternalError());
+#endif
+}
 
 
-                                  // Do REFINEMENT  
-                                  // on every level; exclude highest
-                                  // level as above
 
-                                  //  index of next unused vertex
-  unsigned int next_unused_vertex = 0;
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::fix_coarsen_flags ()
+{
+                                  // copy a piece of code from
+                                  // prepare_coarsening_and_refinement that
+                                  // ensures that the level difference at
+                                  // vertices is limited if so desired. we
+                                  // need this code here since at least in 1d
+                                  // we don't call the dimension-independent
+                                  // version of
+                                  // prepare_coarsening_and_refinement
+                                  // function. in 2d and 3d, having this hunk
+                                  // here makes our lives a bit easier as
+                                  // well as it takes care of these cases
+                                  // earlier than it would otherwise happen.
+                                  //
+                                  // the main difference to the code
+                                  // in p_c_and_r is that here we
+                                  // absolutely have to make sure
+                                  // that we get things right,
+                                  // i.e. that in particular we set
+                                  // flags right if
+                                  // limit_level_difference_at_vertices
+                                  // is set. to do so we iterate
+                                  // until the flags don't change any
+                                  // more
+  std::vector<bool> previous_coarsen_flags (n_active_cells());
+  save_coarsen_flags (previous_coarsen_flags);
 
-                                  // first the refinement of lines.
-                                  // children are stored pairwise
-  if (true)
+  bool continue_iterating = true;
+  
+  do
     {
-                                      // only active objects can be
-                                      // refined further
-      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())
-         {
-                                            // this line needs to be
-                                            // refined
-
-                                            // find the next unused
-                                            // vertex and set it
-                                            // appropriately
-           while (vertices_used[next_unused_vertex] == true)
-             ++next_unused_vertex;
-           Assert (next_unused_vertex < vertices.size(),
-                   ExcTooFewVerticesAllocated());
-           vertices_used[next_unused_vertex] = true;
-
-           if (line->at_boundary())
-             vertices[next_unused_vertex]
-               = boundary[line->boundary_indicator()]->get_new_point_on_line (line);
-           else
-             vertices[next_unused_vertex]
-               = (line->vertex(0) + line->vertex(1)) / 2;
+      if (smooth_grid & limit_level_difference_at_vertices)
+       {
+         Assert(!anisotropic_refinement,
+                ExcMessage("In case of anisotropic refinement the "
+                           "limit_level_difference_at_vertices flag for "
+                           "mesh smoothing must not be set!"));
          
-                                            // now that we created
-                                            // the right point, make
-                                            // up the two child
-                                            // lines.  To this end,
-                                            // find a pair of unused
-                                            // lines
-           bool pair_found=false;
-           for (; next_unused_line!=endl; ++next_unused_line)
-             if (!next_unused_line->used() &&
-                 !(++next_unused_line)->used())
-               {
-                                                  // go back to the
-                                                  // first of the two
-                                                  // unused lines
-                 --next_unused_line;
-                 pair_found=true;
-                 break;
+                                          // store highest level one
+                                          // of the cells adjacent to
+                                          // a vertex belongs to
+         std::vector<int> vertex_level (vertices.size(), 0);
+         active_cell_iterator cell = begin_active(),
+                              endc = end();
+         for (; cell!=endc; ++cell)
+           {
+             if (cell->refine_flag_set())
+               for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+                    ++vertex)
+                 vertex_level[cell->vertex_index(vertex)]
+                   = std::max (vertex_level[cell->vertex_index(vertex)],
+                               cell->level()+1);
+             else if (!cell->coarsen_flag_set())
+               for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+                    ++vertex)
+                 vertex_level[cell->vertex_index(vertex)]
+                   = std::max (vertex_level[cell->vertex_index(vertex)],
+                               cell->level());
+             else
+               {
+                                                  // if coarsen flag is
+                                                  // set then tentatively
+                                                  // assume that the cell
+                                                  // will be
+                                                  // coarsened. this
+                                                  // isn't always true
+                                                  // (the coarsen flag
+                                                  // could be removed
+                                                  // again) and so we may
+                                                  // make an error
+                                                  // here. we try to
+                                                  // correct this by
+                                                  // iterating over the
+                                                  // entire process until
+                                                  // we are converged
+                 Assert (cell->coarsen_flag_set(), ExcInternalError());
+                 for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+                      ++vertex)
+                   vertex_level[cell->vertex_index(vertex)]
+                     = std::max (vertex_level[cell->vertex_index(vertex)],
+                                 cell->level()-1);
                }
-           Assert (pair_found, ExcInternalError());
-
-                                            // there are now two
-                                            // consecutive unused
-                                            // lines, such that the
-                                            // children of a line
-                                            // will be consecutive.
-                                            // then set the child
-                                            // pointer of the present
-                                            // line
-           line->set_children (0, next_unused_line->index());
-         
-                                            // set the two new lines
-           const raw_line_iterator children[2] = { next_unused_line,
-                                                   ++next_unused_line };
-                                            // some tests; if any of
-                                            // the iterators should
-                                            // be invalid, then
-                                            // already dereferencing
-                                            // will fail
-           Assert (children[0]->used() == false, ExcCellShouldBeUnused());
-           Assert (children[1]->used() == false, ExcCellShouldBeUnused());
-         
-           children[0]->set (internal::Triangulation
-                              ::TriaObject<1>(line->vertex_index(0),
-                                             next_unused_vertex));
-           children[1]->set (internal::Triangulation
-                              ::TriaObject<1>(next_unused_vertex,
-                                             line->vertex_index(1)));
-    
-           children[0]->set_used_flag();
-           children[1]->set_used_flag();
-           children[0]->clear_children();
-           children[1]->clear_children();
-           children[0]->clear_user_data();
-           children[1]->clear_user_data();
-           children[0]->clear_user_flag();
-           children[1]->clear_user_flag();
-
-           children[0]->set_boundary_indicator (line->boundary_indicator());
-           children[1]->set_boundary_indicator (line->boundary_indicator());
-           
-                                            // finally clear flag
-                                            // indicating the need
-                                            // for refinement
-           line->clear_user_flag ();
-         }
-    }
+           }
+      
+
+                                          // loop over all cells in reverse
+                                          // order. do so because we can then
+                                          // update the vertex levels on the
+                                          // adjacent vertices and maybe
+                                          // already flag additional cells in
+                                          // this loop
+                                          //
+                                          // note that not only may we have
+                                          // to add additional refinement
+                                          // flags, but we will also have to
+                                          // remove coarsening flags on cells
+                                          // adjacent to vertices that will
+                                          // see refinement
+         for (cell=last_active(); cell != endc; --cell)
+           if (cell->refine_flag_set() == false)
+             {
+               for (unsigned int vertex=0;
+                    vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+                 if (vertex_level[cell->vertex_index(vertex)] >=
+                     cell->level()+1)
+                   {
+                                                      // remove coarsen flag...
+                     cell->clear_coarsen_flag();
+
+                                                      // ...and if necessary also
+                                                      // refine the current cell,
+                                                      // at the same time
+                                                      // updating the level
+                                                      // information about
+                                                      // vertices
+                     if (vertex_level[cell->vertex_index(vertex)] >
+                         cell->level()+1)
+                       {
+                         cell->set_refine_flag();
+                     
+                         for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
+                              ++v)
+                           vertex_level[cell->vertex_index(v)]
+                             = std::max (vertex_level[cell->vertex_index(v)],
+                                         cell->level()+1);
+                       }
 
+                                                      // continue and see whether
+                                                      // we may, for example, go
+                                                      // into the inner 'if'
+                                                      // above based on a
+                                                      // different vertex
+                   }
+             }
+       }
   
-                                  // Now set up the new cells
-
-                                  // reserve space for inner
-                                  // lines (can be stored as
-                                  // single lines)
-  faces->lines.
-    reserve_space (0,n_single_lines);
-
-                                  // reset next_unused_line, as
-                                  // now also single empty places
-                                  // in the vector can be used
-  raw_line_iterator next_unused_line = begin_raw_line ();
-                                  // dummy argument needed for the call to
-                                  // create_children()
-  raw_quad_iterator dummy_quad;
+                                      // loop over all cells. Flag all
+                                      // cells of which all children are
+                                      // flagged for coarsening and
+                                      // delete the childrens'
+                                      // flags. Also delete all flags of
+                                      // cells for which not all children
+                                      // of a cell are flagged. In
+                                      // effect, only those cells are
+                                      // flagged of which originally all
+                                      // children were flagged and for
+                                      // which all children are on the
+                                      // same refinement level. For
+                                      // flagging, the user flags are
+                                      // used, to avoid confusion and
+                                      // because non-active cells can't
+                                      // be flagged for coarsening
+                                      //
+                                      // In effect, all coarsen flags are
+                                      // turned into user flags of the
+                                      // mother cell if coarsening is
+                                      // possible or deleted
+                                      // otherwise.
+      clear_user_flags ();
+                                      // Coarsen flags of
+                                      // cells with no mother cell,
+                                      // i.e. on the coarsest level are
+                                      // deleted explicitly.
+      active_cell_iterator acell  = begin_active(0),
+                          end_ac = end_active(0);
+      for (; acell!=end_ac; ++acell)
+       acell->clear_coarsen_flag();
   
-  for (int level=0; level<static_cast<int>(levels.size())-1; ++level) 
-    {
-      
-                                      // Remember: as we don't operate
-                                      // on the finest level, begin_*(level+1)
-                                      // is allowed
-      active_cell_iterator cell = begin_active(level),
-                          endc = begin_active(level+1);
-      
-      raw_cell_iterator next_unused_cell = begin_raw (level+1);
-
+      cell_iterator cell = begin(),
+                   endc = end();
       for (; cell!=endc; ++cell) 
-       if (cell->refine_flag_set()) 
-         {
-                                            // set the user flag to
-                                            // indicate, that at least one
-                                            // line is at the boundary
-           
-                                            // TODO[Tobias Leicht] find a
-                                            // better place to set this flag,
-                                            // so that we do not need so much
-                                            // time to check each cell here
-           if (cell->at_boundary())
-             cell->set_user_flag();
-                                            // actually set up the children and
-                                            // update neighbor information
-           create_children(next_unused_vertex,
-                           next_unused_line,
-                           dummy_quad,
-                           next_unused_cell,
-                           cell);
-         }
-    }
-
-                                  // re-compute number of lines and
-                                  // quads
-  update_number_cache ();
+       {
+                                          // nothing to do if we are
+                                          // already on the finest level
+         if (cell->active()) 
+           continue;
 
+         const unsigned int n_children=cell->n_children();
+         unsigned int flagged_children=0;
+         for (unsigned int child=0; child<n_children; ++child)
+           if (cell->child(child)->active() &&
+               cell->child(child)->coarsen_flag_set()) 
+             {
+               ++flagged_children;
+                                                // clear flag since we
+                                                // don't need it anymore
+               cell->child(child)->clear_coarsen_flag();
+             }
+         
+                                          // flag this cell for
+                                          // coarsening if all children
+                                          // were flagged
+         if (flagged_children == n_children)
+           cell->set_user_flag();
+       }
+      
+                                      // in principle no coarsen flags
+                                      // should be set any more at this
+                                      // point
+#if DEBUG
+      for (cell=begin(); cell!=endc; ++cell)
+       Assert (cell->coarsen_flag_set() == false, ExcInternalError());
+#endif
 
-#ifdef DEBUG
-  for (unsigned int level=0; level<levels.size(); ++level) 
-    levels[level]->cells.monitor_memory (2);
+                                      // now loop over all cells which have the
+                                      // user flag set. their children were
+                                      // flagged for coarsening. set the coarsen
+                                      // flag again if we are sure that none of
+                                      // the neighbors of these children are
+                                      // refined, or will be refined, since then
+                                      // we would get a two-level jump in
+                                      // refinement. on the other hand, if one of
+                                      // the children's neighbors has their user
+                                      // flag set, then we know that its children
+                                      // will go away by coarsening, and we will
+                                      // be ok.
+                                      //
+                                      // note on the other hand that we do allow
+                                      // level-2 jumps in refinement between
+                                      // neighbors in 1d, so this whole procedure
+                                      // is only necessary if we are not in 1d
+                                      //
+                                      // since we remove some coarsening/user
+                                      // flags in the process, we have to work
+                                      // from the finest level to the coarsest
+                                      // one, since we occasionally inspect user
+                                      // flags of cells on finer levels and need
+                                      // to be sure that these flags are final
+      for (cell=last(); cell!=endc; --cell)
+       if (cell->user_flag_set())
+                                          // if allowed: flag the
+                                          // children for coarsening
+         if (Implementation::template coarsening_allowed<dim,spacedim>(cell))
+           for (unsigned int c=0; c<cell->n_children(); ++c)
+             {
+               Assert (cell->child(c)->refine_flag_set()==false,
+                       ExcInternalError());
+           
+               cell->child(c)->set_coarsen_flag();
+             }
+  
+                                      // clear all user flags again, now that we
+                                      // don't need them any more
+      clear_user_flags ();
 
-                                  // check whether really all
-                                  // refinement flags are reset (also
-                                  // of previously non-active cells
-                                  // which we may not have
-                                  // touched. If the refinement flag
-                                  // of a non-active cell is set,
-                                  // something went wrong since the
-                                  // cell-accessors should have
-                                  // caught this)
-  line_iterator line = begin_line(),
-               endl = end_line();
-  while (line != endl)
-    Assert (!(line++)->user_flag_set(), ExcInternalError ());
+      
+                                      // now see if anything has
+                                      // changed in the last
+                                      // iteration of this function
+      std::vector<bool> current_coarsen_flags (n_active_cells());
+      save_coarsen_flags (current_coarsen_flags);
 
-  cell_iterator cell = begin(),
-               endc = end();
-  while (cell != endc)
-    Assert (!(cell++)->refine_flag_set(), ExcInternalError ());
-#endif
+      continue_iterating = (current_coarsen_flags != previous_coarsen_flags);
+      previous_coarsen_flags = current_coarsen_flags;
+    }
+  while (continue_iterating == true);
 }
 
-#endif
-
 
-#if deal_II_dimension == 3
+#if deal_II_dimension == 1
 
 template <>
-void
-Triangulation<3>::execute_refinement ()
+bool Triangulation<1,1>::prepare_coarsening_and_refinement ()
 {
-  const unsigned int dim = 3;
+                                  // save the flags to determine
+                                  // whether something was changed in
+                                  // the course of this function
+  std::vector<bool> flags_before;
+  save_coarsen_flags (flags_before);
+
+                                  // do nothing in 1d, except setting
+                                  // the coarsening flags correctly
+  fix_coarsen_flags ();
+  
+  std::vector<bool> flags_after;
+  save_coarsen_flags (flags_after);
+  
+  return (flags_before != flags_after);
+}
 
-                                  // check whether a new level is
-                                  // needed we have to check for this
-                                  // on the highest level only (on
-                                  // this, all used cells are also
-                                  // active, so we only have to check
-                                  // for this)
-  if (true)
-    {
-      raw_cell_iterator cell = begin_active (levels.size()-1),
-                       endc = end();
-      for (; cell != endc; ++cell)
-       if (cell->used())
-         if (cell->refine_flag_set()) 
-           {
-             levels.push_back (new internal::Triangulation::TriaLevel<dim>);
-             break;
-           }
-    }
 
+template <>
+bool Triangulation<1,2>::prepare_coarsening_and_refinement ()
+{
+                                  // save the flags to determine
+                                  // whether something was changed in
+                                  // the course of this function
+  std::vector<bool> flags_before;
+  save_coarsen_flags (flags_before);
 
-                                  // first clear user flags for quads
-                                  // and lines; we're going to use them
-                                  // to flag which lines and quads
-                                  // need refinement
-  faces->quads.clear_user_data();
+                                  // do nothing in 1d, except setting
+                                  // the coarsening flags correctly
+  fix_coarsen_flags ();
   
-  for (line_iterator line=begin_line(); line!=end_line(); ++line)
-    line->clear_user_flag();
-  for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad)
-    {
-      quad->clear_user_flag();
-    }
-                                  // create an array of face refine cases. User
-                                  // indices of faces will be set to values
-                                  // corresponding with indices in this array.
-  const RefinementCase<dim-1>  face_refinement_cases[4]=
-    {RefinementCase<dim-1>::no_refinement,
-     RefinementCase<dim-1>::cut_x,
-     RefinementCase<dim-1>::cut_y,
-     RefinementCase<dim-1>::cut_xy};
+  std::vector<bool> flags_after;
+  save_coarsen_flags (flags_after);
   
-                                  // check how much space is needed
-                                  // on every level
-                                  // we need not check the highest
-                                  // level since either
-                                  // - on the highest level no cells
-                                  //   are flagged for refinement
-                                  // - there are, but prepare_refinement
-                                  //   added another empty level which
-                                  //   then is the highest level
-
-                                  // variables to hold the number of newly to
-                                  // be created vertices, lines and quads. as
-                                  // these are stored globally, declare them
-                                  // outside the loop over al levels. we need
-                                  // lines and quads in pairs for refinement of
-                                  // old ones and lines and quads, that can be
-                                  // stored as single ones, as they are newly
-                                  // created in the inside of an existing cell
-  unsigned int needed_vertices = 0;
-  unsigned int needed_lines_single  = 0;
-  unsigned int needed_quads_single  = 0;
-  unsigned int needed_lines_pair  = 0;
-  unsigned int needed_quads_pair  = 0;
-  for (int level=levels.size()-2; level>=0; --level)
-    {
-                                      // count number of flagged
-                                      // cells on this level and
-                                      // compute how many new
-                                      // vertices and new lines will
-                                      // be needed
-      unsigned int new_cells = 0;
-      
-      active_cell_iterator acell = begin_active(level),
-                          aendc = begin_active(level+1);
-      for (; acell!=aendc; ++acell) 
-       if (acell->refine_flag_set()) 
-         {
-           RefinementCase<dim> ref_case=acell->refine_flag_set();
-           
-                                            // now for interior vertices, lines
-                                            // and quads, which are needed in
-                                            // any case
-           if (ref_case==RefinementCase<dim>::cut_x ||
-               ref_case==RefinementCase<dim>::cut_y ||
-               ref_case==RefinementCase<dim>::cut_z)
-             {
-               ++needed_quads_single;
-               new_cells+=2;
-               anisotropic_refinement=true;
-             }
-           else if (ref_case==RefinementCase<dim>::cut_xy ||
-                    ref_case==RefinementCase<dim>::cut_xz ||
-                    ref_case==RefinementCase<dim>::cut_yz)
-             {
-               ++needed_lines_single;
-               needed_quads_single += 4;
-               new_cells+=4;
-               anisotropic_refinement=true;
-             }
-           else if  (ref_case==RefinementCase<dim>::cut_xyz)
-             {
-               ++needed_vertices;
-               needed_lines_single += 6;
-               needed_quads_single += 12;
-               new_cells+=8;
-             }
-           else
-             {
-                                                // we should never get here
-               Assert(false, ExcInternalError());
-             }
-           
-                                            // mark all faces for refinement;
-                                            // checking locally
-                                            // if and how the neighbor
-                                            // would like to
-                                            // refine these is
-                                            // difficult so
-                                            // we only flag them and
-                                            // after visiting all
-                                            // cells, we decide which
-                                            // faces need which refinement;
-           for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell;
-                ++face)
-             {
-               face_iterator aface = acell->face(face);
-                                                // get the RefineCase this
-                                                // faces has for the given
-                                                // RefineCase of the cell
-               RefinementCase<dim-1> face_ref_case=
-                 GeometryInfo<dim>::face_refinement_case(ref_case,
-                                                         face,
-                                                         acell->face_orientation(face),
-                                                         acell->face_flip(face),
-                                                         acell->face_rotation(face));
-                                                // only do something, if this
-                                                // face has to be refined
-               if (face_ref_case)
-                 {
-                   if (face_ref_case==RefinementCase<dim-1>::isotropic_refinement)
-                     {
-                       if (aface->number_of_children()<4)
-                                                          // we use user_flags to
-                                                          // denote needed isotropic
-                                                          // refinement
-                         aface->set_user_flag();
-                     }
-                   else if (aface->refinement_case()!=face_ref_case)
-                                                      // we use user_indices
-                                                      // to denote needed
-                                                      // anisotropic
-                                                      // refinement. note, that
-                                                      // we can have at most
-                                                      // one anisotropic
-                                                      // refinement case for
-                                                      // this face, as
-                                                      // otherwise
-                                                      // prepare_refinement()
-                                                      // would have changed one
-                                                      // of the cells to yield
-                                                      // isotropic refinement
-                                                      // at this
-                                                      // face. therefore we set
-                                                      // the user_index
-                                                      // uniquely
-                     {
-                       Assert(aface->refinement_case()==RefinementCase<dim-1>::isotropic_refinement ||
-                              aface->refinement_case()==RefinementCase<dim-1>::no_refinement,
-                              ExcInternalError());
-                       aface->set_user_index(face_ref_case);
-                     }
-                 }
-             }// for all faces
-           
-                                            // flag all lines, that have to be
-                                            // refined
-           for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-             if (GeometryInfo<dim>::line_refinement_case(ref_case,line) &&
-                 !acell->line(line)->has_children())
-               acell->line(line)->set_user_flag();
-               
-         }// if refine_flag set and for all cells on this level
-      
+  return (flags_before != flags_after);
+}
 
-                                      // count number of used cells on
-                                      // the next higher level
-      const unsigned int used_cells
-       = std::count_if (levels[level+1]->cells.used.begin(),
-                        levels[level+1]->cells.used.end(),
-                        std::bind2nd (std::equal_to<bool>(), true));
-
-
-                                      // reserve space for the
-                                      // used_cells cells already
-                                      // existing on the next higher
-                                      // level as well as for the
-                                      // 8*flagged_cells that will be
-                                      // created on that level
-      levels[level+1]->reserve_space (used_cells+new_cells, 3);
-                                      // reserve space for
-                                      // 8*flagged_cells
-                                      // new hexes on the next higher
-                                      // level
-      levels[level+1]->cells.reserve_space (new_cells);
-    }// for all levels
-                                  // 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())
-       {
-                                          // isotropic refinement: 1 interior
-                                          // vertex, 4 quads and 4 interior
-                                          // lines. we store the interior lines
-                                          // in pairs in case the face is
-                                          // already or will be refined
-                                          // anisotropically
-         needed_quads_pair += 4;
-         needed_lines_pair += 4;
-         needed_vertices += 1;
-       }
-      if (quad->user_index())
-       {
-                                          // anisotropic refinement: 1 interior
-                                          // line and two quads
-         needed_quads_pair += 2;
-         needed_lines_single += 1;
-                                          // there is a kind of complicated
-                                          // situation here which requires our
-                                          // attention. if the quad is refined
-                                          // isotropcally, two of the interior
-                                          // lines will get a new mother line -
-                                          // the interior line of our
-                                          // anisotropically refined quad. if
-                                          // those two lines are not
-                                          // consecutive, we cannot do so and
-                                          // have to replace them by two lines
-                                          // that are consecutive. we try to
-                                          // avoid that situation, but it may
-                                          // happen nevertheless throug
-                                          // repeated refinement and
-                                          // coarsening. thus we have to check
-                                          // here, as we will need some
-                                          // additional space to store those
-                                          // new lines in case we need them...
-         if (quad->has_children())
-           {
-             Assert(quad->refinement_case()==RefinementCase<dim-1>::isotropic_refinement, ExcInternalError());
-             if ((face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_x
-                  && (quad->child(0)->line_index(1)+1!=quad->child(2)->line_index(1))) ||
-                 (face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_y
-                  && (quad->child(0)->line_index(3)+1!=quad->child(1)->line_index(3))))
-               needed_lines_pair +=2;
-           }
-       }
-    }
-  
-  for (line_iterator line=begin_line(); line!=end_line(); ++line)
-    if (line->user_flag_set())
-      {
-       needed_lines_pair += 2;
-       needed_vertices += 1;
-      }
 
-                                  // reserve space for
-                                  // needed_lines new lines
-                                  // stored in pairs
-  faces->lines.
-    reserve_space (needed_lines_pair,needed_lines_single);
-                                  // reserve space for
-                                  // needed_quads new quads
-                                  // stored in pairs
-  faces->quads.
-    reserve_space (needed_quads_pair,needed_quads_single);
-
-
-                                  // add to needed vertices how many
-                                  // vertices are already in use
-  needed_vertices += std::count_if (vertices_used.begin(), vertices_used.end(),
-                                   std::bind2nd (std::equal_to<bool>(), true));
-                                  // if we need more vertices: create
-                                  // them, if not: leave the array as
-                                  // is, since shrinking is not
-                                  // really possible because some of
-                                  // the vertices at the end may be
-                                  // in use
-  if (needed_vertices > vertices.size())
-    {
-      vertices.resize (needed_vertices, Point<dim>());
-      vertices_used.resize (needed_vertices, false);
-    }
+#endif
 
 
-                                  ///////////////////////////////////////////
-                                  // Before we start with the actual
-                                  // refinement, we do some sanity
-                                  // checks if in debug
-                                  // mode. especially, we try to
-                                  // catch the notorious problem with
-                                  // lines being twice refined,
-                                  // i.e. there are cells adjacent at
-                                  // one line ("around the edge", but
-                                  // not at a face), with two cells
-                                  // differing by more than one
-                                  // refinement level
-                                  //
-                                  // this check is very simple to
-                                  // implement here, since we have
-                                  // all lines flagged if they shall
-                                  // be refined
-#ifdef DEBUG
-  for (active_cell_iterator cell=begin_active(); cell!=end(); ++cell)
-    if (!cell->refine_flag_set())
-      for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-       if (cell->line(line)->has_children())
-         for (unsigned int c=0; c<2; ++c)
-           Assert (cell->line(line)->child(c)->user_flag_set() == false,
-                   ExcInternalError());
-#endif
 
-                                  ///////////////////////////////////////////
-                                  // Do refinement on every level
+template <int dim, int spacedim>
+bool Triangulation<dim,spacedim>::prepare_coarsening_and_refinement ()
+{
+                                  // save the flags to determine
+                                  // whether something was changed in
+                                  // the course of this function
+  std::vector<bool> flags_before[2];
+  save_coarsen_flags (flags_before[0]);
+  save_refine_flags (flags_before[1]);
+
+                                  // save the flags at the outset of
+                                  // each loop. we do so in order to
+                                  // find out whether something was
+                                  // changed in the present loop, in
+                                  // which case we would have to
+                                  // re-run the loop. the other
+                                  // possibility to find this out
+                                  // would be to set a flag
+                                  // @p{something_changed} to true
+                                  // each time we change something.
+                                  // however, sometimes one change in
+                                  // one of the parts of the loop is
+                                  // undone by another one, so we
+                                  // might end up in an endless
+                                  // loop. we could be tempted to
+                                  // break this loop at an arbitrary
+                                  // number of runs, but that would
+                                  // not be a clean solution, since
+                                  // we would either have to  
+                                  // 1/ break the loop too early, in which
+                                  //    case the promise that a second
+                                  //    call to this function immediately
+                                  //    after the first one does not
+                                  //    change anything, would be broken,
+                                  // or
+                                  // 2/ we do as many loops as there are
+                                  //    levels. we know that information
+                                  //    is transported over one level
+                                  //    in each run of the loop, so this
+                                  //    is enough. Unfortunately, each
+                                  //    loop is rather expensive, so
+                                  //    we chose the way presented here
+  std::vector<bool> flags_before_loop[2] = {flags_before[0],
+                                            flags_before[1]};
+
+                                  // now for what is done in each
+                                  // loop: we have to fulfill several
+                                  // tasks at the same time, namely
+                                  // several mesh smoothing
+                                  // algorithms and mesh
+                                  // regularisation, by which we mean
+                                  // that the next mesh fulfills
+                                  // several requirements such as no
+                                  // double refinement at each face
+                                  // or line, etc.
+                                  //
+                                  // since doing these things at once
+                                  // seems almost impossible (in the
+                                  // first year of this library, they
+                                  // were done in two functions, one
+                                  // for refinement and one for
+                                  // coarsening, and most things
+                                  // within these were done at once,
+                                  // so the code was rather
+                                  // impossible to join into this,
+                                  // only, function), we do them one
+                                  // after each other. the order in
+                                  // which we do them is such that
+                                  // the important tasks, namely
+                                  // regularisation, are done last
+                                  // and the least important things
+                                  // are done the first. the
+                                  // following order is chosen:
                                   //
-                                  // To make life a bit easier, we
-                                  // first refine those lines and
-                                  // quads that were flagged for
-                                  // refinement and then compose the
-                                  // newly to be created cells.
+                                  // 0/ Only if coarsest_level_1 or
+                                  //    patch_level_1 is set:
+                                  //    clear all coarsen flags on level 1
+                                  //    to avoid level 0 cells being
+                                  //    created by coarsening.
+                                  //    As coarsen flags will never be added,
+                                  //    this can be done once and for all
+                                  //    before the actual loop starts.
+                                  // 1/ do not coarsen a cell if
+                                  //    'most of the neighbors' will be
+                                  //    refined after the step. This is
+                                  //    to prevent occurence of
+                                  //    unrefined islands.
+                                  // 2/ eliminate refined islands in the
+                                  //    interior and at the boundary. since
+                                  //    they don't do much harm besides
+                                  //    increasing the number of degrees
+                                  //    of freedom, doing this has a
+                                  //    rather low priority.
+                                  // 3/ limit the level difference of
+                                  //    neighboring cells at each vertex.
+                                  // 4/ eliminate unrefined islands. this
+                                  //    has higher priority since this
+                                  //    diminishes the approximation
+                                  //    properties not only of the unrefined
+                                  //    island, but also of the surrounding
+                                  //    patch.
+                                  // 5/ ensure patch level 1. Then the
+                                  //    triangulation consists of patches,
+                                  //    i.e. of cells that are
+                                  //    refined once. It follows that if at
+                                  //    least one of the children of a cell
+                                  //    is or will be refined than all children
+                                  //    need to be refined. This step
+                                  //    only sets refinement flags and does
+                                  //    not set coarsening flags.
+                                  //    If the patch_level_1 flag is set, then
+                                  //    eliminate_unrefined_islands,
+                                  //    eliminate_refined_inner_islands and
+                                  //    eliminate_refined_boundary_islands will
+                                  //    be fulfilled automatically and do not
+                                  //    need to be enforced separately.
+                                  // 6/ take care of the requirement that no
+                                  //    double refinement is done at each face
+                                  // 7/ take care that no double refinement
+                                  //    is done at each line in 3d or higher
+                                  //    dimensions.
+                                  // 8/ make sure that all children of each
+                                  //    cell are either flagged for coarsening
+                                  //    or none of the children is
                                   //
-                                  // index of next unused vertex
-  unsigned int next_unused_vertex = 0;
+                                  // For some of these steps, it is
+                                  // known that they
+                                  // interact. Namely, it is not
+                                  // possible to guarantee that after
+                                  // step 6 another step 5 would have
+                                  // no effect; the same holds for
+                                  // the opposite order and also when
+                                  // taking into account step
+                                  // 7. however, it is important to
+                                  // guarantee that step five or six
+                                  // do not undo something that step
+                                  // 5 did, and step 7 not something
+                                  // of step 6, otherwise the
+                                  // requirements will not be
+                                  // satisfied even if the loop
+                                  // terminates. this is accomplished
+                                  // by the fact that steps 5 and 6
+                                  // only *add* refinement flags and
+                                  // delete coarsening flags
+                                  // (therefore, step 6 can't undo
+                                  // something that step 4 already
+                                  // did), and step 7 only deletes
+                                  // coarsening flags, never adds
+                                  // some. step 7 needs also take
+                                  // care that it won't tag cells for
+                                  // refinement for which some
+                                  // neighbors are more refined or
+                                  // will be refined.
 
-                                  // first for lines
-  if (true)
+                                  //////////////////////////////////////
+                                  // STEP 0:
+                                  //    Only if coarsest_level_1 or
+                                  //    patch_level_1 is set:
+                                  //    clear all coarsen flags on level 1
+                                  //    to avoid level 0 cells being
+                                  //    created by coarsening.
+  if (((smooth_grid & coarsest_level_1) ||
+       (smooth_grid & patch_level_1)) && n_levels()>=2)
     {
-                                      // only active objects can be
-                                      // refined further
-      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())
-         {
-                                            // this line needs to be
-                                            // refined
-
-                                            // find the next unused
-                                            // vertex and set it
-                                            // appropriately
-           while (vertices_used[next_unused_vertex] == true)
-             ++next_unused_vertex;
-           Assert (next_unused_vertex < vertices.size(),
-                   ExcTooFewVerticesAllocated());
-           vertices_used[next_unused_vertex] = true;
-
-           if (line->at_boundary())
-             vertices[next_unused_vertex]
-               = boundary[line->boundary_indicator()]->get_new_point_on_line (line);
-           else
-             vertices[next_unused_vertex]
-               = (line->vertex(0) + line->vertex(1)) / 2;
-         
-                                            // now that we created
-                                            // the right point, make
-                                            // up the two child lines
-                                            // (++ takes care of the
-                                            // end of the vector)
-           next_unused_line=faces->lines.next_free_pair_line(*this);
-           Assert(next_unused_line.state() == IteratorState::valid,
-                  ExcInternalError());
-           
-                                            // now we found
-                                            // two consecutive unused
-                                            // lines, such that the
-                                            // children of a line
-                                            // will be consecutive.
-                                            // then set the child
-                                            // pointer of the present
-                                            // line
-           line->set_children (0, next_unused_line->index());
-         
-                                            // set the two new lines
-           const raw_line_iterator children[2] = { next_unused_line,
-                                                   ++next_unused_line };
-                                            // some tests; if any of
-                                            // the iterators should
-                                            // be invalid, then
-                                            // already dereferencing
-                                            // will fail
-           Assert (children[0]->used() == false, ExcCellShouldBeUnused());
-           Assert (children[1]->used() == false, ExcCellShouldBeUnused());
-         
-           children[0]->set (internal::Triangulation
-                              ::TriaObject<1>(line->vertex_index(0),
-                                             next_unused_vertex));
-           children[1]->set (internal::Triangulation
-                              ::TriaObject<1>(next_unused_vertex,
-                                             line->vertex_index(1)));
-    
-           children[0]->set_used_flag();
-           children[1]->set_used_flag();
-           children[0]->clear_children();
-           children[1]->clear_children();
-           children[0]->clear_user_data();
-           children[1]->clear_user_data();
-           children[0]->clear_user_flag();
-           children[1]->clear_user_flag();
-
-           children[0]->set_boundary_indicator (line->boundary_indicator());
-           children[1]->set_boundary_indicator (line->boundary_indicator());
-           
-                                            // finally clear flag
-                                            // indicating the need
-                                            // for refinement
-           line->clear_user_flag ();
-         }
+      active_cell_iterator
+       cell=begin_active(1),
+       endc=end_active(1);
+      
+      for (; cell!=endc; ++cell)
+       cell->clear_coarsen_flag();
     }
 
+  
+  bool mesh_changed_in_this_loop = false;
+  do
+    {
 
-                                  ///////////////////////////////////////
-                                  // now refine marked quads
-                                  ///////////////////////////////////////
-
-                                  // here we encounter several cases:
-
-                                  // a) the quad is unrefined and shall be
-                                  // refined isotropically
-
-                                  // b) the quad is unrefined and shall be
-                                  // refined anisotropically
-
-                                  // c) the quad is unrefined and shall be
-                                  // refined both anisotropically and
-                                  // isotropically (this is reduced to case b)
-                                  // and then case b) for the children again)
-
-                                  // d) the quad is refined anisotropically and
-                                  // shall be refined isotropically (this is
-                                  // reduced to case b) for the anisotropic
-                                  // children)
-
-                                  // e) the quad is refined isotropically and
-                                  // shall be refined anisotropically (this is
-                                  // transformed to case c), however we might
-                                  // have to renumber/rename children...)
-
-                                  // we need a loop in cases c) and d), as the
-                                  // anisotropic children migt have a lower
-                                  // index than the mother quad
-  for (unsigned int loop=0; loop<2; ++loop)
-    {
-                                      // usually, only active objects can be
-                                      // refined further. however, in cases d)
-                                      // and e) that is not true, so we have to
-                                      // use 'normal' iterators here
-      quad_iterator quad = begin_quad(),
-                   endq = end_quad();
-      raw_line_iterator next_unused_line = begin_raw_line (),
-                                   endl = end_line();
-      raw_quad_iterator next_unused_quad = begin_raw_quad ();
-
-      for (; quad!=endq; ++quad)
+                                      //////////////////////////////////////
+                                      // STEP 1:
+                                      //    do not coarsen a cell if 'most of
+                                      //    the neighbors' will be refined after
+                                      //    the step. This is to prevent the
+                                      //    occurence of unrefined islands.
+                                      //    If patch_level_1 is set, this will
+                                      //    be automatically fulfilled.
+      if (smooth_grid & do_not_produce_unrefined_islands &&
+         !(smooth_grid & patch_level_1))
        {
-         if (quad->user_index())
+         cell_iterator       cell;
+         const cell_iterator endc = end();
+         
+         for (cell=begin(); cell!=endc; ++cell)
            {
-             RefinementCase<dim-1> aniso_quad_ref_case=face_refinement_cases[quad->user_index()];
-                                              // there is one unlikely event
-                                              // here, where we already have
-                                              // refind the face: if the face
-                                              // was refined anisotropically
-                                              // and we want to refine it
-                                              // isotropically, both children
-                                              // are flagged for anisotropic
-                                              // refinement. however, if those
-                                              // children were already flagged
-                                              // for anisotropic refinement,
-                                              // they might already be
-                                              // processed and refined.
-             if (aniso_quad_ref_case == quad->refinement_case())
-               continue;
-             
-             Assert(quad->refinement_case()==RefinementCase<dim-1>::cut_xy ||
-                    quad->refinement_case()==RefinementCase<dim-1>::no_refinement,
-                    ExcInternalError());
-             
-                                              // this quad needs to be refined
-                                              // anisotropically
-             Assert(quad->user_index() == RefinementCase<dim-1>::cut_x ||
-                    quad->user_index() == RefinementCase<dim-1>::cut_y,
-                    ExcInternalError());
-
-                                              // make the new line interior to
-                                              // the quad
-             raw_line_iterator new_line;
-             
-             new_line=faces->lines.next_free_single_line(*this);
-             Assert (new_line->used() == false,
-                     ExcCellShouldBeUnused());
-
-                                              // first collect the
-                                              // indices of the vertices:
-                                              // *--1--*
-                                              // |  |  |
-                                              // |  |  |    cut_x
-                                              // |  |  |
-                                              // *--0--*
-                                              //
-                                              // *-----*
-                                              // |     |
-                                              // 0-----1    cut_y
-                                              // |     |
-                                              // *-----*
-             unsigned int vertex_indices[2];
-             if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
-               {
-                 vertex_indices[0]=quad->line(2)->child(0)->vertex_index(1);
-                 vertex_indices[1]=quad->line(3)->child(0)->vertex_index(1);
-               }
-             else
-               {
-                 vertex_indices[0]=quad->line(0)->child(0)->vertex_index(1);
-                 vertex_indices[1]=quad->line(1)->child(0)->vertex_index(1);
-               }
-
-             new_line->set (internal::Triangulation::
-                            TriaObject<1>(vertex_indices[0], vertex_indices[1]));
-             new_line->set_used_flag();
-             new_line->clear_user_flag();
-             new_line->clear_user_data();
-             new_line->clear_children();
-             new_line->set_boundary_indicator(quad->boundary_indicator());
-
-                                              // child 0 and 1 of a line are
-                                              // switched if the line
-                                              // orientation is false. set up a
-                                              // miniature table, indicating
-                                              // which child to take for line
-                                              // orientations false and
-                                              // true. first index: child index
-                                              // in standard orientation,
-                                              // second index: line orientation
-             const unsigned int index[2][2]=
-               {{1,0},   // child 0, line_orientation=false and true
-                {0,1}};  // child 1, line_orientation=false and true
-             
-                                              // find some space (consecutive)
-                                              // for the two newly to be
-                                              // created quads.
-             raw_quad_iterator new_quads[2];
-             
-             next_unused_quad=faces->quads.next_free_pair_quad(*this);
-             new_quads[0] = next_unused_quad;
-             Assert (new_quads[0]->used() == false, ExcCellShouldBeUnused());
-             
-             ++next_unused_quad;
-             new_quads[1] = next_unused_quad;
-             Assert (new_quads[1]->used() == false, ExcCellShouldBeUnused());
-
-
-             if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
-               {
-                 new_quads[0]->set (internal::Triangulation
-                                    ::TriaObject<2>(quad->line_index(0),
-                                                    new_line->index(),
-                                                    quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
-                                                    quad->line(3)->child(index[0][quad->line_orientation(3)])->index()));
-                 new_quads[1]->set (internal::Triangulation
-                                    ::TriaObject<2>(new_line->index(),
-                                                    quad->line_index(1),
-                                                    quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
-                                                    quad->line(3)->child(index[1][quad->line_orientation(3)])->index()));
-               }
-             else
-               {
-                 new_quads[0]->set (internal::Triangulation
-                                    ::TriaObject<2>(quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
-                                                    quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
-                                                    quad->line_index(2),
-                                                    new_line->index()));
-                 new_quads[1]->set (internal::Triangulation
-                                    ::TriaObject<2>(quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
-                                                    quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
-                                                    new_line->index(),
-                                                    quad->line_index(3)));
-               }
-             
-             for (unsigned int i=0; i<2; ++i)
-               {
-                 new_quads[i]->set_used_flag();
-                 new_quads[i]->clear_user_flag();
-                 new_quads[i]->clear_user_data();
-                 new_quads[i]->clear_children();
-                 new_quads[i]->set_boundary_indicator (quad->boundary_indicator());
-                                                  // set all line orientations to
-                                                  // true, change this after the
-                                                  // loop, as we have to consider
-                                                  // different lines for each
-                                                  // child
-                 for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
-                   new_quads[i]->set_line_orientation(j,true);
-               }
-                                              // now set the line orientation of
-                                              // children of outer lines
-                                              // correctly, the lines in the
-                                              // interior of the refined quad are
-                                              // automatically oriented
-                                              // conforming to the standard
-             new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
-             new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
-             new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
-             new_quads[1]->set_line_orientation(2,quad->line_orientation(3));
-             if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
-               {
-                 new_quads[0]->set_line_orientation(3,quad->line_orientation(3));
-                 new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
-               }
-             else
-               {
-                 new_quads[0]->set_line_orientation(1,quad->line_orientation(1));
-                 new_quads[1]->set_line_orientation(0,quad->line_orientation(0));
-               }
-
-                                              // test, whether this face is
-                                              // refined isotropically
-                                              // already. if so, set the
-                                              // correct children pointers.
-             if (quad->refinement_case()==RefinementCase<dim-1>::cut_xy)
+             if (!cell->active())
                {
-                                                  // we will put a new
-                                                  // refinemnt level of
-                                                  // anisotropic refinement
-                                                  // between the unrefined and
-                                                  // isotropically refined quad
-                                                  // ending up with the same
-                                                  // fine quads but introducing
-                                                  // anisotropically refined
-                                                  // ones as children of the
-                                                  // unrefined quad and mother
-                                                  // cells of the original fine
-                                                  // ones.
-
-                                                  // this process includes the
-                                                  // creation of a new middle
-                                                  // line which we will assign
-                                                  // as the mother line of two
-                                                  // of the existing inner
-                                                  // lines. If those inner
-                                                  // lines are not consecutive
-                                                  // in memory, we won't find
-                                                  // them later on, so we have
-                                                  // to create new ones instead
-                                                  // and replace all occurances
-                                                  // of the old ones with those
-                                                  // new ones. As this is kind
-                                                  // of ugly, we hope we don't
-                                                  // have to do it often...
-                 line_iterator old_child[2];
-                 if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
-                   {
-                     old_child[0]=quad->child(0)->line(1);
-                     old_child[1]=quad->child(2)->line(1);
-                   }
-                 else
-                   {
-                     Assert(aniso_quad_ref_case==RefinementCase<dim-1>::cut_y, ExcInternalError());
-                     
-                     old_child[0]=quad->child(0)->line(3);
-                     old_child[1]=quad->child(1)->line(3);
-                   }
-                 
-                 if (old_child[0]->index()+1 != old_child[1]->index())
+                                                  // only do something if this
+                                                  // cell will be coarsened
+                 if (cell_will_be_coarsened(cell))
                    {
-                                                      // this is exactly the
-                                                      // ugly case we taked
-                                                      // about. so, no
-                                                      // coimplaining, lets get
-                                                      // two new lines and copy
-                                                      // all info
-                     raw_line_iterator new_child[2];
-                     
-                     new_child[0]=new_child[1]=faces->lines.next_free_pair_line(*this);
-                     ++new_child[1];
-
-                     new_child[0]->set_used_flag();
-                     new_child[1]->set_used_flag();
-                     
-                     const int old_index_0=old_child[0]->index(),
-                               old_index_1=old_child[1]->index(),
-                               new_index_0=new_child[0]->index(),
-                               new_index_1=new_child[1]->index();
-
-                                                      // loop over all quads
-                                                      // and replace the old
-                                                      // lines
-                     for (unsigned int q=0; q<faces->quads.cells.size(); ++q)
-                       for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
-                           {
-                             const int index=faces->quads.cells[q].face(l);
-                             if (index==old_index_0)
-                               faces->quads.cells[q].set_face(l,new_index_0);
-                             else if (index==old_index_1)
-                               faces->quads.cells[q].set_face(l,new_index_1);
-                           }
-                                                      // now we have to copy
-                                                      // all information of the
-                                                      // two lines
-                     for (unsigned int i=0; i<2; ++i)
+                     unsigned int n_neighbors=0;
+                                                      // count all neighbors
+                                                      // that will be refined
+                                                      // along the face of our
+                                                      // cell after the next
+                                                      // step
+                     unsigned int count=0;
+                     for (unsigned int n=0;
+                          n<GeometryInfo<dim>::faces_per_cell; ++n)
                        {
-                         Assert(!old_child[i]->has_children(), ExcInternalError());
-                         
-                         new_child[i]->set(internal::Triangulation::TriaObject<1>(old_child[i]->vertex_index(0),
-                                                                                 old_child[i]->vertex_index(1)));
-                         new_child[i]->set_boundary_indicator(old_child[i]->boundary_indicator());
-                         new_child[i]->set_user_index(old_child[i]->user_index());
-                         if (old_child[i]->user_flag_set())
-                           new_child[i]->set_user_flag();
-                         else
-                           new_child[i]->clear_user_flag();
-                         
-                         new_child[i]->clear_children();
-                         
-                         old_child[i]->clear_user_flag();
-                         old_child[i]->clear_user_index();
-                         old_child[i]->clear_used_flag();
-                       }
-                   }
-                                                      // now that we cared
-                                                      // about the lines, go on
-                                                      // with the quads
-                                                      // themselves, where we
-                                                      // might encounter
-                                                      // similar situations...
-                 if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
-                   {
-                     new_line->set_children(0, quad->child(0)->line_index(1));
-                     Assert(new_line->child(1)==quad->child(2)->line(1),
-                            ExcInternalError());
-                                                      // now evereything is
-                                                      // quite complicated. we
-                                                      // have the children
-                                                      // numbered according to
-                                                      //
-                                                      // *---*---*
-                                                      // |n+2|n+3|
-                                                      // *---*---*
-                                                      // | n |n+1|
-                                                      // *---*---*
-                                                      //
-                                                      // from the original
-                                                      // isotropic
-                                                      // refinement. we have to
-                                                      // reorder them as
-                                                      //
-                                                      // *---*---*
-                                                      // |n+1|n+3|
-                                                      // *---*---*
-                                                      // | n |n+2|
-                                                      // *---*---*
-                                                      //
-                                                      // such that n and n+1
-                                                      // are consecutive
-                                                      // children of m and n+2
-                                                      // and n+3 are
-                                                      // consecutive children
-                                                      // of m+1, where m and
-                                                      // m+1 are given as in
-                                                      //
-                                                      // *---*---*
-                                                      // |   |   |
-                                                      // | m |m+1|
-                                                      // |   |   |
-                                                      // *---*---*
-                                                      //
-                                                      // this is a bit ugly, of
-                                                      // course: loop over all
-                                                      // cells on all levels
-                                                      // and look for faces n+1
-                                                      // (switch_1) and n+2
-                                                      // (switch_2).
-                     const quad_iterator switch_1=quad->child(1);
-                     const quad_iterator switch_2=quad->child(2);
-                     const int switch_1_index=switch_1->index();
-                     const int switch_2_index=switch_2->index();
-                     for (unsigned int l=0; l<levels.size(); ++l)
-                       for (unsigned int h=0; h<levels[l]->cells.cells.size(); ++h)
-                         for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
+                         const cell_iterator neighbor = cell->neighbor(n);
+                         if (neighbor.state() == IteratorState::valid)
                            {
-                             const int index=levels[l]->cells.cells[h].face(q);
-                             if (index==switch_1_index)
-                               levels[l]->cells.cells[h].set_face(q,switch_2_index);
-                             else if (index==switch_2_index)
-                               levels[l]->cells.cells[h].set_face(q,switch_1_index);
+                             ++n_neighbors;
+                             if (face_will_be_refined_by_neighbor(cell,n))
+                               ++count;
                            }
-                                                      // now we have to copy
-                                                      // all information of the
-                                                      // two quads
-                     const int switch_1_lines[4]=
-                       {switch_1->line_index(0),
-                        switch_1->line_index(1),
-                        switch_1->line_index(2),
-                        switch_1->line_index(3)};
-                     const bool switch_1_line_orientations[4]=
-                       {switch_1->line_orientation(0),
-                        switch_1->line_orientation(1),
-                        switch_1->line_orientation(2),
-                        switch_1->line_orientation(3)};
-                     const unsigned char switch_1_boundary_indicator=switch_1->boundary_indicator();
-                     const unsigned int switch_1_user_index=switch_1->user_index();
-                     const bool switch_1_user_flag=switch_1->user_flag_set();
-                     const RefinementCase<dim-1> switch_1_refinement_case=switch_1->refinement_case();
-                     const int switch_1_first_child_pair=(switch_1_refinement_case ? switch_1->child_index(0) : -1);
-                     const int switch_1_second_child_pair=(switch_1_refinement_case==RefinementCase<dim-1>::cut_xy ? switch_1->child_index(2) : -1);
-
-                     switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
-                                                                          switch_2->line_index(1),
-                                                                          switch_2->line_index(2),
-                                                                          switch_2->line_index(3)));
-                     switch_1->set_line_orientation(0, switch_2->line_orientation(0));
-                     switch_1->set_line_orientation(1, switch_2->line_orientation(1));
-                     switch_1->set_line_orientation(2, switch_2->line_orientation(2));
-                     switch_1->set_line_orientation(3, switch_2->line_orientation(3));
-                     switch_1->set_boundary_indicator(switch_2->boundary_indicator());
-                     switch_1->set_user_index(switch_2->user_index());
-                     if (switch_2->user_flag_set())
-                       switch_1->set_user_flag();
-                     else
-                       switch_1->clear_user_flag();
-                     switch_1->clear_refinement_case();
-                     switch_1->set_refinement_case(switch_2->refinement_case());
-                     switch_1->clear_children();
-                     if (switch_2->refinement_case())
-                       switch_1->set_children(0, switch_2->child_index(0));
-                     if (switch_2->refinement_case()==RefinementCase<dim-1>::cut_xy)
-                       switch_1->set_children(2, switch_2->child_index(2));
-                       
-                     switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
-                                                                          switch_1_lines[1],
-                                                                          switch_1_lines[2],
-                                                                          switch_1_lines[3]));
-                     switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
-                     switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
-                     switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
-                     switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
-                     switch_2->set_boundary_indicator(switch_1_boundary_indicator);
-                     switch_2->set_user_index(switch_1_user_index);
-                     if (switch_1_user_flag)
-                       switch_2->set_user_flag();
-                     else
-                       switch_2->clear_user_flag();
-                     switch_2->clear_refinement_case();
-                     switch_2->set_refinement_case(switch_1_refinement_case);
-                     switch_2->clear_children();
-                     switch_2->set_children(0, switch_1_first_child_pair);
-                     switch_2->set_children(2, switch_1_second_child_pair);
-
-                     new_quads[0]->set_refinement_case(RefinementCase<2>::cut_y);
-                     new_quads[0]->set_children(0, quad->child_index(0));
-                     new_quads[1]->set_refinement_case(RefinementCase<2>::cut_y);
-                     new_quads[1]->set_children(0, quad->child_index(2));
-                   }
-                 else
-                   {
-                     new_quads[0]->set_refinement_case(RefinementCase<2>::cut_x);
-                     new_quads[0]->set_children(0, quad->child_index(0));
-                     new_quads[1]->set_refinement_case(RefinementCase<2>::cut_x);
-                     new_quads[1]->set_children(0, quad->child_index(2));
-                     new_line->set_children(0, quad->child(0)->line_index(3));
-                     Assert(new_line->child(1)==quad->child(1)->line(3),
-                            ExcInternalError());
-                   }
-                 quad->clear_children();
-               }
-             
-                                              // note these quads as children
-                                              // to the present one
-             quad->set_children (0, new_quads[0]->index());
-
-             quad->set_refinement_case(aniso_quad_ref_case);
-             
-                                              // finally clear flag
-                                              // indicating the need
-                                              // for refinement
-             quad->clear_user_data ();
-           } // if (anisotropic refinement)
-
-         if (quad->user_flag_set())
-           {
-                                              // this quad needs to be
-                                              // refined isotropically
-
-                                              // first of all: we only get here
-                                              // in the first run of the loop
-             Assert(loop==0,ExcInternalError());
-
-                                              // find the next unused
-                                              // vertex. we'll need this in any
-                                              // case
-             while (vertices_used[next_unused_vertex] == true)
-               ++next_unused_vertex;
-             Assert (next_unused_vertex < vertices.size(),
-                     ExcTooFewVerticesAllocated());
-           
-                                              // now: if the quad is refined
-                                              // anisotropically already, set
-                                              // the anisotropic refinement
-                                              // flag for both
-                                              // children. Additionally, we
-                                              // have to refine the inner line,
-                                              // as it is an outer line of the
-                                              // two (anisotropic) children
-             const RefinementCase<dim-1> quad_ref_case=quad->refinement_case();
-           
-             if (quad_ref_case==RefinementCase<dim-1>::cut_x ||
-                 quad_ref_case==RefinementCase<dim-1>::cut_y)
-               {
-                                                  // set the 'opposite' refine case for children
-                 quad->child(0)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
-                 quad->child(1)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
-                                                  // refine the inner line
-                 line_iterator middle_line;
-                 if (quad_ref_case==RefinementCase<dim-1>::cut_x)
-                   middle_line=quad->child(0)->line(1);
-                 else
-                   middle_line=quad->child(0)->line(3);
-
-                                                  // if the face has been
-                                                  // refined anisotropically in
-                                                  // the last refinement step
-                                                  // it might be, that it is
-                                                  // flagged already and that
-                                                  // the middle line is thus
-                                                  // refined already. if not
-                                                  // create children.
-                 if (!middle_line->has_children())
-                   {
-                                                      // set the middle vertex
-                                                      // appropriately. double
-                                                      // refinement of quads can only
-                                                      // happen in the interior of
-                                                      // the domain, so we need not
-                                                      // care about boundary quads
-                                                      // here
-                     vertices[next_unused_vertex]
-                       = (middle_line->vertex(0) + middle_line->vertex(1)) / 2;
-                     vertices_used[next_unused_vertex] = true;
-                     
-                                                      // now search a slot for the two
-                                                      // child lines
-                     next_unused_line=faces->lines.next_free_pair_line(*this);
-                     
-                                                      // set the child
-                                                      // pointer of the present
-                                                      // line
-                     middle_line->set_children (0, next_unused_line->index());
-                     
-                                                      // set the two new lines
-                     const raw_line_iterator children[2] = { next_unused_line,
-                                                             ++next_unused_line };
-                                                      // some tests; if any of
-                                                      // the iterators should
-                                                      // be invalid, then
-                                                      // already dereferencing
-                                                      // will fail
-                     Assert (children[0]->used() == false, ExcCellShouldBeUnused());
-                     Assert (children[1]->used() == false, ExcCellShouldBeUnused());
-                     
-                     children[0]->set (internal::Triangulation::
-                                       TriaObject<1>(middle_line->vertex_index(0),
-                                                     next_unused_vertex));
-                     children[1]->set (internal::Triangulation::
-                                       TriaObject<1>(next_unused_vertex,
-                                                     middle_line->vertex_index(1)));
-                     
-                     children[0]->set_used_flag();
-                     children[1]->set_used_flag();
-                     children[0]->clear_children();
-                     children[1]->clear_children();
-                     children[0]->clear_user_data();
-                     children[1]->clear_user_data();
-                     children[0]->clear_user_flag();
-                     children[1]->clear_user_flag();
-                     
-                     children[0]->set_boundary_indicator (middle_line->boundary_indicator());
-                     children[1]->set_boundary_indicator (middle_line->boundary_indicator());
+                       }
+                                                      // clear coarsen flags if
+                                                      // either all existing
+                                                      // neighbors will be
+                                                      // refined or all but one
+                                                      // will be and the cell
+                                                      // is in the interior of
+                                                      // the domain
+                     if (count==n_neighbors ||
+                         (count>=n_neighbors-1 &&
+                          n_neighbors==
+                          GeometryInfo<dim>::faces_per_cell))
+                       for (unsigned int c=0; c<cell->n_children(); ++c)
+                         cell->child(c)->clear_coarsen_flag();
                    }
-                                                  // now remove the flag from the
-                                                  // quad and go to the next
-                                                  // quad, the actual refinement
-                                                  // of the quad takes place
-                                                  // later on in this pass of the
-                                                  // loop or in the next one
-                 quad->clear_user_flag();
-                 continue;
-               } // if (several refinement cases)
-
-                                              // if we got here, we have an
-                                              // unrefined quad and have to do
-                                              // the usual work like in an purely
-                                              // isotropic refinement
-             Assert(quad_ref_case==RefinementCase<dim-1>::no_refinement, ExcInternalError());
-
-                                              // set the middle vertex
-                                              // appropriately
-             if (quad->at_boundary()) 
-               vertices[next_unused_vertex]
-                 = boundary[quad->boundary_indicator()]->get_new_point_on_quad (quad);
-             else
-                                                // it might be that the
-                                                // quad itself is not
-                                                // at the boundary, but
-                                                // that one of its lines
-                                                // actually is. in this
-                                                // case, the newly
-                                                // created vertices at
-                                                // the centers of the
-                                                // lines are not
-                                                // necessarily the mean
-                                                // values of the
-                                                // adjacent vertices,
-                                                // so do not compute
-                                                // the new vertex as
-                                                // the mean value of
-                                                // the 4 vertices of
-                                                // the face, but rather
-                                                // as a weighted mean
-                                                // value of the 8
-                                                // vertices which we
-                                                // already have (the
-                                                // four old ones, and
-                                                // the four ones
-                                                // inserted as middle
-                                                // points for the four
-                                                // lines). summing up
-                                                // some more points is
-                                                // generally cheaper
-                                                // than first asking
-                                                // whether one of the
-                                                // lines is at the
-                                                // boundary
-                                                //
-                                                // note that the exact
-                                                // weights are chosen
-                                                // such as to minimize
-                                                // the distortion of
-                                                // the four new quads
-                                                // from the optimal
-                                                // shape; their
-                                                // derivation and
-                                                // values is copied
-                                                // over from the
-                                                // @p{MappingQ::set_laplace_on_vector}
-                                                // function
-               vertices[next_unused_vertex]
-                 = (quad->vertex(0) + quad->vertex(1) +
-                    quad->vertex(2) + quad->vertex(3) +
-                    3*(quad->line(0)->child(0)->vertex(1) +
-                       quad->line(1)->child(0)->vertex(1) +
-                       quad->line(2)->child(0)->vertex(1) +
-                       quad->line(3)->child(0)->vertex(1))   ) / 16;
-
-             vertices_used[next_unused_vertex] = true;
-
-                                              // now that we created
-                                              // the right point, make
-                                              // up the four lines
-                                              // interior to the quad
-                                              // (++ takes care of the
-                                              // end of the vector)
-             raw_line_iterator new_lines[4];
-
-             for (unsigned int i=0; i<4; ++i)
-               {
-                 if (i%2==0)
-                                                    // search a free pair of
-                                                    // lines for 0. and 2. line,
-                                                    // so that two of them end up
-                                                    // together, which is
-                                                    // necessary if later on we
-                                                    // want to refine the quad
-                                                    // anisotropically and the
-                                                    // two lines end up as
-                                                    // children of new line
-                   next_unused_line=faces->lines.next_free_pair_line(*this);
-
-                 new_lines[i] = next_unused_line;
-                 ++next_unused_line;
-
-                 Assert (new_lines[i]->used() == false,
-                         ExcCellShouldBeUnused());
-               }
-
-                                              // set the data of the
-                                              // four lines.
-                                              // first collect the
-                                              // indices of the five
-                                              // vertices:
-                                              // *--3--*
-                                              // |  |  |
-                                              // 0--4--1
-                                              // |  |  |
-                                              // *--2--*
-                                              // the lines are numbered
-                                              // as follows:
-                                              // *--*--*
-                                              // |  1  |
-                                              // *2-*-3*
-                                              // |  0  |
-                                              // *--*--*
-           
-             const unsigned int vertex_indices[5]
-               = { quad->line(0)->child(0)->vertex_index(1),
-                   quad->line(1)->child(0)->vertex_index(1),
-                   quad->line(2)->child(0)->vertex_index(1),
-                   quad->line(3)->child(0)->vertex_index(1),
-                   next_unused_vertex 
-               };
-             
-             new_lines[0]->set (internal::Triangulation::
-                                TriaObject<1>(vertex_indices[2], vertex_indices[4]));
-             new_lines[1]->set (internal::Triangulation::
-                                TriaObject<1>(vertex_indices[4], vertex_indices[3]));
-             new_lines[2]->set (internal::Triangulation::
-                                TriaObject<1>(vertex_indices[0], vertex_indices[4]));
-             new_lines[3]->set (internal::Triangulation::
-                                TriaObject<1>(vertex_indices[4], vertex_indices[1]));
-
-             for (unsigned int i=0; i<4; ++i)
-               {
-                 new_lines[i]->set_used_flag();
-                 new_lines[i]->clear_user_flag();
-                 new_lines[i]->clear_user_data();
-                 new_lines[i]->clear_children();
-                 new_lines[i]->set_boundary_indicator(quad->boundary_indicator());
-               }
-             
-                                              // now for the
-                                              // quads. again, first
-                                              // collect some data
-                                              // about the indices of
-                                              // the lines, with the
-                                              // following numbering:
-                                              //   .-6-.-7-.
-                                              //   1   9   3
-                                              //   .-10.11-.
-                                              //   0   8   2
-                                              //   .-4-.-5-.
-
-                                              // child 0 and 1 of a line are
-                                              // switched if the line orientation
-                                              // is false. set up a miniature
-                                              // table, indicating which child to
-                                              // take for line orientations false
-                                              // and true. first index: child
-                                              // index in standard orientation,
-                                              // second index: line orientation
-             const unsigned int index[2][2]=
-               {{1,0},   // child 0, line_orientation=false and true
-                {0,1}};  // child 1, line_orientation=false and true
-                   
-             const unsigned int line_indices[12]
-               = { quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
-                   quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
-                   quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
-                   quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
-                   quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
-                   quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
-                   quad->line(3)->child(index[0][quad->line_orientation(3)])->index(),
-                   quad->line(3)->child(index[1][quad->line_orientation(3)])->index(),
-                   new_lines[0]->index(),
-                   new_lines[1]->index(),
-                   new_lines[2]->index(),
-                   new_lines[3]->index() 
-               };
-           
-                                              // find some space (consecutive)
-                                              // for the first two newly to be
-                                              // created quads.
-             raw_quad_iterator new_quads[4];
-
-             next_unused_quad=faces->quads.next_free_pair_quad(*this);
-           
-             new_quads[0] = next_unused_quad;
-             Assert (new_quads[0]->used() == false, ExcCellShouldBeUnused());
-
-             ++next_unused_quad;
-             new_quads[1] = next_unused_quad;
-             Assert (new_quads[1]->used() == false, ExcCellShouldBeUnused());
-
-             next_unused_quad=faces->quads.next_free_pair_quad(*this);
-             new_quads[2] = next_unused_quad;
-             Assert (new_quads[2]->used() == false, ExcCellShouldBeUnused());
-
-             ++next_unused_quad;
-             new_quads[3] = next_unused_quad;
-             Assert (new_quads[3]->used() == false, ExcCellShouldBeUnused());
-
-                                              // note these quads as
-                                              // children to the
-                                              // present one
-             quad->set_children (0, new_quads[0]->index());
-             quad->set_children (2, new_quads[2]->index());
-             new_quads[0]->set (internal::Triangulation
-                                ::TriaObject<2>(line_indices[0],
-                                                line_indices[8],
-                                                line_indices[4],
-                                                line_indices[10]));
-             
-             quad->set_refinement_case(RefinementCase<2>::cut_xy);
-
-             new_quads[0]->set (internal::Triangulation
-                                ::TriaObject<2>(line_indices[0],
-                                                line_indices[8],
-                                                line_indices[4],
-                                                line_indices[10]));
-             new_quads[1]->set (internal::Triangulation
-                                ::TriaObject<2>(line_indices[8],
-                                                line_indices[2],
-                                                line_indices[5],
-                                                line_indices[11]));
-             new_quads[2]->set (internal::Triangulation
-                                ::TriaObject<2>(line_indices[1],
-                                                line_indices[9],
-                                                line_indices[10],
-                                                line_indices[6]));
-             new_quads[3]->set (internal::Triangulation
-                                ::TriaObject<2>(line_indices[9],
-                                                line_indices[3],
-                                                line_indices[11],
-                                                line_indices[7]));
-             for (unsigned int i=0; i<4; ++i)
-               {
-                 new_quads[i]->set_used_flag();
-                 new_quads[i]->clear_user_flag();
-                 new_quads[i]->clear_user_data();
-                 new_quads[i]->clear_children();
-                 new_quads[i]->set_boundary_indicator (quad->boundary_indicator());
-                                                  // set all line orientations to
-                                                  // true, change this after the
-                                                  // loop, as we have to consider
-                                                  // different lines for each
-                                                  // child
-                 for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
-                   new_quads[i]->set_line_orientation(j,true);
-               }
-                                              // now set the line orientation of
-                                              // children of outer lines
-                                              // correctly, the lines in the
-                                              // interior of the refined quad are
-                                              // automatically oriented
-                                              // conforming to the standard
-             new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
-             new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
-             new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
-             new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
-             new_quads[2]->set_line_orientation(0,quad->line_orientation(0));
-             new_quads[2]->set_line_orientation(3,quad->line_orientation(3));
-             new_quads[3]->set_line_orientation(1,quad->line_orientation(1));
-             new_quads[3]->set_line_orientation(3,quad->line_orientation(3));
-                                      
-                                              // finally clear flag
-                                              // indicating the need
-                                              // for refinement
-             quad->clear_user_flag ();
-           } // if (isotropic refinement)
-       } // for all quads
-    } // looped two times over all quads, all quads refined now
-
-                                  ///////////////////////////////////
-                                  // Now, finally, set up the new
-                                  // cells
-                                  ///////////////////////////////////
-  for (unsigned int level=0; level!=levels.size()-1; ++level)
-    {
-                                      // only active objects can be
-                                      // refined further; remember
-                                      // that we won't operate on the
-                                      // finest level, so
-                                      // 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 ();
-      raw_quad_iterator next_unused_quad = begin_raw_quad ();
-      raw_hex_iterator  next_unused_hex  = begin_raw_hex (level+1);
-
-      for (; hex!=endh; ++hex)
-       if (hex->refine_flag_set())
-         {
-                                            // this hex needs to be
-                                            // refined
-           
-                                            // clear flag indicating
-                                            // the need for
-                                            // refinement. do it here
-                                            // already, since we
-                                            // can't do it anymore
-                                            // once the cell has
-                                            // children
-           const RefinementCase<dim> ref_case=hex->refine_flag_set();
-           hex->clear_refine_flag ();
-           hex->set_refinement_case(ref_case);
-
-                                            // depending on the refine case we
-                                            // might have to create additional
-                                            // vertices, lines and quads
-                                            // interior of the hex before the
-                                            // actual children can be set up.
-
-                                            // in a first step: reserve the
-                                            // needed space for lines, quads
-                                            // and hexes and initialize them
-                                            // correctly
-
-           unsigned int n_new_lines=0;
-           unsigned int n_new_quads=0;
-           unsigned int n_new_hexes=0;
-           switch (ref_case)
-             {
-               case RefinementCase<dim>::cut_x:
-               case RefinementCase<dim>::cut_y:
-               case RefinementCase<dim>::cut_z:
-                     n_new_lines=0;
-                     n_new_quads=1;
-                     n_new_hexes=2;
-                     break;
-               case RefinementCase<dim>::cut_xy:
-               case RefinementCase<dim>::cut_xz:
-               case RefinementCase<dim>::cut_yz:
-                     n_new_lines=1;
-                     n_new_quads=4;
-                     n_new_hexes=4;
-                     break;
-               case RefinementCase<dim>::cut_xyz:
-                     n_new_lines=6;
-                     n_new_quads=12;
-                     n_new_hexes=8;
-                     break;
-               default:
-                     Assert(false, ExcInternalError());
-                     break;
-             }
-           
-                                            // find some space for the newly to
-                                            // be created interior lines and
-                                            // initialize them.
-           std::vector<raw_line_iterator> new_lines(n_new_lines);
-           for (unsigned int i=0; i<n_new_lines; ++i)
-             {
-               new_lines[i] = faces->lines.next_free_single_line(*this);
-               
-               Assert (new_lines[i]->used() == false,
-                        ExcCellShouldBeUnused());
-               new_lines[i]->set_used_flag();
-               new_lines[i]->clear_user_flag();
-               new_lines[i]->clear_user_data();
-               new_lines[i]->clear_children();
-                                                // interior line
-               new_lines[i]->set_boundary_indicator(255);
-             }
-
-                                            // find some space for the newly to
-                                            // be created interior quads and
-                                            // initialize them.
-           std::vector<raw_quad_iterator> new_quads(n_new_quads);
-           for (unsigned int i=0; i<n_new_quads; ++i)
-             {
-               new_quads[i] = faces->quads.next_free_single_quad(*this);
-               
-               Assert (new_quads[i]->used() == false,
-                        ExcCellShouldBeUnused());
-               new_quads[i]->set_used_flag();
-               new_quads[i]->clear_user_flag();
-               new_quads[i]->clear_user_data();
-               new_quads[i]->clear_children();
-                                                // interior quad
-               new_quads[i]->set_boundary_indicator (255);
-                                                // set all line orientation
-                                                // flags to true by default,
-                                                // change this afterwards, if
-                                                // necessary
-               for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
-                 new_quads[i]->set_line_orientation(j,true);
-             }
+               }  // if (!cell->active())
+           }  // for (all cells)
+       } // if (smooth_grid & ...)
 
-                                            // find some space for the newly to
-                                            // be created hexes and initialize
-                                            // them.
-           std::vector<raw_hex_iterator> new_hexes(n_new_hexes);
-           for (unsigned int i=0; i<n_new_hexes; ++i)
-             {
-               if (i%2==0)
-                 next_unused_hex=levels[level+1]->cells.next_free_hex(*this,level+1);
-               else
-                 ++next_unused_hex;
-               
-               new_hexes[i]=next_unused_hex;
-               
-               Assert (new_hexes[i]->used() == false,
-                        ExcCellShouldBeUnused());
-               new_hexes[i]->set_used_flag();
-               new_hexes[i]->clear_user_flag();
-               new_hexes[i]->clear_user_data();
-               new_hexes[i]->clear_children();
-                                                // inherit material
-                                                // properties
-               new_hexes[i]->set_material_id (hex->material_id());
-               new_hexes[i]->set_subdomain_id (hex->subdomain_id());
-                                                // set the face_orientation
-                                                // flag to true for all faces
-                                                // initially, as this is the
-                                                // default value which is true
-                                                // for all faces interior to
-                                                // the hex. later on go the
-                                                // other way round and reset
-                                                // faces that are at the
-                                                // boundary of the mother cube
-                                                //
-                                                // the same is true for the
-                                                // face_flip and face_rotation
-                                                // flags. however, the latter
-                                                // two are set to false by
-                                                // default as this is the
-                                                // standard value
-               for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-                 {
-                   new_hexes[i]->set_face_orientation(f, true);
-                   new_hexes[i]->set_face_flip(f, false);
-                   new_hexes[i]->set_face_rotation(f, false);
-                 }
-             }
-                                            // note these hexes as
-                                            // children to the
-                                            // present cell
-           for (unsigned int i=0; i<n_new_hexes/2; ++i) 
-             hex->set_children (2*i, new_hexes[2*i]->index());
-
-                                            // we have to take into account
-                                             // whether the different faces are
-                                             // oriented correctly or in the
-                                             // opposite direction, so store
-                                             // that up front
-
-                                            // face_orientation
-            const bool f_or[6]
-              = { hex->face_orientation (0),
-                  hex->face_orientation (1),
-                  hex->face_orientation (2),
-                  hex->face_orientation (3),
-                  hex->face_orientation (4),
-                  hex->face_orientation (5) };
-                    
-                                            // face_flip
-            const bool f_fl[6]
-              = { hex->face_flip (0),
-                  hex->face_flip (1),
-                  hex->face_flip (2),
-                  hex->face_flip (3),
-                  hex->face_flip (4),
-                  hex->face_flip (5) };
-                    
-                                            // face_rotation
-            const bool f_ro[6]
-              = { hex->face_rotation (0),
-                  hex->face_rotation (1),
-                  hex->face_rotation (2),
-                  hex->face_rotation (3),
-                  hex->face_rotation (4),
-                  hex->face_rotation (5) };
-
-                                            // some commonly used fields which
-                                            // have varying size
-           const unsigned int *vertex_indices=0;
-           const raw_line_iterator *lines=0;
-           const unsigned int *line_indices=0;
-           const bool *line_orientation=0;
-           const unsigned int *quad_indices=0;
-
-                                            // little helper table, indicating,
-                                            // whether the child with index 0
-                                            // or with index 1 can be found at
-                                            // the standard origin of an
-                                            // anisotropically refined quads in
-                                            // real orientation
-                                            // index 1: (RefineCase - 1)
-                                            // index 2: face_flip
-
-                                            // index 3: face rotation
-                                            // note: face orientation has no influence
-           const unsigned int child_at_origin[2][2][2]=
-             { { { 0, 0 },  // RefinementCase<dim>::cut_x, face_flip=false, face_rotation=false and true
-                 { 1, 1 }}, // RefinementCase<dim>::cut_x, face_flip=true,  face_rotation=false and true
-               { { 0, 1 },  // RefinementCase<dim>::cut_y, face_flip=false, face_rotation=false and true
-                 { 1, 0 }}};// RefinementCase<dim>::cut_y, face_flip=true,  face_rotation=false and true
-            
-                                            ///////////////////////////////////////
-                                            //
-                                            // in the following we will do the
-                                            // same thing for each refinement
-                                            // case: create a new vertex (if
-                                            // needed), create new interior
-                                            // lines (if needed), create new
-                                            // interior quads and afterwards
-                                            // build the children hexes out of
-                                            // these and the existing subfaces
-                                            // of the outer quads (which have
-                                            // been created above). However,
-                                            // even if the steps are quite
-                                            // similar, the actual work
-                                            // strongly depends on the actual
-                                            // refinement case. therefore, we
-                                            // use seperate blocks of code for
-                                            // each of these cases, which
-                                            // hopefully increases the
-                                            // readability to some extend.
-
-           switch (ref_case)
+      
+                                      //////////////////////////////////////
+                                      // STEP 2:
+                                      //    eliminate refined islands in the
+                                      //    interior and at the boundary. since
+                                      //    they don't do much harm besides
+                                      //    increasing the number of degrees of
+                                      //    freedom, doing this has a rather low
+                                      //    priority.
+                                      //    If patch_level_1 is set, this will
+                                      //    be automatically fulfilled.
+      if (smooth_grid & (eliminate_refined_inner_islands |
+                        eliminate_refined_boundary_islands) &&
+         !(smooth_grid & patch_level_1)) 
+       {
+         cell_iterator       cell;
+         const cell_iterator endc = end();
+         
+         for (cell=begin(); cell!=endc; ++cell)
+           if (!cell->active() || (cell->active() && cell->refine_flag_set()))
              {
-               case RefinementCase<dim>::cut_x:
-               {
-                                                  //////////////////////////////
-                                                  //
-                                                  //     RefinementCase<dim>::cut_x
-                                                  //
-                                                  // the refined cube will look
-                                                  // like this:
-                                                  //
-                                                  //        *----*----*
-                                                  //       /    /    /|
-                                                  //      /    /    / |
-                                                  //     /    /    /  |
-                                                  //    *----*----*   |
-                                                  //    |    |    |   |
-                                                  //    |    |    |   *
-                                                  //    |    |    |  /
-                                                  //    |    |    | /
-                                                  //    |    |    |/
-                                                  //    *----*----*
-                                                  // 
-                                                  // again, first
-                                                  // collect some data
-                                                  // about the indices of
-                                                  // the lines, with the
-                                                  // following numbering:
-           
-                                                  // face 2: front plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *---*---*
-                                                  //   |   |   |
-                                                  //   |   0   |
-                                                  //   |   |   |
-                                                  //   *---*---*
-                                                  //       m0
-                                                  // face 3: back plane
-                                                  //   (note: x,y exchanged)
-                                                  //       m1
-                                                  //   *---*---*
-                                                  //   |   |   | 
-                                                  //   |   1   |
-                                                  //   |   |   | 
-                                                  //   *---*---*
-                                                  // face 4: bottom plane
-                                                  //       *---*---*
-                                                  //      /   /   /
-                                                  //     /   2   /
-                                                  //    /   /   /
-                                                  //   *---*---*
-                                                  //       m0
-                                                  // face 5: top plane
-                                                  //           m1
-                                                  //       *---*---*
-                                                  //      /   /   /
-                                                  //     /   3   /
-                                                  //    /   /   /
-                                                  //   *---*---*
-
-                                                  // set up a list of line iterators
-                                                  // first. from this, construct
-                                                  // lists of line_indices and
-                                                  // line orientations later on
-                 const raw_line_iterator lines_x[4]
-                   = {
-                         hex->face(2)->child(0)
-                         ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
-                         hex->face(3)->child(0)
-                         ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
-                         hex->face(4)->child(0)
-                         ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
-                         hex->face(5)->child(0)
-                         ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3)         //3
-                   };
-                 
-                 lines=&lines_x[0];
-                 
-                 unsigned int line_indices_x[4];
-                     
-                 for (unsigned int i=0; i<4; ++i)
-                   line_indices_x[i]=lines[i]->index();
-                 line_indices=&line_indices_x[0];
-
-                                                  // the orientation of lines for the
-                                                  // inner quads is quite tricky. as
-                                                  // these lines are newly created
-                                                  // ones and thus have no parents,
-                                                  // they cannot inherit this
-                                                  // property. set up an array and
-                                                  // fill it with the respective
-                                                  // values
-                 bool line_orientation_x[4];
-
-                                                  // the middle vertice marked
-                                                  // as m0 above is the start
-                                                  // vertex for lines 0 and 2
-                                                  // in standard orientation,
-                                                  // whereas m1 is the end
-                                                  // vertex of lines 1 and 3 in
-                                                  // standard orientation
-                 const unsigned int middle_vertices[2]=
-                   {
-                         hex->line(2)->child(0)->vertex_index(1),
-                         hex->line(7)->child(0)->vertex_index(1)
-                   };
-
-                 for (unsigned int i=0; i<4; ++i)
-                   if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
-                     line_orientation_x[i]=true;
-                   else
+                                                // check whether all
+                                                // children are
+                                                // active, i.e. not
+                                                // refined
+                                                // themselves. This
+                                                // is a precondition
+                                                // that the children
+                                                // may be coarsened
+                                                // away. If the cell
+                                                // is only flagged
+                                                // for refinement,
+                                                // then all future
+                                                // children will be
+                                                // active
+               bool all_children_active = true;
+               if (!cell->active())
+                 for (unsigned int c=0; c<cell->n_children(); ++c)
+                   if (!cell->child(c)->active()) 
                      {
-                                                        // it must be the other
-                                                        // way round then
-                       Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
-                              ExcInternalError());
-                       line_orientation_x[i]=false;
+                       all_children_active = false;
+                       break;
                      }
-                 
-                 line_orientation=&line_orientation_x[0];
-
-                                                  // set up the new quad, line
-                                                  // numbering is as indicated
-                                                  // above
-                 new_quads[0]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[0],
-                                                    line_indices[1],
-                                                    line_indices[2],
-                                                    line_indices[3]));
-
-                 new_quads[0]->set_line_orientation(0,line_orientation[0]);
-                 new_quads[0]->set_line_orientation(1,line_orientation[1]);
-                 new_quads[0]->set_line_orientation(2,line_orientation[2]);
-                 new_quads[0]->set_line_orientation(3,line_orientation[3]);
-                 
-                                                  // the quads are
-                                                  // numbered as follows:
-                                                  //
-                                                  // planes in the interior
-                                                  // of the old hex:
-                                                  //      *
-                                                  //     /|
-                                                  //    / | x         
-                                                  //   /  | *-------*      *---------*
-                                                  //  *   | |       |     /         /
-                                                  //  | 0 | |       |    /         /
-                                                  //  |   * |       |   /         /
-                                                  //  |  /  *-------*y *---------*x
-                                                  //  | /
-                                                  //  |/
-                                                  //  *
-                                                  //
-                                                  // children of the faces
-                                                  // of the old hex
-                                                  //      *---*---*        *---*---*
-                                                  //     /|   |   |       /   /   /|
-                                                  //    / |   |   |      / 9 / 10/ |
-                                                  //   /  | 5 | 6 |     /   /   /  |
-                                                  //  *   |   |   |    *---*---*   |
-                                                  //  | 1 *---*---*    |   |   | 2 *
-                                                  //  |  /   /   /     |   |   |  /
-                                                  //  | / 7 / 8 /      | 3 | 4 | /
-                                                  //  |/   /   /       |   |   |/
-                                                  //  *---*---*        *---*---*
-                                                  //
-                                                  // note that we have to
-                                                  // take care of the
-                                                  // orientation of
-                                                  // faces.
-                 const unsigned int quad_indices_x[11]
-                   = {
-                         new_quads[0]->index(),     //0
-                             
-                         hex->face(0)->index(),     //1
-                         
-                         hex->face(1)->index(),     //2
-
-                         hex->face(2)->child_index(  child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),  //3
-                         hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
-                             
-                         hex->face(3)->child_index(  child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),  //5
-                         hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
-                             
-                         hex->face(4)->child_index(  child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),  //7
-                         hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
-                             
-                         hex->face(5)->child_index(  child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]),  //9
-                         hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
-                             
-                   };
-                 quad_indices=&quad_indices_x[0];
-
-                 new_hexes[0]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[1],
-                                                    quad_indices[0],
-                                                    quad_indices[3],
-                                                    quad_indices[5],
-                                                    quad_indices[7],
-                                                    quad_indices[9]));
-                 new_hexes[1]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[0],
-                                                    quad_indices[2],
-                                                    quad_indices[4],
-                                                    quad_indices[6],
-                                                    quad_indices[8],
-                                                    quad_indices[10]));
-                 break;
-               }
-               case RefinementCase<dim>::cut_y:
-               {
-                                                  //////////////////////////////
-                                                  //
-                                                  //     RefinementCase<dim>::cut_y
-                                                  //
-                                                  // the refined cube will look
-                                                  // like this:
-                                                  //
-                                                  //        *---------*
-                                                  //       /         /|
-                                                  //      *---------* |
-                                                  //     /         /| |
-                                                  //    *---------* | |
-                                                  //    |         | | |
-                                                  //    |         | | *
-                                                  //    |         | |/
-                                                  //    |         | *
-                                                  //    |         |/
-                                                  //    *---------*
-                                                  // 
-                                                  // again, first
-                                                  // collect some data
-                                                  // about the indices of
-                                                  // the lines, with the
-                                                  // following numbering:
-           
-                                                  // face 0: left plane
-                                                  //       *
-                                                  //      /| 
-                                                  //     * |
-                                                  //    /| |
-                                                  //   * | |
-                                                  //   | 0 |
-                                                  //   | | *
-                                                  //   | |/ 
-                                                  //   | *m0
-                                                  //   |/   
-                                                  //   *    
-                                                  // face 1: right plane
-                                                  //       *
-                                                  //      /| 
-                                                  //   m1* |
-                                                  //    /| |
-                                                  //   * | |
-                                                  //   | 1 |
-                                                  //   | | *
-                                                  //   | |/ 
-                                                  //   | *  
-                                                  //   |/   
-                                                  //   *    
-                                                  // face 4: bottom plane
-                                                  //       *-------*
-                                                  //      /       /
-                                                  //   m0*---2---*
-                                                  //    /       /
-                                                  //   *-------*
-                                                  // face 5: top plane
-                                                  //       *-------*
-                                                  //      /       /
-                                                  //     *---3---*m1
-                                                  //    /       /
-                                                  //   *-------*
-
-                                                  // set up a list of line iterators
-                                                  // first. from this, construct
-                                                  // lists of line_indices and
-                                                  // line orientations later on
-                 const raw_line_iterator lines_y[4]
-                   = {
-                         hex->face(0)->child(0)
-                         ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
-                         hex->face(1)->child(0)
-                         ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
-                         hex->face(4)->child(0)
-                         ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
-                         hex->face(5)->child(0)
-                         ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3)         //3
-                   };
-                 
-                 lines=&lines_y[0];
-                 
-                 unsigned int line_indices_y[4];
-                     
-                 for (unsigned int i=0; i<4; ++i)
-                   line_indices_y[i]=lines[i]->index();
-                 line_indices=&line_indices_y[0];
-
-                                                  // the orientation of lines for the
-                                                  // inner quads is quite tricky. as
-                                                  // these lines are newly created
-                                                  // ones and thus have no parents,
-                                                  // they cannot inherit this
-                                                  // property. set up an array and
-                                                  // fill it with the respective
-                                                  // values
-                 bool line_orientation_y[4];
-
-                                                  // the middle vertice marked
-                                                  // as m0 above is the start
-                                                  // vertex for lines 0 and 2
-                                                  // in standard orientation,
-                                                  // whereas m1 is the end
-                                                  // vertex of lines 1 and 3 in
-                                                  // standard orientation
-                 const unsigned int middle_vertices[2]=
-                   {
-                         hex->line(0)->child(0)->vertex_index(1),
-                         hex->line(5)->child(0)->vertex_index(1)
-                   };
-
-                 for (unsigned int i=0; i<4; ++i)
-                   if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
-                     line_orientation_y[i]=true;
-                   else
-                     {
-                                                        // it must be the other way round then
-                       Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
-                              ExcInternalError());
-                       line_orientation_y[i]=false;
-                     }
-                 
-                 line_orientation=&line_orientation_y[0];
-
-                                                  // set up the new quad, line
-                                                  // numbering is as indicated
-                                                  // above
-                 new_quads[0]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[2],
-                                                    line_indices[3],
-                                                    line_indices[0],
-                                                    line_indices[1]));
-
-                 new_quads[0]->set_line_orientation(0,line_orientation[2]);
-                 new_quads[0]->set_line_orientation(1,line_orientation[3]);
-                 new_quads[0]->set_line_orientation(2,line_orientation[0]);
-                 new_quads[0]->set_line_orientation(3,line_orientation[1]);
-
-                                                  // the quads are
-                                                  // numbered as follows:
-                                                  //
-                                                  // planes in the interior
-                                                  // of the old hex:
-                                                  //      *
-                                                  //     /|
-                                                  //    / | x         
-                                                  //   /  | *-------*      *---------*
-                                                  //  *   | |       |     /         /
-                                                  //  |   | |   0   |    /         /
-                                                  //  |   * |       |   /         /
-                                                  //  |  /  *-------*y *---------*x
-                                                  //  | /
-                                                  //  |/
-                                                  //  *
-                                                  //
-                                                  // children of the faces
-                                                  // of the old hex
-                                                  //      *-------*        *-------*
-                                                  //     /|       |       /   10  /|
-                                                  //    * |       |      *-------* |
-                                                  //   /| |   6   |     /   9   /| |
-                                                  //  * |2|       |    *-------* |4|
-                                                  //  | | *-------*    |       | | *
-                                                  //  |1|/   8   /     |       |3|/
-                                                  //  | *-------*      |   5   | *
-                                                  //  |/   7   /       |       |/
-                                                  //  *-------*        *-------*
-                                                  //
-                                                  // note that we have to
-                                                  // take care of the
-                                                  // orientation of
-                                                  // faces.
-                 const unsigned int quad_indices_y[11]
-                   = {
-                         new_quads[0]->index(),     //0
-                             
-                         hex->face(0)->child_index(  child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),  //1
-                         hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
-                             
-                         hex->face(1)->child_index(  child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),  //3
-                         hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
-                             
-                         hex->face(2)->index(),     //5
-                         
-                         hex->face(3)->index(),     //6
 
-                         hex->face(4)->child_index(  child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),  //7
-                         hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
-                             
-                         hex->face(5)->child_index(  child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]),  //9
-                         hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
-                             
-                   };
-                 quad_indices=&quad_indices_y[0];
-
-                 new_hexes[0]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[1],
-                                                    quad_indices[3],
-                                                    quad_indices[5],
-                                                    quad_indices[0],
-                                                    quad_indices[7],
-                                                    quad_indices[9]));
-                 new_hexes[1]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[2],
-                                                    quad_indices[4],
-                                                    quad_indices[0],
-                                                    quad_indices[6],
-                                                    quad_indices[8],
-                                                    quad_indices[10]));
-                 break;
-               }
-               case RefinementCase<dim>::cut_z:
-               {
-                                                  //////////////////////////////
-                                                  //
-                                                  //     RefinementCase<dim>::cut_z
-                                                  //
-                                                  // the refined cube will look
-                                                  // like this:
-                                                  //
-                                                  //        *---------*
-                                                  //       /         /|
-                                                  //      /         / |
-                                                  //     /         /  *
-                                                  //    *---------*  /|
-                                                  //    |         | / |
-                                                  //    |         |/  *
-                                                  //    *---------*  /
-                                                  //    |         | /
-                                                  //    |         |/
-                                                  //    *---------*
-                                                  // 
-                                                  // again, first
-                                                  // collect some data
-                                                  // about the indices of
-                                                  // the lines, with the
-                                                  // following numbering:
-           
-                                                  // face 0: left plane
-                                                  //       *
-                                                  //      /| 
-                                                  //     / |
-                                                  //    /  *
-                                                  //   *  /|
-                                                  //   | 0 |
-                                                  //   |/  *
-                                                  // m0*  / 
-                                                  //   | /  
-                                                  //   |/   
-                                                  //   *    
-                                                  // face 1: right plane
-                                                  //       *
-                                                  //      /| 
-                                                  //     / |
-                                                  //    /  *m1
-                                                  //   *  /|
-                                                  //   | 1 |
-                                                  //   |/  *
-                                                  //   *  / 
-                                                  //   | /  
-                                                  //   |/   
-                                                  //   *    
-                                                  // face 2: front plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *-------*
-                                                  //   |       |
-                                                  // m0*---2---*
-                                                  //   |       |
-                                                  //   *-------*
-                                                  // face 3: back plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *-------*
-                                                  //   |       | 
-                                                  //   *---3---*m1
-                                                  //   |       | 
-                                                  //   *-------*
-
-                                                  // set up a list of line iterators
-                                                  // first. from this, construct
-                                                  // lists of line_indices and
-                                                  // line orientations later on
-                 const raw_line_iterator lines_z[4]
-                   = {
-                         hex->face(0)->child(0)
-                         ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
-                         hex->face(1)->child(0)
-                         ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
-                         hex->face(2)->child(0)
-                         ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
-                         hex->face(3)->child(0)
-                         ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3)         //3
-                   };
-                 
-                 lines=&lines_z[0];
-                 
-                 unsigned int line_indices_z[4];
-                     
-                 for (unsigned int i=0; i<4; ++i)
-                   line_indices_z[i]=lines[i]->index();
-                 line_indices=&line_indices_z[0];
-
-                                                  // the orientation of lines for the
-                                                  // inner quads is quite tricky. as
-                                                  // these lines are newly created
-                                                  // ones and thus have no parents,
-                                                  // they cannot inherit this
-                                                  // property. set up an array and
-                                                  // fill it with the respective
-                                                  // values
-                 bool line_orientation_z[4];
-
-                                                  // the middle vertex marked
-                                                  // as m0 above is the start
-                                                  // vertex for lines 0 and 2
-                                                  // in standard orientation,
-                                                  // whereas m1 is the end
-                                                  // vertex of lines 1 and 3 in
-                                                  // standard orientation
-                 const unsigned int middle_vertices[2]=
-                   {
-                         hex->line(8)->middle_vertex_index(),
-                         hex->line(11)->middle_vertex_index()
-                   };
+               if (all_children_active) 
+                 {
+                                                    // count number
+                                                    // of refined and
+                                                    // unrefined
+                                                    // neighbors of
+                                                    // cell.
+                                                    // neighbors on
+                                                    // lower levels
+                                                    // are counted as
+                                                    // unrefined
+                                                    // since they can
+                                                    // only get to
+                                                    // the same level
+                                                    // as this cell
+                                                    // by the next
+                                                    // refinement
+                                                    // cycle
+                   unsigned int unrefined_neighbors = 0,
+                                    total_neighbors = 0;
 
-                 for (unsigned int i=0; i<4; ++i)
-                   if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
-                     line_orientation_z[i]=true;
-                   else
+                   for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n) 
                      {
-                                                        // it must be the other way round then
-                       Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
-                              ExcInternalError());
-                       line_orientation_z[i]=false;
-                     }
-                 
-                 line_orientation=&line_orientation_z[0];
-
-                                                  // set up the new quad, line
-                                                  // numbering is as indicated
-                                                  // above
-                 new_quads[0]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[0],
-                                                    line_indices[1],
-                                                    line_indices[2],
-                                                    line_indices[3]));
-                 
-                 new_quads[0]->set_line_orientation(0,line_orientation[0]);
-                 new_quads[0]->set_line_orientation(1,line_orientation[1]);
-                 new_quads[0]->set_line_orientation(2,line_orientation[2]);
-                 new_quads[0]->set_line_orientation(3,line_orientation[3]);
-
-                                                  // the quads are
-                                                  // numbered as follows:
-                                                  //
-                                                  // planes in the interior
-                                                  // of the old hex:
-                                                  //      *
-                                                  //     /|
-                                                  //    / | x         
-                                                  //   /  | *-------*      *---------*
-                                                  //  *   | |       |     /         /
-                                                  //  |   | |       |    /    0    /
-                                                  //  |   * |       |   /         /
-                                                  //  |  /  *-------*y *---------*x
-                                                  //  | /
-                                                  //  |/
-                                                  //  *
-                                                  //
-                                                  // children of the faces
-                                                  // of the old hex
-                                                  //      *---*---*        *-------*
-                                                  //     /|   8   |       /       /|
-                                                  //    / |       |      /   10  / |
-                                                  //   /  *-------*     /       /  *
-                                                  //  * 2/|       |    *-------* 4/|
-                                                  //  | / |   7   |    |   6   | / |
-                                                  //  |/1 *-------*    |       |/3 *
-                                                  //  *  /       /     *-------*  /
-                                                  //  | /   9   /      |       | /
-                                                  //  |/       /       |   5   |/
-                                                  //  *-------*        *---*---*
-                                                  //
-                                                  // note that we have to
-                                                  // take care of the
-                                                  // orientation of
-                                                  // faces.
-                 const unsigned int quad_indices_z[11]
-                   = {
-                         new_quads[0]->index(),     //0
-                             
-                         hex->face(0)->child_index(  child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),  //1
-                         hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
-                             
-                         hex->face(1)->child_index(  child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),  //3
-                         hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
-                             
-                         hex->face(2)->child_index(  child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),  //5
-                         hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
-                             
-                         hex->face(3)->child_index(  child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),  //7
-                         hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
-                             
-                         hex->face(4)->index(),     //9
-                         
-                         hex->face(5)->index()      //10
-                   };
-                 quad_indices=&quad_indices_z[0];
-
-                 new_hexes[0]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[1],
-                                                    quad_indices[3],
-                                                    quad_indices[5],
-                                                    quad_indices[7],
-                                                    quad_indices[9],
-                                                    quad_indices[0]));
-                 new_hexes[1]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[2],
-                                                    quad_indices[4],
-                                                    quad_indices[6],
-                                                    quad_indices[8],
-                                                    quad_indices[0],
-                                                    quad_indices[10]));
-                 break;
-               }
-               case RefinementCase<dim>::cut_xy:
-               {
-                                                  //////////////////////////////
-                                                  //
-                                                  //     RefinementCase<dim>::cut_xy
-                                                  //
-                                                  // the refined cube will look
-                                                  // like this:
-                                                  //
-                                                  //        *----*----*
-                                                  //       /    /    /|
-                                                  //      *----*----* |
-                                                  //     /    /    /| |
-                                                  //    *----*----* | |
-                                                  //    |    |    | | |
-                                                  //    |    |    | | *
-                                                  //    |    |    | |/
-                                                  //    |    |    | *
-                                                  //    |    |    |/
-                                                  //    *----*----*
-                                                  // 
-
-                                                  // first, create the new
-                                                  // internal line
-                 new_lines[0]->set (internal::Triangulation::
-                                    TriaObject<1>(hex->face(4)->middle_vertex_index(),
-                                                  hex->face(5)->middle_vertex_index()));
-
-                                                  // again, first
-                                                  // collect some data
-                                                  // about the indices of
-                                                  // the lines, with the
-                                                  // following numbering:
-           
-                                                  // face 0: left plane
-                                                  //       *
-                                                  //      /| 
-                                                  //     * |
-                                                  //    /| |
-                                                  //   * | |
-                                                  //   | 0 |
-                                                  //   | | *
-                                                  //   | |/ 
-                                                  //   | *  
-                                                  //   |/   
-                                                  //   *    
-                                                  // face 1: right plane
-                                                  //       *
-                                                  //      /| 
-                                                  //     * |
-                                                  //    /| |
-                                                  //   * | |
-                                                  //   | 1 |
-                                                  //   | | *
-                                                  //   | |/ 
-                                                  //   | *  
-                                                  //   |/   
-                                                  //   *    
-                                                  // face 2: front plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *---*---*
-                                                  //   |   |   |
-                                                  //   |   2   |
-                                                  //   |   |   |
-                                                  //   *-------*
-                                                  // face 3: back plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *---*---*
-                                                  //   |   |   | 
-                                                  //   |   3   |
-                                                  //   |   |   | 
-                                                  //   *---*---*
-                                                  // face 4: bottom plane
-                                                  //       *---*---*
-                                                  //      /   5   /
-                                                  //     *-6-*-7-*
-                                                  //    /   4   /
-                                                  //   *---*---*
-                                                  // face 5: top plane
-                                                  //       *---*---*
-                                                  //      /   9   /
-                                                  //     *10-*-11*
-                                                  //    /   8   /
-                                                  //   *---*---*
-                                                  // middle planes
-                                                  //     *-------*   *---*---*
-                                                  //    /       /    |   |   |
-                                                  //   /       /     |   12  |
-                                                  //  /       /      |   |   |
-                                                  // *-------*       *---*---*
-
-                                                  // set up a list of line iterators
-                                                  // first. from this, construct
-                                                  // lists of line_indices and
-                                                  // line orientations later on
-                 const raw_line_iterator lines_xy[13]
-                   = {
-                         hex->face(0)->child(0)
-                         ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
-                         hex->face(1)->child(0)
-                         ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
-                         hex->face(2)->child(0)
-                         ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
-                         hex->face(3)->child(0)
-                         ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //3
-
-                         hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])),        //4
-                         hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])),        //5
-                         hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])),        //6
-                         hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])),        //7
-                         
-                         hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])),        //8
-                         hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])),        //9
-                         hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])),        //10
-                         hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])),        //11
-
-                         new_lines[0]                        //12
-                   };
-                 
-                 lines=&lines_xy[0];
-                 
-                 unsigned int line_indices_xy[13];
-                     
-                 for (unsigned int i=0; i<13; ++i)
-                   line_indices_xy[i]=lines[i]->index();
-                 line_indices=&line_indices_xy[0];
-
-                                                  // the orientation of lines for the
-                                                  // inner quads is quite tricky. as
-                                                  // these lines are newly created
-                                                  // ones and thus have no parents,
-                                                  // they cannot inherit this
-                                                  // property. set up an array and
-                                                  // fill it with the respective
-                                                  // values
-                 bool line_orientation_xy[13];
-
-                                                  // the middle vertices of the
-                                                  // lines of our bottom face
-                 const unsigned int middle_vertices[4]=
-                   {
-                         hex->line(0)->child(0)->vertex_index(1),
-                         hex->line(1)->child(0)->vertex_index(1),
-                         hex->line(2)->child(0)->vertex_index(1),
-                         hex->line(3)->child(0)->vertex_index(1),
-                   };
+                       const cell_iterator neighbor = cell->neighbor(n);
+                       if (neighbor.state() == IteratorState::valid)
+                       {
+                         ++total_neighbors;
 
-                                                  // note: for lines 0 to 3 the
-                                                  // orientation of the line
-                                                  // is 'true', if vertex 0 is
-                                                  // on the bottom face
-                 for (unsigned int i=0; i<4; ++i)
-                   if (lines[i]->vertex_index(0)==middle_vertices[i])
-                     line_orientation_xy[i]=true;
-                   else
-                     {
-                                                        // it must be the other way round then
-                       Assert(lines[i]->vertex_index(1)==middle_vertices[i],
-                              ExcInternalError());
-                       line_orientation_xy[i]=false;
+                         if (!face_will_be_refined_by_neighbor(cell,n))
+                           ++unrefined_neighbors;
+                       }
+                       
                      }
-                 
-                                                  // note: for lines 4 to 11
-                                                  // (inner lines of the outer quads)
-                                                  // the following holds: the second
-                                                  // vertex of the even lines in
-                                                  // standard orientation is the
-                                                  // vertex in the middle of the
-                                                  // quad, whereas for odd lines the
-                                                  // first vertex is the same middle
-                                                  // vertex.
-                 for (unsigned int i=4; i<12; ++i)
-                   if (lines[i]->vertex_index((i+1)%2)==hex->face(3+i/4)->middle_vertex_index())
-                     line_orientation_xy[i]=true;
-                   else
+                   
+                                                    // if all
+                                                    // neighbors
+                                                    // unrefined:
+                                                    // mark this cell
+                                                    // for coarsening
+                                                    // or don't
+                                                    // refine if
+                                                    // marked for
+                                                    // that
+                                                    //
+                                                    // also do the
+                                                    // distinction
+                                                    // between the
+                                                    // two versions
+                                                    // of the
+                                                    // eliminate_refined_*_islands
+                                                    // flag
+                                                    //
+                                                    // the last check
+                                                    // is whether
+                                                    // there are any
+                                                    // neighbors at
+                                                    // all. if not
+                                                    // so, then we
+                                                    // are (e.g.) on
+                                                    // the coarsest
+                                                    // grid with one
+                                                    // cell, for
+                                                    // which, of
+                                                    // course, we do
+                                                    // not remove the
+                                                    // refine flag.
+                   if ((unrefined_neighbors == total_neighbors)
+                       &&
+                       (((unrefined_neighbors==GeometryInfo<dim>::faces_per_cell) &&
+                         (smooth_grid & eliminate_refined_inner_islands)) ||
+                        ((unrefined_neighbors<GeometryInfo<dim>::faces_per_cell) &&
+                         (smooth_grid & eliminate_refined_boundary_islands)) )
+                       &&
+                       (total_neighbors != 0))
                      {
-                                                        // it must be the other way
-                                                        // round then
-                       Assert(lines[i]->vertex_index(i%2)==hex->face(3+i/4)->middle_vertex_index(),
-                              ExcInternalError());
-                       line_orientation_xy[i]=false;
+                       if (!cell->active())
+                         for (unsigned int c=0; c<cell->n_children(); ++c)
+                           {
+                             cell->child(c)->clear_refine_flag ();
+                             cell->child(c)->set_coarsen_flag ();
+                           }
+                       else 
+                         cell->clear_refine_flag();
                      }
-                                                  // for the last line the line
-                                                  // orientation is always true,
-                                                  // since it was just constructed
-                                                  // that way
-
-                 line_orientation_xy[12]=true;
-                 line_orientation=&line_orientation_xy[0];
-
-                                                  // set up the 4 quads,
-                                                  // numbered as follows
-                                                  // (left quad numbering,
-                                                  // right line numbering
-                                                  // extracted from above)
-                                                  //
-                                                  //      *          *
-                                                  //     /|         9|
-                                                  //    * |        * |
-                                                  //  y/| |       8| 3  
-                                                  //  * |1|      * | | 
-                                                  //  | | |x     | 12|
-                                                  //  |0| *      | | * 
-                                                  //  | |/       2 |5 
-                                                  //  | *        | *
-                                                  //  |/         |4
-                                                  //  *          *
-                                                  //
-                                                  //  x
-                                                  //  *---*---*      *10-*-11*
-                                                  //  |   |   |      |   |   |
-                                                  //  | 2 | 3 |      0   12  1 
-                                                  //  |   |   |      |   |   |
-                                                  //  *---*---*y     *-6-*-7-*
-                 
-                 new_quads[0]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[2],
-                                                    line_indices[12],
-                                                    line_indices[4],
-                                                    line_indices[8]));
-                 new_quads[1]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[12],
-                                                    line_indices[3],
-                                                    line_indices[5],
-                                                    line_indices[9]));
-                 new_quads[2]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[6],
-                                                    line_indices[10],
-                                                    line_indices[0],
-                                                    line_indices[12]));
-                 new_quads[3]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[7],
-                                                    line_indices[11],
-                                                    line_indices[12],
-                                                    line_indices[1]));
-
-                 new_quads[0]->set_line_orientation(0,line_orientation[2]);
-                 new_quads[0]->set_line_orientation(2,line_orientation[4]);
-                 new_quads[0]->set_line_orientation(3,line_orientation[8]);
-                     
-                 new_quads[1]->set_line_orientation(1,line_orientation[3]);
-                 new_quads[1]->set_line_orientation(2,line_orientation[5]);
-                 new_quads[1]->set_line_orientation(3,line_orientation[9]);
-                     
-                 new_quads[2]->set_line_orientation(0,line_orientation[6]);
-                 new_quads[2]->set_line_orientation(1,line_orientation[10]);
-                 new_quads[2]->set_line_orientation(2,line_orientation[0]);
-
-                 new_quads[3]->set_line_orientation(0,line_orientation[7]);
-                 new_quads[3]->set_line_orientation(1,line_orientation[11]);
-                 new_quads[3]->set_line_orientation(3,line_orientation[1]);
-
-                                                  // the quads are
-                                                  // numbered as follows:
-                                                  //
-                                                  // planes in the interior
-                                                  // of the old hex:
-                                                  //      *
-                                                  //     /|
-                                                  //    * | x         
-                                                  //   /| | *---*---*      *---------*
-                                                  //  * |1| |   |   |     /         /
-                                                  //  | | | | 2 | 3 |    /         /
-                                                  //  |0| * |   |   |   /         /
-                                                  //  | |/  *---*---*y *---------*x
-                                                  //  | *
-                                                  //  |/
-                                                  //  *
-                                                  //
-                                                  // children of the faces
-                                                  // of the old hex
-                                                  //      *---*---*        *---*---*
-                                                  //     /|   |   |       /18 / 19/|
-                                                  //    * |10 | 11|      /---/---* |
-                                                  //   /| |   |   |     /16 / 17/| |
-                                                  //  * |5|   |   |    *---*---* |7|
-                                                  //  | | *---*---*    |   |   | | *
-                                                  //  |4|/14 / 15/     |   |   |6|/
-                                                  //  | *---/---/      | 8 | 9 | *
-                                                  //  |/12 / 13/       |   |   |/
-                                                  //  *---*---*        *---*---*
-                                                  //
-                                                  // note that we have to
-                                                  // take care of the
-                                                  // orientation of
-                                                  // faces.
-                 const unsigned int quad_indices_xy[20]
-                   = {
-                         new_quads[0]->index(),     //0
-                         new_quads[1]->index(),
-                         new_quads[2]->index(),
-                         new_quads[3]->index(),
-                             
-                         hex->face(0)->child_index(  child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),  //4
-                         hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
+                 }
+             }
+       }
 
-                         hex->face(1)->child_index(  child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),  //6
-                         hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
-                             
-                         hex->face(2)->child_index(  child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),  //8
-                         hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
-                             
-                         hex->face(3)->child_index(  child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),  //10
-                         hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
-                             
-                         hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])),  //12
-                         hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
-                         hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
-                         hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
-                             
-                         hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])),  //16
-                         hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
-                         hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
-                         hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
-                   };
-                 quad_indices=&quad_indices_xy[0];
-
-                 new_hexes[0]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[4],
-                                                    quad_indices[0],
-                                                    quad_indices[8],
-                                                    quad_indices[2],
-                                                    quad_indices[12],
-                                                    quad_indices[16]));
-                 new_hexes[1]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[0],
-                                                    quad_indices[6],
-                                                    quad_indices[9],
-                                                    quad_indices[3],
-                                                    quad_indices[13],
-                                                    quad_indices[17]));
-                 new_hexes[2]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[5],
-                                                    quad_indices[1],
-                                                    quad_indices[2],
-                                                    quad_indices[10],
-                                                    quad_indices[14],
-                                                    quad_indices[18]));
-                 new_hexes[3]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[1],
-                                                    quad_indices[7],
-                                                    quad_indices[3],
-                                                    quad_indices[11],
-                                                    quad_indices[15],
-                                                    quad_indices[19]));
-                 break;
-               }
-               case RefinementCase<dim>::cut_xz:
+                                      //////////////////////////////////////
+                                      // STEP 3:
+                                      //    limit the level difference of
+                                      //    neighboring cells at each vertex.
+                                      //
+                                      //    in case of anisotropic refinement
+                                      //    this does not make sense. as soon
+                                      //    as one cell is anisotropically
+                                      //    refined, an Assertion is
+                                      //    thrown. therefore we can ignore
+                                      //    this problem later on
+      if (smooth_grid & limit_level_difference_at_vertices)
+       {
+         Assert(!anisotropic_refinement,
+                ExcMessage("In case of anisotropic refinement the "
+                           "limit_level_difference_at_vertices flag for "
+                           "mesh smoothing must not be set!"));
+         
+                                          // store highest level one
+                                          // of the cells adjacent to
+                                          // a vertex belongs to
+         std::vector<int> vertex_level (vertices.size(), 0);
+         active_cell_iterator cell = begin_active(),
+                              endc = end();
+         for (; cell!=endc; ++cell)
+           {
+             if (cell->refine_flag_set())
+               for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+                    ++vertex)
+                 vertex_level[cell->vertex_index(vertex)]
+                   = std::max (vertex_level[cell->vertex_index(vertex)],
+                               cell->level()+1);
+             else if (!cell->coarsen_flag_set())
+               for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+                    ++vertex)
+                 vertex_level[cell->vertex_index(vertex)]
+                   = std::max (vertex_level[cell->vertex_index(vertex)],
+                               cell->level());
+             else
                {
-                                                  //////////////////////////////
-                                                  //
-                                                  //     RefinementCase<dim>::cut_xz
-                                                  //
-                                                  // the refined cube will look
-                                                  // like this:
-                                                  //
-                                                  //        *----*----*
-                                                  //       /    /    /|
-                                                  //      /    /    / |
-                                                  //     /    /    /  *
-                                                  //    *----*----*  /|
-                                                  //    |    |    | / |
-                                                  //    |    |    |/  *
-                                                  //    *----*----*  /
-                                                  //    |    |    | /
-                                                  //    |    |    |/
-                                                  //    *----*----*
-                                                  // 
-
-                                                  // first, create the new
-                                                  // internal line
-                 new_lines[0]->set (internal::Triangulation::
-                                    TriaObject<1>(hex->face(2)->middle_vertex_index(),
-                                                  hex->face(3)->middle_vertex_index()));
-
-                                                  // again, first
-                                                  // collect some data
-                                                  // about the indices of
-                                                  // the lines, with the
-                                                  // following numbering:
-           
-                                                  // face 0: left plane
-                                                  //       *
-                                                  //      /| 
-                                                  //     / |
-                                                  //    /  *
-                                                  //   *  /|
-                                                  //   | 0 |
-                                                  //   |/  *
-                                                  //   *  / 
-                                                  //   | /  
-                                                  //   |/   
-                                                  //   *    
-                                                  // face 1: right plane
-                                                  //       *
-                                                  //      /| 
-                                                  //     / |
-                                                  //    /  *
-                                                  //   *  /|
-                                                  //   | 1 |
-                                                  //   |/  *
-                                                  //   *  / 
-                                                  //   | /  
-                                                  //   |/   
-                                                  //   *    
-                                                  // face 2: front plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *---*---*
-                                                  //   |   5   |
-                                                  //   *-6-*-7-*
-                                                  //   |   4   |
-                                                  //   *---*---*
-                                                  // face 3: back plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *---*---*
-                                                  //   |   9   | 
-                                                  //   *10-*-11*
-                                                  //   |   8   | 
-                                                  //   *---*---*
-                                                  // face 4: bottom plane
-                                                  //       *---*---*
-                                                  //      /   /   /
-                                                  //     /   2   /
-                                                  //    /   /   /
-                                                  //   *---*---*
-                                                  // face 5: top plane
-                                                  //       *---*---*
-                                                  //      /   /   /
-                                                  //     /   3   /
-                                                  //    /   /   /
-                                                  //   *---*---*
-                                                  // middle planes
-                                                  //     *---*---*   *-------*
-                                                  //    /   /   /    |       |
-                                                  //   /   12  /     |       |
-                                                  //  /   /   /      |       |
-                                                  // *---*---*       *-------*
-
-                                                  // set up a list of line iterators
-                                                  // first. from this, construct
-                                                  // lists of line_indices and
-                                                  // line orientations later on
-                 const raw_line_iterator lines_xz[13]
-                   = {
-                         hex->face(0)->child(0)
-                         ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
-                         hex->face(1)->child(0)
-                         ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
-                         hex->face(4)->child(0)
-                         ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
-                         hex->face(5)->child(0)
-                         ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //3
-
-                         hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])),        //4
-                         hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])),        //5
-                         hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])),        //6
-                         hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])),        //7
-                         
-                         hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])),        //8
-                         hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])),        //9
-                         hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])),        //10
-                         hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])),        //11
-
-                         new_lines[0]                        //12
-                   };
-                 
-                 lines=&lines_xz[0];
-                 
-                 unsigned int line_indices_xz[13];
-                     
-                 for (unsigned int i=0; i<13; ++i)
-                   line_indices_xz[i]=lines[i]->index();
-                 line_indices=&line_indices_xz[0];
-
-                                                  // the orientation of lines for the
-                                                  // inner quads is quite tricky. as
-                                                  // these lines are newly created
-                                                  // ones and thus have no parents,
-                                                  // they cannot inherit this
-                                                  // property. set up an array and
-                                                  // fill it with the respective
-                                                  // values
-                 bool line_orientation_xz[13];
-
-                                                  // the middle vertices of the
-                                                  // lines of our front face
-                 const unsigned int middle_vertices[4]=
-                   {
-                         hex->line(8)->child(0)->vertex_index(1),
-                         hex->line(9)->child(0)->vertex_index(1),
-                         hex->line(2)->child(0)->vertex_index(1),
-                         hex->line(6)->child(0)->vertex_index(1),
-                   };
+                                                  // if coarsen flag is set then
+                                                  // tentatively assume that the
+                                                  // cell will be coarsened. this
+                                                  // isn't always true (the
+                                                  // coarsen flag could be
+                                                  // removed again) and so we may
+                                                  // make an error here
+                 Assert (cell->coarsen_flag_set(), ExcInternalError());
+                 for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+                      ++vertex)
+                   vertex_level[cell->vertex_index(vertex)]
+                     = std::max (vertex_level[cell->vertex_index(vertex)],
+                                 cell->level()-1);
+               }
+           }
+      
 
-                                                  // note: for lines 0 to 3 the
-                                                  // orientation of the line
-                                                  // is 'true', if vertex 0 is
-                                                  // on the front
-                 for (unsigned int i=0; i<4; ++i)
-                   if (lines[i]->vertex_index(0)==middle_vertices[i])
-                     line_orientation_xz[i]=true;
-                   else
-                     {
-                                                        // it must be the other way round then
-                       Assert(lines[i]->vertex_index(1)==middle_vertices[i],
-                              ExcInternalError());
-                       line_orientation_xz[i]=false;
-                     }
-                 
-                                                  // note: for lines 4 to 11
-                                                  // (inner lines of the outer quads)
-                                                  // the following holds: the second
-                                                  // vertex of the even lines in
-                                                  // standard orientation is the
-                                                  // vertex in the middle of the
-                                                  // quad, whereas for odd lines the
-                                                  // first vertex is the same middle
-                                                  // vertex.
-                 for (unsigned int i=4; i<12; ++i)
-                   if (lines[i]->vertex_index((i+1)%2)==hex->face(1+i/4)->middle_vertex_index())
-                     line_orientation_xz[i]=true;
-                   else
-                     {
-                                                        // it must be the other way
-                                                        // round then
-                       Assert(lines[i]->vertex_index(i%2)==hex->face(1+i/4)->middle_vertex_index(),
-                              ExcInternalError());
-                       line_orientation_xz[i]=false;
-                     }
-                                                  // for the last line the line
-                                                  // orientation is always true,
-                                                  // since it was just constructed
-                                                  // that way
-
-                 line_orientation_xz[12]=true;
-                 line_orientation=&line_orientation_xz[0];
-
-                                                      // set up the 4 quads,
-                                                      // numbered as follows
-                                                      // (left quad numbering,
-                                                      // right line numbering
-                                                      // extracted from above),
-                                                      // the drawings denote
-                                                      // middle planes
-                                                      //
-                                                      //      *          *
-                                                      //     /|         /|
-                                                      //    / |        3 9 
-                                                      //  y/  *       /  *  
-                                                      //  * 3/|      *  /|
-                                                      //  | / |x     5 12|8
-                                                      //  |/  *      |/  * 
-                                                      //  * 2/       *  /  
-                                                      //  | /        4 2
-                                                      //  |/         |/ 
-                                                      //  *          *
-                                                      //
-                                                      //       y
-                                                      //      *----*----*      *-10-*-11-*
-                                                      //     /    /    /      /    /    /
-                                                      //    / 0  /  1 /      0    12   1
-                                                      //   /    /    /      /    /    /
-                                                      //  *----*----*x     *--6-*--7-*
-           
-                 new_quads[0]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[0],
-                                                    line_indices[12],
-                                                    line_indices[6],
-                                                    line_indices[10]));
-                 new_quads[1]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[12],
-                                                    line_indices[1],
-                                                    line_indices[7],
-                                                    line_indices[11]));
-                 new_quads[2]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[4],
-                                                    line_indices[8],
-                                                    line_indices[2],
-                                                    line_indices[12]));
-                 new_quads[3]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[5],
-                                                    line_indices[9],
-                                                    line_indices[12],
-                                                    line_indices[3]));
-
-                 new_quads[0]->set_line_orientation(0,line_orientation[0]);
-                 new_quads[0]->set_line_orientation(2,line_orientation[6]);
-                 new_quads[0]->set_line_orientation(3,line_orientation[10]);
-                     
-                 new_quads[1]->set_line_orientation(1,line_orientation[1]);
-                 new_quads[1]->set_line_orientation(2,line_orientation[7]);
-                 new_quads[1]->set_line_orientation(3,line_orientation[11]);
-                     
-                 new_quads[2]->set_line_orientation(0,line_orientation[4]);
-                 new_quads[2]->set_line_orientation(1,line_orientation[8]);
-                 new_quads[2]->set_line_orientation(2,line_orientation[2]);
-
-                 new_quads[3]->set_line_orientation(0,line_orientation[5]);
-                 new_quads[3]->set_line_orientation(1,line_orientation[9]);
-                 new_quads[3]->set_line_orientation(3,line_orientation[3]);
+                                          // loop over all cells in reverse
+                                          // order. do so because we can then
+                                          // update the vertex levels on the
+                                          // adjacent vertices and maybe
+                                          // already flag additional cells in
+                                          // this loop
+                                          //
+                                          // note that not only may we have
+                                          // to add additional refinement
+                                          // flags, but we will also have to
+                                          // remove coarsening flags on cells
+                                          // adjacent to vertices that will
+                                          // see refinement
+         for (cell=last_active(); cell != endc; --cell)
+           if (cell->refine_flag_set() == false)
+             {
+               for (unsigned int vertex=0;
+                    vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+                 if (vertex_level[cell->vertex_index(vertex)] >=
+                     cell->level()+1)
+                   {
+                                                      // remove coarsen flag...
+                     cell->clear_coarsen_flag();
 
-                                                  // the quads are
-                                                  // numbered as follows:
-                                                  //
-                                                  // planes in the interior
-                                                  // of the old hex:
-                                                  //      *
-                                                  //     /|
-                                                  //    / | x         
-                                                  //   /3 * *-------*      *----*----*
-                                                  //  *  /| |       |     /    /    /
-                                                  //  | / | |       |    /  0 /  1 /
-                                                  //  |/  * |       |   /    /    /
-                                                  //  * 2/  *-------*y *----*----*x
-                                                  //  | /
-                                                  //  |/
-                                                  //  *
-                                                  //
-                                                  // children of the faces
-                                                  // of the old hex
-                                                  //      *---*---*        *---*---*
-                                                  //     /|13 | 15|       /   /   /|
-                                                  //    / |   |   |      /18 / 19/ |
-                                                  //   /  *---*---*     /   /   /  *
-                                                  //  * 5/|   |   |    *---*---* 7/|
-                                                  //  | / |12 | 14|    | 9 | 11| / |
-                                                  //  |/4 *---*---*    |   |   |/6 *
-                                                  //  *  /   /   /     *---*---*  /
-                                                  //  | /16 / 17/      |   |   | /
-                                                  //  |/   /   /       | 8 | 10|/
-                                                  //  *---*---*        *---*---*
-                                                  //
-                                                  // note that we have to
-                                                  // take care of the
-                                                  // orientation of
-                                                  // faces.
-                 const unsigned int quad_indices_xz[20]
-                   = {
-                         new_quads[0]->index(),     //0
-                         new_quads[1]->index(),
-                         new_quads[2]->index(),
-                         new_quads[3]->index(),
-                             
-                         hex->face(0)->child_index(  child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),  //4
-                         hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
+                                                      // ...and if necessary also
+                                                      // refine the current cell,
+                                                      // at the same time
+                                                      // updating the level
+                                                      // information about
+                                                      // vertices
+                     if (vertex_level[cell->vertex_index(vertex)] >
+                         cell->level()+1)
+                       {
+                         cell->set_refine_flag();
+                     
+                         for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
+                              ++v)
+                           vertex_level[cell->vertex_index(v)]
+                             = std::max (vertex_level[cell->vertex_index(v)],
+                                         cell->level()+1);
+                       }
 
-                         hex->face(1)->child_index(  child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),  //6
-                         hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
-                             
-                         hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])),  //8 
-                         hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
-                         hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
-                         hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
-                             
-                         hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])),  //12
-                         hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
-                         hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
-                         hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
+                                                      // continue and see whether
+                                                      // we may, for example, go
+                                                      // into the inner 'if'
+                                                      // above based on a
+                                                      // different vertex
+                   }
+             }
+       }
 
-                         hex->face(4)->child_index(  child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),  //16
-                         hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
-                             
-                         hex->face(5)->child_index(  child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]),  //18
-                         hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
-                   };
-                 quad_indices=&quad_indices_xz[0];
+                                      /////////////////////////////////////
+                                      // STEP 4:      
+                                      //    eliminate unrefined
+                                      //    islands. this has higher
+                                      //    priority since this
+                                      //    diminishes the
+                                      //    approximation properties
+                                      //    not only of the unrefined
+                                      //    island, but also of the
+                                      //    surrounding patch.
+      if (smooth_grid & eliminate_unrefined_islands)
+       {
+         active_cell_iterator cell = begin_active(),
+                              endc = end();
+         for (; cell!=endc; ++cell) 
+           {
+                                              // if cell is already
+                                              // flagged for (isotropic)
+                                              // refinement: nothing
+                                              // to do anymore
+             if (cell->refine_flag_set()==RefinementCase<dim>::isotropic_refinement)
+               continue;
 
-                                                  // due to the exchange of x
-                                                  // and y for the front and
-                                                  // back face, we order the
-                                                  // children according to
-                                                  //
-                                                  // *---*---*
-                                                  // | 1 | 3 |
-                                                  // *---*---*
-                                                  // | 0 | 2 |
-                                                  // *---*---*
-                 new_hexes[0]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[4],
-                                                    quad_indices[2],
-                                                    quad_indices[8],
-                                                    quad_indices[12],
-                                                    quad_indices[16],
-                                                    quad_indices[0]));
-                 new_hexes[1]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[5],
-                                                    quad_indices[3],
-                                                    quad_indices[9],
-                                                    quad_indices[13],
-                                                    quad_indices[0],
-                                                    quad_indices[18]));
-                 new_hexes[2]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[2],
-                                                    quad_indices[6],
-                                                    quad_indices[10],
-                                                    quad_indices[14],
-                                                    quad_indices[17],
-                                                    quad_indices[1]));
-                 new_hexes[3]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[3],
-                                                    quad_indices[7],
-                                                    quad_indices[11],
-                                                    quad_indices[15],
-                                                    quad_indices[1],
-                                                    quad_indices[19]));
-                 break;
-               }
-               case RefinementCase<dim>::cut_yz:
+                                              // now we provide two
+                                              // algorithms. the first one is
+                                              // the standard one, coming from
+                                              // the time, where only isotropic
+                                              // refinement was possible. it
+                                              // simply counts the neighbors
+                                              // that are or will be refined
+                                              // and compares to the number of
+                                              // other ones. the second one
+                                              // does this check independently
+                                              // for each direction: if all
+                                              // neighbors in one direction
+                                              // (normally two, at the boundary
+                                              // only one) are refined, the
+                                              // current cell is flagged to be
+                                              // refined in an according
+                                              // direction.
+             
+             if (!(smooth_grid & allow_anisotropic_smoothing))
                {
-                                                  //////////////////////////////
-                                                  //
-                                                  //     RefinementCase<dim>::cut_yz
-                                                  //
-                                                  // the refined cube will look
-                                                  // like this:
-                                                  //
-                                                  //        *---------*
-                                                  //       /         /|
-                                                  //      *---------* |
-                                                  //     /         /| |
-                                                  //    *---------* |/|
-                                                  //    |         | * |
-                                                  //    |         |/| *
-                                                  //    *---------* |/
-                                                  //    |         | *
-                                                  //    |         |/
-                                                  //    *---------*
-                                                  // 
-
-                                                  // first, create the new
-                                                  // internal line
-                 new_lines[0]->set (internal::Triangulation::
-                                    TriaObject<1>(hex->face(0)->middle_vertex_index(),
-                                                  hex->face(1)->middle_vertex_index()));
-
-                                                  // again, first
-                                                  // collect some data
-                                                  // about the indices of
-                                                  // the lines, with the
-                                                  // following numbering:
-                                                  // (note that face 0 and
-                                                  // 1 each are shown twice
-                                                  // for better
-                                                  // readability)
-                 
-                                                  // face 0: left plane
-                                                  //       *            *
-                                                  //      /|           /| 
-                                                  //     * |          * |
-                                                  //    /| *         /| *
-                                                  //   * 5/|        * |7|
-                                                  //   | * |        | * |
-                                                  //   |/| *        |6| *
-                                                  //   * 4/         * |/
-                                                  //   | *          | *
-                                                  //   |/           |/ 
-                                                  //   *            *
-                                                  // face 1: right plane
-                                                  //       *            *
-                                                  //      /|           /| 
-                                                  //     * |          * |
-                                                  //    /| *         /| *
-                                                  //   * 9/|        * |11
-                                                  //   | * |        | * |
-                                                  //   |/| *        |10 *
-                                                  //   * 8/         * |/
-                                                  //   | *          | *
-                                                  //   |/           |/
-                                                  //   *            *
-                                                  // face 2: front plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *-------*
-                                                  //   |       |
-                                                  //   *---0---*
-                                                  //   |       |
-                                                  //   *-------*
-                                                  // face 3: back plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *-------*
-                                                  //   |       | 
-                                                  //   *---1---*
-                                                  //   |       | 
-                                                  //   *-------*
-                                                  // face 4: bottom plane
-                                                  //       *-------*
-                                                  //      /       /
-                                                  //     *---2---*
-                                                  //    /       /
-                                                  //   *-------*
-                                                  // face 5: top plane
-                                                  //       *-------*
-                                                  //      /       /
-                                                  //     *---3---*
-                                                  //    /       /
-                                                  //   *-------*
-                                                  // middle planes
-                                                  //     *-------*   *-------*
-                                                  //    /       /    |       |
-                                                  //   *---12--*     |       |
-                                                  //  /       /      |       |
-                                                  // *-------*       *-------*
-
-                                                  // set up a list of line iterators
-                                                  // first. from this, construct
-                                                  // lists of line_indices and
-                                                  // line orientations later on
-                 const raw_line_iterator lines_yz[13]
-                   = {
-                         hex->face(2)->child(0)
-                         ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //0
-                         hex->face(3)->child(0)
-                         ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //1
-                         hex->face(4)->child(0)
-                         ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //2
-                         hex->face(5)->child(0)
-                         ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3),        //3
-
-                         hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])),        //4
-                         hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])),        //5
-                         hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])),        //6
-                         hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])),        //7
-                         
-                         hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])),        //8
-                         hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])),        //9
-                         hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])),        //10
-                         hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])),        //11
-
-                         new_lines[0]                        //12
-                   };
-                 
-                 lines=&lines_yz[0];
-                 
-                 unsigned int line_indices_yz[13];
-                     
-                 for (unsigned int i=0; i<13; ++i)
-                   line_indices_yz[i]=lines[i]->index();
-                 line_indices=&line_indices_yz[0];
-
-                                                  // the orientation of lines for the
-                                                  // inner quads is quite tricky. as
-                                                  // these lines are newly created
-                                                  // ones and thus have no parents,
-                                                  // they cannot inherit this
-                                                  // property. set up an array and
-                                                  // fill it with the respective
-                                                  // values
-                 bool line_orientation_yz[13];
-
-                                                  // the middle vertices of the
-                                                  // lines of our front face
-                 const unsigned int middle_vertices[4]=
-                   {
-                         hex->line(8)->child(0)->vertex_index(1),
-                         hex->line(10)->child(0)->vertex_index(1),
-                         hex->line(0)->child(0)->vertex_index(1),
-                         hex->line(4)->child(0)->vertex_index(1),
-                   };
-
-                                                  // note: for lines 0 to 3 the
-                                                  // orientation of the line
-                                                  // is 'true', if vertex 0 is
-                                                  // on the front
-                 for (unsigned int i=0; i<4; ++i)
-                   if (lines[i]->vertex_index(0)==middle_vertices[i])
-                     line_orientation_yz[i]=true;
-                   else
-                     {
-                                                        // it must be the other way round then
-                       Assert(lines[i]->vertex_index(1)==middle_vertices[i],
-                              ExcInternalError());
-                       line_orientation_yz[i]=false;
-                     }
-                 
-                                                  // note: for lines 4 to 11
-                                                  // (inner lines of the outer quads)
-                                                  // the following holds: the second
-                                                  // vertex of the even lines in
-                                                  // standard orientation is the
-                                                  // vertex in the middle of the
-                                                  // quad, whereas for odd lines the
-                                                  // first vertex is the same middle
-                                                  // vertex.
-                 for (unsigned int i=4; i<12; ++i)
-                   if (lines[i]->vertex_index((i+1)%2)==hex->face(i/4-1)->middle_vertex_index())
-                     line_orientation_yz[i]=true;
-                   else
+                                                  // use first algorithm
+                 unsigned int refined_neighbors = 0,
+                            unrefined_neighbors = 0;
+                 for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+                   if (!cell->at_boundary(face))
                      {
-                                                        // it must be the other way
-                                                        // round then
-                       Assert(lines[i]->vertex_index(i%2)==hex->face(i/4-1)->middle_vertex_index(),
-                              ExcInternalError());
-                       line_orientation_yz[i]=false;
+                       if (face_will_be_refined_by_neighbor(cell,face)) 
+                         ++refined_neighbors;
+                       else
+                         ++unrefined_neighbors;
                      }
-                                                  // for the last line the line
-                                                  // orientation is always true,
-                                                  // since it was just constructed
-                                                  // that way
-
-                 line_orientation_yz[12]=true;
-                 line_orientation=&line_orientation_yz[0];
-
-                                                  // set up the 4 quads,
-                                                  // numbered as follows (left
-                                                  // quad numbering, right line
-                                                  // numbering extracted from
-                                                  // above)
-                                                  //
-                                                  //  x
-                                                  //  *-------*      *---3---*
-                                                  //  |   3   |      5       9
-                                                  //  *-------*      *---12--*
-                                                  //  |   2   |      4       8
-                                                  //  *-------*y     *---2---*
-                                                  //
-                                                  //       y
-                                                  //      *---------*      *----1----*
-                                                  //     /    1    /      7         11
-                                                  //    *---------*      *----12---*
-                                                  //   /    0    /      6         10
-                                                  //  *---------*x     *----0----*
-           
-                 new_quads[0]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[6],
-                                                    line_indices[10],
-                                                    line_indices[0],
-                                                    line_indices[12]));
-                 new_quads[1]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[7],
-                                                    line_indices[11],
-                                                    line_indices[12],
-                                                    line_indices[1]));
-                 new_quads[2]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[2],
-                                                    line_indices[12],
-                                                    line_indices[4],
-                                                    line_indices[8]));
-                 new_quads[3]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[12],
-                                                    line_indices[3],
-                                                    line_indices[5],
-                                                    line_indices[9]));
-
-                 new_quads[0]->set_line_orientation(0,line_orientation[6]);
-                 new_quads[0]->set_line_orientation(1,line_orientation[10]);
-                 new_quads[0]->set_line_orientation(2,line_orientation[0]);
-                     
-                 new_quads[1]->set_line_orientation(0,line_orientation[7]);
-                 new_quads[1]->set_line_orientation(1,line_orientation[11]);
-                 new_quads[1]->set_line_orientation(3,line_orientation[1]);
-                     
-                 new_quads[2]->set_line_orientation(0,line_orientation[2]);
-                 new_quads[2]->set_line_orientation(2,line_orientation[4]);
-                 new_quads[2]->set_line_orientation(3,line_orientation[8]);
-
-                 new_quads[3]->set_line_orientation(1,line_orientation[3]);
-                 new_quads[3]->set_line_orientation(2,line_orientation[5]);
-                 new_quads[3]->set_line_orientation(3,line_orientation[9]);
-
-                                                  // the quads are
-                                                  // numbered as follows:
-                                                  //
-                                                  // planes in the interior
-                                                  // of the old hex:
-                                                  //      *
-                                                  //     /|
-                                                  //    / | x         
-                                                  //   /  | *-------*      *---------*
-                                                  //  *   | |   3   |     /    1    /
-                                                  //  |   | *-------*    *---------*
-                                                  //  |   * |   2   |   /    0    /
-                                                  //  |  /  *-------*y *---------*x
-                                                  //  | /
-                                                  //  |/
-                                                  //  *
-                                                  //
-                                                  // children of the faces
-                                                  // of the old hex
-                                                  //      *-------*        *-------*
-                                                  //     /|       |       /  19   /|
-                                                  //    * |  15   |      *-------* |
-                                                  //   /|7*-------*     /  18   /|11
-                                                  //  * |/|       |    *-------* |/|
-                                                  //  |6* |  14   |    |       10* |
-                                                  //  |/|5*-------*    |  13   |/|9*
-                                                  //  * |/  17   /     *-------* |/
-                                                  //  |4*-------*      |       |8*
-                                                  //  |/  16   /       |  12   |/
-                                                  //  *-------*        *-------*
-                                                  //
-                                                  // note that we have to
-                                                  // take care of the
-                                                  // orientation of
-                                                  // faces.
-                 const unsigned int quad_indices_yz[20]
-                   = {
-                         new_quads[0]->index(),     //0
-                         new_quads[1]->index(),
-                         new_quads[2]->index(),
-                         new_quads[3]->index(),
-                             
-                         hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])),  //4 
-                         hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
-                         hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
-                         hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
-                             
-                         hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])),  //8 
-                         hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
-                         hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
-                         hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
-
-                         hex->face(2)->child_index(  child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),  //12
-                         hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
 
-                         hex->face(3)->child_index(  child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),  //14
-                         hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
-                             
-                         hex->face(4)->child_index(  child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),  //16
-                         hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
-                             
-                         hex->face(5)->child_index(  child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]),  //18
-                         hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
-                   };
-                 quad_indices=&quad_indices_yz[0];
-
-                 new_hexes[0]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[4],
-                                                    quad_indices[8],
-                                                    quad_indices[12],
-                                                    quad_indices[2],
-                                                    quad_indices[16],
-                                                    quad_indices[0]));
-                 new_hexes[1]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[5],
-                                                    quad_indices[9],
-                                                    quad_indices[2],
-                                                    quad_indices[14],
-                                                    quad_indices[17],
-                                                    quad_indices[1]));
-                 new_hexes[2]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[6],
-                                                    quad_indices[10],
-                                                    quad_indices[13],
-                                                    quad_indices[3],
-                                                    quad_indices[0],
-                                                    quad_indices[18]));
-                 new_hexes[3]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[7],
-                                                    quad_indices[11],
-                                                    quad_indices[3],
-                                                    quad_indices[15],
-                                                    quad_indices[1],
-                                                    quad_indices[19]));
-                 break;
+                 if (unrefined_neighbors < refined_neighbors)
+                   {
+                     if (cell->coarsen_flag_set())
+                       cell->clear_coarsen_flag();
+                     cell->set_refine_flag ();
+                   }
                }
-               case RefinementCase<dim>::cut_xyz:
-               {
-                                                  //////////////////////////////
-                                                  //
-                                                  //     RefinementCase<dim>::cut_xyz
-                                                  //     isotropic refinement
-                                                  //
-                                                  // the refined cube will look
-                                                  // like this:
-                                                  //
-                                                  //        *----*----*
-                                                  //       /    /    /|
-                                                  //      *----*----* |
-                                                  //     /    /    /| *
-                                                  //    *----*----* |/|
-                                                  //    |    |    | * |
-                                                  //    |    |    |/| *
-                                                  //    *----*----* |/
-                                                  //    |    |    | *
-                                                  //    |    |    |/
-                                                  //    *----*----*
-                                                  // 
-
-                                                  // find the next unused
-                                                  // vertex and set it
-                                                  // appropriately
-                 while (vertices_used[next_unused_vertex] == true)
-                   ++next_unused_vertex;
-                 Assert (next_unused_vertex < vertices.size(),
-                         ExcTooFewVerticesAllocated());
-                 vertices_used[next_unused_vertex] = true;
+             else
+               { 
+                                                  // variable to store the cell
+                                                  // refine case needed to
+                                                  // fulfill all smoothing
+                                                  // requirements
+                 RefinementCase<dim> smoothing_cell_refinement_case=RefinementCase<dim>::no_refinement;
                  
-                                                  // the new vertex is
-                                                  // definitely in the
-                                                  // interior, so we need not
-                                                  // worry about the boundary.
-                                                  // let it be the average of
-                                                  // the 26 vertices
-                                                  // surrounding it. weight
-                                                  // these vertices in the same
-                                                  // way as they are weighted
-                                                  // in the
-                                                  // @p{MappingQ::set_laplace_on_hex_vector}
-                                                  // function, and like the new
-                                                  // vertex at the center of
-                                                  // the quad is weighted (see
-                                                  // above)
-                 vertices[next_unused_vertex] = Point<dim>();
-                                                  // first add corners of hex
-                 for (unsigned int vertex=0;
-                      vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
-                   vertices[next_unused_vertex] += hex->vertex(vertex) / 128;
-                                                  // now add center of lines
-                 for (unsigned int line=0;
-                      line<GeometryInfo<dim>::lines_per_cell; ++line)
-                   vertices[next_unused_vertex] += hex->line(line)->child(0)->vertex(1) *
-                                                   7./192.;
-                                                  // finally add centers of
-                                                  // faces. note that vertex 3
-                                                  // of child 0 is an invariant
-                                                  // with respect to the face
-                                                  // orientation, flip and
-                                                  // rotation
-                 for (unsigned int face=0;
-                      face<GeometryInfo<dim>::faces_per_cell; ++face)
-                   vertices[next_unused_vertex] += hex->face(face)->isotropic_child(0)->vertex(3) *
-                                                   1./12.;
-
-                                                  // set the data of the
-                                                  // six lines.  first
-                                                  // collect the indices of
-                                                  // the seven vertices
-                                                  // (consider the two
-                                                  // planes to be crossed
-                                                  // to form the planes
-                                                  // cutting the hex in two
-                                                  // vertically and
-                                                  // horizontally)
-                                                  //     *--3--*   *--5--*
-                                                  //    /  /  /    |  |  |
-                                                  //   0--6--1     0--6--1
-                                                  //  /  /  /      |  |  |
-                                                  // *--2--*       *--4--*
-                                                  // the lines are numbered
-                                                  // as follows:
-                                                  //     *--*--*   *--*--*
-                                                  //    /  1  /    |  5  |
-                                                  //   *2-*-3*     *2-*-3*
-                                                  //  /  0  /      |  4  |
-                                                  // *--*--*       *--*--*
-                                                  //
-                 const unsigned int vertex_indices_xyz[7]
-                   = { hex->face(0)->middle_vertex_index(),
-                       hex->face(1)->middle_vertex_index(),
-                       hex->face(2)->middle_vertex_index(),
-                       hex->face(3)->middle_vertex_index(),
-                       hex->face(4)->middle_vertex_index(),
-                       hex->face(5)->middle_vertex_index(),
-                       next_unused_vertex 
-                   };
-                 vertex_indices=&vertex_indices_xyz[0];
+                                                  // use second algorithm, do
+                                                  // the check individually for
+                                                  // each direction
+                 for (unsigned int face_pair=0; face_pair<GeometryInfo<dim>::faces_per_cell/2; ++face_pair)
+                   {
+                                                      // variable to store the
+                                                      // cell refine case
+                                                      // needed to refine at
+                                                      // the current face pair
+                                                      // in the same way as the
+                                                      // neighbors do...
+                     RefinementCase<dim> directional_cell_refinement_case=RefinementCase<dim>::isotropic_refinement;
                      
-                 new_lines[0]->set (internal::Triangulation::
-                                    TriaObject<1>(vertex_indices[2], vertex_indices[6]));
-                 new_lines[1]->set (internal::Triangulation::
-                                    TriaObject<1>(vertex_indices[6], vertex_indices[3]));
-                 new_lines[2]->set (internal::Triangulation::
-                                    TriaObject<1>(vertex_indices[0], vertex_indices[6]));
-                 new_lines[3]->set (internal::Triangulation::
-                                    TriaObject<1>(vertex_indices[6], vertex_indices[1]));
-                 new_lines[4]->set (internal::Triangulation::
-                                    TriaObject<1>(vertex_indices[4], vertex_indices[6]));
-                 new_lines[5]->set (internal::Triangulation::
-                                    TriaObject<1>(vertex_indices[6], vertex_indices[5]));
-
-                                                  // again, first
-                                                  // collect some data
-                                                  // about the indices of
-                                                  // the lines, with the
-                                                  // following numbering:
-                                                  // (note that face 0 and
-                                                  // 1 each are shown twice
-                                                  // for better
-                                                  // readability)
-                 
-                                                  // face 0: left plane
-                                                  //       *            *
-                                                  //      /|           /| 
-                                                  //     * |          * |
-                                                  //    /| *         /| *
-                                                  //   * 1/|        * |3|
-                                                  //   | * |        | * |
-                                                  //   |/| *        |2| *
-                                                  //   * 0/         * |/
-                                                  //   | *          | *
-                                                  //   |/           |/ 
-                                                  //   *            *
-                                                  // face 1: right plane
-                                                  //       *            *
-                                                  //      /|           /| 
-                                                  //     * |          * |
-                                                  //    /| *         /| *
-                                                  //   * 5/|        * |7|
-                                                  //   | * |        | * |
-                                                  //   |/| *        |6| *
-                                                  //   * 4/         * |/
-                                                  //   | *          | *
-                                                  //   |/           |/
-                                                  //   *            *
-                                                  // face 2: front plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *---*---*
-                                                  //   |   11  |
-                                                  //   *-8-*-9-*
-                                                  //   |   10  |
-                                                  //   *---*---*
-                                                  // face 3: back plane
-                                                  //   (note: x,y exchanged)
-                                                  //   *---*---*
-                                                  //   |   15  | 
-                                                  //   *12-*-13*
-                                                  //   |   14  | 
-                                                  //   *---*---*
-                                                  // face 4: bottom plane
-                                                  //       *---*---*
-                                                  //      /  17   /
-                                                  //     *18-*-19*
-                                                  //    /   16  /
-                                                  //   *---*---*
-                                                  // face 5: top plane
-                                                  //       *---*---*
-                                                  //      /  21   /
-                                                  //     *22-*-23*
-                                                  //    /   20  /
-                                                  //   *---*---*
-                                                  // middle planes
-                                                  //     *---*---*   *---*---*
-                                                  //    /  25   /    |   29  |
-                                                  //   *26-*-27*     *26-*-27*
-                                                  //  /   24  /      |   28  |
-                                                  // *---*---*       *---*---*
-                 
-                                                  // set up a list of line iterators
-                                                  // first. from this, construct
-                                                  // lists of line_indices and
-                                                  // line orientations later on
-                 const raw_line_iterator lines_xyz[30]
-                   = {
-                         hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])),        //0
-                         hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])),        //1
-                         hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])),        //2
-                         hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])),        //3
-                         
-                         hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])),        //4
-                         hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])),        //5
-                         hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])),        //6
-                         hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])),        //7
-                         
-                         hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])),        //8
-                         hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])),        //9
-                         hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])),        //10
-                         hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])),        //11
-                         
-                         hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])),        //12
-                         hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])),        //13
-                         hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])),        //14
-                         hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])),        //15
-                         
-                         hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])),        //16
-                         hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])),        //17
-                         hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])),        //18
-                         hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])),        //19
-                         
-                         hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])),        //20
-                         hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])),        //21
-                         hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])),        //22
-                         hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
-                         ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])),        //23
+                     for (unsigned int face_index=0; face_index<2; ++face_index)
+                       {
+                         unsigned int face=2*face_pair+face_index;
+                                                          // variable to store
+                                                          // the refine case
+                                                          // (to come) of the
+                                                          // face under
+                                                          // consideration
+                         RefinementCase<dim-1> expected_face_ref_case=RefinementCase<dim-1>::no_refinement;
                          
-                         new_lines[0],                       //24
-                         new_lines[1],                       //25
-                         new_lines[2],                       //26
-                         new_lines[3],                       //27
-                         new_lines[4],                       //28
-                         new_lines[5]                        //29
-                   };
-                 
-                 lines=&lines_xyz[0];
-                 
-                 unsigned int line_indices_xyz[30];
-                 for (unsigned int i=0; i<30; ++i)
-                   line_indices_xyz[i]=lines[i]->index();
-                 line_indices=&line_indices_xyz[0];
-                 
-                                                  // the orientation of lines for the
-                                                  // inner quads is quite tricky. as
-                                                  // these lines are newly created
-                                                  // ones and thus have no parents,
-                                                  // they cannot inherit this
-                                                  // property. set up an array and
-                                                  // fill it with the respective
-                                                  // values
-                 bool line_orientation_xyz[30];
-                 
-                                                  // note: for the first 24 lines
-                                                  // (inner lines of the outer quads)
-                                                  // the following holds: the second
-                                                  // vertex of the even lines in
-                                                  // standard orientation is the
-                                                  // vertex in the middle of the
-                                                  // quad, whereas for odd lines the
-                                                  // first vertex is the same middle
-                                                  // vertex.
-                                                  // DEBUG
-                 face_iterator face_0=hex->face(0);
-                 face_iterator face_0_child_0=face_0->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]));
-                 line_iterator face_0_child_0_line_1=face_0_child_0
-                                                     ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0]));
-                                                  // END DEBUG
-                 for (unsigned int i=0; i<24; ++i)
-                   if (lines[i]->vertex_index((i+1)%2)==vertex_indices[i/4])
-                     line_orientation_xyz[i]=true;
-                   else
-                     {
-                                                        // it must be the other way
-                                                        // round then
-                       Assert(lines[i]->vertex_index(i%2)==vertex_indices[i/4],
-                              ExcInternalError());
-                       line_orientation_xyz[i]=false;
-                     }
-                                                  // for the last 6 lines the line
-                                                  // orientation is always true,
-                                                  // since they were just constructed
-                                                  // that way
-                 for (unsigned int i=24; i<30; ++i)
-                   line_orientation_xyz[i]=true;
-                 line_orientation=&line_orientation_xyz[0];
-
-                                                  // set up the 12 quads,
-                                                  // numbered as follows
-                                                  // (left quad numbering,
-                                                  // right line numbering
-                                                  // extracted from above)
-                                                  //
-                                                  //      *          *
-                                                  //     /|        21|
-                                                  //    * |        * 15
-                                                  //  y/|3*      20| *  
-                                                  //  * |/|      * |/| 
-                                                  //  |2* |x    11 * 14
-                                                  //  |/|1*      |/| * 
-                                                  //  * |/       * |17 
-                                                  //  |0*       10 *
-                                                  //  |/         |16
-                                                  //  *          *
-                                                  //
-                                                  //  x
-                                                  //  *---*---*      *22-*-23*
-                                                  //  | 5 | 7 |      1  29   5
-                                                  //  *---*---*      *26-*-27*
-                                                  //  | 4 | 6 |      0  28   4
-                                                  //  *---*---*y     *18-*-19*
-                                                  //
-                                                  //       y
-                                                  //      *----*----*      *-12-*-13-*
-                                                  //     / 10 / 11 /      3   25    7
-                                                  //    *----*----*      *-26-*-27-*
-                                                  //   / 8  / 9  /      2   24    6
-                                                  //  *----*----*x     *--8-*--9-*
-           
-                 new_quads[0]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[10],
-                                                    line_indices[28],
-                                                    line_indices[16],
-                                                    line_indices[24]));
-                 new_quads[1]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[28],
-                                                    line_indices[14],
-                                                    line_indices[17],
-                                                    line_indices[25]));
-                 new_quads[2]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[11],
-                                                    line_indices[29],
-                                                    line_indices[24],
-                                                    line_indices[20]));
-                 new_quads[3]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[29],
-                                                    line_indices[15],
-                                                    line_indices[25],
-                                                    line_indices[21]));
-                 new_quads[4]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[18],
-                                                    line_indices[26],
-                                                    line_indices[0],
-                                                    line_indices[28]));
-                 new_quads[5]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[26],
-                                                    line_indices[22],
-                                                    line_indices[1],
-                                                    line_indices[29]));
-                 new_quads[6]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[19],
-                                                    line_indices[27],
-                                                    line_indices[28],
-                                                    line_indices[4]));
-                 new_quads[7]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[27],
-                                                    line_indices[23],
-                                                    line_indices[29],
-                                                    line_indices[5]));
-                 new_quads[8]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[2],
-                                                    line_indices[24],
-                                                    line_indices[8],
-                                                    line_indices[26]));
-                 new_quads[9]->set (internal::Triangulation
-                                    ::TriaObject<2>(line_indices[24],
-                                                    line_indices[6],
-                                                    line_indices[9],
-                                                    line_indices[27]));
-                 new_quads[10]->set (internal::Triangulation
-                                     ::TriaObject<2>(line_indices[3],
-                                                     line_indices[25],
-                                                     line_indices[26],
-                                                     line_indices[12]));
-                 new_quads[11]->set (internal::Triangulation
-                                     ::TriaObject<2>(line_indices[25],
-                                                     line_indices[7],
-                                                     line_indices[27],
-                                                     line_indices[13]));
-           
-                                                  // now reset the line_orientation
-                                                  // flags of outer lines as they
-                                                  // cannot be set in a loop (at
-                                                  // least not easily)
-                 new_quads[0]->set_line_orientation(0,line_orientation[10]);
-                 new_quads[0]->set_line_orientation(2,line_orientation[16]);
-                     
-                 new_quads[1]->set_line_orientation(1,line_orientation[14]);
-                 new_quads[1]->set_line_orientation(2,line_orientation[17]);
-                     
-                 new_quads[2]->set_line_orientation(0,line_orientation[11]);
-                 new_quads[2]->set_line_orientation(3,line_orientation[20]);
-
-                 new_quads[3]->set_line_orientation(1,line_orientation[15]);
-                 new_quads[3]->set_line_orientation(3,line_orientation[21]);
-                     
-                 new_quads[4]->set_line_orientation(0,line_orientation[18]);
-                 new_quads[4]->set_line_orientation(2,line_orientation[0]);
-                     
-                 new_quads[5]->set_line_orientation(1,line_orientation[22]);
-                 new_quads[5]->set_line_orientation(2,line_orientation[1]);
-                     
-                 new_quads[6]->set_line_orientation(0,line_orientation[19]);
-                 new_quads[6]->set_line_orientation(3,line_orientation[4]);
-                     
-                 new_quads[7]->set_line_orientation(1,line_orientation[23]);
-                 new_quads[7]->set_line_orientation(3,line_orientation[5]);
-                     
-                 new_quads[8]->set_line_orientation(0,line_orientation[2]);
-                 new_quads[8]->set_line_orientation(2,line_orientation[8]);
-                     
-                 new_quads[9]->set_line_orientation(1,line_orientation[6]);
-                 new_quads[9]->set_line_orientation(2,line_orientation[9]);
-                     
-                 new_quads[10]->set_line_orientation(0,line_orientation[3]);
-                 new_quads[10]->set_line_orientation(3,line_orientation[12]);
-                     
-                 new_quads[11]->set_line_orientation(1,line_orientation[7]);
-                 new_quads[11]->set_line_orientation(3,line_orientation[13]);
+                         if (cell->neighbor(face).state() == IteratorState::valid)
+                           face_will_be_refined_by_neighbor(cell,face,expected_face_ref_case);
+                                                          // now extract which
+                                                          // refine case would
+                                                          // be necessary to
+                                                          // achive the same
+                                                          // face
+                                                          // refinement. set
+                                                          // the intersection
+                                                          // with other
+                                                          // requirements for
+                                                          // the same
+                                                          // direction.
 
-                                                  /////////////////////////////////
-                                                  // create the eight new hexes
-                                                  //
-                                                  // again first collect
-                                                  // some data.  here, we
-                                                  // need the indices of a
-                                                  // whole lotta
-                                                  // quads.
-           
-                                                  // the quads are
-                                                  // numbered as follows:
-                                                  //
-                                                  // planes in the interior
-                                                  // of the old hex:
-                                                  //      *
-                                                  //     /|
-                                                  //    * |
-                                                  //   /|3*  *---*---*      *----*----*
-                                                  //  * |/|  | 5 | 7 |     / 10 / 11 /
-                                                  //  |2* |  *---*---*    *----*----*
-                                                  //  |/|1*  | 4 | 6 |   / 8  / 9  /
-                                                  //  * |/   *---*---*y *----*----*x
-                                                  //  |0*
-                                                  //  |/
-                                                  //  *
-                                                  //
-                                                  // children of the faces
-                                                  // of the old hex
-                                                  //      *-------*        *-------*
-                                                  //     /|25   27|       /34   35/|
-                                                  //    15|       |      /       /19
-                                                  //   /  |       |     /32   33/  |
-                                                  //  *   |24   26|    *-------*18 |
-                                                  //  1413*-------*    |21   23| 17*
-                                                  //  |  /30   31/     |       |  /
-                                                  //  12/       /      |       |16
-                                                  //  |/28   29/       |20   22|/
-                                                  //  *-------*        *-------*
-                                                  //
-                                                  // note that we have to
-                                                  // take care of the
-                                                  // orientation of
-                                                  // faces.
-                 const unsigned int quad_indices_xyz[36]
-                   = {
-                         new_quads[0]->index(),     //0
-                         new_quads[1]->index(),
-                         new_quads[2]->index(),
-                         new_quads[3]->index(),
-                         new_quads[4]->index(),
-                         new_quads[5]->index(),
-                         new_quads[6]->index(),
-                         new_quads[7]->index(),
-                         new_quads[8]->index(),
-                         new_quads[9]->index(),
-                         new_quads[10]->index(),
-                         new_quads[11]->index(),    //11
-                             
-                         hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])),  //12
-                         hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
-                         hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
-                         hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
-
-                         hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])),  //16
-                         hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
-                         hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
-                         hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
-                             
-                         hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])),  //20
-                         hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
-                         hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
-                         hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
-                             
-                         hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])),  //24
-                         hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
-                         hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
-                         hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
-                             
-                         hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])),  //28
-                         hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
-                         hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
-                         hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
-                             
-                         hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])),  //32
-                         hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
-                         hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
-                         hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
-                   };
-                 quad_indices=&quad_indices_xyz[0];
-
-                                                  // bottom children
-                 new_hexes[0]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[12],
-                                                    quad_indices[0],
-                                                    quad_indices[20],
-                                                    quad_indices[4],
-                                                    quad_indices[28],
-                                                    quad_indices[8]));
-                 new_hexes[1]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[0],
-                                                    quad_indices[16],
-                                                    quad_indices[22],
-                                                    quad_indices[6],
-                                                    quad_indices[29],
-                                                    quad_indices[9]));
-                 new_hexes[2]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[13],
-                                                    quad_indices[1],
-                                                    quad_indices[4],
-                                                    quad_indices[24],
-                                                    quad_indices[30],
-                                                    quad_indices[10]));
-                 new_hexes[3]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[1],
-                                                    quad_indices[17],
-                                                    quad_indices[6],
-                                                    quad_indices[26],
-                                                    quad_indices[31],
-                                                    quad_indices[11]));
-           
-                                                  // top children
-                 new_hexes[4]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[14],
-                                                    quad_indices[2],
-                                                    quad_indices[21],
-                                                    quad_indices[5],
-                                                    quad_indices[8],
-                                                    quad_indices[32]));
-                 new_hexes[5]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[2],
-                                                    quad_indices[18],
-                                                    quad_indices[23],
-                                                    quad_indices[7],
-                                                    quad_indices[9],
-                                                    quad_indices[33]));
-                 new_hexes[6]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[15],
-                                                    quad_indices[3],
-                                                    quad_indices[5],
-                                                    quad_indices[25],
-                                                    quad_indices[10],
-                                                    quad_indices[34]));
-                 new_hexes[7]->set (internal::Triangulation
-                                    ::TriaObject<3>(quad_indices[3],
-                                                    quad_indices[19],
-                                                    quad_indices[7],
-                                                    quad_indices[27],
-                                                    quad_indices[11],
-                                                    quad_indices[35]));
-                 break;
-               }
-               default:
-                                                      // all refinement cases
-                                                      // have been treated,
-                                                      // there only remains
-                                                      // RefinementCase<dim>::no_refinement
-                                                      // as untreated
-                                                      // enumeration
-                                                      // value. However, in
-                                                      // that case we should
-                                                      // have aborted much
-                                                      // earlier. thus we
-                                                      // should never get here
-                     Assert(false, ExcInternalError());
-                     break;
-             }//switch (ref_case)
-           
-                                             // and set face orientation
-                                             // flags. note that new faces in
-                                             // the interior of the mother cell
-                                             // always have a correctly oriented
-                                             // face, but the ones on the outer
-                                             // faces will inherit this flag
-                                             //
-                                             // the flag have been set to true
-                                             // for all faces initially, now go
-                                             // the other way round and reset
-                                             // faces that are at the boundary
-                                             // of the mother cube
-                                            //
-                                            // the same is true for the
-                                            // face_flip and face_rotation
-                                            // flags. however, the latter two
-                                            // are set to false by default as
-                                            // this is the standard value
-           
-                                            // loop over all faces and all
-                                            // (relevant) subfaces of that in
-                                            // order to set the correct values
-                                            // for face_orientation, face_flip
-                                            // and face_rotation, which are
-                                            // inherited from the corresponding
-                                            // face of the mother cube
-            for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-              for (unsigned int s=0;
-                  s<std::max(GeometryInfo<dim-1>::n_children(GeometryInfo<dim>::face_refinement_case(ref_case,f)),
-                             1U);
-                  ++s)
-                {
-                 const unsigned int current_child
-                   =GeometryInfo<dim>::child_cell_on_face(ref_case,
-                                                          f,
-                                                          s,
-                                                          f_or[f],
-                                                          f_fl[f],
-                                                          f_ro[f],
-                                                          GeometryInfo<dim>::face_refinement_case(ref_case,
-                                                                                                  f,
-                                                                                                  f_or[f],
-                                                                                                  f_fl[f],
-                                                                                                  f_ro[f]));
-                 new_hexes[current_child]->set_face_orientation (f, f_or[f]);
-                 new_hexes[current_child]->set_face_flip        (f, f_fl[f]);
-                 new_hexes[current_child]->set_face_rotation    (f, f_ro[f]);
-               }
-
-                                            /////////////////////////////////
-                                            // now the only thing still
-                                            // to be done is setting
-                                            // neighborship
-                                            // information.
-                                            //
-                                            // the easiest part is setting the
-                                            // inner neighbors, i.e. children
-                                            // neighboring other children of
-                                            // the same mother cube.
-           switch (ref_case)
-             {
-               case RefinementCase<dim>::cut_x:
-                     new_hexes[0]->set_neighbor(1, new_hexes[1]);
-                     
-                     new_hexes[1]->set_neighbor(0, new_hexes[0]);
-                     break;
-               case RefinementCase<dim>::cut_y:
-                     new_hexes[0]->set_neighbor(3, new_hexes[1]);
-
-                     new_hexes[1]->set_neighbor(2, new_hexes[0]);
-                     break;
-               case RefinementCase<dim>::cut_z:
-                     new_hexes[0]->set_neighbor(5, new_hexes[1]);
-
-                     new_hexes[1]->set_neighbor(4, new_hexes[0]);
-                     break;
-               case RefinementCase<dim>::cut_xy:
-                     new_hexes[0]->set_neighbor(1, new_hexes[1]);
-                     new_hexes[0]->set_neighbor(3, new_hexes[2]);
-
-                     new_hexes[1]->set_neighbor(0, new_hexes[0]);
-                     new_hexes[1]->set_neighbor(3, new_hexes[3]);
-
-                     new_hexes[2]->set_neighbor(1, new_hexes[3]);
-                     new_hexes[2]->set_neighbor(2, new_hexes[0]);
-
-                     new_hexes[3]->set_neighbor(0, new_hexes[2]);
-                     new_hexes[3]->set_neighbor(2, new_hexes[1]);
-                     break;
-               case RefinementCase<dim>::cut_xz:
-                     new_hexes[0]->set_neighbor(1, new_hexes[2]);
-                     new_hexes[0]->set_neighbor(5, new_hexes[1]);
-
-                     new_hexes[1]->set_neighbor(1, new_hexes[3]);
-                     new_hexes[1]->set_neighbor(4, new_hexes[0]);
-
-                     new_hexes[2]->set_neighbor(0, new_hexes[0]);
-                     new_hexes[2]->set_neighbor(5, new_hexes[3]);
-
-                     new_hexes[3]->set_neighbor(0, new_hexes[1]);
-                     new_hexes[3]->set_neighbor(4, new_hexes[2]);
-                     break;
-               case RefinementCase<dim>::cut_yz:
-                     new_hexes[0]->set_neighbor(3, new_hexes[1]);
-                     new_hexes[0]->set_neighbor(5, new_hexes[2]);
+                                                          // note: using the
+                                                          // intersection is
+                                                          // not an obvious
+                                                          // decision, we could
+                                                          // also argue that it
+                                                          // is more natural to
+                                                          // use the
+                                                          // union. however,
+                                                          // intersection is
+                                                          // the less
+                                                          // aggressive tactic
+                                                          // and favours a
+                                                          // smaller number of
+                                                          // refined cells over
+                                                          // an intensive
+                                                          // smoothing. this
+                                                          // way we try not to
+                                                          // loose too much of
+                                                          // the effort we put
+                                                          // in anisotropic
+                                                          // refinement
+                                                          // indicators due to
+                                                          // overly aggressive
+                                                          // smoothing...
+                         directional_cell_refinement_case = directional_cell_refinement_case &
+                                                        GeometryInfo<dim>::min_cell_refinement_case_for_face_refinement(
+                                                          expected_face_ref_case,
+                                                          face,
+                                                          cell->face_orientation(face),
+                                                          cell->face_flip(face),
+                                                          cell->face_rotation(face));
+                       }//for both face indices
+                                                      // if both requirements
+                                                      // sum up to something
+                                                      // useful, add this to
+                                                      // the refine case for
+                                                      // smoothing. note: if
+                                                      // directional_cell_refinement_case
+                                                      // is isotropic still,
+                                                      // then something went
+                                                      // wrong...
+                     Assert(directional_cell_refinement_case < RefinementCase<dim>::isotropic_refinement,
+                            ExcInternalError());
+                     smoothing_cell_refinement_case = smoothing_cell_refinement_case |
+                                                  directional_cell_refinement_case;
+                   }//for all face_pairs
+                                                  // no we collected
+                                                  // contributions from all
+                                                  // directions. combine the
+                                                  // new flags with the
+                                                  // existing refine case, but
+                                                  // only if smoothing is
+                                                  // required
+                 if (smoothing_cell_refinement_case)
+                   {
+                     cell->clear_coarsen_flag();
+                     cell->set_refine_flag(cell->refine_flag_set() | smoothing_cell_refinement_case);
+                   }
+               }//else -> allow_anisotropic_smoothing 
+           }// for all cells
+       }
 
-                     new_hexes[1]->set_neighbor(2, new_hexes[0]);
-                     new_hexes[1]->set_neighbor(5, new_hexes[3]);
+                                      /////////////////////////////////
+                                      // STEP 5:
+                                      //    ensure patch level 1.
+                                      //
+                                      //    Introduce some terminology:
+                                      //    - a cell that is refined
+                                      //      once is a patch of
+                                      //      level 1 simply called patch.
+                                      //    - a cell that is globally
+                                      //      refined twice is called
+                                      //      a patch of level 2.
+                                      //    - patch level n says that
+                                      //      the triangulation consists
+                                      //      of patches of level n.
+                                      //      This makes sense only
+                                      //      if the grid is already at
+                                      //      least n times globally
+                                      //      refined.
+                                      //
+                                      //    E.g. from patch level 1
+                                      //    follows: if at least one
+                                      //    of the children of a cell
+                                      //    is or will be refined
+                                      //    than enforce all
+                                      //    children to be
+                                      //    refined.
 
-                     new_hexes[2]->set_neighbor(3, new_hexes[3]);
-                     new_hexes[2]->set_neighbor(4, new_hexes[0]);
+                                      //    This step 4 only
+                                      //    sets refinement flags and
+                                      //    does not set coarsening
+                                      //    flags.
+      if (smooth_grid & patch_level_1) 
+       {
+                                          // An important assumption
+                                          // (A) is that before
+                                          // calling this function
+                                          // the grid was already of
+                                          // patch level 1.
 
-                     new_hexes[3]->set_neighbor(2, new_hexes[2]);
-                     new_hexes[3]->set_neighbor(4, new_hexes[1]);
-                     break;
-               case RefinementCase<dim>::cut_xyz:
-                     new_hexes[0]->set_neighbor(1, new_hexes[1]);
-                     new_hexes[0]->set_neighbor(3, new_hexes[2]);
-                     new_hexes[0]->set_neighbor(5, new_hexes[4]);
-
-                     new_hexes[1]->set_neighbor(0, new_hexes[0]);
-                     new_hexes[1]->set_neighbor(3, new_hexes[3]);
-                     new_hexes[1]->set_neighbor(5, new_hexes[5]);
-
-                     new_hexes[2]->set_neighbor(1, new_hexes[3]);
-                     new_hexes[2]->set_neighbor(2, new_hexes[0]);
-                     new_hexes[2]->set_neighbor(5, new_hexes[6]);
-
-                     new_hexes[3]->set_neighbor(0, new_hexes[2]);
-                     new_hexes[3]->set_neighbor(2, new_hexes[1]);
-                     new_hexes[3]->set_neighbor(5, new_hexes[7]);
-
-                     new_hexes[4]->set_neighbor(1, new_hexes[5]);
-                     new_hexes[4]->set_neighbor(3, new_hexes[6]);
-                     new_hexes[4]->set_neighbor(4, new_hexes[0]);
-
-                     new_hexes[5]->set_neighbor(0, new_hexes[4]);
-                     new_hexes[5]->set_neighbor(3, new_hexes[7]);
-                     new_hexes[5]->set_neighbor(4, new_hexes[1]);
-
-                     new_hexes[6]->set_neighbor(1, new_hexes[7]);
-                     new_hexes[6]->set_neighbor(2, new_hexes[4]);
-                     new_hexes[6]->set_neighbor(4, new_hexes[2]);
-
-                     new_hexes[7]->set_neighbor(0, new_hexes[6]);
-                     new_hexes[7]->set_neighbor(2, new_hexes[5]);
-                     new_hexes[7]->set_neighbor(4, new_hexes[3]);
-                     break;
-               default:
-                     Assert (false, ExcInternalError());
-                     break;
+                                          // loop over all cells
+                                          // whose children are all
+                                          // active.  (By assumption
+                                          // (A) either all or none
+                                          // of the children are
+                                          // active).  If the refine
+                                          // flag of at least one of
+                                          // the children is set then
+                                          // set_refine_flag and
+                                          // clear_coarsen_flag of
+                                          // all children.
+         for (cell_iterator cell = begin(); cell != end(); ++cell)
+           if (!cell->active())
+             {
+                                                // ensure the
+                                                // invariant. we can
+                                                // then check whether
+                                                // all of its
+                                                // children are
+                                                // further refined or
+                                                // not by simply
+                                                // looking at the
+                                                // first child
+               Assert (cell_is_patch_level_1(cell),
+                       ExcInternalError());
+               if (cell->child(0)->has_children() == true)
+                 continue;
+               
+                                                // cell is found to
+                                                // be a patch.
+                                                // combine the refine
+                                                // cases of all
+                                                // children
+               RefinementCase<dim> combined_ref_case = RefinementCase<dim>::no_refinement;
+               for (unsigned int i=0; i<cell->n_children(); ++i)
+                 combined_ref_case = combined_ref_case |
+                                     cell->child(i)->refine_flag_set();
+               if (combined_ref_case != RefinementCase<dim>::no_refinement)
+                 for (unsigned int i=0; i<cell->n_children(); ++i)
+                   {
+                     cell_iterator child = cell->child(i);
+                     
+                     child->clear_coarsen_flag();
+                     child->set_refine_flag(combined_ref_case);
+                   }
              }
-           
-                                            // it's a bit more complicated for
-                                            // outer neighbors. Leave this to a
-                                            // separate function
-           update_neighbors(hex, true);
-
-                                            // note that the
-                                            // refinement flag was
-                                            // already cleared at the
-                                            // beginning of this loop
-         }
-    }
 
-                                  // clear user data on quads. we used some of
-                                  // this data to indicate anisotropic
-                                  // refinemnt cases on faces. all data should
-                                  // be cleared by now, but the information
-                                  // whether we used indices or pointers is
-                                  // still present. reset it now to enable the
-                                  // user to use whichever he likes later on.
-  faces->quads.clear_user_data();
-  
-                                  // re-compute number of lines and
-                                  // quads
-  update_number_cache ();
+                                          // The code above dealt
+                                          // with the case where we
+                                          // may get a
+                                          // non-patch_level_1 mesh
+                                          // from refinement. Now
+                                          // also deal with the case
+                                          // where we could get such
+                                          // a mesh by coarsening.
+                                          // Coarsen the children
+                                          // (and remove the
+                                          // grandchildren) only if
+                                          // all cell->grandchild(i)
+                                          //   ->coarsen_flag_set()
+                                          // are set.
+                                          //
+                                          // for a case where this is
+                                          // a bit tricky, take a
+                                          // look at the
+                                          // mesh_smoothing_0[12]
+                                          // testcases
+         for (cell_iterator cell = begin(); cell != end(); ++cell)
+           {
+                                              // check if this cell
+                                              // has active
+                                              // grandchildren. note
+                                              // that we know that it
+                                              // is patch_level_1,
+                                              // i.e. if one of its
+                                              // children is active
+                                              // then so are all, and
+                                              // it isn't going to
+                                              // have any
+                                              // grandchildren at
+                                              // all:
+             if (cell->active()
+                 ||
+                 cell->child(0)->active())
+               continue;
 
+                                              // cell is not active,
+                                              // and so are none of
+                                              // its children. check
+                                              // the
+                                              // grandchildren. note
+                                              // that the children
+                                              // are also
+                                              // patch_level_1, and
+                                              // so we only ever need
+                                              // to check their first
+                                              // child
+             const unsigned int n_children=cell->n_children();
+             bool has_active_grandchildren = false;
 
-#ifdef DEBUG
-  for (unsigned int level=0; level<levels.size(); ++level) 
-    levels[level]->cells.monitor_memory (3);
+             for (unsigned int i=0; i<n_children; ++i)
+               if (cell->child(i)->child(0)->active())
+                 {
+                   has_active_grandchildren = true;
+                   break;
+                 }
 
-                                  // check whether really all
-                                  // refinement flags are reset (also
-                                  // of previously non-active cells
-                                  // which we may not have
-                                  // touched. If the refinement flag
-                                  // of a non-active cell is set,
-                                  // something went wrong since the
-                                  // cell-accessors should have
-                                  // caught this)
-  line_iterator line = begin_line(),
-               endl = end_line();
-  while (line != endl)
-    Assert (!(line++)->user_flag_set(), ExcInternalError ());
-
-  quad_iterator quad = begin_quad(),
-               endq = end_quad();
-  while (quad != endq)
-    Assert (!(quad++)->user_flag_set(), ExcInternalError ());
-
-  cell_iterator cell = begin(),
-               endc = end();
-  while (cell != endc)
-    Assert (!(cell++)->refine_flag_set(), ExcInternalError ());
-
-  cell_iterator testcell=begin(),
-                     ec=end();
-  for (;testcell!=ec; ++testcell)
-    {
-      std::set<unsigned int> verts;
-      for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-       for (unsigned int v=0; v<GeometryInfo<dim-1>::vertices_per_cell; ++v)
-         verts.insert(testcell->face(f)->vertex_index(v));
-      Assert (verts.size()==GeometryInfo<dim>::vertices_per_cell, ExcInternalError());
-    }
-#endif
-}
-
-#endif
-
-
-
-template <int dim>
-void Triangulation<dim>::execute_coarsening ()
-{
-                                  // create a vector counting for each line how
-                                  // many cells contain this line. in 3D, this
-                                  // is used later on to decide which lines can
-                                  // be deleted after coarsening a cell. in
-                                  // other dimensions it will be ignored
-  std::vector<unsigned int> line_cell_count(0);
-  std::vector<unsigned int> quad_cell_count(0);
-  if (dim==3)
-    {
-      count_cells_at_line(line_cell_count);
-      count_cells_at_quad(quad_cell_count);
-    }
-  
-                                  // loop over all cells. Flag all
-                                  // cells of which all children are
-                                  // flagged for
-                                  // coarsening and delete the childrens'
-                                  // flags. In effect, only those
-                                  // cells are flagged of which originally
-                                  // all children were flagged and for which
-                                  // all children are on the same refinement
-                                  // level. For flagging, the user flags are
-                                  // used, to avoid confusion and because
-                                  // non-active cells can't be flagged for
-                                  // coarsening. Note that because of the
-                                  // effects of @p{fix_coarsen_flags}, of a
-                                  // cell either all or no children must
-                                  // be flagged for coarsening, so it is
-                                  // ok to only check the first child
-  clear_user_flags ();
-
-  cell_iterator cell = begin(),
-               endc = end();
-  for (; cell!=endc; ++cell) 
-    if (!cell->active())
-      if (cell->child(0)->coarsen_flag_set())
-       {
-         cell->set_user_flag();
-         for (unsigned int child=0; child<cell->n_children(); ++child)
-           {
-             Assert (cell->child(child)->coarsen_flag_set(),
-                     ExcInternalError());
-             cell->child(child)->clear_coarsen_flag();
-           }
-       }
-
-
-                                  // now do the actual coarsening
-                                  // step. Since the loop goes over
-                                  // used cells we only need not
-                                  // worry about deleting some cells
-                                  // since the ++operator will then
-                                  // just hop over them if we should
-                                  // hit one. Do the loop in the
-                                  // reverse way since we may only
-                                  // delete some cells if their
-                                  // neighbors have already been
-                                  // deleted (if the latter are on a
-                                  // higher level for example)
-                                  //
-                                  // if there is only one level,
-                                  // there can not be anything to do
-  if (levels.size() >= 2)
-    for (cell = last(levels.size()-2); cell!=endc; --cell)
-      if (cell->user_flag_set())
-                                        // use a separate function,
-                                        // since this is dimension
-                                        // specific
-       delete_children (cell, line_cell_count, quad_cell_count);
-
-                                  // re-compute number of lines and
-                                  // quads
-  update_number_cache ();
-
-                                  // in principle no user flags
-                                  // should be
-                                  // set any more at this point
-#if DEBUG
-  for (cell=begin(); cell!=endc; ++cell)
-    Assert (cell->user_flag_set() == false, ExcInternalError());
-#endif
-}
-
-
-
-#if deal_II_dimension == 1
-
-template<>
-void
-Triangulation<1>::prevent_distorted_boundary_cells ()
-{}
-
-#else
+             if (has_active_grandchildren == false)
+               continue;
+             
 
-template<int dim>
-void
-Triangulation<dim>::prevent_distorted_boundary_cells ()
-{
-  for (cell_iterator cell=begin(); cell!=end(); ++cell)
-    if (cell->at_boundary() &&
-       cell->refine_flag_set() &&
-       cell->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
-      {
-                                        // The cell is at the boundary
-                                        // and it is flagged for
-                                        // anisotropic
-                                        // refinement. Therefore, we have
-                                        // a closer look
-       const RefinementCase<dim> ref_case=cell->refine_flag_set();
-       for (unsigned int face_no=0;
-            face_no<GeometryInfo<dim>::faces_per_cell;
-            ++face_no)
-         if (cell->face(face_no)->at_boundary())
-           {
-                                              // this is the critical
-                                              // face at the boundary.
-             if (GeometryInfo<dim>::face_refinement_case(ref_case,face_no)
-                 !=RefinementCase<dim-1>::isotropic_refinement)
+                                              // ok, there are active
+                                              // grandchildren. see
+                                              // if either all or
+                                              // none of them are
+                                              // flagged for
+                                              // coarsening
+             unsigned int n_grandchildren=0;           
+                                              // count all coarsen
+                                              // flags of the
+                                              // grandchildren.
+             unsigned int n_coarsen_flags=0;
+                                              // cell is not a
+                                              // patch (of level 1)
+                                              // as it has a
+                                              // grandchild.  Is
+                                              // cell a patch of
+                                              // level 2??
+                                              // Therefore: find
+                                              // out whether all
+                                              // cell->child(i) are
+                                              // patches
+             for (unsigned int c=0; c<n_children; ++c)
                {
-                                                  // up to now, we do not
-                                                  // want to refine this
-                                                  // cell along the face
-                                                  // under consideration
-                                                  // here.
-                 face_iterator face=cell->face(face_no);
-                                                  // the new point on the
-                                                  // boundary would be
-                                                  // this one.
-                 Point<dim> new_bound=boundary[face->boundary_indicator()]
-                                      ->get_new_point_on_face (face);
-                                                  // to check it,
-                                                  // transform to the
-                                                  // unit cell with
-                                                  // Q1Mapping
-                 Point<dim> new_unit=StaticMappingQ1<dim>::mapping.
-                                     transform_real_to_unit_cell(cell,
-                                                                 new_bound);
-                                                  // Now, we have to
-                                                  // calculate the
-                                                  // distance from the
-                                                  // face in the unit
-                                                  // cell.
-                       
-                                                  // take the correct
-                                                  // coordinate direction (0
-                                                  // for faces 0 and 1, 1 for
-                                                  // faces 2 and 3, 2 for faces
-                                                  // 4 and 5) and substract the
-                                                  // correct boundary value of
-                                                  // the face (0 for faces 0,
-                                                  // 2, and 4; 1 for faces 1, 3
-                                                  // and 5)
-                 double dist=fabs(new_unit[face_no/2] - face_no%2);
-                                                  // compare this with
-                                                  // the empirical value
-                                                  // allowed. if it is
-                                                  // too big, flag the
-                                                  // cell for isotropic
-                                                  // refinement
-                 const double allowed=0.25;
-                       
-                 if (dist>allowed)
-                   cell->flag_for_face_refinement(face_no);
-               }//if flagged for anistropic refinement
-           }//if (cell->face(face)->at_boundary())
-      }//for all cells
-}
-#endif      
-
-
-
-template <int dim>
-void Triangulation<dim>::prepare_refinement_dim_dependent () 
-{}
-
-
-#if deal_II_dimension == 3
-
-template <>
-void Triangulation<3>::prepare_refinement_dim_dependent () 
-{
-  const unsigned int dim = 3;
-  
-                                  // first clear flags on lines,
-                                  // since we need them to determine
-                                  // which lines will be refined
-  clear_user_flags_line();
-
-                                  // also clear flags on hexes, since we need
-                                  // them to mark those cells which are to be
-                                  // coarsened
-  clear_user_flags_hex();
-
-                                  // variable to store whether the
-                                  // mesh was changed in the present
-                                  // loop and in the whole process
-  bool mesh_changed      = false;
-
-  do
-    {
-      mesh_changed = false;
-
-                                      // for this following, we need to know
-                                      // which cells are going to be
-                                      // coarsened, if we had to make a
-                                      // decision. the following function
-                                      // sets these flags:
-      fix_coarsen_flags ();
+                                                  // get at the
+                                                  // child. by
+                                                  // assumption
+                                                  // (A), and the
+                                                  // check by which
+                                                  // we got here,
+                                                  // the child is
+                                                  // not active
+                 cell_iterator child=cell->child(c);
 
-      
-                                      // flag those lines that are refined and
-                                      // will not be coarsened and those that
-                                      // will be refined
-      for (cell_iterator cell=begin(); cell!=end(); ++cell)
-       if (cell->refine_flag_set())
-         {
-           for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-             if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
-                 ==RefinementCase<1>::cut_x)
-                                                // flag a line, that will be
-                                                // refined
-               cell->line(line)->set_user_flag();
-         }
-       else if(cell->has_children() && !cell->child(0)->coarsen_flag_set())
-         {
-           for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-             if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), line)
-                 ==RefinementCase<1>::cut_x)
-                                                // flag a line, that is refined
-                                                // and will stay so
-               cell->line(line)->set_user_flag();
-         }
-       else if(cell->has_children() && cell->child(0)->coarsen_flag_set())
-         cell->set_user_flag();
+                 const unsigned int nn_children=child->n_children();
+                 n_grandchildren += nn_children;
 
+                                                  // if child is
+                                                  // found to be a
+                                                  // patch of
+                                                  // active cells
+                                                  // itself, then
+                                                  // add up how
+                                                  // many of its
+                                                  // children are
+                                                  // supposed to be
+                                                  // coarsened
+                 if (child->child(0)->active())
+                   for (unsigned int cc=0; cc<nn_children; ++cc)
+                     if (child->child(cc)->coarsen_flag_set())
+                       ++n_coarsen_flags;
+               }
 
-                                      // now check whether there are
-                                      // cells with lines that are
-                                      // more than once refined or
-                                      // that will be more than once
-                                      // refined. The first thing
-                                      // should never be the case, in
-                                      // the second case we flag the
-                                      // cell for refinement
-      for (active_cell_iterator cell=last_active(); cell!=end(); --cell)
-       for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-         {
-           if (cell->line(line)->has_children())
-             {
-                                                // if this line is
-                                                // refined, its
-                                                // children should
-                                                // not have further
-                                                // children
-                                                //
-                                                // however, if any of
-                                                // the children is
-                                                // flagged for
-                                                // further
-                                                // refinement, we
-                                                // need to refine
-                                                // this cell also (at
-                                                // least, if the cell
-                                                // is not already
-                                                // flagged)
-               bool offending_line_found = false;
-               
-               for (unsigned int c=0; c<2; ++c)
+                                              // if not all
+                                              // grandchildren are
+                                              // supposed to be
+                                              // coarsened
+                                              // (e.g. because some
+                                              // simply don't have
+                                              // the flag set, or
+                                              // because they are not
+                                              // active and therefore
+                                              // cannot carry the
+                                              // flag), then remove
+                                              // the coarsen flag
+                                              // from all of the
+                                              // active
+                                              // grandchildren. note
+                                              // that there may be
+                                              // coarsen flags on the
+                                              // grandgrandchildren
+                                              // -- we don't clear
+                                              // them here, but we'll
+                                              // get to them in later
+                                              // iterations if
+                                              // necessary
+                                              //
+                                              // there is nothing
+                                              // we have to do if
+                                              // no coarsen flags
+                                              // have been set at
+                                              // all
+             if ((n_coarsen_flags != n_grandchildren)
+                 &&
+                 (n_coarsen_flags > 0))
+               for (unsigned int c=0; c<n_children; ++c)
                  {
-                   Assert (cell->line(line)->child(c)->has_children() == false,
-                           ExcInternalError());
-                   
-                   if (cell->line(line)->child(c)->user_flag_set () &&
-                       (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
-                                                                line)
-                        ==RefinementCase<1>::no_refinement))
-                     {
-                                                        // tag this
-                                                        // cell for
-                                                        // refinement
-                       cell->clear_coarsen_flag ();
-                                                        // if anisotropic
-                                                        // coarsening is
-                                                        // allowed: extend the
-                                                        // refine_flag in the
-                                                        // needed direction,
-                                                        // else set refine_flag
-                                                        // (isotropic)
-                       if (smooth_grid & allow_anisotropic_smoothing)
-                         cell->flag_for_line_refinement(line);
-                       else
-                         cell->set_refine_flag();
-                       
-                       for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
-                         if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
-                             ==RefinementCase<1>::cut_x)
-                                                            // flag a line,
-                                                            // that will be
-                                                            // refined
-                           cell->line(l)->set_user_flag();
-                                                        // note that
-                                                        // we have
-                                                        // changed
-                                                        // the grid
-                       offending_line_found = true;
-                       
-                                                        // it may save us several
-                                                        // loop iterations if we
-                                                        // flag all lines of
-                                                        // this cell now (and not
-                                                        // at the outset of the
-                                                        // next iteration) for
-                                                        // refinement
-                       for (unsigned int line=0;
-                            line<GeometryInfo<dim>::lines_per_cell; ++line)
-                         if (!cell->line(line)->has_children() &&
-                             (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
-                                                                      line)
-                              !=RefinementCase<1>::no_refinement))
-                           cell->line(line)->set_user_flag();
-                       
-                       break;
-                     }
+                   const cell_iterator child = cell->child(c);
+                   if (child->child(0)->active())
+                     for (unsigned int cc=0; cc<child->n_children(); ++cc)
+                       child->child(cc)->clear_coarsen_flag();
                  }
+           }
+       }
 
-               if (offending_line_found)
-                 {
-                   mesh_changed = true;
-                   break;
-                 }
-             }
-         }
-       
-
-                                      // there is another thing here:
-                                      // if any of the lines will be
-                                      // refined, then we may not
-                                      // coarsen the present cell
-                                      // similarly, if any of the lines
-                                      // *is* already refined, we may
-                                      // not coarsen the current
-                                      // cell. however, there's a
-                                      // catch: if the line is refined,
-                                      // but the cell behind it is
-                                      // going to be coarsened, then
-                                      // the situation changes. if we
-                                      // forget this second condition,
-                                      // the refine_and_coarsen_3d test
-                                      // will start to fail. note that
-                                      // to know which cells are going
-                                      // to be coarsened, the call for
-                                      // fix_coarsen_flags above is
-                                      // necessary
-      for (cell_iterator cell=last(); cell!=end(); --cell)
-       {
-         if (cell->user_flag_set())
-           for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-             if (cell->line(line)->has_children() &&
-                 (cell->line(line)->child(0)->user_flag_set() ||
-                  cell->line(line)->child(1)->user_flag_set()))
-               {
-                 for (unsigned int c=0; c<cell->n_children(); ++c)
-                   cell->child(c)->clear_coarsen_flag ();
-                 cell->clear_user_flag();
-                 for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
-                   if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), l)
-                       ==RefinementCase<1>::cut_x)
-                                                // flag a line, that is refined
-                                                // and will stay so
-                     cell->line(l)->set_user_flag();
-                 mesh_changed = true;
-                 break;
-               }
-       }
-    }
-  while (mesh_changed == true);
-}
-
-#endif
-
-
-
-#if deal_II_dimension == 1
-template<>
-bool
-Triangulation<1>::coarsening_allowed(cell_iterator&)
-{
-                                  // in 1D the difference in refinement
-                                  // level is not limited for neighboring
-                                  // cells, so we simply return true
-  return true;
-}
-#endif
-
-
-template<int dim>
-bool
-Triangulation<dim>::coarsening_allowed(cell_iterator& cell)
-{
-  const RefinementCase<dim> ref_case = cell->refinement_case();
-  for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
-    {
-                                      // if the cell is not refined
-                                      // along that face, coarsening
-                                      // will not change anything, so
-                                      // do nothing. the same applies,
-                                      // if the face is at the boandary 
-      const RefinementCase<dim-1> face_ref_case =
-       GeometryInfo<dim>::face_refinement_case(cell->refinement_case(), n);
-               
-      unsigned int n_subfaces = GeometryInfo<dim-1>
-                               ::n_children(face_ref_case);
-                                     
-      if (n_subfaces == 0 || cell->face(n)->at_boundary())
-       continue;
-      for (unsigned int c=0; c<n_subfaces; ++c)
-       {
-         const cell_iterator child = cell->child(GeometryInfo<dim>::
-                                                 child_cell_on_face(ref_case,
-                                                                    n,c));
-                 
-         const cell_iterator child_neighbor = child->neighbor(n);
-         if (!child->neighbor_is_coarser(n))
-                                            // in 2d, if the child's neighbor
-                                            // is coarser, then it has no
-                                            // children. however, in 3d it
-                                            // might be otherwise. consider
-                                            // for example, that our face
-                                            // might be refined with cut_x,
-                                            // but the neighbor is refined
-                                            // with cut_xy at that face. then
-                                            // the neighbor pointers of the
-                                            // children of our cell will point
-                                            // to the common neighbor cell,
-                                            // not to its children. what we
-                                            // really want to know in the
-                                            // following is, wether the
-                                            // neighbor cell is refined twice
-                                            // with reference to our cell.
-                                            // that only has to be asked, if
-                                            // the child's neighbor is not a
-                                            // coarser one.
-           if ((child_neighbor->has_children() &&
-                !child_neighbor->user_flag_set())||
-                                                // neighbor has children, which
-                                                // are further refined along
-                                                // the face, otherwise
-                                                // something went wrong in the
-                                                // contruction of neighbor
-                                                // pointers.  then only allow
-                                                // coarsening if this neighbor
-                                                // will be coarsened as well
-                                                // (user_pointer is set).  the
-                                                // same applies, if the
-                                                // neighbors children are not
-                                                // refined but will be after
-                                                // refinement
-               child_neighbor->refine_flag_set())
-             return false;
-       }
-    }
-  return true;
-}
-
-
-template <int dim>
-void Triangulation<dim>::fix_coarsen_flags ()
-{
-                                  // copy a piece of code from
-                                  // prepare_coarsening_and_refinement that
-                                  // ensures that the level difference at
-                                  // vertices is limited if so desired. we
-                                  // need this code here since at least in 1d
-                                  // we don't call the dimension-independent
-                                  // version of
-                                  // prepare_coarsening_and_refinement
-                                  // function. in 2d and 3d, having this hunk
-                                  // here makes our lives a bit easier as
-                                  // well as it takes care of these cases
-                                  // earlier than it would otherwise happen.
-                                  //
-                                  // the main difference to the code
-                                  // in p_c_and_r is that here we
-                                  // absolutely have to make sure
-                                  // that we get things right,
-                                  // i.e. that in particular we set
-                                  // flags right if
-                                  // limit_level_difference_at_vertices
-                                  // is set. to do so we iterate
-                                  // until the flags don't change any
-                                  // more
-  std::vector<bool> previous_coarsen_flags (n_active_cells());
-  save_coarsen_flags (previous_coarsen_flags);
+                                      //////////////////////////////////
+                                      //
+                                      //  at the boundary we could end up with
+                                      //  cells with negative volume or at
+                                      //  least with a part, that is negative,
+                                      //  if the cell is refined
+                                      //  anisotropically. we have to check,
+                                      //  whether that can happen
+      Implementation::prevent_distorted_boundary_cells(*this);
 
-  bool continue_iterating = true;
-  
-  do
-    {
-      if (smooth_grid & limit_level_difference_at_vertices)
+                                      /////////////////////////////////
+                                      // STEP 6:
+                                      //    take care of the requirement that no
+                                      //    double refinement is done at each face
+                                      //
+                                      //    in case of anisotropic refinement
+                                      //    it is only likely, but not sure,
+                                      //    that the cells, which are more
+                                      //    refined along a certain face common
+                                      //    to two cells are on a higher
+                                      //    level. therefore we cannot be sure,
+                                      //    that the requirement of no double
+                                      //    refinement is fulfilled after a
+                                      //    single pass of the following
+                                      //    actions. We could just wait for the
+                                      //    next global loop. when this
+                                      //    function terminates, the
+                                      //    requirement will be
+                                      //    fullfilled. However, it might be
+                                      //    faster to insert an inner loop
+                                      //    here.
+      bool changed = true;
+      while (changed)
        {
-         Assert(!anisotropic_refinement,
-                ExcMessage("In case of anisotropic refinement the "
-                           "limit_level_difference_at_vertices flag for "
-                           "mesh smoothing must not be set!"));
+         changed=false;
+         active_cell_iterator cell=last_active(),
+                              endc=end();
          
-                                          // store highest level one
-                                          // of the cells adjacent to
-                                          // a vertex belongs to
-         std::vector<int> vertex_level (vertices.size(), 0);
-         active_cell_iterator cell = begin_active(),
-                              endc = end();
-         for (; cell!=endc; ++cell)
-           {
-             if (cell->refine_flag_set())
-               for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
-                    ++vertex)
-                 vertex_level[cell->vertex_index(vertex)]
-                   = std::max (vertex_level[cell->vertex_index(vertex)],
-                               cell->level()+1);
-             else if (!cell->coarsen_flag_set())
-               for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
-                    ++vertex)
-                 vertex_level[cell->vertex_index(vertex)]
-                   = std::max (vertex_level[cell->vertex_index(vertex)],
-                               cell->level());
-             else
-               {
-                                                  // if coarsen flag is
-                                                  // set then tentatively
-                                                  // assume that the cell
-                                                  // will be
-                                                  // coarsened. this
-                                                  // isn't always true
-                                                  // (the coarsen flag
-                                                  // could be removed
-                                                  // again) and so we may
-                                                  // make an error
-                                                  // here. we try to
-                                                  // correct this by
-                                                  // iterating over the
-                                                  // entire process until
-                                                  // we are converged
-                 Assert (cell->coarsen_flag_set(), ExcInternalError());
-                 for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
-                      ++vertex)
-                   vertex_level[cell->vertex_index(vertex)]
-                     = std::max (vertex_level[cell->vertex_index(vertex)],
-                                 cell->level()-1);
-               }
-           }
-      
-
-                                          // loop over all cells in reverse
-                                          // order. do so because we can then
-                                          // update the vertex levels on the
-                                          // adjacent vertices and maybe
-                                          // already flag additional cells in
-                                          // this loop
-                                          //
-                                          // note that not only may we have
-                                          // to add additional refinement
-                                          // flags, but we will also have to
-                                          // remove coarsening flags on cells
-                                          // adjacent to vertices that will
-                                          // see refinement
-         for (cell=last_active(); cell != endc; --cell)
-           if (cell->refine_flag_set() == false)
+         for (; cell != endc; --cell)
+           if (cell->refine_flag_set()) 
              {
-               for (unsigned int vertex=0;
-                    vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
-                 if (vertex_level[cell->vertex_index(vertex)] >=
-                     cell->level()+1)
-                   {
-                                                      // remove coarsen flag...
-                     cell->clear_coarsen_flag();
+                                                // loop over neighbors of cell
+               for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+                 {
+                                                    // only do something if the
+                                                    // face is not at the boundary
+                                                    // and if the face will be
+                                                    // refined with the RefineCase
+                                                    // currently flagged for
+                   if (cell->neighbor(i).state() == IteratorState::valid &&
+                       (GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
+                                                                i)
+                        != RefinementCase<dim-1>::no_refinement))
+                     {
+                                                        // 1) if the neighbor has
+                                                        // children: nothing to
+                                                        // worry about.
+                                                        // 2) if the neighbor is
+                                                        // active and a coarser
+                                                        // one, ensure, that its
+                                                        // refine_flag is set
+                                                        // 3) if the neighbor is
+                                                        // active and as
+                                                        // refined along the face
+                                                        // as our current cell,
+                                                        // make sure, that no
+                                                        // coarsen_flag is set. if
+                                                        // we remove the coarsen
+                                                        // flag of our neighbor,
+                                                        // fix_coarsen_flags() makes
+                                                        // sure, that the mother
+                                                        // cell will not be
+                                                        // coarsened
+                       if (cell->neighbor(i)->active())
+                         {
+                           if (cell->neighbor_is_coarser(i))
+                             {
+                               if (cell->neighbor(i)->coarsen_flag_set())
+                                 cell->neighbor(i)->clear_coarsen_flag();
+                                                                // we'll set the
+                                                                // refine flag
+                                                                // for this
+                                                                // neighbor
+                                                                // below. we
+                                                                // note, that we
+                                                                // have changed
+                                                                // something by
+                                                                // setting the
+                                                                // changed flag
+                                                                // to true. We do
+                                                                // not need to do
+                                                                // so, if we just
+                                                                // removed the
+                                                                // coarsen flag,
+                                                                // as the changed
+                                                                // flag only
+                                                                // indicates the
+                                                                // need to re-run
+                                                                // the inner
+                                                                // loop. however,
+                                                                // we only loop
+                                                                // over cells
+                                                                // flagged for
+                                                                // refinement
+                                                                // here, so
+                                                                // nothing to
+                                                                // worry about if
+                                                                // we remove
+                                                                // coarsen flags
 
-                                                      // ...and if necessary also
-                                                      // refine the current cell,
-                                                      // at the same time
-                                                      // updating the level
-                                                      // information about
-                                                      // vertices
-                     if (vertex_level[cell->vertex_index(vertex)] >
-                         cell->level()+1)
-                       {
-                         cell->set_refine_flag();
-                     
-                         for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
-                              ++v)
-                           vertex_level[cell->vertex_index(v)]
-                             = std::max (vertex_level[cell->vertex_index(v)],
-                                         cell->level()+1);
-                       }
-
-                                                      // continue and see whether
-                                                      // we may, for example, go
-                                                      // into the inner 'if'
-                                                      // above based on a
-                                                      // different vertex
-                   }
-             }
-       }
-  
-                                      // loop over all cells. Flag all
-                                      // cells of which all children are
-                                      // flagged for coarsening and
-                                      // delete the childrens'
-                                      // flags. Also delete all flags of
-                                      // cells for which not all children
-                                      // of a cell are flagged. In
-                                      // effect, only those cells are
-                                      // flagged of which originally all
-                                      // children were flagged and for
-                                      // which all children are on the
-                                      // same refinement level. For
-                                      // flagging, the user flags are
-                                      // used, to avoid confusion and
-                                      // because non-active cells can't
-                                      // be flagged for coarsening
-                                      //
-                                      // In effect, all coarsen flags are
-                                      // turned into user flags of the
-                                      // mother cell if coarsening is
-                                      // possible or deleted
-                                      // otherwise.
-      clear_user_flags ();
-                                      // Coarsen flags of
-                                      // cells with no mother cell,
-                                      // i.e. on the coarsest level are
-                                      // deleted explicitly.
-      active_cell_iterator acell  = begin_active(0),
-                          end_ac = end_active(0);
-      for (; acell!=end_ac; ++acell)
-       acell->clear_coarsen_flag();
-  
-      cell_iterator cell = begin(),
-                   endc = end();
-      for (; cell!=endc; ++cell) 
-       {
-                                          // nothing to do if we are
-                                          // already on the finest level
-         if (cell->active()) 
-           continue;
-
-         const unsigned int n_children=cell->n_children();
-         unsigned int flagged_children=0;
-         for (unsigned int child=0; child<n_children; ++child)
-           if (cell->child(child)->active() &&
-               cell->child(child)->coarsen_flag_set()) 
-             {
-               ++flagged_children;
-                                                // clear flag since we
-                                                // don't need it anymore
-               cell->child(child)->clear_coarsen_flag();
-             }
-         
-                                          // flag this cell for
-                                          // coarsening if all children
-                                          // were flagged
-         if (flagged_children == n_children)
-           cell->set_user_flag();
-       }
-      
-                                      // in principle no coarsen flags
-                                      // should be set any more at this
-                                      // point
-#if DEBUG
-      for (cell=begin(); cell!=endc; ++cell)
-       Assert (cell->coarsen_flag_set() == false, ExcInternalError());
-#endif
-
-                                      // now loop over all cells which have the
-                                      // user flag set. their children were
-                                      // flagged for coarsening. set the coarsen
-                                      // flag again if we are sure that none of
-                                      // the neighbors of these children are
-                                      // refined, or will be refined, since then
-                                      // we would get a two-level jump in
-                                      // refinement. on the other hand, if one of
-                                      // the children's neighbors has their user
-                                      // flag set, then we know that its children
-                                      // will go away by coarsening, and we will
-                                      // be ok.
-                                      //
-                                      // note on the other hand that we do allow
-                                      // level-2 jumps in refinement between
-                                      // neighbors in 1d, so this whole procedure
-                                      // is only necessary if we are not in 1d
-                                      //
-                                      // since we remove some coarsening/user
-                                      // flags in the process, we have to work
-                                      // from the finest level to the coarsest
-                                      // one, since we occasionally inspect user
-                                      // flags of cells on finer levels and need
-                                      // to be sure that these flags are final
-      for (cell=last(); cell!=endc; --cell)
-       if (cell->user_flag_set())
-                                          // if allowed: flag the
-                                          // children for coarsening
-         if (coarsening_allowed(cell))
-           for (unsigned int c=0; c<cell->n_children(); ++c)
-             {
-               Assert (cell->child(c)->refine_flag_set()==false,
-                       ExcInternalError());
-           
-               cell->child(c)->set_coarsen_flag();
-             }
-  
-                                      // clear all user flags again, now that we
-                                      // don't need them any more
-      clear_user_flags ();
-
-      
-                                      // now see if anything has
-                                      // changed in the last
-                                      // iteration of this function
-      std::vector<bool> current_coarsen_flags (n_active_cells());
-      save_coarsen_flags (current_coarsen_flags);
-
-      continue_iterating = (current_coarsen_flags != previous_coarsen_flags);
-      previous_coarsen_flags = current_coarsen_flags;
-    }
-  while (continue_iterating == true);
-}
-
-
-#if deal_II_dimension == 1
-
-template <>
-bool Triangulation<1>::prepare_coarsening_and_refinement ()
-{
-                                  // save the flags to determine
-                                  // whether something was changed in
-                                  // the course of this function
-  std::vector<bool> flags_before;
-  save_coarsen_flags (flags_before);
-
-                                  // do nothing in 1d, except setting
-                                  // the coarsening flags correctly
-  fix_coarsen_flags ();
-  
-  std::vector<bool> flags_after;
-  save_coarsen_flags (flags_after);
-  
-  return (flags_before != flags_after);
-}
-
-#endif
-
-
-
-template <int dim>
-bool Triangulation<dim>::prepare_coarsening_and_refinement ()
-{
-                                  // save the flags to determine
-                                  // whether something was changed in
-                                  // the course of this function
-  std::vector<bool> flags_before[2];
-  save_coarsen_flags (flags_before[0]);
-  save_refine_flags (flags_before[1]);
-
-                                  // save the flags at the outset of
-                                  // each loop. we do so in order to
-                                  // find out whether something was
-                                  // changed in the present loop, in
-                                  // which case we would have to
-                                  // re-run the loop. the other
-                                  // possibility to find this out
-                                  // would be to set a flag
-                                  // @p{something_changed} to true
-                                  // each time we change something.
-                                  // however, sometimes one change in
-                                  // one of the parts of the loop is
-                                  // undone by another one, so we
-                                  // might end up in an endless
-                                  // loop. we could be tempted to
-                                  // break this loop at an arbitrary
-                                  // number of runs, but that would
-                                  // not be a clean solution, since
-                                  // we would either have to  
-                                  // 1/ break the loop too early, in which
-                                  //    case the promise that a second
-                                  //    call to this function immediately
-                                  //    after the first one does not
-                                  //    change anything, would be broken,
-                                  // or
-                                  // 2/ we do as many loops as there are
-                                  //    levels. we know that information
-                                  //    is transported over one level
-                                  //    in each run of the loop, so this
-                                  //    is enough. Unfortunately, each
-                                  //    loop is rather expensive, so
-                                  //    we chose the way presented here
-  std::vector<bool> flags_before_loop[2] = {flags_before[0],
-                                            flags_before[1]};
-
-                                  // now for what is done in each
-                                  // loop: we have to fulfill several
-                                  // tasks at the same time, namely
-                                  // several mesh smoothing
-                                  // algorithms and mesh
-                                  // regularisation, by which we mean
-                                  // that the next mesh fulfills
-                                  // several requirements such as no
-                                  // double refinement at each face
-                                  // or line, etc.
-                                  //
-                                  // since doing these things at once
-                                  // seems almost impossible (in the
-                                  // first year of this library, they
-                                  // were done in two functions, one
-                                  // for refinement and one for
-                                  // coarsening, and most things
-                                  // within these were done at once,
-                                  // so the code was rather
-                                  // impossible to join into this,
-                                  // only, function), we do them one
-                                  // after each other. the order in
-                                  // which we do them is such that
-                                  // the important tasks, namely
-                                  // regularisation, are done last
-                                  // and the least important things
-                                  // are done the first. the
-                                  // following order is chosen:
-                                  //
-                                  // 0/ Only if coarsest_level_1 or
-                                  //    patch_level_1 is set:
-                                  //    clear all coarsen flags on level 1
-                                  //    to avoid level 0 cells being
-                                  //    created by coarsening.
-                                  //    As coarsen flags will never be added,
-                                  //    this can be done once and for all
-                                  //    before the actual loop starts.
-                                  // 1/ do not coarsen a cell if
-                                  //    'most of the neighbors' will be
-                                  //    refined after the step. This is
-                                  //    to prevent occurence of
-                                  //    unrefined islands.
-                                  // 2/ eliminate refined islands in the
-                                  //    interior and at the boundary. since
-                                  //    they don't do much harm besides
-                                  //    increasing the number of degrees
-                                  //    of freedom, doing this has a
-                                  //    rather low priority.
-                                  // 3/ limit the level difference of
-                                  //    neighboring cells at each vertex.
-                                  // 4/ eliminate unrefined islands. this
-                                  //    has higher priority since this
-                                  //    diminishes the approximation
-                                  //    properties not only of the unrefined
-                                  //    island, but also of the surrounding
-                                  //    patch.
-                                  // 5/ ensure patch level 1. Then the
-                                  //    triangulation consists of patches,
-                                  //    i.e. of cells that are
-                                  //    refined once. It follows that if at
-                                  //    least one of the children of a cell
-                                  //    is or will be refined than all children
-                                  //    need to be refined. This step
-                                  //    only sets refinement flags and does
-                                  //    not set coarsening flags.
-                                  //    If the patch_level_1 flag is set, then
-                                  //    eliminate_unrefined_islands,
-                                  //    eliminate_refined_inner_islands and
-                                  //    eliminate_refined_boundary_islands will
-                                  //    be fulfilled automatically and do not
-                                  //    need to be enforced separately.
-                                  // 6/ take care of the requirement that no
-                                  //    double refinement is done at each face
-                                  // 7/ take care that no double refinement
-                                  //    is done at each line in 3d or higher
-                                  //    dimensions.
-                                  // 8/ make sure that all children of each
-                                  //    cell are either flagged for coarsening
-                                  //    or none of the children is
-                                  //
-                                  // For some of these steps, it is
-                                  // known that they
-                                  // interact. Namely, it is not
-                                  // possible to guarantee that after
-                                  // step 6 another step 5 would have
-                                  // no effect; the same holds for
-                                  // the opposite order and also when
-                                  // taking into account step
-                                  // 7. however, it is important to
-                                  // guarantee that step five or six
-                                  // do not undo something that step
-                                  // 5 did, and step 7 not something
-                                  // of step 6, otherwise the
-                                  // requirements will not be
-                                  // satisfied even if the loop
-                                  // terminates. this is accomplished
-                                  // by the fact that steps 5 and 6
-                                  // only *add* refinement flags and
-                                  // delete coarsening flags
-                                  // (therefore, step 6 can't undo
-                                  // something that step 4 already
-                                  // did), and step 7 only deletes
-                                  // coarsening flags, never adds
-                                  // some. step 7 needs also take
-                                  // care that it won't tag cells for
-                                  // refinement for which some
-                                  // neighbors are more refined or
-                                  // will be refined.
-
-                                  //////////////////////////////////////
-                                  // STEP 0:
-                                  //    Only if coarsest_level_1 or
-                                  //    patch_level_1 is set:
-                                  //    clear all coarsen flags on level 1
-                                  //    to avoid level 0 cells being
-                                  //    created by coarsening.
-  if (((smooth_grid & coarsest_level_1) ||
-       (smooth_grid & patch_level_1)) && n_levels()>=2)
-    {
-      active_cell_iterator
-       cell=begin_active(1),
-       endc=end_active(1);
-      
-      for (; cell!=endc; ++cell)
-       cell->clear_coarsen_flag();
-    }
-
-  
-  bool mesh_changed_in_this_loop = false;
-  do
-    {
-                                      //////////////////////////////////////
-                                      // STEP 1:
-                                      //    do not coarsen a cell if 'most of
-                                      //    the neighbors' will be refined after
-                                      //    the step. This is to prevent the
-                                      //    occurence of unrefined islands.
-                                      //    If patch_level_1 is set, this will
-                                      //    be automatically fulfilled.
-      if (smooth_grid & do_not_produce_unrefined_islands &&
-         !(smooth_grid & patch_level_1))
-       {
-         cell_iterator       cell;
-         const cell_iterator endc = end();
-         
-         for (cell=begin(); cell!=endc; ++cell)
-           {
-             if (!cell->active())
-               {
-                                                  // only do something if this
-                                                  // cell will be coarsened
-                 if (cell_will_be_coarsened(cell))
-                   {
-                     unsigned int n_neighbors=0;
-                                                      // count all neighbors
-                                                      // that will be refined
-                                                      // along the face of our
-                                                      // cell after the next
-                                                      // step
-                     unsigned int count=0;
-                     for (unsigned int n=0;
-                          n<GeometryInfo<dim>::faces_per_cell; ++n)
-                       {
-                         const cell_iterator neighbor = cell->neighbor(n);
-                         if (neighbor.state() == IteratorState::valid)
-                           {
-                             ++n_neighbors;
-                             if (face_will_be_refined_by_neighbor(cell,n))
-                               ++count;
-                           }
-                       }
-                                                      // clear coarsen flags if
-                                                      // either all existing
-                                                      // neighbors will be
-                                                      // refined or all but one
-                                                      // will be and the cell
-                                                      // is in the interior of
-                                                      // the domain
-                     if (count==n_neighbors ||
-                         (count>=n_neighbors-1 &&
-                          n_neighbors==
-                          GeometryInfo<dim>::faces_per_cell))
-                       for (unsigned int c=0; c<cell->n_children(); ++c)
-                         cell->child(c)->clear_coarsen_flag();
-                   }
-               }  // if (!cell->active())
-           }  // for (all cells)
-       } // if (smooth_grid & ...)
-
-      
-                                      //////////////////////////////////////
-                                      // STEP 2:
-                                      //    eliminate refined islands in the
-                                      //    interior and at the boundary. since
-                                      //    they don't do much harm besides
-                                      //    increasing the number of degrees of
-                                      //    freedom, doing this has a rather low
-                                      //    priority.
-                                      //    If patch_level_1 is set, this will
-                                      //    be automatically fulfilled.
-      if (smooth_grid & (eliminate_refined_inner_islands |
-                        eliminate_refined_boundary_islands) &&
-         !(smooth_grid & patch_level_1)) 
-       {
-         cell_iterator       cell;
-         const cell_iterator endc = end();
-         
-         for (cell=begin(); cell!=endc; ++cell)
-           if (!cell->active() || (cell->active() && cell->refine_flag_set()))
-             {
-                                                // check whether all
-                                                // children are
-                                                // active, i.e. not
-                                                // refined
-                                                // themselves. This
-                                                // is a precondition
-                                                // that the children
-                                                // may be coarsened
-                                                // away. If the cell
-                                                // is only flagged
-                                                // for refinement,
-                                                // then all future
-                                                // children will be
-                                                // active
-               bool all_children_active = true;
-               if (!cell->active())
-                 for (unsigned int c=0; c<cell->n_children(); ++c)
-                   if (!cell->child(c)->active()) 
-                     {
-                       all_children_active = false;
-                       break;
-                     }
-
-               if (all_children_active) 
-                 {
-                                                    // count number
-                                                    // of refined and
-                                                    // unrefined
-                                                    // neighbors of
-                                                    // cell.
-                                                    // neighbors on
-                                                    // lower levels
-                                                    // are counted as
-                                                    // unrefined
-                                                    // since they can
-                                                    // only get to
-                                                    // the same level
-                                                    // as this cell
-                                                    // by the next
-                                                    // refinement
-                                                    // cycle
-                   unsigned int unrefined_neighbors = 0,
-                                    total_neighbors = 0;
-
-                   for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n) 
-                     {
-                       const cell_iterator neighbor = cell->neighbor(n);
-                       if (neighbor.state() == IteratorState::valid)
-                       {
-                         ++total_neighbors;
-
-                         if (!face_will_be_refined_by_neighbor(cell,n))
-                           ++unrefined_neighbors;
-                       }
-                       
-                     }
-                   
-                                                    // if all
-                                                    // neighbors
-                                                    // unrefined:
-                                                    // mark this cell
-                                                    // for coarsening
-                                                    // or don't
-                                                    // refine if
-                                                    // marked for
-                                                    // that
-                                                    //
-                                                    // also do the
-                                                    // distinction
-                                                    // between the
-                                                    // two versions
-                                                    // of the
-                                                    // eliminate_refined_*_islands
-                                                    // flag
-                                                    //
-                                                    // the last check
-                                                    // is whether
-                                                    // there are any
-                                                    // neighbors at
-                                                    // all. if not
-                                                    // so, then we
-                                                    // are (e.g.) on
-                                                    // the coarsest
-                                                    // grid with one
-                                                    // cell, for
-                                                    // which, of
-                                                    // course, we do
-                                                    // not remove the
-                                                    // refine flag.
-                   if ((unrefined_neighbors == total_neighbors)
-                       &&
-                       (((unrefined_neighbors==GeometryInfo<dim>::faces_per_cell) &&
-                         (smooth_grid & eliminate_refined_inner_islands)) ||
-                        ((unrefined_neighbors<GeometryInfo<dim>::faces_per_cell) &&
-                         (smooth_grid & eliminate_refined_boundary_islands)) )
-                       &&
-                       (total_neighbors != 0))
-                     {
-                       if (!cell->active())
-                         for (unsigned int c=0; c<cell->n_children(); ++c)
-                           {
-                             cell->child(c)->clear_refine_flag ();
-                             cell->child(c)->set_coarsen_flag ();
-                           }
-                       else 
-                         cell->clear_refine_flag();
-                     }
-                 }
-             }
-       }
-
-                                      //////////////////////////////////////
-                                      // STEP 3:
-                                      //    limit the level difference of
-                                      //    neighboring cells at each vertex.
-                                      //
-                                      //    in case of anisotropic refinement
-                                      //    this does not make sense. as soon
-                                      //    as one cell is anisotropically
-                                      //    refined, an Assertion is
-                                      //    thrown. therefore we can ignore
-                                      //    this problem later on
-      if (smooth_grid & limit_level_difference_at_vertices)
-       {
-         Assert(!anisotropic_refinement,
-                ExcMessage("In case of anisotropic refinement the "
-                           "limit_level_difference_at_vertices flag for "
-                           "mesh smoothing must not be set!"));
-         
-                                          // store highest level one
-                                          // of the cells adjacent to
-                                          // a vertex belongs to
-         std::vector<int> vertex_level (vertices.size(), 0);
-         active_cell_iterator cell = begin_active(),
-                              endc = end();
-         for (; cell!=endc; ++cell)
-           {
-             if (cell->refine_flag_set())
-               for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
-                    ++vertex)
-                 vertex_level[cell->vertex_index(vertex)]
-                   = std::max (vertex_level[cell->vertex_index(vertex)],
-                               cell->level()+1);
-             else if (!cell->coarsen_flag_set())
-               for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
-                    ++vertex)
-                 vertex_level[cell->vertex_index(vertex)]
-                   = std::max (vertex_level[cell->vertex_index(vertex)],
-                               cell->level());
-             else
-               {
-                                                  // if coarsen flag is set then
-                                                  // tentatively assume that the
-                                                  // cell will be coarsened. this
-                                                  // isn't always true (the
-                                                  // coarsen flag could be
-                                                  // removed again) and so we may
-                                                  // make an error here
-                 Assert (cell->coarsen_flag_set(), ExcInternalError());
-                 for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
-                      ++vertex)
-                   vertex_level[cell->vertex_index(vertex)]
-                     = std::max (vertex_level[cell->vertex_index(vertex)],
-                                 cell->level()-1);
-               }
-           }
-      
-
-                                          // loop over all cells in reverse
-                                          // order. do so because we can then
-                                          // update the vertex levels on the
-                                          // adjacent vertices and maybe
-                                          // already flag additional cells in
-                                          // this loop
-                                          //
-                                          // note that not only may we have
-                                          // to add additional refinement
-                                          // flags, but we will also have to
-                                          // remove coarsening flags on cells
-                                          // adjacent to vertices that will
-                                          // see refinement
-         for (cell=last_active(); cell != endc; --cell)
-           if (cell->refine_flag_set() == false)
-             {
-               for (unsigned int vertex=0;
-                    vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
-                 if (vertex_level[cell->vertex_index(vertex)] >=
-                     cell->level()+1)
-                   {
-                                                      // remove coarsen flag...
-                     cell->clear_coarsen_flag();
-
-                                                      // ...and if necessary also
-                                                      // refine the current cell,
-                                                      // at the same time
-                                                      // updating the level
-                                                      // information about
-                                                      // vertices
-                     if (vertex_level[cell->vertex_index(vertex)] >
-                         cell->level()+1)
-                       {
-                         cell->set_refine_flag();
-                     
-                         for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
-                              ++v)
-                           vertex_level[cell->vertex_index(v)]
-                             = std::max (vertex_level[cell->vertex_index(v)],
-                                         cell->level()+1);
-                       }
-
-                                                      // continue and see whether
-                                                      // we may, for example, go
-                                                      // into the inner 'if'
-                                                      // above based on a
-                                                      // different vertex
-                   }
-             }
-       }
-
-                                      /////////////////////////////////////
-                                      // STEP 4:      
-                                      //    eliminate unrefined
-                                      //    islands. this has higher
-                                      //    priority since this
-                                      //    diminishes the
-                                      //    approximation properties
-                                      //    not only of the unrefined
-                                      //    island, but also of the
-                                      //    surrounding patch.
-      if (smooth_grid & eliminate_unrefined_islands)
-       {
-         active_cell_iterator cell = begin_active(),
-                              endc = end();
-         for (; cell!=endc; ++cell) 
-           {
-                                              // if cell is already
-                                              // flagged for (isotropic)
-                                              // refinement: nothing
-                                              // to do anymore
-             if (cell->refine_flag_set()==RefinementCase<dim>::isotropic_refinement)
-               continue;
-
-                                              // now we provide two
-                                              // algorithms. the first one is
-                                              // the standard one, coming from
-                                              // the time, where only isotropic
-                                              // refinement was possible. it
-                                              // simply counts the neighbors
-                                              // that are or will be refined
-                                              // and compares to the number of
-                                              // other ones. the second one
-                                              // does this check independently
-                                              // for each direction: if all
-                                              // neighbors in one direction
-                                              // (normally two, at the boundary
-                                              // only one) are refined, the
-                                              // current cell is flagged to be
-                                              // refined in an according
-                                              // direction.
-             
-             if (!(smooth_grid & allow_anisotropic_smoothing))
-               {
-                                                  // use first algorithm
-                 unsigned int refined_neighbors = 0,
-                            unrefined_neighbors = 0;
-                 for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-                   if (!cell->at_boundary(face))
-                     {
-                       if (face_will_be_refined_by_neighbor(cell,face)) 
-                         ++refined_neighbors;
-                       else
-                         ++unrefined_neighbors;
-                     }
-
-                 if (unrefined_neighbors < refined_neighbors)
-                   {
-                     if (cell->coarsen_flag_set())
-                       cell->clear_coarsen_flag();
-                     cell->set_refine_flag ();
-                   }
-               }
-             else
-               { 
-                                                  // variable to store the cell
-                                                  // refine case needed to
-                                                  // fulfill all smoothing
-                                                  // requirements
-                 RefinementCase<dim> smoothing_cell_refinement_case=RefinementCase<dim>::no_refinement;
-                 
-                                                  // use second algorithm, do
-                                                  // the check individually for
-                                                  // each direction
-                 for (unsigned int face_pair=0; face_pair<GeometryInfo<dim>::faces_per_cell/2; ++face_pair)
-                   {
-                                                      // variable to store the
-                                                      // cell refine case
-                                                      // needed to refine at
-                                                      // the current face pair
-                                                      // in the same way as the
-                                                      // neighbors do...
-                     RefinementCase<dim> directional_cell_refinement_case=RefinementCase<dim>::isotropic_refinement;
-                     
-                     for (unsigned int face_index=0; face_index<2; ++face_index)
-                       {
-                         unsigned int face=2*face_pair+face_index;
-                                                          // variable to store
-                                                          // the refine case
-                                                          // (to come) of the
-                                                          // face under
-                                                          // consideration
-                         RefinementCase<dim-1> expected_face_ref_case=RefinementCase<dim-1>::no_refinement;
-                         
-                         if (cell->neighbor(face).state() == IteratorState::valid)
-                           face_will_be_refined_by_neighbor(cell,face,expected_face_ref_case);
-                                                          // now extract which
-                                                          // refine case would
-                                                          // be necessary to
-                                                          // achive the same
-                                                          // face
-                                                          // refinement. set
-                                                          // the intersection
-                                                          // with other
-                                                          // requirements for
-                                                          // the same
-                                                          // direction.
-
-                                                          // note: using the
-                                                          // intersection is
-                                                          // not an obvious
-                                                          // decision, we could
-                                                          // also argue that it
-                                                          // is more natural to
-                                                          // use the
-                                                          // union. however,
-                                                          // intersection is
-                                                          // the less
-                                                          // aggressive tactic
-                                                          // and favours a
-                                                          // smaller number of
-                                                          // refined cells over
-                                                          // an intensive
-                                                          // smoothing. this
-                                                          // way we try not to
-                                                          // loose too much of
-                                                          // the effort we put
-                                                          // in anisotropic
-                                                          // refinement
-                                                          // indicators due to
-                                                          // overly aggressive
-                                                          // smoothing...
-                         directional_cell_refinement_case = directional_cell_refinement_case &
-                                                        GeometryInfo<dim>::min_cell_refinement_case_for_face_refinement(
-                                                          expected_face_ref_case,
-                                                          face,
-                                                          cell->face_orientation(face),
-                                                          cell->face_flip(face),
-                                                          cell->face_rotation(face));
-                       }//for both face indices
-                                                      // if both requirements
-                                                      // sum up to something
-                                                      // useful, add this to
-                                                      // the refine case for
-                                                      // smoothing. note: if
-                                                      // directional_cell_refinement_case
-                                                      // is isotropic still,
-                                                      // then something went
-                                                      // wrong...
-                     Assert(directional_cell_refinement_case < RefinementCase<dim>::isotropic_refinement,
-                            ExcInternalError());
-                     smoothing_cell_refinement_case = smoothing_cell_refinement_case |
-                                                  directional_cell_refinement_case;
-                   }//for all face_pairs
-                                                  // no we collected
-                                                  // contributions from all
-                                                  // directions. combine the
-                                                  // new flags with the
-                                                  // existing refine case, but
-                                                  // only if smoothing is
-                                                  // required
-                 if (smoothing_cell_refinement_case)
-                   {
-                     cell->clear_coarsen_flag();
-                     cell->set_refine_flag(cell->refine_flag_set() | smoothing_cell_refinement_case);
-                   }
-               }//else -> allow_anisotropic_smoothing 
-           }// for all cells
-       }
-
-                                      /////////////////////////////////
-                                      // STEP 5:
-                                      //    ensure patch level 1.
-                                      //
-                                      //    Introduce some terminology:
-                                      //    - a cell that is refined
-                                      //      once is a patch of
-                                      //      level 1 simply called patch.
-                                      //    - a cell that is globally
-                                      //      refined twice is called
-                                      //      a patch of level 2.
-                                      //    - patch level n says that
-                                      //      the triangulation consists
-                                      //      of patches of level n.
-                                      //      This makes sense only
-                                      //      if the grid is already at
-                                      //      least n times globally
-                                      //      refined.
-                                      //
-                                      //    E.g. from patch level 1
-                                      //    follows: if at least one
-                                      //    of the children of a cell
-                                      //    is or will be refined
-                                      //    than enforce all
-                                      //    children to be
-                                      //    refined.
-
-                                      //    This step 4 only
-                                      //    sets refinement flags and
-                                      //    does not set coarsening
-                                      //    flags.
-      if (smooth_grid & patch_level_1) 
-       {
-                                          // An important assumption
-                                          // (A) is that before
-                                          // calling this function
-                                          // the grid was already of
-                                          // patch level 1.
-
-                                          // loop over all cells
-                                          // whose children are all
-                                          // active.  (By assumption
-                                          // (A) either all or none
-                                          // of the children are
-                                          // active).  If the refine
-                                          // flag of at least one of
-                                          // the children is set then
-                                          // set_refine_flag and
-                                          // clear_coarsen_flag of
-                                          // all children.
-         for (cell_iterator cell = begin(); cell != end(); ++cell)
-           if (!cell->active())
-             {
-                                                // ensure the
-                                                // invariant. we can
-                                                // then check whether
-                                                // all of its
-                                                // children are
-                                                // further refined or
-                                                // not by simply
-                                                // looking at the
-                                                // first child
-               Assert (cell_is_patch_level_1(cell),
-                       ExcInternalError());
-               if (cell->child(0)->has_children() == true)
-                 continue;
-               
-                                                // cell is found to
-                                                // be a patch.
-                                                // combine the refine
-                                                // cases of all
-                                                // children
-               RefinementCase<dim> combined_ref_case = RefinementCase<dim>::no_refinement;
-               for (unsigned int i=0; i<cell->n_children(); ++i)
-                 combined_ref_case = combined_ref_case |
-                                     cell->child(i)->refine_flag_set();
-               if (combined_ref_case != RefinementCase<dim>::no_refinement)
-                 for (unsigned int i=0; i<cell->n_children(); ++i)
-                   {
-                     cell_iterator child = cell->child(i);
-                     
-                     child->clear_coarsen_flag();
-                     child->set_refine_flag(combined_ref_case);
-                   }
-             }
-
-                                          // The code above dealt
-                                          // with the case where we
-                                          // may get a
-                                          // non-patch_level_1 mesh
-                                          // from refinement. Now
-                                          // also deal with the case
-                                          // where we could get such
-                                          // a mesh by coarsening.
-                                          // Coarsen the children
-                                          // (and remove the
-                                          // grandchildren) only if
-                                          // all cell->grandchild(i)
-                                          //   ->coarsen_flag_set()
-                                          // are set.
-                                          //
-                                          // for a case where this is
-                                          // a bit tricky, take a
-                                          // look at the
-                                          // mesh_smoothing_0[12]
-                                          // testcases
-         for (cell_iterator cell = begin(); cell != end(); ++cell)
-           {
-                                              // check if this cell
-                                              // has active
-                                              // grandchildren. note
-                                              // that we know that it
-                                              // is patch_level_1,
-                                              // i.e. if one of its
-                                              // children is active
-                                              // then so are all, and
-                                              // it isn't going to
-                                              // have any
-                                              // grandchildren at
-                                              // all:
-             if (cell->active()
-                 ||
-                 cell->child(0)->active())
-               continue;
-
-                                              // cell is not active,
-                                              // and so are none of
-                                              // its children. check
-                                              // the
-                                              // grandchildren. note
-                                              // that the children
-                                              // are also
-                                              // patch_level_1, and
-                                              // so we only ever need
-                                              // to check their first
-                                              // child
-             const unsigned int n_children=cell->n_children();
-             bool has_active_grandchildren = false;
-
-             for (unsigned int i=0; i<n_children; ++i)
-               if (cell->child(i)->child(0)->active())
-                 {
-                   has_active_grandchildren = true;
-                   break;
-                 }
-
-             if (has_active_grandchildren == false)
-               continue;
-             
-
-                                              // ok, there are active
-                                              // grandchildren. see
-                                              // if either all or
-                                              // none of them are
-                                              // flagged for
-                                              // coarsening
-             unsigned int n_grandchildren=0;           
-                                              // count all coarsen
-                                              // flags of the
-                                              // grandchildren.
-             unsigned int n_coarsen_flags=0;
-                                              // cell is not a
-                                              // patch (of level 1)
-                                              // as it has a
-                                              // grandchild.  Is
-                                              // cell a patch of
-                                              // level 2??
-                                              // Therefore: find
-                                              // out whether all
-                                              // cell->child(i) are
-                                              // patches
-             for (unsigned int c=0; c<n_children; ++c)
-               {
-                                                  // get at the
-                                                  // child. by
-                                                  // assumption
-                                                  // (A), and the
-                                                  // check by which
-                                                  // we got here,
-                                                  // the child is
-                                                  // not active
-                 cell_iterator child=cell->child(c);
-
-                 const unsigned int nn_children=child->n_children();
-                 n_grandchildren += nn_children;
-
-                                                  // if child is
-                                                  // found to be a
-                                                  // patch of
-                                                  // active cells
-                                                  // itself, then
-                                                  // add up how
-                                                  // many of its
-                                                  // children are
-                                                  // supposed to be
-                                                  // coarsened
-                 if (child->child(0)->active())
-                   for (unsigned int cc=0; cc<nn_children; ++cc)
-                     if (child->child(cc)->coarsen_flag_set())
-                       ++n_coarsen_flags;
-               }
-
-                                              // if not all
-                                              // grandchildren are
-                                              // supposed to be
-                                              // coarsened
-                                              // (e.g. because some
-                                              // simply don't have
-                                              // the flag set, or
-                                              // because they are not
-                                              // active and therefore
-                                              // cannot carry the
-                                              // flag), then remove
-                                              // the coarsen flag
-                                              // from all of the
-                                              // active
-                                              // grandchildren. note
-                                              // that there may be
-                                              // coarsen flags on the
-                                              // grandgrandchildren
-                                              // -- we don't clear
-                                              // them here, but we'll
-                                              // get to them in later
-                                              // iterations if
-                                              // necessary
-                                              //
-                                              // there is nothing
-                                              // we have to do if
-                                              // no coarsen flags
-                                              // have been set at
-                                              // all
-             if ((n_coarsen_flags != n_grandchildren)
-                 &&
-                 (n_coarsen_flags > 0))
-               for (unsigned int c=0; c<n_children; ++c)
-                 {
-                   const cell_iterator child = cell->child(c);
-                   if (child->child(0)->active())
-                     for (unsigned int cc=0; cc<child->n_children(); ++cc)
-                       child->child(cc)->clear_coarsen_flag();
-                 }
-           }
-       }
-
-                                      //////////////////////////////////
-                                      //
-                                      //  at the boundary we could end up with
-                                      //  cells with negative volume or at
-                                      //  least with a part, that is negative,
-                                      //  if the cell is refined
-                                      //  anisotropically. we have to check,
-                                      //  whether that can happen
-      
-      prevent_distorted_boundary_cells();
-
-                                      /////////////////////////////////
-                                      // STEP 6:
-                                      //    take care of the requirement that no
-                                      //    double refinement is done at each face
-                                      //
-                                      //    in case of anisotropic refinement
-                                      //    it is only likely, but not sure,
-                                      //    that the cells, which are more
-                                      //    refined along a certain face common
-                                      //    to two cells are on a higher
-                                      //    level. therefore we cannot be sure,
-                                      //    that the requirement of no double
-                                      //    refinement is fulfilled after a
-                                      //    single pass of the following
-                                      //    actions. We could just wait for the
-                                      //    next global loop. when this
-                                      //    function terminates, the
-                                      //    requirement will be
-                                      //    fullfilled. However, it might be
-                                      //    faster to insert an inner loop
-                                      //    here.
-      bool changed = true;
-      while (changed)
-       {
-         changed=false;
-         active_cell_iterator cell=last_active(),
-                              endc=end();
-         
-         for (; cell != endc; --cell)
-           if (cell->refine_flag_set()) 
-             {
-                                                // loop over neighbors of cell
-               for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
-                 {
-                                                    // only do something if the
-                                                    // face is not at the boundary
-                                                    // and if the face will be
-                                                    // refined with the RefineCase
-                                                    // currently flagged for
-                   if (cell->neighbor(i).state() == IteratorState::valid &&
-                       (GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
-                                                                i)
-                        != RefinementCase<dim-1>::no_refinement))
-                     {
-                                                        // 1) if the neighbor has
-                                                        // children: nothing to
-                                                        // worry about.
-                                                        // 2) if the neighbor is
-                                                        // active and a coarser
-                                                        // one, ensure, that its
-                                                        // refine_flag is set
-                                                        // 3) if the neighbor is
-                                                        // active and as
-                                                        // refined along the face
-                                                        // as our current cell,
-                                                        // make sure, that no
-                                                        // coarsen_flag is set. if
-                                                        // we remove the coarsen
-                                                        // flag of our neighbor,
-                                                        // fix_coarsen_flags() makes
-                                                        // sure, that the mother
-                                                        // cell will not be
-                                                        // coarsened
-                       if (cell->neighbor(i)->active())
-                         {
-                           if (cell->neighbor_is_coarser(i))
-                             {
-                               if (cell->neighbor(i)->coarsen_flag_set())
-                                 cell->neighbor(i)->clear_coarsen_flag();
-                                                                // we'll set the
-                                                                // refine flag
-                                                                // for this
-                                                                // neighbor
-                                                                // below. we
-                                                                // note, that we
-                                                                // have changed
-                                                                // something by
-                                                                // setting the
-                                                                // changed flag
-                                                                // to true. We do
-                                                                // not need to do
-                                                                // so, if we just
-                                                                // removed the
-                                                                // coarsen flag,
-                                                                // as the changed
-                                                                // flag only
-                                                                // indicates the
-                                                                // need to re-run
-                                                                // the inner
-                                                                // loop. however,
-                                                                // we only loop
-                                                                // over cells
-                                                                // flagged for
-                                                                // refinement
-                                                                // here, so
-                                                                // nothing to
-                                                                // worry about if
-                                                                // we remove
-                                                                // coarsen flags
-
-                               if (dim==2)
-                                 {
-                                   if (smooth_grid & allow_anisotropic_smoothing)
-                                     changed=cell->neighbor(i)->flag_for_face_refinement(cell->neighbor_of_coarser_neighbor(i).first,
-                                                                                         RefinementCase<dim-1>::cut_x);
-                                   else
-                                     {
-                                       if (!cell->neighbor(i)->refine_flag_set())
-                                         changed=true;
-                                       cell->neighbor(i)->set_refine_flag();
-                                     }
-                                 }
-                               else //i.e. if (dim==3)
-                                 {
-// ugly situations might arise here, consider the following situation, which
-// shows neighboring cells at the common face, where the upper right element is
-// coarser at the given face. Now the upper child element of the lower left
-// wants to refine according to cut_z, such that there is a 'horizontal'
-// refinement of the face marked with #####
-//   
-//                            /               /
-//                           /               /
-//                          *---------------*
-//                          |               |
-//                          |               |
-//                          |               |
-//                          |               |
-//                          |               |
-//                          |               | /
-//                          |               |/
-//                          *---------------*
-//   
-//   
-//     *---------------*
-//    /|              /|
-//   / |     #####   / |
-//     |               |
-//     *---------------*
-//    /|              /|
-//   / |             / |
-//     |               |
-//     *---------------*
-//    /               /
-//   /               /
-//
-// this introduces too many hanging nodes and the neighboring (coarser) cell
-// (upper right) has to be refined. If it is only refined according to cut_z,
-// then everything is ok:
-//   
-//                            /               /
-//                           /               /
-//                          *---------------*
-//                          |               |
-//                          |               | /
-//                          |               |/
-//                          *---------------*
-//                          |               |
-//                          |               | /
-//                          |               |/
-//                          *---------------*
-//   
-//   
-//     *---------------*
-//    /|              /|
-//   / *---------------*
-//    /|              /|
-//     *---------------*
-//    /|              /|
-//   / |             / |
-//     |               |
-//     *---------------*
-//    /               /
-//   /               /
-//
-// if however the cell wants to refine itself in an other way, or if we disallow
-// anisotropic smoothing, then simply refining the neighbor isotropically is not
-// going to work, since this introduces a refinement of face ##### with both
-// cut_x and cut_y, which is not possible:
-//
-//                            /       /       /
-//                           /       /       /
-//                          *-------*-------*
-//                          |       |       |
-//                          |       |       | /
-//                          |       |       |/
-//                          *-------*-------*
-//                          |       |       |
-//                          |       |       | /
-//                          |       |       |/
-//                          *-------*-------*
-//   
-//   
-//     *---------------*
-//    /|              /|
-//   / *---------------*
-//    /|              /|
-//     *---------------*
-//    /|              /|
-//   / |             / |
-//     |               |
-//     *---------------*
-//    /               /
-//   /               /
-//
-// thus, in this case we also need to refine our current cell in the new
-// direction:
-//
-//                            /       /       /
-//                           /       /       /
-//                          *-------*-------*
-//                          |       |       |
-//                          |       |       | /
-//                          |       |       |/
-//                          *-------*-------*
-//                          |       |       |
-//                          |       |       | /
-//                          |       |       |/
-//                          *-------*-------*
-//   
-//   
-//     *-------*-------*
-//    /|      /|      /|
-//   / *-------*-------*
-//    /|      /|      /|
-//     *-------*-------*
-//    /|      /       /|
-//   / |             / |
-//     |               |
-//     *---------------*
-//    /               /
-//   /               /
-
-                                   std::pair<unsigned int, unsigned int> nb_indices
-                                     =cell->neighbor_of_coarser_neighbor(i);
-                                   unsigned int refined_along_x=0,
-                                                refined_along_y=0,
-                                          to_be_refined_along_x=0,
-                                          to_be_refined_along_y=0;
-
-                                   const int this_face_index=cell->face_index(i);
-                                 
-// step 1: detect, along which axis the face is currently refined
-                                   if ((this_face_index
-                                        == cell->neighbor(i)->face(nb_indices.first)->child_index(0)) ||
-                                       (this_face_index
-                                        == cell->neighbor(i)->face(nb_indices.first)->child_index(1)))
-                                     {
-                                                                        // this
-                                                                        // might
-                                                                        // be an
-                                                                        // anisotropic
-                                                                        // child. get
-                                                                        // the
-                                                                        // face
-                                                                        // refine
-                                                                        // case
-                                                                        // of the
-                                                                        // neighbors
-                                                                        // face
-                                                                        // and
-                                                                        // count
-                                                                        // refinements
-                                                                        // in x
-                                                                        // and y
-                                                                        // direction.
-                                       RefinementCase<dim-1> frc=cell->neighbor(i)->face(nb_indices.first)->refinement_case();
-                                       if (frc & RefinementCase<dim>::cut_x)
-                                         ++refined_along_x;
-                                       if (frc & RefinementCase<dim>::cut_y)
-                                         ++refined_along_y;
-                                     }
-                                   else
-                                                                      // this has
-                                                                      // to be an
-                                                                      // isotropic
-                                                                      // child
-                                     {
-                                       ++refined_along_x;
-                                       ++refined_along_y;
-                                     }
-// step 2: detect, along which axis the face has to be refined given the current
-// refine flag
-                                   RefinementCase<dim-1> flagged_frc=
-                                     GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
-                                                                             i,
-                                                                             cell->face_orientation(i),
-                                                                             cell->face_flip(i),
-                                                                             cell->face_rotation(i));
-                                   if (flagged_frc & RefinementCase<dim>::cut_x)
-                                     ++to_be_refined_along_x;
-                                   if (flagged_frc & RefinementCase<dim>::cut_y)
-                                     ++to_be_refined_along_y;
-                                 
-// step 3: set the refine flag of the (coarser and active) neighbor. 
-                                   if ((smooth_grid & allow_anisotropic_smoothing) ||
-                                       cell->neighbor(i)->refine_flag_set())
-                                     {
-                                       if (refined_along_x + to_be_refined_along_x > 1)
-                                         changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
-                                                                                                RefinementCase<dim-1>::cut_axis(0));
-                                       if (refined_along_y + to_be_refined_along_y > 1)
-                                         changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
-                                                                                                RefinementCase<dim-1>::cut_axis(1));
-                                     }
-                                   else
-                                     {
-                                       if (cell->neighbor(i)->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
-                                         changed=true;
-                                       cell->neighbor(i)->set_refine_flag();
-                                     }
-                                 
-// step 4: if necessary (see above) add to the refine flag of the current cell
-                                   cell_iterator nb=cell->neighbor(i);
-                                   RefinementCase<dim-1> nb_frc
-                                     = GeometryInfo<dim>::face_refinement_case(nb->refine_flag_set(),
-                                                                               nb_indices.first,
-                                                                               nb->face_orientation(nb_indices.first),
-                                                                               nb->face_flip(nb_indices.first),
-                                                                               nb->face_rotation(nb_indices.first));
-                                   if ((nb_frc & RefinementCase<dim>::cut_x) &&
-                                       !(refined_along_x || to_be_refined_along_x))
-                                     changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(0));
-                                   if ((nb_frc & RefinementCase<dim>::cut_y) &&
-                                       !(refined_along_y || to_be_refined_along_y))
-                                     changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(1));
-                                 }
-                             }// if neighbor is coarser
-                           else // -> now the neighbor is not coarser
-                             {
-                               cell->neighbor(i)->clear_coarsen_flag();
-                               const unsigned int nb_nb=cell->neighbor_of_neighbor(i);
-                               const cell_iterator neighbor=cell->neighbor(i);
-                               RefinementCase<dim-1> face_ref_case=
-                                 GeometryInfo<dim>::face_refinement_case(neighbor->refine_flag_set(),
-                                                                         nb_nb,
-                                                                         neighbor->face_orientation(nb_nb),
-                                                                         neighbor->face_flip(nb_nb),
-                                                                         neighbor->face_rotation(nb_nb));
-                               RefinementCase<dim-1> needed_face_ref_case
-                                 =GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
-                                                                          i,
-                                                                          cell->face_orientation(i),
-                                                                          cell->face_flip(i),
-                                                                          cell->face_rotation(i));
-                                                                // if the
-                                                                // neighbor wants
-                                                                // to refine the
-                                                                // face with
-                                                                // cut_x and we
-                                                                // want cut_y or
-                                                                // vice versa, we
-                                                                // have to refine
-                                                                // isotropically
-                                                                // at the given
-                                                                // face
-                               if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
-                                   (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
-                                 {
-                                   changed=cell->flag_for_face_refinement(i, face_ref_case);
-                                   neighbor->flag_for_face_refinement(nb_nb, needed_face_ref_case);
-                                 }
-                             }
-                         }
-                       else //-> the neighbor is not active
-                         {
-                           RefinementCase<dim-1> face_ref_case = cell->face(i)->refinement_case(),
-                                          needed_face_ref_case = GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
-                                                                                                         i,
-                                                                                                         cell->face_orientation(i),
-                                                                                                         cell->face_flip(i),
-                                                                                                         cell->face_rotation(i));
-                                                            // if the face is
-                                                            // refined with cut_x
-                                                            // and we want cut_y
-                                                            // or vice versa, we
-                                                            // have to refine
-                                                            // isotropically at
-                                                            // the given face
-                           if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
-                               (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
-                             changed=cell->flag_for_face_refinement(i, face_ref_case);
-                         }
-                     }
-                 }
-             }
-       }
-                                      //////////////////////////////////////
-                                      // STEP 7:
-                                      //    take care that no double refinement
-                                      //    is done at each line in 3d or higher
-                                      //    dimensions.
-      prepare_refinement_dim_dependent ();
-      
-                                      //////////////////////////////////////
-                                      // STEP 8:
-                                      //    make sure that all children of each
-                                      //    cell are either flagged for coarsening
-                                      //    or none of the children is
-      fix_coarsen_flags ();
-                                      // get the refinement and coarsening
-                                      // flags
-      std::vector<bool> flags_after_loop[2];
-      save_coarsen_flags (flags_after_loop[0]);
-      save_refine_flags (flags_after_loop[1]);
-
-                                      // find out whether something was
-                                      // changed in this loop
-      mesh_changed_in_this_loop
-       = ((flags_before_loop[0] != flags_after_loop[0]) ||
-          (flags_before_loop[1] != flags_after_loop[1]));
-
-                                      // set the flags for the next loop
-                                      // already
-      flags_before_loop[0].swap(flags_after_loop[0]);
-      flags_before_loop[1].swap(flags_after_loop[1]);
-    }
-  while (mesh_changed_in_this_loop);
-
-  
-                                  // find out whether something was really
-                                  // changed in this function. Note that
-                                  // @p{flags_before_loop} represents the
-                                  // state after the last loop, i.e.
-                                  // the present state
-  return ((flags_before[0] != flags_before_loop[0]) ||
-         (flags_before[1] != flags_before_loop[1]));
-}
-
-
-
-#if deal_II_dimension == 3
-
-template <>
-void Triangulation<3>::count_cells_at_line (std::vector<unsigned int> &line_cell_count)
-{
-  line_cell_count.clear();
-  line_cell_count.resize(n_raw_lines(),0);
-  cell_iterator cell=begin(),
-               endc=end();
-  for (; cell!=endc; ++cell)
-    for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
-      ++line_cell_count[cell->line_index(l)];
-}
-
-#else
-
-template <int dim>
-void Triangulation<dim>::count_cells_at_line (std::vector<unsigned int> &line_cell_count)
-{
-  Assert(false, ExcNotImplemented());
-  line_cell_count.clear();
-}
-
-#endif
-
-
-
-#if deal_II_dimension == 3
-
-template <>
-void Triangulation<3>::count_cells_at_quad (std::vector<unsigned int> &quad_cell_count)
-{
-  quad_cell_count.clear();
-  quad_cell_count.resize(n_raw_quads(),0);
-  cell_iterator cell=begin(),
-               endc=end();
-  for (; cell!=endc; ++cell)
-    for (unsigned int q=0; q<GeometryInfo<3>::faces_per_cell; ++q)
-      ++quad_cell_count[cell->quad_index(q)];
-}
-
-#else
-
-template <int dim>
-void Triangulation<dim>::count_cells_at_quad (std::vector<unsigned int> &quad_cell_count)
-{
-  Assert(false, ExcNotImplemented());
-  quad_cell_count.clear();
-}
-
-#endif
-
-
-
-#if deal_II_dimension == 1
-
-template <>
-void Triangulation<1>::delete_children (cell_iterator &cell,
-                                       std::vector<unsigned int> &,
-                                       std::vector<unsigned int> &)
-{
-                                  // first we need to reset the
-                                  // neighbor pointers of the
-                                  // neighbors of this cell's
-                                  // children to this cell. This is
-                                  // different for one dimension,
-                                  // since there neighbors can have a
-                                  // refinement level differing from
-                                  // that of this cell's children by
-                                  // more than one level.
-
-  Assert (!cell->child(0)->has_children() && !cell->child(1)->has_children(),
-         ExcInternalError());
-  
-                                  // first do it for the cells to the
-                                  // left
-  if (cell->neighbor(0).state() == IteratorState::valid)
-    if (cell->neighbor(0)->has_children())
-      {
-       cell_iterator neighbor = cell->neighbor(0);
-       Assert (neighbor->level() == cell->level(), ExcInternalError());
-       
-                                        // right child
-       neighbor = neighbor->child(1);
-       while (1)
-         {
-           Assert (neighbor->neighbor(1) == cell->child(0),
-                   ExcInternalError());
-           neighbor->set_neighbor (1, cell);
-           
-                                            // move on to further
-                                            // children on the
-                                            // boundary between this
-                                            // cell and its neighbor
-           if (neighbor->has_children())
-             neighbor = neighbor->child(1);
-           else
-             break;
-         }
-      }
-
-                                  // now do it for the cells to the
-                                  // left
-  if (cell->neighbor(1).state() == IteratorState::valid)
-    if (cell->neighbor(1)->has_children())
-      {
-       cell_iterator neighbor = cell->neighbor(1);
-       Assert (neighbor->level() == cell->level(), ExcInternalError());
-       
-                                        // left child
-       neighbor = neighbor->child(0);
-       while (1)
-         {
-           Assert (neighbor->neighbor(0) == cell->child(1),
-                   ExcInternalError());
-           neighbor->set_neighbor (0, cell);
-           
-                                            // move on to further
-                                            // children on the
-                                            // boundary between this
-                                            // cell and its neighbor
-           if (neighbor->has_children())
-             neighbor = neighbor->child(0);
-           else
-             break;
-         }
-      }
-
-
-                                  // delete the vertex which will not
-                                  // be needed anymore. This vertex
-                                  // is the second of the first child
-  vertices_used[cell->child(0)->vertex_index(1)] = false;
-
-                                  // invalidate children.  clear user
-                                  // pointers, to avoid that they may
-                                  // appear at unwanted places later
-                                  // on...
-  for (unsigned int child=0; child<cell->n_children(); ++child)
-    {
-      cell->child(child)->clear_user_data();
-      cell->child(child)->clear_user_flag();
-      cell->child(child)->clear_used_flag();
-    }
-
-
-                                  // delete pointer to children
-  cell->clear_children ();
-  cell->clear_user_flag();
-}
-
-#endif
-
-
-#if deal_II_dimension == 2
-
-template <>
-void Triangulation<2>::delete_children (cell_iterator &cell,
-                                       std::vector<unsigned int> &,
-                                       std::vector<unsigned int> &)
-{
-  const unsigned int dim=2;
-  const RefinementCase<dim> ref_case=cell->refinement_case();
-
-  for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
-    if (!cell->at_boundary(face_no))
-      {
-       if (GeometryInfo<dim>::face_refinement_case(ref_case, face_no)
-           ==RefinementCase<1>::no_refinement)
-         cell->set_neighbor(face_no,cell->child(face_no%2)->neighbor(face_no));
-       
-       cell_iterator neighbor=cell->neighbor(face_no);
-       
-                                        // it is possible that the neighbor is
-                                        // coarser if it has already been
-                                        // coarsened earlier in this cycle. for
-                                        // anisotropic refinement that can
-                                        // happen, even if the neighbor is on a
-                                        // higher level.
-       
-                                        // it is also possible, that the
-                                        // neighbor information of cell was not
-                                        // the best information currently
-                                        // available. however, the neighbor
-                                        // information now set should be
-                                        // accurate, as we have taken the
-                                        // pointer from one of our children, if
-                                        // that could be mor accurate and these
-                                        // children can't be further refined.
-       
-                                        // if the neighbor is coarser, do
-                                        // nothing: we won't have to reset our
-                                        // pointer of course and the coarser
-                                        // neighbor does not point to this cell
-       if (cell->neighbor_is_coarser(face_no))
-         {
-           Assert(neighbor->active(),
-                  ExcInternalError());
-           continue;
-         }
-       
-       const unsigned int nb_nb=cell->neighbor_of_neighbor(face_no);
-       neighbor->set_neighbor(nb_nb, cell);
-                                        // go down the list of children which
-                                        // are not refined along the face (if
-                                        // any)
-       while (neighbor->has_children() &&
-              (GeometryInfo<dim>::face_refinement_case(neighbor->refinement_case(), nb_nb)
-               ==RefinementCase<dim-1>::no_refinement))
-         {
-           neighbor=neighbor->child(GeometryInfo<dim>
-                                    ::child_cell_on_face(neighbor->refinement_case(),
-                                                         nb_nb,
-                                                         0));
-           neighbor->set_neighbor(nb_nb, cell);
-         }
-               
-                                        // now we can safely set the cells
-                                        // neighbor
-       cell->set_neighbor(face_no,neighbor);
-                          
-                                        // if there are still children, they
-                                        // have to be refined along the face
-                                        // currently under consideration
-       if (neighbor->has_children())
-             {
-               unsigned int n_subfaces=GeometryInfo<dim-1>::n_children(
-                 GeometryInfo<dim>::face_refinement_case(neighbor->refinement_case(), nb_nb));
-               Assert (n_subfaces>0, ExcInternalError());
-               
-               for (unsigned int i=0; i<n_subfaces; ++i)
-                 {
-                   cell_iterator neighbor_child=neighbor->child(
-                     GeometryInfo<dim>::child_cell_on_face(neighbor->refinement_case(),
-                                                           nb_nb, i));
-                   neighbor_child->set_neighbor(nb_nb, cell);
-                                                    // once again, this
-                                                    // neighbor_child can be
-                                                    // refined several times,
-                                                    // as long as this
-                                                    // refinement is not along
-                                                    // the current subface. if
-                                                    // there are children
-                                                    // refined along the
-                                                    // subface they will be
-                                                    // coarsened away later in
-                                                    // this process, so we
-                                                    // don't care about them
-                                                    // here
-                   while (neighbor_child->has_children() &&
-                          (GeometryInfo<dim>::face_refinement_case(neighbor_child->refinement_case(),
-                                                                   nb_nb)
-                           == RefinementCase<dim-1>::no_refinement))
-                     {
-                       neighbor_child=neighbor_child
-                                      ->child(GeometryInfo<dim>
-                                              ::child_cell_on_face(neighbor_child->refinement_case(),
-                                                                   nb_nb,
-                                                                   0));
-                       neighbor_child->set_neighbor(nb_nb, cell);
-                     }
-                 }
-             }
-      }
-                                  // delete the vertex which will not
-                                  // be needed anymore. This vertex
-                                  // is the second of the second line
-                                  // of the first child, if the cell
-                                  // is refined with cut_xy, else there
-                                  // is no inner vertex.
-                                  // additionally delete unneeded inner
-                                  // lines
-  if (ref_case==RefinementCase<dim>::cut_xy)
-    {
-      vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
-      
-                                      // clear user pointers, to
-                                      // avoid that they may appear
-                                      // at unwanted places later
-                                      // on...
-      cell->child(0)->line(1)->clear_user_data();
-      cell->child(0)->line(3)->clear_user_data();
-      cell->child(3)->line(0)->clear_user_data();
-      cell->child(3)->line(2)->clear_user_data();
-      
-                                      // same for user flags
-      cell->child(0)->line(1)->clear_user_flag();
-      cell->child(0)->line(3)->clear_user_flag();
-      cell->child(3)->line(0)->clear_user_flag();
-      cell->child(3)->line(2)->clear_user_flag();
-      
-                                      // delete the four interior
-                                      // lines
-      cell->child(0)->line(1)->clear_used_flag();
-      cell->child(0)->line(3)->clear_used_flag();
-      cell->child(3)->line(0)->clear_used_flag();
-      cell->child(3)->line(2)->clear_used_flag();
-    }
-  else
-    {
-      unsigned int inner_face_no=ref_case==RefinementCase<dim>::cut_x ? 1 : 3;
-                                
-                                      // the inner line will not be
-                                      // used any more
-      cell->child(0)->line(inner_face_no)->clear_user_data();
-      cell->child(0)->line(inner_face_no)->clear_user_flag();
-      cell->child(0)->line(inner_face_no)->clear_used_flag();
-    }
-                                  
-                                  // if the neighbor does not need
-                                  // the subfaces, delete them.  in case of
-                                  // anisotropic refinement we can't just
-                                  // ask the neighbor's level here to
-                                  // assure, that he is not refined along
-                                  // the face
-  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face) 
-    if (((cell->neighbor(face).state() != IteratorState::valid) ||
-        (!cell->neighbor(face)->has_children())) &&
-       (GeometryInfo<dim>::face_refinement_case(ref_case,face)
-        !=RefinementCase<dim-1>::no_refinement))
-      {
-       line_iterator line=cell->face(face);
-                                        // delete middle vertex
-       vertices_used[line->child(0)->vertex_index(1)] = false;
-                                        // delete the two subfaces
-       for (unsigned int subface=0;
-            subface<line->n_children(); ++subface)
-         {
-           line->child(subface)->clear_user_data ();
-           line->child(subface)->clear_user_flag ();
-           line->child(subface)->clear_used_flag ();
-         }
-       
-       line->clear_children();
-      }
-                                  // invalidate children
-  for (unsigned int child=0; child<cell->n_children(); ++child)
-    {
-      cell->child(child)->clear_user_data();
-      cell->child(child)->clear_user_flag();
-      cell->child(child)->clear_used_flag();
-    }
-
-
-                                  // delete pointer to children
-  cell->clear_children ();
-  cell->clear_refinement_case();
-  cell->clear_user_flag();
-}
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-
-template <>
-void Triangulation<3>::delete_children (cell_iterator &cell,
-                                       std::vector<unsigned int> &line_cell_count,
-                                       std::vector<unsigned int> &quad_cell_count)
-{
-  const unsigned int dim=3;
-  Assert(line_cell_count.size()==n_raw_lines(), ExcInternalError());
-  Assert(quad_cell_count.size()==n_raw_quads(), ExcInternalError());
-
-                                  // first of all, we store the RefineCase of
-                                  // this cell
-  const RefinementCase<dim> ref_case=cell->refinement_case();
-                                  // vectors to hold all lines and quads which
-                                  // may be deleted
-  std::vector<line_iterator> lines_to_delete(0);
-  std::vector<quad_iterator> quads_to_delete(0);
-  lines_to_delete.reserve(12*2+6*4+6);
-  quads_to_delete.reserve(6*4+12);
-  
-                                  // now we decrease the counters for lines and
-                                  // quads contained in the child cells
-  for (unsigned int c=0; c<cell->n_children(); ++c)
-    {
-      cell_iterator child=cell->child(c);
-      for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
-       --line_cell_count[child->line_index(l)];
-      for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-       --quad_cell_count[child->quad_index(f)];
-    }
-  
-                                  // first we need to reset the neighbor
-                                  // pointers of the neighbors from this cell's
-                                  // children to this cell. This is done by a
-                                  // seperate function.
-  update_neighbors(cell, false);
-
-                                  ///////////////////////////////////////
-                                  // delete interior quads and lines and the
-                                  // interior vertex, depending on the
-                                  // refinement case of the cell
-                                  //
-                                  // for append quads and lines: only append
-                                  // them to the list of objects to be deleted
-  
-  switch (ref_case)
-    {
-      case RefinementCase<dim>::cut_x:
-           quads_to_delete.push_back(cell->child(0)->face(1));
-           break;
-      case RefinementCase<dim>::cut_y:
-           quads_to_delete.push_back(cell->child(0)->face(3));
-           break;
-      case RefinementCase<dim>::cut_z:
-           quads_to_delete.push_back(cell->child(0)->face(5));
-           break;
-      case RefinementCase<dim>::cut_xy:
-           quads_to_delete.push_back(cell->child(0)->face(1));
-           quads_to_delete.push_back(cell->child(0)->face(3));
-           quads_to_delete.push_back(cell->child(3)->face(0));
-           quads_to_delete.push_back(cell->child(3)->face(2));
-
-           lines_to_delete.push_back(cell->child(0)->line(11));
-           break;
-      case RefinementCase<dim>::cut_xz:
-           quads_to_delete.push_back(cell->child(0)->face(1));
-           quads_to_delete.push_back(cell->child(0)->face(5));
-           quads_to_delete.push_back(cell->child(3)->face(0));
-           quads_to_delete.push_back(cell->child(3)->face(4));
-
-           lines_to_delete.push_back(cell->child(0)->line(5));
-           break;
-      case RefinementCase<dim>::cut_yz:
-           quads_to_delete.push_back(cell->child(0)->face(3));
-           quads_to_delete.push_back(cell->child(0)->face(5));
-           quads_to_delete.push_back(cell->child(3)->face(2));
-           quads_to_delete.push_back(cell->child(3)->face(4));
-
-           lines_to_delete.push_back(cell->child(0)->line(7));
-           break;
-      case RefinementCase<dim>::cut_xyz:
-           quads_to_delete.push_back(cell->child(0)->face(1));
-           quads_to_delete.push_back(cell->child(2)->face(1));
-           quads_to_delete.push_back(cell->child(4)->face(1));
-           quads_to_delete.push_back(cell->child(6)->face(1));
-           
-           quads_to_delete.push_back(cell->child(0)->face(3));
-           quads_to_delete.push_back(cell->child(1)->face(3));
-           quads_to_delete.push_back(cell->child(4)->face(3));
-           quads_to_delete.push_back(cell->child(5)->face(3));
-           
-           quads_to_delete.push_back(cell->child(0)->face(5));
-           quads_to_delete.push_back(cell->child(1)->face(5));
-           quads_to_delete.push_back(cell->child(2)->face(5));
-           quads_to_delete.push_back(cell->child(3)->face(5)); 
-           
-           lines_to_delete.push_back(cell->child(0)->line(5));
-           lines_to_delete.push_back(cell->child(0)->line(7));
-           lines_to_delete.push_back(cell->child(0)->line(11));
-           lines_to_delete.push_back(cell->child(7)->line(0));
-           lines_to_delete.push_back(cell->child(7)->line(2));
-           lines_to_delete.push_back(cell->child(7)->line(8));
-                                            // delete the vertex which will not
-                                            // be needed anymore. This vertex
-                                            // is the vertex at the heart of
-                                            // this cell, which is the sixth of
-                                            // the first child
-           vertices_used[cell->child(0)->vertex_index(7)] = false;
-           break;
-      default:
-                                            // only remaining case is
-                                            // no_refinement, thus an error
-           Assert(false, ExcInternalError());
-           break;
-    }
-  
-
-                                  // invalidate children
-  for (unsigned int child=0; child<cell->n_children(); ++child)
-    {
-      cell->child(child)->clear_user_data();
-      cell->child(child)->clear_user_flag();
-
-      for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-       {
-                                          // set flags denoting deviations from
-                                          // standard orientation of faces back
-                                          // to initialization values
-         cell->child(child)->set_face_orientation (f, true);
-         cell->child(child)->set_face_flip(f,false);
-         cell->child(child)->set_face_rotation(f,false);
-       }
-      
-      cell->child(child)->clear_used_flag();
-    }
-
-
-                                  // delete pointer to children
-  cell->clear_children ();
-  cell->clear_refinement_case ();
-  cell->clear_user_flag();
-
-                                  // so far we only looked at inner quads,
-                                  // lines and vertices. Now we have to
-                                  // consider outer ones as well. here, we have
-                                  // to check, whether there are other cells
-                                  // still needing these objects. oherwise we
-                                  // can delete them. first for quads (and
-                                  // their inner lines).
-  
-  for (unsigned int quad_no=0; quad_no<GeometryInfo<dim>::faces_per_cell; ++quad_no)
-    {
-      quad_iterator quad=cell->face(quad_no);
-
-      Assert((GeometryInfo<dim>::face_refinement_case(ref_case,quad_no) && quad->has_children()) ||
-            GeometryInfo<dim>::face_refinement_case(ref_case,quad_no)==RefinementCase<dim-1>::no_refinement,
-            ExcInternalError());
-
-      switch (quad->refinement_case())
-       {
-         case RefinementCase<dim-1>::no_refinement:
-                                                // nothing to do as the quad
-                                                // is not refined
-               break;
-         case RefinementCase<dim-1>::cut_x:
-         case RefinementCase<dim-1>::cut_y:
-         {
-                                            // if one of the cell counters is
-                                            // zero, the other has to be as
-                                            // well
-           Assert((quad_cell_count[quad->child_index(0)] == 0 &&
-                   quad_cell_count[quad->child_index(1)] == 0) ||
-                  (quad_cell_count[quad->child_index(0)] > 0 &&
-                   quad_cell_count[quad->child_index(1)] > 0),
-                  ExcInternalError());
-                                            // it might be, that the quad is
-                                            // refined twice anisotropically,
-                                            // first check, whether we may
-                                            // delete possible grand_children
-           unsigned int deleted_grandchildren=0;
-           unsigned int number_of_child_refinements=0;
-           
-           for (unsigned int c=0; c<2; ++c)
-             if (quad->child(c)->has_children())
-               {
-                 ++number_of_child_refinements;
-                                                  // if one of the cell counters is
-                                                  // zero, the other has to be as
-                                                  // well
-                 Assert((quad_cell_count[quad->child(c)->child_index(0)] == 0 &&
-                         quad_cell_count[quad->child(c)->child_index(1)] == 0) ||
-                        (quad_cell_count[quad->child(c)->child_index(0)] > 0 &&
-                         quad_cell_count[quad->child(c)->child_index(1)] > 0),
-                        ExcInternalError());
-                 if (quad_cell_count[quad->child(c)->child_index(0)]==0)
-                   {
-                                                      // Assert, that the two
-                                                      // anisotropic
-                                                      // refinements add up to
-                                                      // isotropic refinement
-                     Assert(quad->refinement_case()+quad->child(c)->refinement_case()==RefinementCase<dim>::cut_xy,
-                            ExcInternalError());
-                                                      // we may delete the
-                                                      // quad's children and
-                                                      // the inner line as no
-                                                      // cell references them
-                                                      // anymore
-                     quads_to_delete.push_back(quad->child(c)->child(0));
-                     quads_to_delete.push_back(quad->child(c)->child(1));
-                     if (quad->child(c)->refinement_case()==RefinementCase<2>::cut_x)
-                       lines_to_delete.push_back(quad->child(c)->child(0)->line(1));
-                     else
-                       lines_to_delete.push_back(quad->child(c)->child(0)->line(3));
-                     quad->child(c)->clear_children();
-                     quad->child(c)->clear_refinement_case();
-                     ++deleted_grandchildren;
-                   }
-               }
-                                            // if no grandchildren are left, we
-                                            // may as well delete the
-                                            // refinement of the inner line
-                                            // between our children and the
-                                            // corresponding vertex
-           if (number_of_child_refinements>0 &&
-               deleted_grandchildren==number_of_child_refinements)
-             {
-               line_iterator middle_line;
-               if (quad->refinement_case()==RefinementCase<2>::cut_x)
-                 middle_line=quad->child(0)->line(1);
-               else
-                 middle_line=quad->child(0)->line(3);
-
-               lines_to_delete.push_back(middle_line->child(0));
-               lines_to_delete.push_back(middle_line->child(1));
-               vertices_used[middle_line->middle_vertex_index()]=false;
-               middle_line->clear_children();
-             }
-
-                                            // now consider the direct children
-                                            // of the given quad
-           if (quad_cell_count[quad->child_index(0)]==0)
-             {
-                                                // we may delete the quad's
-                                                // children and the inner line
-                                                // as no cell references them
-                                                // anymore
-               quads_to_delete.push_back(quad->child(0));
-               quads_to_delete.push_back(quad->child(1));
-               if (quad->refinement_case()==RefinementCase<2>::cut_x)
-                 lines_to_delete.push_back(quad->child(0)->line(1));
-               else
-                 lines_to_delete.push_back(quad->child(0)->line(3));
-
-                                                // if the counters just dropped
-                                                // to zero, otherwise the
-                                                // children would have been
-                                                // deleted earlier, then this
-                                                // cell's children must have
-                                                // contained the anisotropic
-                                                // quad children. thus, if
-                                                // those have again anisotropic
-                                                // children, which are in
-                                                // effect isotropic children of
-                                                // the original quad, those are
-                                                // still needed by a
-                                                // neighboring cell and we
-                                                // cannot delete them. instead,
-                                                // we have to reset this quad's
-                                                // refine case to isotropic and
-                                                // set the children
-                                                // accordingly.
-               if (quad->child(0)->has_children())
-                 if (quad->refinement_case()==RefinementCase<2>::cut_x)
-                   {
-                                                      // now evereything is
-                                                      // quite complicated. we
-                                                      // have the children
-                                                      // numbered according to
-                                                      //
-                                                      // *---*---*
-                                                      // |n+1|m+1|
-                                                      // *---*---*
-                                                      // | n | m |
-                                                      // *---*---*
-                                                      //
-                                                      // from the original
-                                                      // anisotropic
-                                                      // refinement. we have to
-                                                      // reorder them as
-                                                      //
-                                                      // *---*---*
-                                                      // | m |m+1|
-                                                      // *---*---*
-                                                      // | n |n+1|
-                                                      // *---*---*
-                                                      //
-                                                      // for isotropic refinement.
-                                                      //
-                                                      // this is a bit ugly, of
-                                                      // course: loop over all
-                                                      // cells on all levels
-                                                      // and look for faces n+1
-                                                      // (switch_1) and m
-                                                      // (switch_2).
-                     const quad_iterator switch_1=quad->child(0)->child(1);
-                     const quad_iterator switch_2=quad->child(1)->child(0);
-
-                     Assert(!switch_1->has_children(), ExcInternalError());
-                     Assert(!switch_2->has_children(), ExcInternalError());
-                     
-                     const int switch_1_index=switch_1->index();
-                     const int switch_2_index=switch_2->index();
-                     for (unsigned int l=0; l<levels.size(); ++l)
-                       for (unsigned int h=0; h<levels[l]->cells.cells.size(); ++h)
-                         for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
-                           {
-                             const int index=levels[l]->cells.cells[h].face(q);
-                             if (index==switch_1_index)
-                               levels[l]->cells.cells[h].set_face(q,switch_2_index);
-                             else if (index==switch_2_index)
-                               levels[l]->cells.cells[h].set_face(q,switch_1_index);
-                           }
-                                                      // now we have to copy
-                                                      // all information of the
-                                                      // two quads
-                     const int switch_1_lines[4]=
-                       {switch_1->line_index(0),
-                        switch_1->line_index(1),
-                        switch_1->line_index(2),
-                        switch_1->line_index(3)};
-                     const bool switch_1_line_orientations[4]=
-                       {switch_1->line_orientation(0),
-                        switch_1->line_orientation(1),
-                        switch_1->line_orientation(2),
-                        switch_1->line_orientation(3)};
-                     const unsigned char switch_1_boundary_indicator=switch_1->boundary_indicator();
-                     const unsigned int switch_1_user_index=switch_1->user_index();
-                     const bool switch_1_user_flag=switch_1->user_flag_set();
-
-                     switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
-                                                                          switch_2->line_index(1),
-                                                                          switch_2->line_index(2),
-                                                                          switch_2->line_index(3)));
-                     switch_1->set_line_orientation(0, switch_2->line_orientation(0));
-                     switch_1->set_line_orientation(1, switch_2->line_orientation(1));
-                     switch_1->set_line_orientation(2, switch_2->line_orientation(2));
-                     switch_1->set_line_orientation(3, switch_2->line_orientation(3));
-                     switch_1->set_boundary_indicator(switch_2->boundary_indicator());
-                     switch_1->set_user_index(switch_2->user_index());
-                     if (switch_2->user_flag_set())
-                       switch_1->set_user_flag();
-                     else
-                       switch_1->clear_user_flag();
-
-                     switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
-                                                                          switch_1_lines[1],
-                                                                          switch_1_lines[2],
-                                                                          switch_1_lines[3]));
-                     switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
-                     switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
-                     switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
-                     switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
-                     switch_2->set_boundary_indicator(switch_1_boundary_indicator);
-                     switch_2->set_user_index(switch_1_user_index);
-                     if (switch_1_user_flag)
-                       switch_2->set_user_flag();
-                     else
-                       switch_2->clear_user_flag();
-
-                     const unsigned int child_0=quad->child(0)->child_index(0);
-                     const unsigned int child_2=quad->child(1)->child_index(0);
-                     quad->clear_children();
-                     quad->clear_refinement_case();
-                     quad->set_refinement_case(RefinementCase<2>::cut_xy);
-                     quad->set_children(0,child_0);
-                     quad->set_children(2,child_2);
-                     std::swap(quad_cell_count[child_0+1],quad_cell_count[child_2]);
-                   }
-                 else
-                   {
-                                                      // the face was refined
-                                                      // with cut_y, thus the
-                                                      // children are already
-                                                      // in correct order. we
-                                                      // only have to set them
-                                                      // correctly, deleting
-                                                      // the indirection of two
-                                                      // anisotropic refinement
-                                                      // and going directly
-                                                      // from the quad to
-                                                      // isotropic children
-                     const unsigned int child_0=quad->child(0)->child_index(0);
-                     const unsigned int child_2=quad->child(1)->child_index(0);
-                     quad->clear_children();
-                     quad->clear_refinement_case();
-                     quad->set_refinement_case(RefinementCase<2>::cut_xy);
-                     quad->set_children(0,child_0);
-                     quad->set_children(2,child_2);                 
-                   }
-               else
-                 {
-                   quad->clear_children();
-                   quad->clear_refinement_case();
-                 }
-               
-               
-             }
-           break;
-         }
-         case RefinementCase<dim-1>::cut_xy:
-         {
-                                            // if one of the cell counters is
-                                            // zero, the others have to be as
-                                            // well
-
-           Assert((quad_cell_count[quad->child_index(0)] == 0 &&
-                   quad_cell_count[quad->child_index(1)] == 0 &&
-                   quad_cell_count[quad->child_index(2)] == 0 &&
-                   quad_cell_count[quad->child_index(3)] == 0) ||
-                  (quad_cell_count[quad->child_index(0)] > 0 &&
-                   quad_cell_count[quad->child_index(1)] > 0 &&
-                   quad_cell_count[quad->child_index(2)] > 0 &&
-                   quad_cell_count[quad->child_index(3)] > 0),
-                  ExcInternalError());
-      
-           if (quad_cell_count[quad->child_index(0)]==0)
-             {
-                                                // we may delete the quad's
-                                                // children, the inner lines
-                                                // and the middle vertex as no
-                                                // cell references them anymore
-               lines_to_delete.push_back(quad->child(0)->line(1));
-               lines_to_delete.push_back(quad->child(3)->line(0));
-               lines_to_delete.push_back(quad->child(0)->line(3));
-               lines_to_delete.push_back(quad->child(3)->line(2));
-
-               for (unsigned int child=0; child<quad->n_children(); ++child)
-                 quads_to_delete.push_back(quad->child(child));
-               
-               vertices_used[quad->child(0)->vertex_index(3)] = false;
-               
-               quad->clear_children();
-               quad->clear_refinement_case();
-             }
-         }
-         break;
-
-         default:
-               Assert(false, ExcInternalError());
-               break;
-       }
-      
-    }
-
-                                  // now we repeat a similar procedure for the
-                                  // outer lines of this cell.
-  
-                                  // if in debug mode: check that each of the
-                                  // lines for which we consider deleting the
-                                  // children in fact has children (the
-                                  // bits/coarsening_3d test tripped over this
-                                  // initially)
-  for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
-    {
-      line_iterator line=cell->line(line_no);
-
-      Assert((GeometryInfo<dim>::line_refinement_case(ref_case,line_no) && line->has_children()) ||
-            GeometryInfo<dim>::line_refinement_case(ref_case,line_no)==RefinementCase<1>::no_refinement,
-            ExcInternalError());
-      
-      if (line->has_children())
-       {
-                                          // if one of the cell counters is
-                                          // zero, the other has to be as well
-
-         Assert((line_cell_count[line->child_index(0)] == 0 &&
-                 line_cell_count[line->child_index(1)] == 0) ||
-                (line_cell_count[line->child_index(0)] > 0 &&
-                 line_cell_count[line->child_index(1)] > 0),
-                ExcInternalError());
-      
-         if (line_cell_count[line->child_index(0)]==0)
-           {
-             for (unsigned int c=0; c<2; ++c)
-               Assert (!line->child(c)->has_children(),
-                       ExcInternalError());
-             
-                                              // we may delete the line's
-                                              // children and the middle vertex
-                                              // as no cell references them
-                                              // anymore
-             vertices_used[line->child(0)->vertex_index(1)] = false;
-             
-             lines_to_delete.push_back(line->child(0));
-             lines_to_delete.push_back(line->child(1));
-             
-             line->clear_children();
-           }
-       }
-    }
-
-                                  // finally, delete unneeded quads and lines
-  
-                                  // clear user pointers, to avoid that
-                                  // they may appear at unwanted places
-                                  // later on...
-                                  // same for user flags, then finally
-                                  // delete the quads and lines
-  std::vector<line_iterator>::iterator line=lines_to_delete.begin(),
-                                   endline=lines_to_delete.end();
-  for (; line!=endline; ++line)
-    {
-      (*line)->clear_user_data();
-      (*line)->clear_user_flag();
-      (*line)->clear_used_flag();
-    }
-
-  std::vector<quad_iterator>::iterator quad=quads_to_delete.begin(),
-                                   endquad=quads_to_delete.end();
-  for (; quad!=endquad; ++quad)
-    {
-      (*quad)->clear_user_data();
-      (*quad)->clear_children();
-      (*quad)->clear_refinement_case();
-      (*quad)->clear_user_flag();
-      (*quad)->clear_used_flag();
-    }
-}
-
-#endif
-
-
-
-#if deal_II_dimension == 2
-template<>
-void Triangulation<2>::create_children (unsigned int &next_unused_vertex,
-                                       raw_line_iterator &next_unused_line,
-                                       raw_quad_iterator &,
-                                       raw_cell_iterator &next_unused_cell,
-                                       cell_iterator &cell)
-{
-  const unsigned int dim=2;
-                                // clear refinement flag
-  const RefinementCase<dim> ref_case=cell->refine_flag_set();
-  cell->clear_refine_flag ();
-
-/* For the refinement process: since we go the levels up from the lowest, there
-   are (unlike above) only two possibilities: a neighbor cell is on the same
-   level or one level up (in both cases, it may or may not be refined later on,
-   but we don't care here).
-   
-   First:
-   Set up an array of the 3x3 vertices, which are distributed on the cell
-   (the array consists of indices into the @p{vertices} std::vector
-   
-   2--7--3
-   |  |  |
-   4--8--5
-   |  |  |
-   0--6--1
-
-   note: in case of cut_x or cut_y not all these vertices are needed for the new
-   cells
-       
-   Second:  
-   Set up an array of the new lines (the array consists of iterator pointers
-   into the lines arrays)
-   
-   .-6-.-7-.         The directions are:  .->-.->-.
-   1   9   3                              ^   ^   ^
-   .-10.11-.                             .->-.->-.
-   0   8   2                              ^   ^   ^
-   .-4-.-5-.                              .->-.->-.
-
-   cut_x:   
-   .-4-.-5-. 
-   |   |   | 
-   0   6   1 
-   |   |   | 
-   .-2-.-3-.
-   
-   cut_y:
-   .---5---. 
-   1       3 
-   .---6---. 
-   0       2 
-   .---4---. 
-
-     
-   Third:
-   Set up an array of neighbors:
-   
-   6  7
-   .--.--.
-   1|  |  |3
-   .--.--.
-   0|  |  |2
-   .--.--.
-   4   5
-
-   We need this array for two reasons: first to get the lines which will
-   bound the four subcells (if the neighboring cell is refined, these
-   lines already exist), and second to update neighborship information.
-   Since if a neighbor is not refined, its neighborship record only
-   points to the present, unrefined, cell rather than the children we
-   are presently creating, we only need the neighborship information
-   if the neighbor cells are refined. In all other cases, we store
-   the unrefined neighbor address
-
-   We also need for every neighbor (if refined) which number among its
-   neighbors the present (unrefined) cell has, since that number is to
-   be replaced and because that also is the number of the subline which
-   will be the interface between that neighbor and the to be created cell.
-   We will store this number (between 0 and 3) in the field
-   @p{neighbors_neighbor}.
-
-   It would be sufficient to use the children of the common line to the
-   neighbor, if we only wanted to get the new sublines and the new vertex,
-   but because we need to update the neighborship information of the
-   two refined subcells of the neighbor, we need to search these anyway.
-
-   Convention:
-   The created children are numbered like this:
-
-   .--.--.
-   |2 . 3|
-   .--.--.
-   |0 | 1|
-   .--.--.
-*/
+                               if (dim==2)
+                                 {
+                                   if (smooth_grid & allow_anisotropic_smoothing)
+                                     changed=cell->neighbor(i)->flag_for_face_refinement(cell->neighbor_of_coarser_neighbor(i).first,
+                                                                                         RefinementCase<dim-1>::cut_x);
+                                   else
+                                     {
+                                       if (!cell->neighbor(i)->refine_flag_set())
+                                         changed=true;
+                                       cell->neighbor(i)->set_refine_flag();
+                                     }
+                                 }
+                               else //i.e. if (dim==3)
+                                 {
+// ugly situations might arise here, consider the following situation, which
+// shows neighboring cells at the common face, where the upper right element is
+// coarser at the given face. Now the upper child element of the lower left
+// wants to refine according to cut_z, such that there is a 'horizontal'
+// refinement of the face marked with #####
+//   
+//                            /               /
+//                           /               /
+//                          *---------------*
+//                          |               |
+//                          |               |
+//                          |               |
+//                          |               |
+//                          |               |
+//                          |               | /
+//                          |               |/
+//                          *---------------*
+//   
+//   
+//     *---------------*
+//    /|              /|
+//   / |     #####   / |
+//     |               |
+//     *---------------*
+//    /|              /|
+//   / |             / |
+//     |               |
+//     *---------------*
+//    /               /
+//   /               /
+//
+// this introduces too many hanging nodes and the neighboring (coarser) cell
+// (upper right) has to be refined. If it is only refined according to cut_z,
+// then everything is ok:
+//   
+//                            /               /
+//                           /               /
+//                          *---------------*
+//                          |               |
+//                          |               | /
+//                          |               |/
+//                          *---------------*
+//                          |               |
+//                          |               | /
+//                          |               |/
+//                          *---------------*
+//   
+//   
+//     *---------------*
+//    /|              /|
+//   / *---------------*
+//    /|              /|
+//     *---------------*
+//    /|              /|
+//   / |             / |
+//     |               |
+//     *---------------*
+//    /               /
+//   /               /
+//
+// if however the cell wants to refine itself in an other way, or if we disallow
+// anisotropic smoothing, then simply refining the neighbor isotropically is not
+// going to work, since this introduces a refinement of face ##### with both
+// cut_x and cut_y, which is not possible:
+//
+//                            /       /       /
+//                           /       /       /
+//                          *-------*-------*
+//                          |       |       |
+//                          |       |       | /
+//                          |       |       |/
+//                          *-------*-------*
+//                          |       |       |
+//                          |       |       | /
+//                          |       |       |/
+//                          *-------*-------*
+//   
+//   
+//     *---------------*
+//    /|              /|
+//   / *---------------*
+//    /|              /|
+//     *---------------*
+//    /|              /|
+//   / |             / |
+//     |               |
+//     *---------------*
+//    /               /
+//   /               /
+//
+// thus, in this case we also need to refine our current cell in the new
+// direction:
+//
+//                            /       /       /
+//                           /       /       /
+//                          *-------*-------*
+//                          |       |       |
+//                          |       |       | /
+//                          |       |       |/
+//                          *-------*-------*
+//                          |       |       |
+//                          |       |       | /
+//                          |       |       |/
+//                          *-------*-------*
+//   
+//   
+//     *-------*-------*
+//    /|      /|      /|
+//   / *-------*-------*
+//    /|      /|      /|
+//     *-------*-------*
+//    /|      /       /|
+//   / |             / |
+//     |               |
+//     *---------------*
+//    /               /
+//   /               /
 
-                                  // collect the indices
-                                  // all vertices
-                                  //   2--7--3
-                                  //   |  |  |
-                                  //   4--8--5
-                                  //   |  |  |
-                                  //   0--6--1
-  int new_vertices[9];
-  for (unsigned int vertex_no=0; vertex_no<4; ++vertex_no)
-    new_vertices[vertex_no]=cell->vertex_index(vertex_no);
-  for (unsigned int line_no=0; line_no<4; ++line_no)
-    if (cell->line(line_no)->has_children())
-      new_vertices[4+line_no]=cell->line(line_no)->child(0)->vertex_index(1);
-           
-  if (ref_case==RefinementCase<dim>::cut_xy)
-    {
-                                      // find the next
-                                      // unused vertex and
-                                      // set it
-                                      // appropriately
-      while (vertices_used[next_unused_vertex] == true)
-       ++next_unused_vertex;
-      Assert (next_unused_vertex < vertices.size(),
-             ExcTooFewVerticesAllocated());
-      vertices_used[next_unused_vertex] = true;
-
-      new_vertices[8]=next_unused_vertex;
-               
-                                      // new vertex is
-                                      // placed at the
-                                      // arithmetic mean of
-                                      // all 8 neighboring
-                                      // points.
-      Point<2> new_point(0,0);
-      for (unsigned int i=0; i<8; ++i)
-       new_point +=  vertices[new_vertices[i]];
-      new_point /= 8.0;
-               
-      vertices[new_vertices[8]] = new_point;
-    
+                                   std::pair<unsigned int, unsigned int> nb_indices
+                                     =cell->neighbor_of_coarser_neighbor(i);
+                                   unsigned int refined_along_x=0,
+                                                refined_along_y=0,
+                                          to_be_refined_along_x=0,
+                                          to_be_refined_along_y=0;
 
-                                      // if the user_flag is set, i.e. if the
-                                      // cell is at the boundary, use a
-                                      // different calculation of the middle
-                                      // vertex here. this is of advantage, if
-                                      // the boundary is strongly curved and
-                                      // the cell has a high aspect ratio. this
-                                      // can happen for example, if it was
-                                      // refined anisotropically before.
-      if (cell->user_flag_set())
-       {
-                                          // first reset the user_flag
-         cell->clear_user_flag();
-                                          // the user flag indicates: at least
-                                          // one face is at the boundary. if it
-                                          // is only one, set the new middle
-                                          // vertex in a different way to avoid
-                                          // some mis-shaped elements if the
-                                          // new point on the boundary is not
-                                          // where we expect it, especially if
-                                          // it is to far inside the current
-                                          // cell
-         unsigned int bound_face=GeometryInfo<dim>::faces_per_cell;
-         for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-           if (cell->face(face)->at_boundary())
-             {
-               if (bound_face == GeometryInfo<dim>::faces_per_cell)
-                                                  // no boundary face found so
-                                                  // far, so set it now
-                 bound_face=face;
-               else
-                                                  // there is another boundary
-                                                  // face, so reset bound_face to
-                                                  // invalid value as a flag to
-                                                  // do nothing in the following
-                 bound_face=GeometryInfo<dim>::faces_per_cell+1;
+                                   const int this_face_index=cell->face_index(i);
+                                 
+// step 1: detect, along which axis the face is currently refined
+                                   if ((this_face_index
+                                        == cell->neighbor(i)->face(nb_indices.first)->child_index(0)) ||
+                                       (this_face_index
+                                        == cell->neighbor(i)->face(nb_indices.first)->child_index(1)))
+                                     {
+                                                                        // this
+                                                                        // might
+                                                                        // be an
+                                                                        // anisotropic
+                                                                        // child. get
+                                                                        // the
+                                                                        // face
+                                                                        // refine
+                                                                        // case
+                                                                        // of the
+                                                                        // neighbors
+                                                                        // face
+                                                                        // and
+                                                                        // count
+                                                                        // refinements
+                                                                        // in x
+                                                                        // and y
+                                                                        // direction.
+                                       RefinementCase<dim-1> frc=cell->neighbor(i)->face(nb_indices.first)->refinement_case();
+                                       if (frc & RefinementCase<dim>::cut_x)
+                                         ++refined_along_x;
+                                       if (frc & RefinementCase<dim>::cut_y)
+                                         ++refined_along_y;
+                                     }
+                                   else
+                                                                      // this has
+                                                                      // to be an
+                                                                      // isotropic
+                                                                      // child
+                                     {
+                                       ++refined_along_x;
+                                       ++refined_along_y;
+                                     }
+// step 2: detect, along which axis the face has to be refined given the current
+// refine flag
+                                   RefinementCase<dim-1> flagged_frc=
+                                     GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
+                                                                             i,
+                                                                             cell->face_orientation(i),
+                                                                             cell->face_flip(i),
+                                                                             cell->face_rotation(i));
+                                   if (flagged_frc & RefinementCase<dim>::cut_x)
+                                     ++to_be_refined_along_x;
+                                   if (flagged_frc & RefinementCase<dim>::cut_y)
+                                     ++to_be_refined_along_y;
+                                 
+// step 3: set the refine flag of the (coarser and active) neighbor. 
+                                   if ((smooth_grid & allow_anisotropic_smoothing) ||
+                                       cell->neighbor(i)->refine_flag_set())
+                                     {
+                                       if (refined_along_x + to_be_refined_along_x > 1)
+                                         changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
+                                                                                                RefinementCase<dim-1>::cut_axis(0));
+                                       if (refined_along_y + to_be_refined_along_y > 1)
+                                         changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
+                                                                                                RefinementCase<dim-1>::cut_axis(1));
+                                     }
+                                   else
+                                     {
+                                       if (cell->neighbor(i)->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
+                                         changed=true;
+                                       cell->neighbor(i)->set_refine_flag();
+                                     }
+                                 
+// step 4: if necessary (see above) add to the refine flag of the current cell
+                                   cell_iterator nb=cell->neighbor(i);
+                                   RefinementCase<dim-1> nb_frc
+                                     = GeometryInfo<dim>::face_refinement_case(nb->refine_flag_set(),
+                                                                               nb_indices.first,
+                                                                               nb->face_orientation(nb_indices.first),
+                                                                               nb->face_flip(nb_indices.first),
+                                                                               nb->face_rotation(nb_indices.first));
+                                   if ((nb_frc & RefinementCase<dim>::cut_x) &&
+                                       !(refined_along_x || to_be_refined_along_x))
+                                     changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(0));
+                                   if ((nb_frc & RefinementCase<dim>::cut_y) &&
+                                       !(refined_along_y || to_be_refined_along_y))
+                                     changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(1));
+                                 }
+                             }// if neighbor is coarser
+                           else // -> now the neighbor is not coarser
+                             {
+                               cell->neighbor(i)->clear_coarsen_flag();
+                               const unsigned int nb_nb=cell->neighbor_of_neighbor(i);
+                               const cell_iterator neighbor=cell->neighbor(i);
+                               RefinementCase<dim-1> face_ref_case=
+                                 GeometryInfo<dim>::face_refinement_case(neighbor->refine_flag_set(),
+                                                                         nb_nb,
+                                                                         neighbor->face_orientation(nb_nb),
+                                                                         neighbor->face_flip(nb_nb),
+                                                                         neighbor->face_rotation(nb_nb));
+                               RefinementCase<dim-1> needed_face_ref_case
+                                 =GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
+                                                                          i,
+                                                                          cell->face_orientation(i),
+                                                                          cell->face_flip(i),
+                                                                          cell->face_rotation(i));
+                                                                // if the
+                                                                // neighbor wants
+                                                                // to refine the
+                                                                // face with
+                                                                // cut_x and we
+                                                                // want cut_y or
+                                                                // vice versa, we
+                                                                // have to refine
+                                                                // isotropically
+                                                                // at the given
+                                                                // face
+                               if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
+                                   (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
+                                 {
+                                   changed=cell->flag_for_face_refinement(i, face_ref_case);
+                                   neighbor->flag_for_face_refinement(nb_nb, needed_face_ref_case);
+                                 }
+                             }
+                         }
+                       else //-> the neighbor is not active
+                         {
+                           RefinementCase<dim-1> face_ref_case = cell->face(i)->refinement_case(),
+                                          needed_face_ref_case = GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
+                                                                                                         i,
+                                                                                                         cell->face_orientation(i),
+                                                                                                         cell->face_flip(i),
+                                                                                                         cell->face_rotation(i));
+                                                            // if the face is
+                                                            // refined with cut_x
+                                                            // and we want cut_y
+                                                            // or vice versa, we
+                                                            // have to refine
+                                                            // isotropically at
+                                                            // the given face
+                           if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
+                               (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
+                             changed=cell->flag_for_face_refinement(i, face_ref_case);
+                         }
+                     }
+                 }
              }
-         
-         if (bound_face<GeometryInfo<dim>::faces_per_cell)
-                                            // reset the cell's middle vertex
-                                            // to the middle of the straight
-                                            // connection between the new
-                                            // points on this face and on the
-                                            // opposite face
-           vertices[new_vertices[8]]=0.5*(cell->face(bound_face)
-                                          ->child(0)->vertex(1)+
-                                          cell->face(GeometryInfo<dim>
-                                                     ::opposite_face[bound_face])
-                                          ->child(0)->vertex(1));
        }
-    }
-  
-  
-                                  // Now the lines:
-  raw_line_iterator new_lines[12];
-  unsigned int lmin=8;
-  unsigned int lmax=12;
-  if (ref_case!=RefinementCase<dim>::cut_xy)
-    {
-      lmin=6;
-      lmax=7;
-    }
-           
-  for (unsigned int l=lmin; l<lmax; ++l)
-    {
-      while (next_unused_line->used() == true)
-       ++next_unused_line;
-      new_lines[l] = next_unused_line;
-      ++next_unused_line;
-
-      Assert (new_lines[l]->used() == false,
-             ExcCellShouldBeUnused());
-    }
-           
-  if (ref_case==RefinementCase<dim>::cut_xy)
-    {
-                                      //   .-6-.-7-.   
-                                      //   1   9   3 
-                                      //   .-10.11-. 
-                                      //   0   8   2 
-                                      //   .-4-.-5-. 
-
-                                      // lines 0-7 already
-                                      // exist, create only
-                                      // the four interior
-                                      // lines 8-11
-      unsigned int l=0;
-      for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
-       for (unsigned int c=0; c<2; ++c, ++l)
-         new_lines[l]=cell->line(face_no)->child(c);
-      Assert(l==8, ExcInternalError());
-
-      new_lines[8] ->set (internal::Triangulation::
-                         TriaObject<1>(new_vertices[6], new_vertices[8]));
-      new_lines[9] ->set (internal::Triangulation::
-                         TriaObject<1>(new_vertices[8], new_vertices[7]));
-      new_lines[10]->set (internal::Triangulation::
-                         TriaObject<1>(new_vertices[4], new_vertices[8]));
-      new_lines[11]->set (internal::Triangulation::
-                         TriaObject<1>(new_vertices[8], new_vertices[5]));
-    }
-  else if (ref_case==RefinementCase<dim>::cut_x)
-    {
-                                      //   .-4-.-5-. 
-                                      //   |   |   | 
-                                      //   0   6   1 
-                                      //   |   |   | 
-                                      //   .-2-.-3-.
-      new_lines[0]=cell->line(0);
-      new_lines[1]=cell->line(1);
-      new_lines[2]=cell->line(2)->child(0);
-      new_lines[3]=cell->line(2)->child(1);
-      new_lines[4]=cell->line(3)->child(0);
-      new_lines[5]=cell->line(3)->child(1);
-      new_lines[6]->set (internal::Triangulation::
-                        TriaObject<1>(new_vertices[6], new_vertices[7]));
-    }
-  else
-    {
-      Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
-                                      //   .---5---. 
-                                      //   1       3 
-                                      //   .---6---. 
-                                      //   0       2 
-                                      //   .---4---.
-      new_lines[0]=cell->line(0)->child(0);
-      new_lines[1]=cell->line(0)->child(1);
-      new_lines[2]=cell->line(1)->child(0);
-      new_lines[3]=cell->line(1)->child(1);
-      new_lines[4]=cell->line(2);
-      new_lines[5]=cell->line(3);
-      new_lines[6]->set (internal::Triangulation::
-                        TriaObject<1>(new_vertices[4], new_vertices[5]));
-    }
-
-  for (unsigned int l=lmin; l<lmax; ++l)
-    {
-      new_lines[l]->set_used_flag();
-      new_lines[l]->clear_user_flag();
-      new_lines[l]->clear_user_data();
-      new_lines[l]->clear_children();
-                                      // interior line
-      new_lines[l]->set_boundary_indicator(255);
-    }
-
-                                  // Now add the four (two)
-                                  // new cells!
-  raw_cell_iterator subcells[GeometryInfo<dim>::max_children_per_cell];
-  while (next_unused_cell->used() == true)
-    ++next_unused_cell;
-           
-  const unsigned int n_children=
-    GeometryInfo<dim>::n_children(ref_case);
-  for (unsigned int i=0; i<n_children; ++i) 
-    {
-      Assert (next_unused_cell->used() == false,
-             ExcCellShouldBeUnused());
-      subcells[i] = next_unused_cell;
-      ++next_unused_cell;
-      if (i%2==1 && i<n_children-1)
-       while (next_unused_cell->used() == true)
-         ++next_unused_cell;
-    }
-
-  if (ref_case==RefinementCase<dim>::cut_xy)
-    {
-                                      // children:
-                                      //   .--.--.
-                                      //   |2 . 3|
-                                      //   .--.--.
-                                      //   |0 | 1|
-                                      //   .--.--.
-                                      // lines:
-                                      //   .-6-.-7-.   
-                                      //   1   9   3 
-                                      //   .-10.11-. 
-                                      //   0   8   2 
-                                      //   .-4-.-5-. 
-      subcells[0]->set (internal::Triangulation::
-                       TriaObject<2>(new_lines[0]->index(),
-                                     new_lines[8]->index(),
-                                     new_lines[4]->index(),
-                                     new_lines[10]->index()));
-      subcells[1]->set (internal::Triangulation::
-                       TriaObject<2>(new_lines[8]->index(),
-                                     new_lines[2]->index(),
-                                     new_lines[5]->index(),
-                                     new_lines[11]->index()));
-      subcells[2]->set (internal::Triangulation::
-                       TriaObject<2>(new_lines[1]->index(),
-                                     new_lines[9]->index(),
-                                     new_lines[10]->index(),
-                                     new_lines[6]->index()));
-      subcells[3]->set (internal::Triangulation::
-                       TriaObject<2>(new_lines[9]->index(),
-                                     new_lines[3]->index(),
-                                     new_lines[11]->index(),
-                                     new_lines[7]->index()));
-    }
-  else if (ref_case==RefinementCase<dim>::cut_x)
-    {
-                                      // children:
-                                      //   .--.--.
-                                      //   |  .  |
-                                      //   .0 . 1.
-                                      //   |  |  |
-                                      //   .--.--.
-                                      // lines:
-                                      //   .-4-.-5-. 
-                                      //   |   |   | 
-                                      //   0   6   1 
-                                      //   |   |   | 
-                                      //   .-2-.-3-.
-      subcells[0]->set (internal::Triangulation::
-                       TriaObject<2>(new_lines[0]->index(),
-                                     new_lines[6]->index(),
-                                     new_lines[2]->index(),
-                                     new_lines[4]->index()));
-      subcells[1]->set (internal::Triangulation::
-                       TriaObject<2>(new_lines[6]->index(),
-                                     new_lines[1]->index(),
-                                     new_lines[3]->index(),
-                                     new_lines[5]->index()));
-    }
-  else
-    {
-      Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
-                                      // children:
-                                      //   .-----.
-                                      //   |  1  |
-                                      //   .-----.
-                                      //   |  0  |
-                                      //   .-----.
-                                      // lines:
-                                      //   .---5---. 
-                                      //   1       3 
-                                      //   .---6---. 
-                                      //   0       2 
-                                      //   .---4---.
-      subcells[0]->set (internal::Triangulation::
-                       TriaObject<2>(new_lines[0]->index(),
-                                     new_lines[2]->index(),
-                                     new_lines[4]->index(),
-                                     new_lines[6]->index()));
-      subcells[1]->set (internal::Triangulation::
-                       TriaObject<2>(new_lines[1]->index(),
-                                     new_lines[3]->index(),
-                                     new_lines[6]->index(),
-                                     new_lines[5]->index()));
-    }
-           
-
-  for (unsigned int i=0; i<n_children; ++i)
-    {
-      subcells[i]->set_used_flag();
-      subcells[i]->clear_refine_flag();                
-      subcells[i]->clear_user_flag();
-      subcells[i]->clear_user_data();
-      subcells[i]->clear_children();
-                                      // inherit material
-                                      // properties            
-      subcells[i]->set_material_id (cell->material_id());
-      subcells[i]->set_subdomain_id (cell->subdomain_id());
-    }
-           
-                                  // now the only thing
-                                  // still to be done is
-                                  // setting neighborship
-                                  // information.
-                                  //
-                                  // we have to do that for
-                                  // all children of our
-                                  // current cell. if the
-                                  // neighbor is a refined
-                                  // one or if we use anisotropic
-                                  // refinement and there is only
-                                  // one child of the current cell
-                                  // adjacent to a certain face,
-                                  // we also have to reset the
-                                  // neighbors neighbor pointers.
-                                  // In earlier versions of the
-                                  // library these tasks were done one
-                                  // after the other. here we combine
-                                  // these steps, as otherwise we
-                                  // would have to gather the same
-                                  // information on the refinement
-                                  // situation along a certain face
-                                  // twice. As this is a more
-                                  // complicated task for anisotropic
-                                  // refinement, we prefer to do it
-                                  // only once.
-                                  //
-                                  // note that in case the
-                                  // neighboring cell is
-                                  // not refined along the
-                                  // common face, the
-                                  // neighbor iterators
-                                  // point to the common
-                                  // mother cell. the same
-                                  // applies if there is no
-                                  // neighbor: the
-                                  // iterators are past the
-                                  // end
-  cell_iterator nb_children[GeometryInfo<dim>::max_children_per_face],
-    nb_child,
-    children[GeometryInfo<dim>::faces_per_cell][GeometryInfo<dim>::max_children_per_face];
-
-                                  // first, set up an array of our current
-                                  // children / subcells. for all faces and
-                                  // subfaces store the info, which subcell is
-                                  // adjacent to that subface
-  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-    for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_face; ++c)
-      children[face][c]=subcells[GeometryInfo<dim>::child_cell_on_face(ref_case,
-                                                                      face,c)];
-
-
-  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell;
-       ++face)
-    {
-      const cell_iterator neighbor=cell->neighbor(face);
-      const RefinementCase<dim-1> face_ref_case=GeometryInfo<dim>::face_refinement_case(ref_case,face);
-      const unsigned int n_subfaces=std::max(GeometryInfo<dim-1>::n_children(face_ref_case),
-                                            static_cast<unsigned int>(1));
-               
-                                                     
-                                                     
-                                      // if no neighbor set invalid pointer for
-                                      // all children adjacent to that face
-      if (neighbor.state() != IteratorState::valid)
-       for (unsigned int c=0; c<n_subfaces; ++c)
-         children[face][c]
-           ->set_neighbor(face,neighbor);
-      
-      else
-                                        // neighbor exists
-       {
-                                          // now there are two possibilities:
-                                          // either the neighbor is not refined
-                                          // along the common face or it is
-                                          // refined along the common face once,
-                                          // this must be terminal then
-                                          // (otherwise something went wrong in
-                                          // prepare_refinement_and_coarsening()).
-                                          // however, if at any time the neighbor
-                                          // has children, which are not refined
-                                          // along the face currently under
-                                          // consideration, one of these children
-                                          // would have been set as the neighbor
-                                          // of our current cell. therefore the
-                                          // question wether the neighbor is
-                                          // refined along the common face is
-                                          // equivalent to the question, wether
-                                          // the neighbor has children.  if our
-                                          // current cell is not refined along
-                                          // the face face_no, then we have to
-                                          // set the current neighbor as the new
-                                          // neighbor, even if the neighbor is
-                                          // further refined
-         if (!neighbor->has_children())
-           {
-                                              // if the neighbor has no children,
-                                              // set the neighbor-pointer of all
-                                              // children to this neighbor cell
-             for (unsigned int c=0; c<n_subfaces; ++c)
-               children[face][c]
-                 ->set_neighbor(face,neighbor);
-                                              // if the current cell is not
-                                              // refined along the face we have
-                                              // to update the neighbors neighbor
-                                              // pointer. we have to do this only,
-                                              // if the neighbor is not coarser
-             if (n_subfaces==1 && !cell->neighbor_is_coarser(face))
-               {
-                 const unsigned int nb_nb = cell->neighbor_of_neighbor(face);
-                 neighbor->set_neighbor(nb_nb, children[face][0]);
-               }
-           }
-         else
-           {
-                                              // neighbor has children
-             const unsigned int nb_nb = cell->neighbor_of_neighbor(face);
-             const RefinementCase<dim> nb_ref_case = neighbor->refinement_case();
-             const RefinementCase<dim-1> nb_face_ref_case = GeometryInfo<dim>::face_refinement_case(nb_ref_case,
-                                                                                                    nb_nb);
-             const unsigned int nb_n_subfaces = std::max(GeometryInfo<dim-1>::
-                                                         n_children(nb_face_ref_case),
-                                                         static_cast<unsigned int>(1));
-                       
-             for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_face; ++c)
-               {
-                 nb_child=neighbor->child(GeometryInfo<dim>::
-                                          child_cell_on_face(nb_ref_case,
-                                                             nb_nb,
-                                                             c));
-                                                  // there could be an unknown
-                                                  // number of refinements for
-                                                  // nb_child that do
-                                                  // not refine the common
-                                                  // face.
-
-                                                  // consider for example the
-                                                  // following case, where the
-                                                  // lower cell has been refined
-                                                  // in this step into c1 and c2.
-
-                                                  //  ---------------
-                                                  // |       |       |
-                                                  // |       |  n2.1 |
-                                                  // |       |       |
-                                                  // |  n1    -------
-                                                  // |       |       |
-                                                  // |       |  n2.2 |   
-                                                  // |       |       |
-                                                  //  ---------------
-                                                  // |       |       |
-                                                  // |       |       |
-                                                  // |       |       |
-                                                  // |  c1   |  c2   |
-                                                  // |       |       |
-                                                  // |       |       |
-                                                  //  ---------------
-               
-                                                  // the neighbor of cell c was
-                                                  // the whole of cell n. what we
-                                                  // have done so far is setting
-                                                  // the right neighbor
-                                                  // information for cells c1 and
-                                                  // n1 as well as c2 and n2,
-                                                  // where n2 is the mother cell
-                                                  // of n2.1 and n2.2. however,
-                                                  // n2 is further refined and we
-                                                  // would have to set n2.2 as
-                                                  // neighbor of child c2 and
-                                                  // vice versa. this is specific
-                                                  // to anisotropic refinement.
-           
-                                                  // note that n2.2 could be
-                                                  // further refined with cut_y
-                                                  // (if n1 was also refined with
-                                                  // cut_y). 
-                                                   
-                                                  // go down that list to
-                                                  // the end. note, that nb_nb
-                                                  // stays constant, for all
-                                                  // children of a cell have
-                                                  // their faces in the same
-                                                  // direction and orientation as
-                                                  // the mother cell
-                 while(nb_child->has_children()
-                       && (GeometryInfo<dim>::face_refinement_case(nb_child->refinement_case(),
-                                                                   nb_nb)
-                           == RefinementCase<dim-1>::no_refinement))
-                                                    // nb_child has children
-                                                    // which are not refined at
-                                                    // the current (sub)face,
-                                                    // therefore one of these
-                                                    // children is the true
-                                                    // neighbor of our cell
-                   nb_child = nb_child
-                              ->child(GeometryInfo<dim>::
-                                      child_cell_on_face(nb_child->refinement_case(),
-                                                         nb_nb,
-                                                         0));
-                                                  // there's one more possibility
-                                                  // here, if the current cell is
-                                                  // refined along the face: the
-                                                  // last child found above could
-                                                  // still be refined once along
-                                                  // the common face, e.g. n1 or
-                                                  // n2.2 in the above picture
-                                                  // could be refined with
-                                                  // cut_x. this refinement leeds
-                                                  // to an inreased number of
-                                                  // hanging nodes. therefore it
-                                                  // was introduced in this
-                                                  // refinement cycle and the
-                                                  // additional hanging nodes
-                                                  // will be removed now, as the
-                                                  // current cell is also
-                                                  // refined. this temporaray
-                                                  // effect can occur during
-                                                  // anisotropic refinement, as
-                                                  // it is possible there, that a
-                                                  // coarser cell (along the face
-                                                  // between the cells) is on a
-                                                  // higher level and therefore
-                                                  // refined after the already
-                                                  // refined neighbor.
-                 if (nb_child->has_children())
-                   {
-                                                      // This is only valid, if
-                                                      // the current cell is
-                                                      // refined along the face
-                                                      // considered here
-                     Assert(n_subfaces > 1, ExcInternalError());
-                     for (unsigned int sub=0;
-                          sub<GeometryInfo<dim>::max_children_per_face; ++sub)
-                       {
-                                                          // collect all the
-                                                          // children of nb_child
-                                                          // and set their
-                                                          // neighbor
-                                                          // pointers. we will
-                                                          // care for our own
-                                                          // children later on
-                         nb_children[sub]=nb_child->
-                                          child(GeometryInfo<dim>::
-                                                child_cell_on_face(nb_child->refinement_case(),
-                                                                   nb_nb, sub));
-                         nb_children[sub]->set_neighbor(nb_nb, children[face][c]);
-                       }
-                   }
-                           
-                           
-                                                  // now set the neighbor
-                                                  // pointers of the neighbor's
-                                                  // children.
-                 nb_child->set_neighbor(nb_nb, children[face][c]);
-                                                  // if this cell is as refined
-                                                  // as the neighbor, set the
-                                                  // neighbor pointers of the
-                                                  // subcells to the
-                                                  // corresponting
-                                                  // neighbor_child. else, set
-                                                  // the neighbor pointers to the
-                                                  // common neighbor mother cell
-                 if (nb_n_subfaces==n_subfaces)
-                   children[face][c]->set_neighbor(face,nb_child);
-                 else
-                   children[face][c]->set_neighbor(face,neighbor);
-               }
-           }
-       }           
-    }
-                                  // by now, all the outer neighbors have been
-                                  // set, the inner neighbors have to be
-                                  // considered in the following
+                                      //////////////////////////////////////
+                                      // STEP 7:
+                                      //    take care that no double refinement
+                                      //    is done at each line in 3d or higher
+                                      //    dimensions.
+      Implementation::prepare_refinement_dim_dependent (*this);
+      
+                                      //////////////////////////////////////
+                                      // STEP 8:
+                                      //    make sure that all children of each
+                                      //    cell are either flagged for coarsening
+                                      //    or none of the children is
+      fix_coarsen_flags ();
+                                      // get the refinement and coarsening
+                                      // flags
+      std::vector<bool> flags_after_loop[2];
+      save_coarsen_flags (flags_after_loop[0]);
+      save_refine_flags (flags_after_loop[1]);
 
-  if (ref_case==RefinementCase<dim>::cut_xy)
-    {
-                                      // children:
-                                      //   .--.--.
-                                      //   |2 . 3|
-                                      //   .--.--.
-                                      //   |0 | 1|
-                                      //   .--.--.
-      subcells[0]->set_neighbor (1, subcells[1]);
-      subcells[0]->set_neighbor (3, subcells[2]);
-               
-      subcells[1]->set_neighbor (0, subcells[0]);
-      subcells[1]->set_neighbor (3, subcells[3]);
-               
-      subcells[2]->set_neighbor (1, subcells[3]);
-      subcells[2]->set_neighbor (2, subcells[0]);
-               
-      subcells[3]->set_neighbor (0, subcells[2]);
-      subcells[3]->set_neighbor (2, subcells[1]);
-    }
-  else if (ref_case==RefinementCase<dim>::cut_x)
-    {
-                                      // children:
-                                      //   .--.--.
-                                      //   |  .  |
-                                      //   .0 . 1.
-                                      //   |  |  |
-                                      //   .--.--.
-      subcells[0]->set_neighbor (1, subcells[1]);
-               
-      subcells[1]->set_neighbor (0, subcells[0]);
-    }
-  else
-    {
-      Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
-                                      // children:
-                                      //   .-----.
-                                      //   |  1  |
-                                      //   .-----.
-                                      //   |  0  |
-                                      //   .-----.
-      subcells[0]->set_neighbor (3, subcells[1]);
-               
-      subcells[1]->set_neighbor (2, subcells[0]);
-    }
-           
-           
+                                      // find out whether something was
+                                      // changed in this loop
+      mesh_changed_in_this_loop
+       = ((flags_before_loop[0] != flags_after_loop[0]) ||
+          (flags_before_loop[1] != flags_after_loop[1]));
 
-                                  // set child index for
-                                  // even children children
-                                  // i=0,2 (0)
-  for (unsigned int i=0; i<n_children/2; ++i)
-    cell->set_children (2*i, subcells[2*i]->index());
-                                  // set the refine case
-  cell->set_refinement_case(ref_case);     
+                                      // set the flags for the next loop
+                                      // already
+      flags_before_loop[0].swap(flags_after_loop[0]);
+      flags_before_loop[1].swap(flags_after_loop[1]);
+    }
+  while (mesh_changed_in_this_loop);
 
-                                  // note that the
-                                  // refinement flag was
-                                  // already cleared at the
-                                  // beginning of this function            
+  
+                                  // find out whether something was really
+                                  // changed in this function. Note that
+                                  // @p{flags_before_loop} represents the
+                                  // state after the last loop, i.e.
+                                  // the present state
+  return ((flags_before[0] != flags_before_loop[0]) ||
+         (flags_before[1] != flags_before_loop[1]));
 }
-#endif
 
 
 
-template <int dim>
-void Triangulation<dim>::write_bool_vector (const unsigned int  magic_number1,
+
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::write_bool_vector (const unsigned int  magic_number1,
                                            const std::vector<bool> &v,
                                            const unsigned int  magic_number2,
                                            std::ostream            &out)
@@ -13700,8 +14095,8 @@ void Triangulation<dim>::write_bool_vector (const unsigned int  magic_number1,
 }
 
 
-template <int dim>
-void Triangulation<dim>::read_bool_vector (const unsigned int  magic_number1,
+template <int dim, int spacedim>
+void Triangulation<dim, spacedim>::read_bool_vector (const unsigned int  magic_number1,
                                           std::vector<bool>       &v,
                                           const unsigned int  magic_number2,
                                           std::istream            &in)
@@ -13737,9 +14132,9 @@ void Triangulation<dim>::read_bool_vector (const unsigned int  magic_number1,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-Triangulation<dim>::memory_consumption () const 
+Triangulation<dim, spacedim>::memory_consumption () const 
 {
   unsigned int mem = 0;
   mem += MemoryConsumption::memory_consumption(levels);
@@ -13756,322 +14151,50 @@ Triangulation<dim>::memory_consumption () const
   return mem;
 }
 
-  
-#if deal_II_dimension == 1
-
-template <>
-void Triangulation<1>::update_number_cache_lines () 
-{
-                                  ///////////////////////////////////
-                                  // update the number of lines
-                                  // on the different levels in
-                                  // the cache
-  number_cache.n_lines_level.resize (levels.size());
-  number_cache.n_lines = 0;
-  for (unsigned int level=0; level<levels.size(); ++level)
-    {
-                                      // count lines on this level
-      number_cache.n_lines_level[level] = 0;
-      if (levels[level]->cells.cells.size() != 0) 
-       {
-         line_iterator line = begin_line (level),
-                       endc = (level == levels.size()-1 ?
-                               line_iterator(end_line()) :
-                               begin_line (level+1));
-         for (; line!=endc; ++line)
-           ++number_cache.n_lines_level[level];
-       }
-      
-                                      // update total number of lines
-      number_cache.n_lines += number_cache.n_lines_level[level];
-    }
-
-                                  // do the update for the number of
-                                  // active lines as well
-  number_cache.n_active_lines_level.resize (levels.size());
-  number_cache.n_active_lines = 0;
-  for (unsigned int level=0; level<levels.size(); ++level)
-    {
-                                      // count lines on this level
-      number_cache.n_active_lines_level[level] = 0;
-      if (levels[level]->cells.cells.size() != 0) 
-       {
-         active_line_iterator line = begin_active_line (level),
-                              endc = end_active_line (level);
-         for (; line!=endc; ++line)
-           ++number_cache.n_active_lines_level[level];
-       }
-      
-                                      // update total number of lines
-      number_cache.n_active_lines += number_cache.n_active_lines_level[level];
-    }
-}
-
-#endif
-
-
-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 <>
-void Triangulation<1>::update_number_cache_quads () 
-{
-  Assert (false, ExcInternalError());
-}
-
-#endif
-
-#if deal_II_dimension == 2
-
-template <>
-void Triangulation<2>::update_number_cache_quads () 
-{
-                                  ///////////////////////////////////
-                                  // update the number of quads
-                                  // on the different levels in
-                                  // the cache
-  number_cache.n_quads_level.resize (levels.size());
-  number_cache.n_quads = 0;
-  for (unsigned int level=0; level<levels.size(); ++level)
-    {
-                                      // count quads on this level
-      number_cache.n_quads_level[level] = 0;
-      if (levels[level]->cells.cells.size() != 0) 
-       {
-         quad_iterator quad = begin_quad (level),
-                       endc = (level == levels.size()-1 ?
-                               quad_iterator(end_quad()) :
-                               begin_quad (level+1));
-         for (; quad!=endc; ++quad)
-           ++number_cache.n_quads_level[level];
-       }
-      
-                                      // update total number of quads
-      number_cache.n_quads += number_cache.n_quads_level[level];
-    }
-
-                                  // do the update for the number
-                                  // of active quads as well
-  number_cache.n_active_quads_level.resize (levels.size());
-  number_cache.n_active_quads = 0;
-  for (unsigned int level=0; level<levels.size(); ++level)
-    {
-                                      // count quads on this level
-      number_cache.n_active_quads_level[level] = 0;
-      if (levels[level]->cells.cells.size() != 0) 
-       {
-         active_quad_iterator quad = begin_active_quad (level),
-                              endc = end_active_quad (level);
-         for (; quad!=endc; ++quad)
-           ++number_cache.n_active_quads_level[level];
-       }
-      
-                                      // update total number of quads
-      number_cache.n_active_quads += number_cache.n_active_quads_level[level];
-    }
-}
-
-#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 <>
-void Triangulation<1>::update_number_cache_hexes () 
-{
-  Assert (false, ExcInternalError());
-}
-
-#endif
-
-
-#if deal_II_dimension == 2
-
-template <>
-void Triangulation<2>::update_number_cache_hexes () 
-{
-  Assert (false, ExcInternalError());
-}
-
-#endif
-
-#if deal_II_dimension == 3
-
-template <int dim>
-void Triangulation<dim>::update_number_cache_hexes () 
-{
-                                  ///////////////////////////////////
-                                  // update the number of hexes
-                                  // on the different levels in
-                                  // the cache
-  number_cache.n_hexes_level.resize (levels.size());
-  number_cache.n_hexes = 0;
-  for (unsigned int level=0; level<levels.size(); ++level)
-    {
-                                      // count hexes on this level
-      number_cache.n_hexes_level[level] = 0;
-      if (levels[level]->cells.cells.size() != 0) 
-       {
-         hex_iterator hex = begin_hex (level),
-                     endc = (level == levels.size()-1 ?
-                             hex_iterator(end_hex()) :
-                             begin_hex (level+1));
-         for (; hex!=endc; ++hex)
-           ++number_cache.n_hexes_level[level];
-       }
-      
-                                      // update total number of hexes
-      number_cache.n_hexes += number_cache.n_hexes_level[level];
-    }
-
-                                  // do the update for the number
-                                  // of active hexes as well
-  number_cache.n_active_hexes_level.resize (levels.size());
-  number_cache.n_active_hexes = 0;
-  for (unsigned int level=0; level<levels.size(); ++level)
-    {
-                                      // count hexes on this level
-      number_cache.n_active_hexes_level[level] = 0;
-      if (levels[level]->cells.cells.size() != 0) 
-       {
-         active_hex_iterator hex = begin_active_hex (level),
-                            endc = end_active_hex (level);
-         for (; hex!=endc; ++hex)
-           ++number_cache.n_active_hexes_level[level];
-       }
-      
-                                      // update total number of hexes
-      number_cache.n_active_hexes += number_cache.n_active_hexes_level[level];
-    }
-}
-
-#endif
-
-
-template <int dim>
-void Triangulation<dim>::update_number_cache () 
-{
-                                  // play a little bit with switch
-                                  // statements without 'break's
-  switch (dim)
-    {
-      case 3:
-           update_number_cache_hexes();
-      case 2:
-           update_number_cache_quads();
-      case 1:
-           update_number_cache_lines();
-           break;
-           
-      default:
-           Assert (false, ExcInternalError());
-    }
-}
 
 
 
-template<int dim>
-Triangulation<dim>::RefinementListener::~RefinementListener ()
+template<int dim, int spacedim>
+Triangulation<dim, spacedim>::RefinementListener::~RefinementListener ()
 {}
 
 
 
 
-template<int dim>
-void Triangulation<dim>::
-RefinementListener::pre_refinement_notification (const Triangulation<dim> &)
+template<int dim, int spacedim>
+void Triangulation<dim, spacedim>::
+RefinementListener::pre_refinement_notification (const Triangulation<dim, spacedim> &)
 {}
 
 
 
-template<int dim>
-void Triangulation<dim>::
-RefinementListener::post_refinement_notification (const Triangulation<dim> &)
+template<int dim, int spacedim>
+void Triangulation<dim, spacedim>::
+RefinementListener::post_refinement_notification (const Triangulation<dim, spacedim> &)
 {}
 
 
 
-template<int dim>
-void Triangulation<dim>::
-RefinementListener::copy_notification (const Triangulation<dim> &,
-                                      const Triangulation<dim> &)
+template<int dim, int spacedim>
+void Triangulation<dim, spacedim>::
+RefinementListener::copy_notification (const Triangulation<dim, spacedim> &,
+                                      const Triangulation<dim, spacedim> &)
 {}
 
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
-Triangulation<dim>::add_refinement_listener (RefinementListener &listener) const
+Triangulation<dim, spacedim>::add_refinement_listener (RefinementListener &listener) const
 {
   refinement_listeners.push_back (&listener);
 }
 
 
 
-template<int dim>
+template<int dim, int spacedim>
 void
-Triangulation<dim>::remove_refinement_listener (RefinementListener &listener) const
+Triangulation<dim, spacedim>::remove_refinement_listener (RefinementListener &listener) const
 {
   typename std::list<RefinementListener *>::iterator p =
     std::find (refinement_listeners.begin (),
@@ -14081,343 +14204,18 @@ Triangulation<dim>::remove_refinement_listener (RefinementListener &listener) co
   refinement_listeners.erase (p);
 }
 
-#if deal_II_dimension == 3
-
-template<>
-void
-Triangulation<3>::update_neighbors(cell_iterator &cell,
-                                  bool refining)
-{
-  const unsigned int dim=3;
-  
-  Assert(cell->has_children(),
-        ExcMessage("Only cells with children can ask for an update of neighbor information."));
-
-  const RefinementCase<dim> ref_case=cell->refinement_case();
-  
-                                  // visit each face in turn
-  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-    {
-      cell_iterator neighbor=cell->neighbor(f);
-                                      // as default: set all children neighbors
-                                      // to the cell's neighbor first, if we
-                                      // are to set neighbors after refining.
-      if (refining)
-       for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_face; ++c)
-         cell->child(GeometryInfo<dim>::child_cell_on_face(ref_case,f,c))
-           ->set_neighbor(f, neighbor);
-      else
-                                        // in this case, if we are refined
-                                        // anisotropically in a way that does
-                                        // not refine the current face, then
-                                        // set our child's neighbor as our
-                                        // neighbor (the child's neighbor might
-                                        // be more current...).
-       if (GeometryInfo<dim>::face_refinement_case(cell->refinement_case(), f) == RefinementCase<dim-1>::no_refinement)
-         {
-           const active_cell_iterator child_on_this_face=cell->child(GeometryInfo<dim>::child_cell_on_face(cell->refinement_case(),
-                                                                                                           f,
-                                                                                                           cell->face_orientation(f),
-                                                                                                           cell->face_flip(f),
-                                                                                                           cell->face_rotation(f),
-                                                                                                           RefinementCase<dim>::no_refinement));
-           neighbor=child_on_this_face->neighbor(f);
-           cell->set_neighbor(f, child_on_this_face->neighbor(f));
-         }
-               
-      if (neighbor.state()!=IteratorState::valid)
-                                        // the neighbor is at the
-                                        // boundary, so simply copy
-                                        // this to all children at
-                                        // this face. As this has
-                                        // been done already, there
-                                        // is nothing more to do here
-       {}
-      else if (neighbor->active())
-       {
-                   
-                                          // the neighbor is active,
-                                          // so it cannot be refined
-                                          // along the given face. We
-                                          // have to set the neighbor
-                                          // of our children to this
-                                          // neighbor. This has been
-                                          // done already. If our
-                                          // face is not refined AND
-                                          // if the neighbor is not
-                                          // coarser we also have to
-                                          // adjust the neighbor's
-                                          // neighborship info.
-         if ((GeometryInfo<dim>::face_refinement_case(ref_case,f) == RefinementCase<dim-1>::no_refinement) && !cell->neighbor_is_coarser(f))
-           {
-             if (refining)
-               neighbor->set_neighbor(cell->neighbor_of_neighbor(f),
-                                      cell->child(GeometryInfo<dim>::child_cell_on_face(ref_case,f,0)));
-             else
-               neighbor->set_neighbor(cell->neighbor_of_neighbor(f),
-                                      cell);
-           }                               
-       }// else if (neighbor->active())
-      else
-       {
-         const bool f_or=cell->face_orientation(f);
-         const bool f_fl=cell->face_flip(f);
-         const bool f_ro=cell->face_rotation(f);
-         
-                                          // now the neighbor has children, so
-                                          // it is kind of complicated.
-         const RefinementCase<dim-1> our_face_ref_case
-           =GeometryInfo<dim>::face_refinement_case(ref_case,f,f_or,f_fl,f_ro);
-         const RefinementCase<dim-1> face_ref_case
-           =cell->face(f)->refinement_case();
-                   
-         switch (face_ref_case)
-           {
-             case RefinementCase<dim>::no_refinement:
-                                                    // in this case neither our
-                                                    // cell nor the neighbor is
-                                                    // refined along face
-                                                    // f. however, the above
-                                                    // case should have caught
-                                                    // this situation, as the
-                                                    // neighbor has to be
-                                                    // active then.
-                   Assert (false, ExcInternalError());
-                   break;
-             case RefinementCase<dim>::cut_x:
-             case RefinementCase<dim>::cut_y:
-             case RefinementCase<dim>::cut_xy:
-             {
-                         
-                                                // this is really tricky and
-                                                // originally there were some
-                                                // 800 lines of code which were
-                                                // still buggy. thus we use a
-                                                // different kind of approach
-                                                // here: we create a map of our
-                                                // child cells at the given
-                                                // face with the (sub)face as
-                                                // key. Then create a
-                                                // corresponding (multi-)map of
-                                                // the neighbor and its
-                                                // children. As a third
-                                                // ingredient, we need a map
-                                                // pointing us from a face to
-                                                // its parent.
-               const unsigned int nb_nb=cell->neighbor_face_no(f);
-                         
-               std::map<face_iterator,cell_iterator> our_children;
-                                                // we only need to fill this
-                                                // map, if the cell was just
-                                                // refined. after coarsening,
-                                                // we should use our own cell
-                                                // instead
-               if (refining)
-                 for (unsigned int c=0; c<std::max(GeometryInfo<dim-1>::n_children(our_face_ref_case),1U); ++c)
-                   {
-                     cell_iterator child=
-                       cell->child(GeometryInfo<dim>::child_cell_on_face(ref_case,
-                                                                         f,c,
-                                                                         f_or,
-                                                                         f_fl,
-                                                                         f_ro,
-                                                                         our_face_ref_case));
-                     our_children.insert(std::make_pair(child->face(f),child));
-                   }
-               else
-                 our_children.insert(std::make_pair(cell->face(f),cell));
-                         
-               std::map<face_iterator,face_iterator> parents;
-               for (unsigned int face_child=0; face_child<neighbor->face(nb_nb)->n_children(); ++face_child)
-                 parents.insert(std::make_pair(neighbor->face(nb_nb)->child(face_child),neighbor->face(nb_nb)));
-               bool inserted=true;
-               while (inserted)
-                 {
-                   inserted=false;
-                   std::map<face_iterator,face_iterator>::iterator cur_face=parents.begin();
-                   for (;cur_face!=parents.end(); ++cur_face)
-                     if (cur_face->first->has_children())
-                       for (unsigned int fc=0; fc<cur_face->first->n_children(); ++fc)
-                         if (parents.find(cur_face->first->child(fc))==parents.end())
-                           {
-                             parents.insert(std::make_pair(cur_face->first->child(fc),cur_face->first));
-                             inserted=true;
-                           }
-                 }
-                         
-               const bool nb_f_or=neighbor->face_orientation(nb_nb);
-               const bool nb_f_fl=neighbor->face_flip(nb_nb);
-               const bool nb_f_ro=neighbor->face_rotation(nb_nb);
-                         
-               std::multimap<face_iterator,cell_iterator> nb_children;
-               nb_children.insert(std::make_pair(neighbor->face(nb_nb),neighbor));
-                         
-               int current_level=neighbor->level();
-               inserted=true;
-               while (inserted)
-                 {
-                   inserted=false;
-                   std::multimap<face_iterator,cell_iterator>::iterator it=nb_children.begin();
-                   for (;it!=nb_children.end(); ++it)
-                                                      // only treat
-                                                      // untreated
-                                                      // cells,
-                                                      // i.e. those
-                                                      // with
-                                                      // level()==current_level
-                     if (it->second->level()==current_level &&
-                         it->second->has_children())
-                       {
-                         RefinementCase<dim-1> nb_face_ref_case
-                           =GeometryInfo<dim>::face_refinement_case(it->second->refinement_case(),
-                                                                    nb_nb,
-                                                                    nb_f_or,
-                                                                    nb_f_fl,
-                                                                    nb_f_ro);
-                         for (unsigned int c=0; c<std::max(GeometryInfo<dim-1>::n_children(nb_face_ref_case),1U); ++c)
-                           {
-                             cell_iterator child=
-                               it->second->child(GeometryInfo<dim>::child_cell_on_face(it->second->refinement_case(),
-                                                                                       nb_nb,c,
-                                                                                       nb_f_or,
-                                                                                       nb_f_fl,
-                                                                                       nb_f_ro,
-                                                                                       nb_face_ref_case));
-                             nb_children.insert(std::make_pair(child->face(nb_nb),child));
-                             inserted=true;
-                           }
-                       }
-                   ++current_level;
-                 }
-
-                                                // now loop over all of our
-                                                // children and set their
-                                                // neighbor, if available. only
-                                                // necessary, if we are
-                                                // refining.
-
-                                                // declare some iterator which
-                                                // are needed in any case
-               std::map<face_iterator,cell_iterator>::iterator our_it=our_children.begin(),
-                                                           end_our_it=our_children.end();
-               std::multimap <face_iterator,cell_iterator>::iterator nb_it, end_nb_it;
-               
-               if (refining)
-                 {
-                   for (; our_it!=end_our_it; ++our_it)
-                     {
-                       face_iterator parent_face=our_it->first;
-                       bool further_parents=true;
-                       
-                       while(further_parents &&
-                             nb_children.find(parent_face)==nb_children.end())
-                         {
-                           if (parents.find(parent_face)==parents.end())
-                             further_parents=false;
-                           parent_face=parents.find(parent_face)->second;
-                         }
-                             
-                       if (further_parents)
-                                                          // we found a
-                                                          // corresponding
-                                                          // neighbor_child. if
-                                                          // not, do nothing,
-                                                          // as the default
-                                                          // neighbor set above
-                                                          // is correct.
-                         {
-                           nb_it=nb_children.lower_bound(parent_face);
-                           end_nb_it=nb_children.upper_bound(parent_face);
-                           
-                                                            // advance to
-                                                            // the last
-                                                            // child at
-                                                            // the given
-                                                            // face, as
-                                                            // this is on
-                                                            // the
-                                                            // highest
-                                                            // level and
-                                                            // thus the
-                                                            // finest one
-                                                            // possible
-                           for (; nb_it!=end_nb_it; ++nb_it)
-                             our_it->second->set_neighbor(f, nb_it->second);
-                         }
-                     }
-                 }
-               
-                                                // now do the same for the
-                                                // neighbor and its
-                                                // children. this is also
-                                                // necessary if we are
-                                                // coarsening
-               nb_it=nb_children.begin();
-               end_nb_it=nb_children.end();
-                         
-               for (; nb_it!=end_nb_it; ++nb_it)
-                 {
-                   face_iterator parent_face=nb_it->first;
-                   bool further_parents=true;
-                   
-                   while(further_parents &&
-                         our_children.find(parent_face)==our_children.end())
-                     {
-                       if (parents.find(parent_face)==parents.end())
-                         further_parents=false;
-                       parent_face=parents.find(parent_face)->second;
-                     }
-                   
-                   if (further_parents)
-                                                      // we found a
-                                                      // corresponding
-                                                      // child. if
-                                                      // not, do
-                                                      // nothing, as
-                                                      // the old
-                                                      // neighbor is
-                                                      // still
-                                                      // correct.
-                     {
-                                                        // here, we
-                                                        // only have
-                                                        // one child
-                                                        // at any
-                                                        // given
-                                                        // face, so
-                                                        // we do not
-                                                        // need a
-                                                        // loop.
-                       our_it=our_children.find(parent_face);
-                       nb_it->second->set_neighbor(nb_nb, our_it->second);
-                     }
-                 }
-               break;
-             }
-             default:
-                   Assert(false, ExcInternalError());
-                   break;
-           }// switch (our_face_ref_case)
-                   
-       }// else -> neighbor has children
-    }// for all faces
-}
-
-#else
-
-template<int dim>
-void
-Triangulation<dim>::update_neighbors(cell_iterator &,
-                                    bool)
-{
-  Assert(false, ExcNotImplemented());
-}
-
-#endif
 
 
 // explicit instantiations
 template class Triangulation<deal_II_dimension>;
 
+#if deal_II_dimension == 1
+template class Triangulation<1,2>;
+#else 
+#  if deal_II_dimension == 2
+template class Triangulation<2,3>;
+#  endif
+#endif
+
 DEAL_II_NAMESPACE_CLOSE
 
index 231677784d77fdac973fbd9ddc5e0ff588a30129..e732e2686cd3d83bd11acb8119e54488188abafb 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int structdim,int dim>
-const unsigned int TriaAccessor<structdim,dim>::objectdim;
-
-
-// anonymous namespace with two little helper functions
-namespace{
+// anonymous namespace for helper functions
+namespace
+{
                                   // given the number of face's child
                                   // (subface_no), return the number of the
                                   // subface concerning the FaceRefineCase of
                                   // the face
   inline
-  unsigned int translate_subface_no(const TriaIterator<3,TriaObjectAccessor<2, 3> > &face,
-                                   const unsigned int                               subface_no)
+  unsigned int translate_subface_no(const TriaIterator<TriaAccessor<2, 3, 3> > &face,
+                                   const unsigned int                           subface_no)
   {
     Assert(face->has_children(), ExcInternalError());
     Assert(subface_no<face->n_children(), ExcInternalError());
@@ -80,9 +77,9 @@ namespace{
                                   // subface concerning the FaceRefineCase of
                                   // the face
   inline
-  unsigned int translate_subface_no(const TriaIterator<3,TriaObjectAccessor<2, 3> > &face,
-                                   const unsigned int                               subface_no,
-                                   const unsigned int                               subsubface_no)
+  unsigned int translate_subface_no(const TriaIterator<TriaAccessor<2, 3, 3> > &face,
+                                   const unsigned int                           subface_no,
+                                   const unsigned int                           subsubface_no)
   {
     Assert(face->has_children(), ExcInternalError());
                                     // the subface must be refined, otherwise
@@ -96,7 +93,7 @@ namespace{
     
     const bool first_child_has_children=face->child(0)->has_children();
 
-    const unsigned int e = deal_II_numbers::invalid_unsigned_int;
+    static const unsigned int e = deal_II_numbers::invalid_unsigned_int;
     
                                     // array containing the translation of the
                                     // numbers,
@@ -104,7 +101,7 @@ namespace{
                                     // first index: subface_no
                                     // second index: subsubface_no
                                     // third index: does the first subface have children? -> no and yes
-    unsigned int translated_subface_no[2][2][2]
+    static const unsigned int translated_subface_no[2][2][2]
       =
       {{{e,0},       // first  subface, first  subsubface, first_child_has_children==no and yes
        {e,1}},      // first  subface, second subsubface, first_child_has_children==no and yes
@@ -116,1947 +113,904 @@ namespace{
 
     return translated_subface_no[subface_no][subsubface_no][first_child_has_children];
   }
-}
-
-
-
-
-
-/*------------------------ Functions: LineAccessor ---------------------------*/
-
-template <int dim>
-const unsigned int TriaObjectAccessor<1, dim>::objectdim;
-
-
-template <int dim>
-void
-TriaObjectAccessor<1, dim>::set (const internal::Triangulation::TriaObject<1>  &line) const
-{
-  objects().cells[this->present_index] = line;
-}
-
-
-
-template <int dim>
-unsigned int TriaObjectAccessor<1, dim>::vertex_index (const unsigned int i) const
-{
-  Assert (i<2, ExcIndexRange(i,0,2));
-  return objects().cells[this->present_index].face (i);
-}
-
-
-
-template <int dim>
-Point<dim> &
-TriaObjectAccessor<1, dim>::vertex (const unsigned int i) const
-{
-  return const_cast<Point<dim> &> (this->tria->vertices[vertex_index(i)]);
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::set_used_flag () const
-{
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  objects().used[this->present_index] = true;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::clear_used_flag () const
-{
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  objects().used[this->present_index] = false;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::recursively_set_user_flag () const
-{
-  set_user_flag ();
-
-  if (has_children())
-    for (unsigned int c=0; c<2; ++c)
-      child(c)->recursively_set_user_flag ();
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::recursively_clear_user_flag () const
-{
-  clear_user_flag ();
-
-  if (has_children())
-    for (unsigned int c=0; c<2; ++c)
-      child(c)->recursively_clear_user_flag ();
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::clear_user_data () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().clear_user_data(this->present_index);
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::set_user_pointer (void *p) const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_pointer(this->present_index) = p;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::clear_user_pointer () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_pointer(this->present_index) = 0;
-}
 
 
-
-template <int dim>
-void * TriaObjectAccessor<1, dim>::user_pointer () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return objects().user_pointer(this->present_index);
-}
-
-
-
-template <int dim>
-void
-TriaObjectAccessor<1, dim>::recursively_set_user_pointer (void *p) const
-{
-  set_user_pointer (p);
-
-  if (has_children())
-    for (unsigned int c=0; c<2; ++c)
-      child(c)->recursively_set_user_pointer (p);
-}
-
-
-
-template <int dim>
-void
-TriaObjectAccessor<1, dim>::recursively_clear_user_pointer () const
-{
-  clear_user_pointer ();
-
-  if (has_children())
-    for (unsigned int c=0; c<2; ++c)
-      child(c)->recursively_clear_user_pointer ();
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::set_user_index (const unsigned int p) const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_index(this->present_index) = p;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::clear_user_index () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_index(this->present_index) = 0;
-}
-
+  template <int dim, int spacedim>
+  Point<spacedim>
+  barycenter (const TriaAccessor<1, dim, spacedim> &accessor)
+  {
+    return (accessor.vertex(1)+accessor.vertex(0))/2.;
+  }
 
 
-template <int dim>
-unsigned int TriaObjectAccessor<1, dim>::user_index () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return objects().user_index(this->present_index);
-}
+  Point<2>
+  barycenter (const TriaAccessor<2, 2, 2> &accessor)
+  {
+                                    // the evaluation of the formulae
+                                    // is a bit tricky when done dimension
+                                    // independently, so we write this function
+                                    // for 2D and 3D separately
+/*
+  Get the computation of the barycenter by this little Maple script. We
+  use the bilinear mapping of the unit quad to the real quad. However,
+  every transformation mapping the unit faces to strait lines should
+  do.
 
+  Remember that the area of the quad is given by
+  |K| = \int_K 1 dx dy  = \int_{\hat K} |det J| d(xi) d(eta)
+  and that the barycenter is given by
+  \vec x_s = 1/|K| \int_K \vec x dx dy
+  = 1/|K| \int_{\hat K} \vec x(xi,eta) |det J| d(xi) d(eta)
 
+  # x and y are arrays holding the x- and y-values of the four vertices
+  # of this cell in real space. 
+  x := array(0..3);
+  y := array(0..3);
+  tphi[0] := (1-xi)*(1-eta):
+  tphi[1] :=     xi*(1-eta):
+  tphi[2] := (1-xi)*eta:
+  tphi[3] :=     xi*eta:
+  x_real := sum(x[s]*tphi[s], s=0..3):
+  y_real := sum(y[s]*tphi[s], s=0..3):
+  detJ := diff(x_real,xi)*diff(y_real,eta) - diff(x_real,eta)*diff(y_real,xi):
 
-template <int dim>
-void
-TriaObjectAccessor<1, dim>::recursively_set_user_index (const unsigned int p) const
-{
-  set_user_index (p);
+  measure := simplify ( int ( int (detJ, xi=0..1), eta=0..1)):
 
-  if (has_children())
-    for (unsigned int c=0; c<2; ++c)
-      child(c)->recursively_set_user_index (p);
-}
+  xs := simplify (1/measure * int ( int (x_real * detJ, xi=0..1), eta=0..1)):
+  ys := simplify (1/measure * int ( int (y_real * detJ, xi=0..1), eta=0..1)):
+  readlib(C):
 
+  C(array(1..2, [xs, ys]), optimized);
+*/
 
+    const double x[4] = { accessor.vertex(0)(0),
+                         accessor.vertex(1)(0),
+                         accessor.vertex(2)(0),
+                         accessor.vertex(3)(0)  };
+    const double y[4] = { accessor.vertex(0)(1),
+                         accessor.vertex(1)(1),
+                         accessor.vertex(2)(1),
+                         accessor.vertex(3)(1)  };
+    const double t1 = x[0]*x[1];
+    const double t3 = x[0]*x[0];
+    const double t5 = x[1]*x[1];
+    const double t9 = y[0]*x[0];
+    const double t11 = y[1]*x[1];
+    const double t14 = x[2]*x[2];
+    const double t16 = x[3]*x[3];
+    const double t20 = x[2]*x[3];
+    const double t27 = t1*y[1]+t3*y[1]-t5*y[0]-t3*y[2]+t5*y[3]+t9*x[2]-t11*x[3]-t1*y[0]-t14*y[3]+t16*y[2]-t16*y[1]+t14*y[0]-t20*y[3]-x[0]*x[2]*y[2]+x[1]*x[3]*y[3]+t20*y[2];
+    const double t37 = 1/(-x[1]*y[0]+x[1]*y[3]+y[0]*x[2]+x[0]*y[1]-x[0]*y[2]-y[1]*x[3]-x[2]*y[3]+x[3]*y[2]);
+    const double t39 = y[2]*y[2];
+    const double t51 = y[0]*y[0];
+    const double t53 = y[1]*y[1];
+    const double t59 = y[3]*y[3];
+    const double t63 = t39*x[3]+y[2]*y[0]*x[2]+y[3]*x[3]*y[2]-y[2]*x[2]*y[3]-y[3]*y[1]*x[3]-t9*y[2]+t11*y[3]+t51*x[2]-t53*x[3]-x[1]*t51+t9*y[1]-t11*y[0]+x[0]*t53-t59*x[2]+t59*x[1]-t39*x[0];
+
+    return Point<2> (t27*t37/3, t63*t37/3);
+  }
 
-template <int dim>
-void
-TriaObjectAccessor<1, dim>::recursively_clear_user_index () const
-{
-  clear_user_index ();
 
-  if (has_children())
-    for (unsigned int c=0; c<2; ++c)
-      child(c)->recursively_clear_user_index ();
-}
 
+  Point<3>
+  barycenter (const TriaAccessor<3,3,3> &accessor)
+  {
+/*
+  Get the computation of the barycenter by this little Maple script. We
+  use the trilinear mapping of the unit hex to the real hex.
 
+  Remember that the area of the hex is given by
+  |K| = \int_K 1 dx dy dz = \int_{\hat K} |det J| d(xi) d(eta) d(zeta)
+  and that the barycenter is given by
+  \vec x_s = 1/|K| \int_K \vec x dx dy dz
+  = 1/|K| \int_{\hat K} \vec x(xi,eta,zeta) |det J| d(xi) d(eta) d(zeta)
 
-template <int dim>
-void TriaObjectAccessor<1, dim>::set_children (const unsigned int i, const int index) const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  Assert (i%2==0, TriaAccessorExceptions::ExcSetOnlyEvenChildren(i));
-  Assert ((index==-1) ||
-         (!has_children() && (index>=0)),
-         TriaAccessorExceptions::ExcCantSetChildren(index));
+  Note, that in the ordering of the shape functions tphi[0]-tphi[7]
+  below, eta and zeta have been exchanged (zeta belongs to the y, and
+  eta to the z direction). However, the resulting Jacobian determinant
+  detJ should be the same, as a matrix and the matrix created from it
+  by exchanging two consecutive lines and two neighboring columns have
+  the same determinant.
   
-  objects().children[this->present_index] = index;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::clear_children () const
-{
-  set_children (0,-1);
-}
-
-
-
-template <int dim>
-unsigned char TriaObjectAccessor<1, dim>::boundary_indicator () const
-{
-  Assert (dim>=2, ExcImpossibleInDim(dim));
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-
-  return objects().material_id[this->present_index];
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::set_boundary_indicator (const unsigned char boundary_ind) const
-{
-  Assert (dim>=2, ExcImpossibleInDim(dim));
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-
-  objects().material_id[this->present_index] = boundary_ind;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<1, dim>::set_all_boundary_indicators (const unsigned char boundary_ind) const
-{
-  set_boundary_indicator (boundary_ind);
-}
-
-
-
-template <int dim>
-bool TriaObjectAccessor<1, dim>::at_boundary () const
-{
-                                  // error checking is done
-                                  // in boundary_indicator()
-  return (boundary_indicator() != 255);
-}
+  # x, y and z are arrays holding the x-, y- and z-values of the four vertices
+  # of this cell in real space. 
+  x := array(0..7):
+  y := array(0..7):
+  z := array(0..7):
+  tphi[0] := (1-xi)*(1-eta)*(1-zeta):
+  tphi[1] := xi*(1-eta)*(1-zeta):
+  tphi[2] := xi*eta*(1-zeta):
+  tphi[3] := (1-xi)*eta*(1-zeta):
+  tphi[4] := (1-xi)*(1-eta)*zeta:
+  tphi[5] := xi*(1-eta)*zeta:
+  tphi[6] := xi*eta*zeta:
+  tphi[7] := (1-xi)*eta*zeta:
+  x_real := sum(x[s]*tphi[s], s=0..7):
+  y_real := sum(y[s]*tphi[s], s=0..7):
+  z_real := sum(z[s]*tphi[s], s=0..7):
+  with (linalg):
+  J := matrix(3,3, [[diff(x_real, xi), diff(x_real, eta), diff(x_real, zeta)],
+  [diff(y_real, xi), diff(y_real, eta), diff(y_real, zeta)],
+  [diff(z_real, xi), diff(z_real, eta), diff(z_real, zeta)]]): 
+  detJ := det (J):
 
+  measure := simplify ( int ( int ( int (detJ, xi=0..1), eta=0..1), zeta=0..1)):
 
+  xs := simplify (1/measure * int ( int ( int (x_real * detJ, xi=0..1), eta=0..1), zeta=0..1)):
+  ys := simplify (1/measure * int ( int ( int (y_real * detJ, xi=0..1), eta=0..1), zeta=0..1)):
+  zs := simplify (1/measure * int ( int ( int (z_real * detJ, xi=0..1), eta=0..1), zeta=0..1)):
 
-template <int dim>
-double TriaObjectAccessor<1, dim>::diameter () const
-{
-  return std::sqrt((vertex(1)-vertex(0)).square());
-}
+  readlib(C):
 
+  C(array(1..3, [xs, ys, zs]));
 
 
-template <int dim>
-Point<dim> TriaObjectAccessor<1, dim>::center () const
-{
-  return (vertex(1)+vertex(0))/2.;
-}
+  This script takes more than several hours when using an old version
+  of maple on an old and slow computer. Therefore, when changing to
+  the new deal.II numbering scheme (lexicographic numbering) the code
+  lines below have not been reproduced with maple but only the
+  ordering of points in the definitions of x[], y[] and z[] have been
+  changed.
 
+  For the case, someone is willing to rerun the maple script, he/she
+  should use following ordering of shape functions:
+  
+  tphi[0] := (1-xi)*(1-eta)*(1-zeta):
+  tphi[1] :=     xi*(1-eta)*(1-zeta):
+  tphi[2] := (1-xi)*    eta*(1-zeta):
+  tphi[3] :=     xi*    eta*(1-zeta):
+  tphi[4] := (1-xi)*(1-eta)*zeta:
+  tphi[5] :=     xi*(1-eta)*zeta:
+  tphi[6] := (1-xi)*    eta*zeta:
+  tphi[7] :=     xi*    eta*zeta:
 
+  and change the ordering of points in the definitions of x[], y[] and
+  z[] back to the standard ordering.
+*/
 
-template <int dim>
-Point<dim> TriaObjectAccessor<1, dim>::barycenter () const
-{
-  return (vertex(1)+vertex(0))/2.;
-}
+    const double x[8] = { accessor.vertex(0)(0),
+                         accessor.vertex(1)(0),
+                         accessor.vertex(5)(0),
+                         accessor.vertex(4)(0),
+                         accessor.vertex(2)(0),
+                         accessor.vertex(3)(0),
+                         accessor.vertex(7)(0),
+                         accessor.vertex(6)(0)   };
+    const double y[8] = { accessor.vertex(0)(1),
+                         accessor.vertex(1)(1),
+                         accessor.vertex(5)(1),
+                         accessor.vertex(4)(1),
+                         accessor.vertex(2)(1),
+                         accessor.vertex(3)(1),
+                         accessor.vertex(7)(1),
+                         accessor.vertex(6)(1)   };
+    const double z[8] = { accessor.vertex(0)(2),
+                         accessor.vertex(1)(2),
+                         accessor.vertex(5)(2),
+                         accessor.vertex(4)(2),
+                         accessor.vertex(2)(2),
+                         accessor.vertex(3)(2),
+                         accessor.vertex(7)(2),
+                         accessor.vertex(6)(2)   };
+
+    double s1, s2, s3, s4, s5, s6, s7, s8;
+  
+    s1 = 1.0/6.0;
+    s8 = -x[2]*x[2]*y[0]*z[3]-2.0*z[6]*x[7]*x[7]*y[4]-z[5]*x[7]*x[7]*y[4]-z
+        [6]*x[7]*x[7]*y[5]+2.0*y[6]*x[7]*x[7]*z[4]-z[5]*x[6]*x[6]*y[4]+x[6]*x[6]*y[4]*z
+        [7]-z[1]*x[0]*x[0]*y[2]-x[6]*x[6]*y[7]*z[4]+2.0*x[6]*x[6]*y[5]*z[7]-2.0*x[6]*x
+        [6]*y[7]*z[5]+y[5]*x[6]*x[6]*z[4]+2.0*x[5]*x[5]*y[4]*z[6]+x[0]*x[0]*y[7]*z[4]
+        -2.0*x[5]*x[5]*y[6]*z[4];
+    s7 = s8-y[6]*x[5]*x[5]*z[7]+z[6]*x[5]*x[5]*y[7]-y[1]*x[0]*x[0]*z[5]+x[7]*
+        z[5]*x[4]*y[7]-x[7]*y[6]*x[5]*z[7]-2.0*x[7]*x[6]*y[7]*z[4]+2.0*x[7]*x[6]*y[4]*z
+        [7]-x[7]*x[5]*y[7]*z[4]-2.0*x[7]*y[6]*x[4]*z[7]-x[7]*y[5]*x[4]*z[7]+x[2]*x[2]*y
+        [3]*z[0]-x[7]*x[6]*y[7]*z[5]+x[7]*x[6]*y[5]*z[7]+2.0*x[1]*x[1]*y[0]*z[5]+x[7]*z
+        [6]*x[5]*y[7];
+    s8 = -2.0*x[1]*x[1]*y[5]*z[0]+z[1]*x[0]*x[0]*y[5]+2.0*x[2]*x[2]*y[3]*z[1]
+        -z[5]*x[4]*x[4]*y[1]+y[5]*x[4]*x[4]*z[1]-2.0*x[5]*x[5]*y[4]*z[1]+2.0*x[5]*x[5]*
+        y[1]*z[4]-2.0*x[2]*x[2]*y[1]*z[3]-y[1]*x[2]*x[2]*z[0]+x[7]*y[2]*x[3]*z[7]+x[7]*
+        z[2]*x[6]*y[3]+2.0*x[7]*z[6]*x[4]*y[7]+z[5]*x[1]*x[1]*y[4]+z[1]*x[2]*x[2]*y[0]
+        -2.0*y[0]*x[3]*x[3]*z[7];
+    s6 = s8+2.0*z[0]*x[3]*x[3]*y[7]-x[7]*x[2]*y[3]*z[7]-x[7]*z[2]*x[3]*y[7]+x
+        [7]*x[2]*y[7]*z[3]-x[7]*y[2]*x[6]*z[3]+x[4]*x[5]*y[1]*z[4]-x[4]*x[5]*y[4]*z[1]+
+        x[4]*z[5]*x[1]*y[4]-x[4]*y[5]*x[1]*z[4]-2.0*x[5]*z[5]*x[4]*y[1]-2.0*x[5]*y[5]*x
+        [1]*z[4]+2.0*x[5]*z[5]*x[1]*y[4]+2.0*x[5]*y[5]*x[4]*z[1]-x[6]*z[5]*x[7]*y[4]-z
+        [2]*x[3]*x[3]*y[6]+s7;
+    s8 = -2.0*x[6]*z[6]*x[7]*y[5]-x[6]*y[6]*x[4]*z[7]+y[2]*x[3]*x[3]*z[6]+x
+        [6]*y[6]*x[7]*z[4]+2.0*y[2]*x[3]*x[3]*z[7]+x[0]*x[1]*y[0]*z[5]+x[0]*y[1]*x[5]*z
+        [0]-x[0]*z[1]*x[5]*y[0]-2.0*z[2]*x[3]*x[3]*y[7]+2.0*x[6]*z[6]*x[5]*y[7]-x[0]*x
+        [1]*y[5]*z[0]-x[6]*y[5]*x[4]*z[6]-2.0*x[3]*z[0]*x[7]*y[3]-x[6]*z[6]*x[7]*y[4]
+        -2.0*x[1]*z[1]*x[5]*y[0];
+    s7 = s8+2.0*x[1]*y[1]*x[5]*z[0]+2.0*x[1]*z[1]*x[0]*y[5]+2.0*x[3]*y[0]*x
+        [7]*z[3]+2.0*x[3]*x[0]*y[3]*z[7]-2.0*x[3]*x[0]*y[7]*z[3]-2.0*x[1]*y[1]*x[0]*z
+        [5]-2.0*x[6]*y[6]*x[5]*z[7]+s6-y[5]*x[1]*x[1]*z[4]+x[6]*z[6]*x[4]*y[7]-2.0*x[2]
+        *y[2]*x[3]*z[1]+x[6]*z[5]*x[4]*y[6]+x[6]*x[5]*y[4]*z[6]-y[6]*x[7]*x[7]*z[2]-x
+        [6]*x[5]*y[6]*z[4];
+    s8 = x[3]*x[3]*y[7]*z[4]-2.0*y[6]*x[7]*x[7]*z[3]+z[6]*x[7]*x[7]*y[2]+2.0*
+        z[6]*x[7]*x[7]*y[3]+2.0*y[1]*x[0]*x[0]*z[3]+2.0*x[0]*x[1]*y[3]*z[0]-2.0*x[0]*y
+        [0]*x[3]*z[4]-2.0*x[0]*z[1]*x[4]*y[0]-2.0*x[0]*y[1]*x[3]*z[0]+2.0*x[0]*y[0]*x
+        [4]*z[3]-2.0*x[0]*z[0]*x[4]*y[3]+2.0*x[0]*x[1]*y[0]*z[4]+2.0*x[0]*z[1]*x[3]*y
+        [0]-2.0*x[0]*x[1]*y[0]*z[3]-2.0*x[0]*x[1]*y[4]*z[0]+2.0*x[0]*y[1]*x[4]*z[0];
+    s5 = s8+2.0*x[0]*z[0]*x[3]*y[4]+x[1]*y[1]*x[0]*z[3]-x[1]*z[1]*x[4]*y[0]-x
+        [1]*y[1]*x[0]*z[4]+x[1]*z[1]*x[0]*y[4]-x[1]*y[1]*x[3]*z[0]-x[1]*z[1]*x[0]*y[3]-
+        x[0]*z[5]*x[4]*y[1]+x[0]*y[5]*x[4]*z[1]-2.0*x[4]*x[0]*y[4]*z[7]-2.0*x[4]*y[5]*x
+        [0]*z[4]+2.0*x[4]*z[5]*x[0]*y[4]-2.0*x[4]*x[5]*y[4]*z[0]-2.0*x[4]*y[0]*x[7]*z
+        [4]-x[5]*y[5]*x[0]*z[4]+s7;
+    s8 = x[5]*z[5]*x[0]*y[4]-x[5]*z[5]*x[4]*y[0]+x[1]*z[5]*x[0]*y[4]+x[5]*y
+        [5]*x[4]*z[0]-x[0]*y[0]*x[7]*z[4]-x[0]*z[5]*x[4]*y[0]-x[1]*y[5]*x[0]*z[4]+x[0]*
+        z[0]*x[7]*y[4]+x[0]*y[5]*x[4]*z[0]-x[0]*z[0]*x[4]*y[7]+x[0]*x[5]*y[0]*z[4]+x[0]
+        *y[0]*x[4]*z[7]-x[0]*x[5]*y[4]*z[0]-x[3]*x[3]*y[4]*z[7]+2.0*x[2]*z[2]*x[3]*y[1]
+        ;
+    s7 = s8-x[5]*x[5]*y[4]*z[0]+2.0*y[5]*x[4]*x[4]*z[0]-2.0*z[0]*x[4]*x[4]*y
+        [7]+2.0*y[0]*x[4]*x[4]*z[7]-2.0*z[5]*x[4]*x[4]*y[0]+x[5]*x[5]*y[4]*z[7]-x[5]*x
+        [5]*y[7]*z[4]-2.0*y[5]*x[4]*x[4]*z[7]+2.0*z[5]*x[4]*x[4]*y[7]-x[0]*x[0]*y[7]*z
+        [3]+y[2]*x[0]*x[0]*z[3]+x[0]*x[0]*y[3]*z[7]-x[5]*x[1]*y[4]*z[0]+x[5]*y[1]*x[4]*
+        z[0]-x[4]*y[0]*x[3]*z[4];
+    s8 = -x[4]*y[1]*x[0]*z[4]+x[4]*z[1]*x[0]*y[4]+x[4]*x[0]*y[3]*z[4]-x[4]*x
+        [0]*y[4]*z[3]+x[4]*x[1]*y[0]*z[4]-x[4]*x[1]*y[4]*z[0]+x[4]*z[0]*x[3]*y[4]+x[5]*
+        x[1]*y[0]*z[4]+x[1]*z[1]*x[3]*y[0]+x[1]*y[1]*x[4]*z[0]-x[5]*z[1]*x[4]*y[0]-2.0*
+        y[1]*x[0]*x[0]*z[4]+2.0*z[1]*x[0]*x[0]*y[4]+2.0*x[0]*x[0]*y[3]*z[4]-2.0*z[1]*x
+        [0]*x[0]*y[3];
+    s6 = s8-2.0*x[0]*x[0]*y[4]*z[3]+x[1]*x[1]*y[3]*z[0]+x[1]*x[1]*y[0]*z[4]-x
+        [1]*x[1]*y[0]*z[3]-x[1]*x[1]*y[4]*z[0]-z[1]*x[4]*x[4]*y[0]+y[0]*x[4]*x[4]*z[3]-
+        z[0]*x[4]*x[4]*y[3]+y[1]*x[4]*x[4]*z[0]-x[0]*x[0]*y[4]*z[7]-y[5]*x[0]*x[0]*z[4]
+        +z[5]*x[0]*x[0]*y[4]+x[5]*x[5]*y[0]*z[4]-x[0]*y[0]*x[3]*z[7]+x[0]*z[0]*x[3]*y
+        [7]+s7;
+    s8 = s6+x[0]*x[2]*y[3]*z[0]-x[0]*x[2]*y[0]*z[3]+x[0]*y[0]*x[7]*z[3]-x[0]*
+        y[2]*x[3]*z[0]+x[0]*z[2]*x[3]*y[0]-x[0]*z[0]*x[7]*y[3]+x[1]*x[2]*y[3]*z[0]-z[2]
+        *x[0]*x[0]*y[3]+x[3]*z[2]*x[6]*y[3]-x[3]*x[2]*y[3]*z[6]+x[3]*x[2]*y[6]*z[3]-x
+        [3]*y[2]*x[6]*z[3]-2.0*x[3]*y[2]*x[7]*z[3]+2.0*x[3]*z[2]*x[7]*y[3];
+    s7 = s8+2.0*x[4]*y[5]*x[7]*z[4]+2.0*x[4]*x[5]*y[4]*z[7]-2.0*x[4]*z[5]*x
+        [7]*y[4]-2.0*x[4]*x[5]*y[7]*z[4]+x[5]*y[5]*x[7]*z[4]-x[5]*z[5]*x[7]*y[4]-x[5]*y
+        [5]*x[4]*z[7]+x[5]*z[5]*x[4]*y[7]+2.0*x[3]*x[2]*y[7]*z[3]-2.0*x[2]*z[2]*x[1]*y
+        [3]+2.0*x[4]*z[0]*x[7]*y[4]+2.0*x[4]*x[0]*y[7]*z[4]+2.0*x[4]*x[5]*y[0]*z[4]-x
+        [7]*x[6]*y[2]*z[7]-2.0*x[3]*x[2]*y[3]*z[7]-x[0]*x[4]*y[7]*z[3];
+    s8 = x[0]*x[3]*y[7]*z[4]-x[0]*x[3]*y[4]*z[7]+x[0]*x[4]*y[3]*z[7]-2.0*x[7]
+        *z[6]*x[3]*y[7]+x[3]*x[7]*y[4]*z[3]-x[3]*x[4]*y[7]*z[3]-x[3]*x[7]*y[3]*z[4]+x
+        [3]*x[4]*y[3]*z[7]+2.0*x[2]*y[2]*x[1]*z[3]+y[6]*x[3]*x[3]*z[7]-z[6]*x[3]*x[3]*y
+        [7]-x[1]*z[5]*x[4]*y[1]-x[1]*x[5]*y[4]*z[1]-x[1]*z[2]*x[0]*y[3]-x[1]*x[2]*y[0]*
+        z[3]+x[1]*y[2]*x[0]*z[3];
+    s4 = s8+x[1]*x[5]*y[1]*z[4]+x[1]*y[5]*x[4]*z[1]+x[4]*y[0]*x[7]*z[3]-x[4]*
+        z[0]*x[7]*y[3]-x[4]*x[4]*y[7]*z[3]+x[4]*x[4]*y[3]*z[7]+x[3]*z[6]*x[7]*y[3]-x[3]
+        *x[6]*y[3]*z[7]+x[3]*x[6]*y[7]*z[3]-x[3]*z[6]*x[2]*y[7]-x[3]*y[6]*x[7]*z[3]+x
+        [3]*z[6]*x[7]*y[2]+x[3]*y[6]*x[2]*z[7]+2.0*x[5]*z[5]*x[4]*y[6]+s5+s7;
+    s8 = s4-2.0*x[5]*z[5]*x[6]*y[4]-x[5]*z[6]*x[7]*y[5]+x[5]*x[6]*y[5]*z[7]-x
+        [5]*x[6]*y[7]*z[5]-2.0*x[5]*y[5]*x[4]*z[6]+2.0*x[5]*y[5]*x[6]*z[4]-x[3]*y[6]*x
+        [7]*z[2]+x[4]*x[7]*y[4]*z[3]+x[4]*x[3]*y[7]*z[4]-x[4]*x[7]*y[3]*z[4]-x[4]*x[3]*
+        y[4]*z[7]-z[1]*x[5]*x[5]*y[0]+y[1]*x[5]*x[5]*z[0]+x[4]*y[6]*x[7]*z[4];
+    s7 = s8-x[4]*x[6]*y[7]*z[4]+x[4]*x[6]*y[4]*z[7]-x[4]*z[6]*x[7]*y[4]-x[5]*
+        y[6]*x[4]*z[7]-x[5]*x[6]*y[7]*z[4]+x[5]*x[6]*y[4]*z[7]+x[5]*z[6]*x[4]*y[7]-y[6]
+        *x[4]*x[4]*z[7]+z[6]*x[4]*x[4]*y[7]+x[7]*x[5]*y[4]*z[7]-y[2]*x[7]*x[7]*z[3]+z
+        [2]*x[7]*x[7]*y[3]-y[0]*x[3]*x[3]*z[4]-y[1]*x[3]*x[3]*z[0]+z[1]*x[3]*x[3]*y[0];
+    s8 = z[0]*x[3]*x[3]*y[4]-x[2]*y[1]*x[3]*z[0]+x[2]*z[1]*x[3]*y[0]+x[3]*y
+        [1]*x[0]*z[3]+x[3]*x[1]*y[3]*z[0]+x[3]*x[0]*y[3]*z[4]-x[3]*z[1]*x[0]*y[3]-x[3]*
+        x[0]*y[4]*z[3]+x[3]*y[0]*x[4]*z[3]-x[3]*z[0]*x[4]*y[3]-x[3]*x[1]*y[0]*z[3]+x[3]
+        *z[0]*x[7]*y[4]-x[3]*y[0]*x[7]*z[4]+z[0]*x[7]*x[7]*y[4]-y[0]*x[7]*x[7]*z[4];
+    s6 = s8+y[1]*x[0]*x[0]*z[2]-2.0*y[2]*x[3]*x[3]*z[0]+2.0*z[2]*x[3]*x[3]*y
+        [0]-2.0*x[1]*x[1]*y[0]*z[2]+2.0*x[1]*x[1]*y[2]*z[0]-y[2]*x[3]*x[3]*z[1]+z[2]*x
+        [3]*x[3]*y[1]-y[5]*x[4]*x[4]*z[6]+z[5]*x[4]*x[4]*y[6]+x[7]*x[0]*y[7]*z[4]-x[7]*
+        z[0]*x[4]*y[7]-x[7]*x[0]*y[4]*z[7]+x[7]*y[0]*x[4]*z[7]-x[0]*x[1]*y[0]*z[2]+x[0]
+        *z[1]*x[2]*y[0]+s7;
+    s8 = s6+x[0]*x[1]*y[2]*z[0]-x[0]*y[1]*x[2]*z[0]-x[3]*z[1]*x[0]*y[2]+2.0*x
+        [3]*x[2]*y[3]*z[0]+y[0]*x[7]*x[7]*z[3]-z[0]*x[7]*x[7]*y[3]-2.0*x[3]*z[2]*x[0]*y
+        [3]-2.0*x[3]*x[2]*y[0]*z[3]+2.0*x[3]*y[2]*x[0]*z[3]+x[3]*x[2]*y[3]*z[1]-x[3]*x
+        [2]*y[1]*z[3]-x[5]*y[1]*x[0]*z[5]+x[3]*y[1]*x[0]*z[2]+x[4]*y[6]*x[7]*z[5];
+    s7 = s8-x[5]*x[1]*y[5]*z[0]+2.0*x[1]*z[1]*x[2]*y[0]-2.0*x[1]*z[1]*x[0]*y
+        [2]+x[1]*x[2]*y[3]*z[1]-x[1]*x[2]*y[1]*z[3]+2.0*x[1]*y[1]*x[0]*z[2]-2.0*x[1]*y
+        [1]*x[2]*z[0]-z[2]*x[1]*x[1]*y[3]+y[2]*x[1]*x[1]*z[3]+y[5]*x[7]*x[7]*z[4]+y[6]*
+        x[7]*x[7]*z[5]+x[7]*x[6]*y[7]*z[2]+x[7]*y[6]*x[2]*z[7]-x[7]*z[6]*x[2]*y[7]-2.0*
+        x[7]*x[6]*y[3]*z[7];
+    s8 = s7+2.0*x[7]*x[6]*y[7]*z[3]+2.0*x[7]*y[6]*x[3]*z[7]-x[3]*z[2]*x[1]*y
+        [3]+x[3]*y[2]*x[1]*z[3]+x[5]*x[1]*y[0]*z[5]+x[4]*y[5]*x[6]*z[4]+x[5]*z[1]*x[0]*
+        y[5]-x[4]*z[6]*x[7]*y[5]-x[4]*x[5]*y[6]*z[4]+x[4]*x[5]*y[4]*z[6]-x[4]*z[5]*x[6]
+        *y[4]-x[1]*y[2]*x[3]*z[1]+x[1]*z[2]*x[3]*y[1]-x[2]*x[1]*y[0]*z[2]-x[2]*z[1]*x
+        [0]*y[2];
+    s5 = s8+x[2]*x[1]*y[2]*z[0]-x[2]*z[2]*x[0]*y[3]+x[2]*y[2]*x[0]*z[3]-x[2]*
+        y[2]*x[3]*z[0]+x[2]*z[2]*x[3]*y[0]+x[2]*y[1]*x[0]*z[2]+x[5]*y[6]*x[7]*z[5]+x[6]
+        *y[5]*x[7]*z[4]+2.0*x[6]*y[6]*x[7]*z[5]-x[7]*y[0]*x[3]*z[7]+x[7]*z[0]*x[3]*y[7]
+        -x[7]*x[0]*y[7]*z[3]+x[7]*x[0]*y[3]*z[7]+2.0*x[7]*x[7]*y[4]*z[3]-2.0*x[7]*x[7]*
+        y[3]*z[4]-2.0*x[1]*x[1]*y[2]*z[5];
+    s8 = s5-2.0*x[7]*x[4]*y[7]*z[3]+2.0*x[7]*x[3]*y[7]*z[4]-2.0*x[7]*x[3]*y
+        [4]*z[7]+2.0*x[7]*x[4]*y[3]*z[7]+2.0*x[1]*x[1]*y[5]*z[2]-x[1]*x[1]*y[2]*z[6]+x
+        [1]*x[1]*y[6]*z[2]+z[1]*x[5]*x[5]*y[2]-y[1]*x[5]*x[5]*z[2]-x[1]*x[1]*y[6]*z[5]+
+        x[1]*x[1]*y[5]*z[6]+x[5]*x[5]*y[6]*z[2]-x[5]*x[5]*y[2]*z[6]-2.0*y[1]*x[5]*x[5]*
+        z[6];
+    s7 = s8+2.0*z[1]*x[5]*x[5]*y[6]+2.0*x[1]*z[1]*x[5]*y[2]+2.0*x[1]*y[1]*x
+        [2]*z[5]-2.0*x[1]*z[1]*x[2]*y[5]-2.0*x[1]*y[1]*x[5]*z[2]-x[1]*y[1]*x[6]*z[2]-x
+        [1]*z[1]*x[2]*y[6]+x[1]*z[1]*x[6]*y[2]+x[1]*y[1]*x[2]*z[6]-x[5]*x[1]*y[2]*z[5]+
+        x[5]*y[1]*x[2]*z[5]-x[5]*z[1]*x[2]*y[5]+x[5]*x[1]*y[5]*z[2]-x[5]*y[1]*x[6]*z[2]
+        -x[5]*x[1]*y[2]*z[6];
+    s8 = s7+x[5]*x[1]*y[6]*z[2]+x[5]*z[1]*x[6]*y[2]+x[1]*x[2]*y[5]*z[6]-x[1]*
+        x[2]*y[6]*z[5]-x[1]*z[1]*x[6]*y[5]-x[1]*y[1]*x[5]*z[6]+x[1]*z[1]*x[5]*y[6]+x[1]
+        *y[1]*x[6]*z[5]-x[5]*x[6]*y[5]*z[2]+x[5]*x[2]*y[5]*z[6]-x[5]*x[2]*y[6]*z[5]+x
+        [5]*x[6]*y[2]*z[5]-2.0*x[5]*z[1]*x[6]*y[5]-2.0*x[5]*x[1]*y[6]*z[5]+2.0*x[5]*x
+        [1]*y[5]*z[6];
+    s6 = s8+2.0*x[5]*y[1]*x[6]*z[5]+2.0*x[2]*x[1]*y[6]*z[2]+2.0*x[2]*z[1]*x
+        [6]*y[2]-2.0*x[2]*x[1]*y[2]*z[6]+x[2]*x[5]*y[6]*z[2]+x[2]*x[6]*y[2]*z[5]-x[2]*x
+        [5]*y[2]*z[6]+y[1]*x[2]*x[2]*z[5]-z[1]*x[2]*x[2]*y[5]-2.0*x[2]*y[1]*x[6]*z[2]-x
+        [2]*x[6]*y[5]*z[2]-2.0*z[1]*x[2]*x[2]*y[6]+x[2]*x[2]*y[5]*z[6]-x[2]*x[2]*y[6]*z
+        [5]+2.0*y[1]*x[2]*x[2]*z[6]+x[2]*z[1]*x[5]*y[2];
+    s8 = s6-x[2]*x[1]*y[2]*z[5]+x[2]*x[1]*y[5]*z[2]-x[2]*y[1]*x[5]*z[2]+x[6]*
+        y[1]*x[2]*z[5]-x[6]*z[1]*x[2]*y[5]-z[1]*x[6]*x[6]*y[5]+y[1]*x[6]*x[6]*z[5]-y[1]
+        *x[6]*x[6]*z[2]-2.0*x[6]*x[6]*y[5]*z[2]+2.0*x[6]*x[6]*y[2]*z[5]+z[1]*x[6]*x[6]*
+        y[2]-x[6]*x[1]*y[6]*z[5]-x[6]*y[1]*x[5]*z[6]+x[6]*x[1]*y[5]*z[6];
+    s7 = s8+x[6]*z[1]*x[5]*y[6]-x[6]*z[1]*x[2]*y[6]-x[6]*x[1]*y[2]*z[6]+2.0*x
+        [6]*x[5]*y[6]*z[2]+2.0*x[6]*x[2]*y[5]*z[6]-2.0*x[6]*x[2]*y[6]*z[5]-2.0*x[6]*x
+        [5]*y[2]*z[6]+x[6]*x[1]*y[6]*z[2]+x[6]*y[1]*x[2]*z[6]-x[2]*x[2]*y[3]*z[7]+x[2]*
+        x[2]*y[7]*z[3]-x[2]*z[2]*x[3]*y[7]-x[2]*y[2]*x[7]*z[3]+x[2]*z[2]*x[7]*y[3]+x[2]
+        *y[2]*x[3]*z[7]-x[6]*x[6]*y[3]*z[7];
+    s8 = s7+x[6]*x[6]*y[7]*z[3]-x[6]*x[2]*y[3]*z[7]+x[6]*x[2]*y[7]*z[3]-x[6]*
+        y[6]*x[7]*z[3]+x[6]*y[6]*x[3]*z[7]-x[6]*z[6]*x[3]*y[7]+x[6]*z[6]*x[7]*y[3]+y[6]
+        *x[2]*x[2]*z[7]-z[6]*x[2]*x[2]*y[7]+2.0*x[2]*x[2]*y[6]*z[3]-x[2]*y[6]*x[7]*z[2]
+        -2.0*x[2]*y[2]*x[6]*z[3]-2.0*x[2]*x[2]*y[3]*z[6]+2.0*x[2]*y[2]*x[3]*z[6]-x[2]*x
+        [6]*y[2]*z[7];
+    s3 = s8+x[2]*x[6]*y[7]*z[2]+x[2]*z[6]*x[7]*y[2]+2.0*x[2]*z[2]*x[6]*y[3]
+        -2.0*x[2]*z[2]*x[3]*y[6]-y[2]*x[6]*x[6]*z[3]-2.0*x[6]*x[6]*y[2]*z[7]+2.0*x[6]*x
+        [6]*y[7]*z[2]+z[2]*x[6]*x[6]*y[3]-2.0*x[6]*y[6]*x[7]*z[2]+x[6]*y[2]*x[3]*z[6]-x
+        [6]*x[2]*y[3]*z[6]+2.0*x[6]*z[6]*x[7]*y[2]+2.0*x[6]*y[6]*x[2]*z[7]-2.0*x[6]*z
+        [6]*x[2]*y[7]+x[6]*x[2]*y[6]*z[3]-x[6]*z[2]*x[3]*y[6];
+    s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
+        [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
+        z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
+        +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
+    s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
+        x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
+        *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
+        [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
+    s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
+        [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
+        z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
+        -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
+    s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
+        x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
+        *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
+        [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
+    s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
+        y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
+        *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
+        [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
+    s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
+        x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
+        *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
+        [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
+    s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
+        [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
+        z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
+        +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
+    s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
+        x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
+        *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
+        [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
+    s4 = 1/s5;
+    s2 = s3*s4;
+    const double unknown0 = s1*s2;
+    s1 = 1.0/6.0;
+    s8 = 2.0*x[1]*y[0]*y[0]*z[4]+x[5]*y[0]*y[0]*z[4]-x[1]*y[4]*y[4]*z[0]+z[1]
+        *x[0]*y[4]*y[4]+x[1]*y[0]*y[0]*z[5]-z[1]*x[5]*y[0]*y[0]-2.0*z[1]*x[4]*y[0]*y[0]
+        +2.0*z[1]*x[3]*y[0]*y[0]+z[2]*x[3]*y[0]*y[0]+y[0]*y[0]*x[7]*z[3]+2.0*y[0]*y[0]*
+        x[4]*z[3]-2.0*x[1]*y[0]*y[0]*z[3]-2.0*x[5]*y[4]*y[4]*z[0]+2.0*z[5]*x[0]*y[4]*y
+        [4]+2.0*y[4]*y[5]*x[7]*z[4];
+    s7 = s8-x[3]*y[4]*y[4]*z[7]+x[7]*y[4]*y[4]*z[3]+z[0]*x[3]*y[4]*y[4]-2.0*x
+        [0]*y[4]*y[4]*z[7]-y[1]*x[1]*y[4]*z[0]-x[0]*y[4]*y[4]*z[3]+2.0*z[0]*x[7]*y[4]*y
+        [4]+y[4]*z[6]*x[4]*y[7]-y[0]*y[0]*x[7]*z[4]+y[0]*y[0]*x[4]*z[7]+2.0*y[4]*z[5]*x
+        [4]*y[7]-2.0*y[4]*x[5]*y[7]*z[4]-y[4]*x[6]*y[7]*z[4]-y[4]*y[6]*x[4]*z[7]-2.0*y
+        [4]*y[5]*x[4]*z[7];
+    s8 = y[4]*y[6]*x[7]*z[4]-y[7]*y[2]*x[7]*z[3]+y[7]*z[2]*x[7]*y[3]+y[7]*y
+        [2]*x[3]*z[7]+2.0*x[5]*y[4]*y[4]*z[7]-y[7]*x[2]*y[3]*z[7]-y[0]*z[0]*x[4]*y[7]+z
+        [6]*x[7]*y[3]*y[3]-y[0]*x[0]*y[4]*z[7]+y[0]*x[0]*y[7]*z[4]-2.0*x[2]*y[3]*y[3]*z
+        [7]-z[5]*x[4]*y[0]*y[0]+y[0]*z[0]*x[7]*y[4]-2.0*z[6]*x[3]*y[7]*y[7]+z[1]*x[2]*y
+        [0]*y[0];
+    s6 = s8+y[4]*y[0]*x[4]*z[3]-2.0*y[4]*z[0]*x[4]*y[7]+2.0*y[4]*x[0]*y[7]*z
+        [4]-y[4]*z[0]*x[4]*y[3]-y[4]*x[0]*y[7]*z[3]+y[4]*z[0]*x[3]*y[7]-y[4]*y[0]*x[3]*
+        z[4]+y[0]*x[4]*y[3]*z[7]-y[0]*x[7]*y[3]*z[4]-y[0]*x[3]*y[4]*z[7]+y[0]*x[7]*y[4]
+        *z[3]+x[2]*y[7]*y[7]*z[3]-z[2]*x[3]*y[7]*y[7]-2.0*z[2]*x[0]*y[3]*y[3]+2.0*y[0]*
+        z[1]*x[0]*y[4]+s7;
+    s8 = -2.0*y[0]*y[1]*x[0]*z[4]-y[0]*y[1]*x[0]*z[5]-y[0]*y[0]*x[3]*z[7]-z
+        [1]*x[0]*y[3]*y[3]-y[0]*x[1]*y[5]*z[0]-2.0*z[0]*x[7]*y[3]*y[3]+x[0]*y[3]*y[3]*z
+        [4]+2.0*x[0]*y[3]*y[3]*z[7]-z[0]*x[4]*y[3]*y[3]+2.0*x[2]*y[3]*y[3]*z[0]+x[1]*y
+        [3]*y[3]*z[0]+2.0*y[7]*z[6]*x[7]*y[3]+2.0*y[7]*y[6]*x[3]*z[7]-2.0*y[7]*y[6]*x
+        [7]*z[3]-2.0*y[7]*x[6]*y[3]*z[7];
+    s7 = s8+y[4]*x[4]*y[3]*z[7]-y[4]*x[4]*y[7]*z[3]+y[4]*x[3]*y[7]*z[4]-y[4]*
+        x[7]*y[3]*z[4]+2.0*y[4]*y[0]*x[4]*z[7]-2.0*y[4]*y[0]*x[7]*z[4]+2.0*x[6]*y[7]*y
+        [7]*z[3]+y[4]*x[0]*y[3]*z[4]+y[0]*y[1]*x[5]*z[0]+y[0]*z[1]*x[0]*y[5]-x[2]*y[0]*
+        y[0]*z[3]+x[4]*y[3]*y[3]*z[7]-x[7]*y[3]*y[3]*z[4]-x[5]*y[4]*y[4]*z[1]+y[3]*z[0]
+        *x[3]*y[4];
+    s8 = y[3]*y[0]*x[4]*z[3]+2.0*y[3]*y[0]*x[7]*z[3]+2.0*y[3]*y[2]*x[0]*z[3]
+        -2.0*y[3]*y[2]*x[3]*z[0]+2.0*y[3]*z[2]*x[3]*y[0]+y[3]*z[1]*x[3]*y[0]-2.0*y[3]*x
+        [2]*y[0]*z[3]-y[3]*x[1]*y[0]*z[3]-y[3]*y[1]*x[3]*z[0]-2.0*y[3]*x[0]*y[7]*z[3]-y
+        [3]*x[0]*y[4]*z[3]-2.0*y[3]*y[0]*x[3]*z[7]-y[3]*y[0]*x[3]*z[4]+2.0*y[3]*z[0]*x
+        [3]*y[7]+y[3]*y[1]*x[0]*z[3]+z[5]*x[1]*y[4]*y[4];
+    s5 = s8-2.0*y[0]*y[0]*x[3]*z[4]-2.0*y[0]*x[1]*y[4]*z[0]+y[3]*x[7]*y[4]*z
+        [3]-y[3]*x[4]*y[7]*z[3]+y[3]*x[3]*y[7]*z[4]-y[3]*x[3]*y[4]*z[7]+y[3]*x[0]*y[7]*
+        z[4]-y[3]*z[0]*x[4]*y[7]-2.0*y[4]*y[5]*x[0]*z[4]+s6+y[7]*x[0]*y[3]*z[7]-y[7]*z
+        [0]*x[7]*y[3]+y[7]*y[0]*x[7]*z[3]-y[7]*y[0]*x[3]*z[7]+2.0*y[0]*y[1]*x[4]*z[0]+
+        s7;
+    s8 = -2.0*y[7]*x[7]*y[3]*z[4]-2.0*y[7]*x[3]*y[4]*z[7]+2.0*y[7]*x[4]*y[3]*
+        z[7]+y[7]*y[0]*x[4]*z[7]-y[7]*y[0]*x[7]*z[4]+2.0*y[7]*x[7]*y[4]*z[3]-y[7]*x[0]*
+        y[4]*z[7]+y[7]*z[0]*x[7]*y[4]+z[5]*x[4]*y[7]*y[7]+2.0*z[6]*x[4]*y[7]*y[7]-x[5]*
+        y[7]*y[7]*z[4]-2.0*x[6]*y[7]*y[7]*z[4]+2.0*y[7]*x[6]*y[4]*z[7]-2.0*y[7]*z[6]*x
+        [7]*y[4]+2.0*y[7]*y[6]*x[7]*z[4];
+    s7 = s8-2.0*y[7]*y[6]*x[4]*z[7]-y[7]*z[5]*x[7]*y[4]-y[7]*y[5]*x[4]*z[7]-x
+        [0]*y[7]*y[7]*z[3]+z[0]*x[3]*y[7]*y[7]+y[7]*x[5]*y[4]*z[7]+y[7]*y[5]*x[7]*z[4]-
+        y[4]*x[1]*y[5]*z[0]-x[1]*y[0]*y[0]*z[2]-y[4]*y[5]*x[1]*z[4]-2.0*y[4]*z[5]*x[4]*
+        y[0]-y[4]*y[1]*x[0]*z[4]+y[4]*y[5]*x[4]*z[1]+y[0]*z[0]*x[3]*y[7]-y[0]*z[1]*x[0]
+        *y[2];
+    s8 = 2.0*y[0]*x[1]*y[3]*z[0]+y[4]*y[1]*x[4]*z[0]+2.0*y[0]*y[1]*x[0]*z[3]+
+        y[4]*x[1]*y[0]*z[5]-y[4]*z[1]*x[5]*y[0]+y[4]*z[1]*x[0]*y[5]-y[4]*z[1]*x[4]*y[0]
+        +y[4]*x[1]*y[0]*z[4]-y[4]*z[5]*x[4]*y[1]+x[5]*y[4]*y[4]*z[6]-z[5]*x[6]*y[4]*y
+        [4]+y[4]*x[5]*y[1]*z[4]-y[0]*z[2]*x[0]*y[3]+y[0]*y[5]*x[4]*z[0]+y[0]*x[1]*y[2]*
+        z[0];
+    s6 = s8-2.0*y[0]*z[0]*x[4]*y[3]-2.0*y[0]*x[0]*y[4]*z[3]-2.0*y[0]*z[1]*x
+        [0]*y[3]-y[0]*x[0]*y[7]*z[3]-2.0*y[0]*y[1]*x[3]*z[0]+y[0]*x[2]*y[3]*z[0]-y[0]*y
+        [1]*x[2]*z[0]+y[0]*y[1]*x[0]*z[2]-y[0]*x[2]*y[1]*z[3]+y[0]*x[0]*y[3]*z[7]+y[0]*
+        x[2]*y[3]*z[1]-y[0]*y[2]*x[3]*z[0]+y[0]*y[2]*x[0]*z[3]-y[0]*y[5]*x[0]*z[4]-y[4]
+        *y[5]*x[4]*z[6]+s7;
+    s8 = s6+y[4]*z[6]*x[5]*y[7]-y[4]*x[6]*y[7]*z[5]+y[4]*x[6]*y[5]*z[7]-y[4]*
+        z[6]*x[7]*y[5]-y[4]*x[5]*y[6]*z[4]+y[4]*z[5]*x[4]*y[6]+y[4]*y[5]*x[6]*z[4]-2.0*
+        y[1]*y[1]*x[0]*z[5]+2.0*y[1]*y[1]*x[5]*z[0]-2.0*y[2]*y[2]*x[6]*z[3]+x[5]*y[1]*y
+        [1]*z[4]-z[5]*x[4]*y[1]*y[1]-x[6]*y[2]*y[2]*z[7]+z[6]*x[7]*y[2]*y[2];
+    s7 = s8-x[1]*y[5]*y[5]*z[0]+z[1]*x[0]*y[5]*y[5]+y[1]*y[5]*x[4]*z[1]-y[1]*
+        y[5]*x[1]*z[4]-2.0*y[2]*z[2]*x[3]*y[6]+2.0*y[1]*z[1]*x[0]*y[5]-2.0*y[1]*z[1]*x
+        [5]*y[0]+2.0*y[1]*x[1]*y[0]*z[5]-y[2]*x[2]*y[3]*z[7]-y[2]*z[2]*x[3]*y[7]+y[2]*x
+        [2]*y[7]*z[3]+y[2]*z[2]*x[7]*y[3]-2.0*y[2]*x[2]*y[3]*z[6]+2.0*y[2]*x[2]*y[6]*z
+        [3]+2.0*y[2]*z[2]*x[6]*y[3]-y[3]*y[2]*x[6]*z[3];
+    s8 = y[3]*y[2]*x[3]*z[6]+y[3]*x[2]*y[6]*z[3]-y[3]*z[2]*x[3]*y[6]-y[2]*y
+        [2]*x[7]*z[3]+2.0*y[2]*y[2]*x[3]*z[6]+y[2]*y[2]*x[3]*z[7]-2.0*y[1]*x[1]*y[5]*z
+        [0]-x[2]*y[3]*y[3]*z[6]+z[2]*x[6]*y[3]*y[3]+2.0*y[6]*x[2]*y[5]*z[6]+2.0*y[6]*x
+        [6]*y[2]*z[5]-2.0*y[6]*x[5]*y[2]*z[6]+2.0*y[3]*x[2]*y[7]*z[3]-2.0*y[3]*z[2]*x
+        [3]*y[7]-y[0]*z[0]*x[7]*y[3]-y[0]*z[2]*x[1]*y[3];
+    s4 = s8-y[2]*y[6]*x[7]*z[2]+y[0]*z[2]*x[3]*y[1]+y[1]*z[5]*x[1]*y[4]-y[1]*
+        x[5]*y[4]*z[1]+2.0*y[0]*z[0]*x[3]*y[4]+2.0*y[0]*x[0]*y[3]*z[4]+2.0*z[2]*x[7]*y
+        [3]*y[3]-2.0*z[5]*x[7]*y[4]*y[4]+x[6]*y[4]*y[4]*z[7]-z[6]*x[7]*y[4]*y[4]+y[1]*y
+        [1]*x[0]*z[3]+y[3]*x[6]*y[7]*z[2]-y[3]*z[6]*x[2]*y[7]+2.0*y[3]*y[2]*x[3]*z[7]+
+        s5+s7;
+    s8 = s4+y[2]*x[6]*y[7]*z[2]-y[2]*y[6]*x[7]*z[3]+y[2]*y[6]*x[2]*z[7]-y[2]*
+        z[6]*x[2]*y[7]-y[2]*x[6]*y[3]*z[7]+y[2]*y[6]*x[3]*z[7]+y[2]*z[6]*x[7]*y[3]-2.0*
+        y[3]*y[2]*x[7]*z[3]-x[6]*y[3]*y[3]*z[7]+y[1]*y[1]*x[4]*z[0]-y[1]*y[1]*x[3]*z[0]
+        +x[2]*y[6]*y[6]*z[3]-z[2]*x[3]*y[6]*y[6]-y[1]*y[1]*x[0]*z[4];
+    s7 = s8+y[5]*x[1]*y[0]*z[5]+y[6]*x[2]*y[7]*z[3]-y[6]*y[2]*x[6]*z[3]+y[6]*
+        y[2]*x[3]*z[6]-y[6]*x[2]*y[3]*z[6]+y[6]*z[2]*x[6]*y[3]-y[5]*y[1]*x[0]*z[5]-y[5]
+        *z[1]*x[5]*y[0]+y[5]*y[1]*x[5]*z[0]-y[6]*z[2]*x[3]*y[7]-y[7]*y[6]*x[7]*z[2]+2.0
+        *y[6]*y[6]*x[2]*z[7]+y[6]*y[6]*x[3]*z[7]+x[6]*y[7]*y[7]*z[2]-z[6]*x[2]*y[7]*y
+        [7];
+    s8 = -x[2]*y[1]*y[1]*z[3]+2.0*y[1]*y[1]*x[0]*z[2]-2.0*y[1]*y[1]*x[2]*z[0]
+        +z[2]*x[3]*y[1]*y[1]-z[1]*x[0]*y[2]*y[2]+x[1]*y[2]*y[2]*z[0]+y[2]*y[2]*x[0]*z
+        [3]-y[2]*y[2]*x[3]*z[0]-2.0*y[2]*y[2]*x[3]*z[1]+y[1]*x[1]*y[3]*z[0]-2.0*y[6]*y
+        [6]*x[7]*z[2]+2.0*y[5]*y[5]*x[4]*z[1]-2.0*y[5]*y[5]*x[1]*z[4]-y[6]*y[6]*x[7]*z
+        [3]-2.0*y[1]*x[1]*y[0]*z[2];
+    s6 = s8+2.0*y[1]*z[1]*x[2]*y[0]-2.0*y[1]*z[1]*x[0]*y[2]+2.0*y[1]*x[1]*y
+        [2]*z[0]+y[1]*x[2]*y[3]*z[1]-y[1]*y[2]*x[3]*z[1]-y[1]*z[2]*x[1]*y[3]+y[1]*y[2]*
+        x[1]*z[3]-y[2]*x[1]*y[0]*z[2]+y[2]*z[1]*x[2]*y[0]+y[2]*x[2]*y[3]*z[0]-y[7]*x[6]
+        *y[2]*z[7]+y[7]*z[6]*x[7]*y[2]+y[7]*y[6]*x[2]*z[7]-y[6]*x[6]*y[3]*z[7]+y[6]*x
+        [6]*y[7]*z[3]+s7;
+    s8 = s6-y[6]*z[6]*x[3]*y[7]+y[6]*z[6]*x[7]*y[3]+2.0*y[2]*y[2]*x[1]*z[3]+x
+        [2]*y[3]*y[3]*z[1]-z[2]*x[1]*y[3]*y[3]+y[1]*x[1]*y[0]*z[4]+y[1]*z[1]*x[3]*y[0]-
+        y[1]*x[1]*y[0]*z[3]+2.0*y[5]*x[5]*y[1]*z[4]-2.0*y[5]*x[5]*y[4]*z[1]+2.0*y[5]*z
+        [5]*x[1]*y[4]-2.0*y[5]*z[5]*x[4]*y[1]-2.0*y[6]*x[6]*y[2]*z[7]+2.0*y[6]*x[6]*y
+        [7]*z[2];
+    s7 = s8+2.0*y[6]*z[6]*x[7]*y[2]-2.0*y[6]*z[6]*x[2]*y[7]-y[1]*z[1]*x[4]*y
+        [0]+y[1]*z[1]*x[0]*y[4]-y[1]*z[1]*x[0]*y[3]+2.0*y[6]*y[6]*x[7]*z[5]+2.0*y[5]*y
+        [5]*x[6]*z[4]-2.0*y[5]*y[5]*x[4]*z[6]+x[6]*y[5]*y[5]*z[7]-y[3]*x[2]*y[1]*z[3]-y
+        [3]*y[2]*x[3]*z[1]+y[3]*z[2]*x[3]*y[1]+y[3]*y[2]*x[1]*z[3]-y[2]*x[2]*y[0]*z[3]+
+        y[2]*z[2]*x[3]*y[0];
+    s8 = s7+2.0*y[2]*x[2]*y[3]*z[1]-2.0*y[2]*x[2]*y[1]*z[3]+y[2]*y[1]*x[0]*z
+        [2]-y[2]*y[1]*x[2]*z[0]+2.0*y[2]*z[2]*x[3]*y[1]-2.0*y[2]*z[2]*x[1]*y[3]-y[2]*z
+        [2]*x[0]*y[3]+y[5]*z[6]*x[5]*y[7]-y[5]*x[6]*y[7]*z[5]-y[5]*y[6]*x[4]*z[7]-y[5]*
+        y[6]*x[5]*z[7]-2.0*y[5]*x[5]*y[6]*z[4]+2.0*y[5]*x[5]*y[4]*z[6]-2.0*y[5]*z[5]*x
+        [6]*y[4]+2.0*y[5]*z[5]*x[4]*y[6];
+    s5 = s8-y[1]*y[5]*x[0]*z[4]-z[6]*x[7]*y[5]*y[5]+y[6]*y[6]*x[7]*z[4]-y[6]*
+        y[6]*x[4]*z[7]-2.0*y[6]*y[6]*x[5]*z[7]-x[5]*y[6]*y[6]*z[4]+z[5]*x[4]*y[6]*y[6]+
+        z[6]*x[5]*y[7]*y[7]-x[6]*y[7]*y[7]*z[5]+y[1]*y[5]*x[4]*z[0]+y[7]*y[6]*x[7]*z[5]
+        +y[6]*y[5]*x[7]*z[4]+y[5]*y[6]*x[7]*z[5]+y[6]*y[5]*x[6]*z[4]-y[6]*y[5]*x[4]*z
+        [6]+2.0*y[6]*z[6]*x[5]*y[7];
+    s8 = s5-2.0*y[6]*x[6]*y[7]*z[5]+2.0*y[6]*x[6]*y[5]*z[7]-2.0*y[6]*z[6]*x
+        [7]*y[5]-y[6]*x[5]*y[7]*z[4]-y[6]*x[6]*y[7]*z[4]+y[6]*x[6]*y[4]*z[7]-y[6]*z[6]*
+        x[7]*y[4]+y[6]*z[5]*x[4]*y[7]+y[6]*z[6]*x[4]*y[7]+y[6]*x[5]*y[4]*z[6]-y[6]*z[5]
+        *x[6]*y[4]+y[7]*x[6]*y[5]*z[7]-y[7]*z[6]*x[7]*y[5]-2.0*y[6]*x[6]*y[5]*z[2];
+    s7 = s8-y[7]*y[6]*x[5]*z[7]+2.0*y[4]*y[5]*x[4]*z[0]+2.0*x[3]*y[7]*y[7]*z
+        [4]-2.0*x[4]*y[7]*y[7]*z[3]-z[0]*x[4]*y[7]*y[7]+x[0]*y[7]*y[7]*z[4]-y[0]*z[5]*x
+        [4]*y[1]+y[0]*x[5]*y[1]*z[4]-y[0]*x[5]*y[4]*z[0]+y[0]*z[5]*x[0]*y[4]-y[5]*y[5]*
+        x[0]*z[4]+y[5]*y[5]*x[4]*z[0]+2.0*y[1]*y[1]*x[2]*z[5]-2.0*y[1]*y[1]*x[5]*z[2]+z
+        [1]*x[5]*y[2]*y[2];
+    s8 = s7-x[1]*y[2]*y[2]*z[5]-y[5]*z[5]*x[4]*y[0]+y[5]*z[5]*x[0]*y[4]-y[5]*
+        x[5]*y[4]*z[0]-y[2]*x[1]*y[6]*z[5]-y[2]*y[1]*x[5]*z[6]+y[2]*z[1]*x[5]*y[6]+y[2]
+        *y[1]*x[6]*z[5]-y[1]*z[1]*x[6]*y[5]-y[1]*x[1]*y[6]*z[5]+y[1]*x[1]*y[5]*z[6]+y
+        [1]*z[1]*x[5]*y[6]+y[5]*x[5]*y[0]*z[4]+y[2]*y[1]*x[2]*z[5]-y[2]*z[1]*x[2]*y[5];
+    s6 = s8+y[2]*x[1]*y[5]*z[2]-y[2]*y[1]*x[5]*z[2]-y[1]*y[1]*x[5]*z[6]+y[1]*
+        y[1]*x[6]*z[5]-z[1]*x[2]*y[5]*y[5]+x[1]*y[5]*y[5]*z[2]+2.0*y[1]*z[1]*x[5]*y[2]
+        -2.0*y[1]*x[1]*y[2]*z[5]-2.0*y[1]*z[1]*x[2]*y[5]+2.0*y[1]*x[1]*y[5]*z[2]-y[1]*y
+        [1]*x[6]*z[2]+y[1]*y[1]*x[2]*z[6]-2.0*y[5]*x[1]*y[6]*z[5]-2.0*y[5]*y[1]*x[5]*z
+        [6]+2.0*y[5]*z[1]*x[5]*y[6]+2.0*y[5]*y[1]*x[6]*z[5];
+    s8 = s6-y[6]*z[1]*x[6]*y[5]-y[6]*y[1]*x[5]*z[6]+y[6]*x[1]*y[5]*z[6]+y[6]*
+        y[1]*x[6]*z[5]-2.0*z[1]*x[6]*y[5]*y[5]+2.0*x[1]*y[5]*y[5]*z[6]-x[1]*y[6]*y[6]*z
+        [5]+z[1]*x[5]*y[6]*y[6]+y[5]*z[1]*x[5]*y[2]-y[5]*x[1]*y[2]*z[5]+y[5]*y[1]*x[2]*
+        z[5]-y[5]*y[1]*x[5]*z[2]-y[6]*z[1]*x[2]*y[5]+y[6]*x[1]*y[5]*z[2];
+    s7 = s8-y[1]*z[1]*x[2]*y[6]-y[1]*x[1]*y[2]*z[6]+y[1]*x[1]*y[6]*z[2]+y[1]*
+        z[1]*x[6]*y[2]+y[5]*x[5]*y[6]*z[2]-y[5]*x[2]*y[6]*z[5]+y[5]*x[6]*y[2]*z[5]-y[5]
+        *x[5]*y[2]*z[6]-x[6]*y[5]*y[5]*z[2]+x[2]*y[5]*y[5]*z[6]-y[5]*y[5]*x[4]*z[7]+y
+        [5]*y[5]*x[7]*z[4]-y[1]*x[6]*y[5]*z[2]+y[1]*x[2]*y[5]*z[6]-y[2]*x[6]*y[5]*z[2]
+        -2.0*y[2]*y[1]*x[6]*z[2];
+    s8 = s7-2.0*y[2]*z[1]*x[2]*y[6]+2.0*y[2]*x[1]*y[6]*z[2]+2.0*y[2]*y[1]*x
+        [2]*z[6]-2.0*x[1]*y[2]*y[2]*z[6]+2.0*z[1]*x[6]*y[2]*y[2]+x[6]*y[2]*y[2]*z[5]-x
+        [5]*y[2]*y[2]*z[6]+2.0*x[5]*y[6]*y[6]*z[2]-2.0*x[2]*y[6]*y[6]*z[5]-z[1]*x[2]*y
+        [6]*y[6]-y[6]*y[1]*x[6]*z[2]-y[6]*x[1]*y[2]*z[6]+y[6]*z[1]*x[6]*y[2]+y[6]*y[1]*
+        x[2]*z[6]+x[1]*y[6]*y[6]*z[2];
+    s3 = s8+y[2]*x[5]*y[6]*z[2]+y[2]*x[2]*y[5]*z[6]-y[2]*x[2]*y[6]*z[5]+y[5]*
+        z[5]*x[4]*y[7]+y[5]*x[5]*y[4]*z[7]-y[5]*z[5]*x[7]*y[4]-y[5]*x[5]*y[7]*z[4]+2.0*
+        y[4]*x[5]*y[0]*z[4]-y[3]*z[6]*x[3]*y[7]+y[3]*y[6]*x[3]*z[7]+y[3]*x[6]*y[7]*z[3]
+        -y[3]*y[6]*x[7]*z[3]-y[2]*y[1]*x[3]*z[0]-y[2]*z[1]*x[0]*y[3]+y[2]*y[1]*x[0]*z
+        [3]+y[2]*x[1]*y[3]*z[0];
+    s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
+        [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
+        z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
+        +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
+    s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
+        x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
+        *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
+        [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
+    s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
+        [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
+        z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
+        -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
+    s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
+        x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
+        *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
+        [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
+    s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
+        y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
+        *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
+        [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
+    s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
+        x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
+        *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
+        [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
+    s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
+        [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
+        z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
+        +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
+    s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
+        x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
+        *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
+        [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
+    s4 = 1/s5;
+    s2 = s3*s4;
+    const double unknown1 = s1*s2;
+    s1 = 1.0/6.0;
+    s8 = -z[2]*x[1]*y[2]*z[5]+z[2]*y[1]*x[2]*z[5]-z[2]*z[1]*x[2]*y[5]+z[2]*z
+        [1]*x[5]*y[2]+2.0*y[5]*x[7]*z[4]*z[4]-y[1]*x[2]*z[0]*z[0]+x[0]*y[3]*z[7]*z[7]
+        -2.0*z[5]*z[5]*x[4]*y[1]+2.0*z[5]*z[5]*x[1]*y[4]+z[5]*z[5]*x[0]*y[4]-2.0*z[2]*z
+        [2]*x[1]*y[3]+2.0*z[2]*z[2]*x[3]*y[1]-x[0]*y[4]*z[7]*z[7]-y[0]*x[3]*z[7]*z[7]+x
+        [1]*y[0]*z[5]*z[5];
+    s7 = s8-y[1]*x[0]*z[5]*z[5]+z[1]*y[1]*x[2]*z[6]+y[1]*x[0]*z[2]*z[2]+z[2]*
+        z[2]*x[3]*y[0]-z[2]*z[2]*x[0]*y[3]-x[1]*y[0]*z[2]*z[2]+2.0*z[5]*z[5]*x[4]*y[6]
+        -2.0*z[5]*z[5]*x[6]*y[4]-z[5]*z[5]*x[7]*y[4]-x[6]*y[7]*z[5]*z[5]+2.0*z[2]*y[1]*
+        x[2]*z[6]-2.0*z[2]*x[1]*y[2]*z[6]+2.0*z[2]*z[1]*x[6]*y[2]-y[6]*x[5]*z[7]*z[7]+
+        2.0*x[6]*y[4]*z[7]*z[7];
+    s8 = -2.0*y[6]*x[4]*z[7]*z[7]+x[6]*y[5]*z[7]*z[7]-2.0*z[2]*z[1]*x[2]*y[6]
+        +z[4]*y[6]*x[7]*z[5]+x[5]*y[4]*z[6]*z[6]+z[6]*z[6]*x[4]*y[7]-z[6]*z[6]*x[7]*y
+        [4]-2.0*z[6]*z[6]*x[7]*y[5]+2.0*z[6]*z[6]*x[5]*y[7]-y[5]*x[4]*z[6]*z[6]+2.0*z
+        [0]*z[0]*x[3]*y[4]-x[6]*y[5]*z[2]*z[2]+z[1]*z[1]*x[5]*y[6]-z[1]*z[1]*x[6]*y[5]-
+        z[5]*z[5]*x[4]*y[0];
+    s6 = s8+2.0*x[1]*y[3]*z[0]*z[0]+2.0*x[1]*y[6]*z[2]*z[2]-2.0*y[1]*x[6]*z
+        [2]*z[2]-y[1]*x[5]*z[2]*z[2]-z[1]*z[1]*x[2]*y[6]-2.0*z[1]*z[1]*x[2]*y[5]+2.0*z
+        [1]*z[1]*x[5]*y[2]+z[1]*y[1]*x[6]*z[5]+y[1]*x[2]*z[5]*z[5]+z[2]*z[1]*x[2]*y[0]+
+        z[1]*x[1]*y[5]*z[6]-z[1]*x[1]*y[6]*z[5]-z[1]*y[1]*x[5]*z[6]-z[1]*x[2]*y[6]*z[5]
+        +z[1]*x[6]*y[2]*z[5]+s7;
+    s8 = -x[1]*y[2]*z[5]*z[5]+z[1]*x[5]*y[6]*z[2]-2.0*z[2]*z[2]*x[3]*y[6]+2.0
+        *z[2]*z[2]*x[6]*y[3]+z[2]*z[2]*x[7]*y[3]-z[2]*z[2]*x[3]*y[7]-z[1]*x[6]*y[5]*z
+        [2]+2.0*z[1]*x[1]*y[5]*z[2]-2.0*x[3]*y[4]*z[7]*z[7]+2.0*x[4]*y[3]*z[7]*z[7]+x
+        [5]*y[6]*z[2]*z[2]+y[1]*x[2]*z[6]*z[6]+y[0]*x[4]*z[7]*z[7]+z[2]*x[2]*y[3]*z[0]-
+        x[1]*y[2]*z[6]*z[6];
+    s7 = s8-z[7]*z[2]*x[3]*y[7]+x[2]*y[6]*z[3]*z[3]-y[2]*x[6]*z[3]*z[3]-z[6]*
+        x[2]*y[3]*z[7]-z[2]*z[1]*x[0]*y[2]+z[6]*z[2]*x[6]*y[3]-z[6]*z[2]*x[3]*y[6]+z[6]
+        *x[2]*y[6]*z[3]+z[2]*x[1]*y[2]*z[0]+z[6]*y[2]*x[3]*z[7]-z[4]*z[5]*x[6]*y[4]+z
+        [4]*z[5]*x[4]*y[6]-z[4]*y[6]*x[5]*z[7]+z[4]*z[6]*x[4]*y[7]+z[4]*x[5]*y[4]*z[6];
+    s8 = -z[6]*y[2]*x[6]*z[3]-z[4]*y[5]*x[4]*z[6]-z[2]*y[1]*x[5]*z[6]+z[2]*x
+        [1]*y[5]*z[6]+z[4]*x[6]*y[4]*z[7]+2.0*z[4]*z[5]*x[4]*y[7]-z[4]*z[6]*x[7]*y[4]+x
+        [6]*y[7]*z[3]*z[3]-2.0*z[4]*z[5]*x[7]*y[4]-2.0*z[4]*y[5]*x[4]*z[7]-z[4]*y[6]*x
+        [4]*z[7]+z[4]*x[6]*y[5]*z[7]-z[4]*x[6]*y[7]*z[5]+2.0*z[4]*x[5]*y[4]*z[7]+z[2]*x
+        [2]*y[5]*z[6]-z[2]*x[2]*y[6]*z[5];
+    s5 = s8+z[2]*x[6]*y[2]*z[5]-z[2]*x[5]*y[2]*z[6]-z[2]*x[2]*y[3]*z[7]-x[2]*
+        y[3]*z[7]*z[7]+2.0*z[2]*x[2]*y[3]*z[1]-z[2]*y[2]*x[3]*z[0]+z[2]*y[2]*x[0]*z[3]-
+        z[2]*x[2]*y[0]*z[3]-z[7]*y[2]*x[7]*z[3]+z[7]*z[2]*x[7]*y[3]+z[7]*x[2]*y[7]*z[3]
+        +z[6]*y[1]*x[2]*z[5]-z[6]*x[1]*y[2]*z[5]+z[5]*x[1]*y[5]*z[2]+s6+s7;
+    s8 = z[5]*z[1]*x[5]*y[2]-z[5]*z[1]*x[2]*y[5]-y[6]*x[7]*z[2]*z[2]+2.0*z[2]
+        *x[2]*y[6]*z[3]-2.0*z[2]*x[2]*y[3]*z[6]+2.0*z[2]*y[2]*x[3]*z[6]+y[2]*x[3]*z[6]*
+        z[6]+y[6]*x[7]*z[5]*z[5]+z[2]*y[2]*x[3]*z[7]-z[2]*y[2]*x[7]*z[3]-2.0*z[2]*y[2]*
+        x[6]*z[3]+z[2]*x[2]*y[7]*z[3]+x[6]*y[2]*z[5]*z[5]-2.0*z[2]*x[2]*y[1]*z[3]-x[2]*
+        y[6]*z[5]*z[5];
+    s7 = s8-y[1]*x[5]*z[6]*z[6]+z[6]*x[1]*y[6]*z[2]-z[3]*z[2]*x[3]*y[6]+z[6]*
+        z[1]*x[6]*y[2]-z[6]*z[1]*x[2]*y[6]-z[6]*y[1]*x[6]*z[2]-2.0*x[5]*y[2]*z[6]*z[6]+
+        z[4]*z[1]*x[0]*y[4]-z[3]*x[2]*y[3]*z[6]-z[5]*y[1]*x[5]*z[2]+z[3]*y[2]*x[3]*z[6]
+        +2.0*x[2]*y[5]*z[6]*z[6]-z[5]*x[1]*y[5]*z[0]+y[2]*x[3]*z[7]*z[7]-x[2]*y[3]*z[6]
+        *z[6];
+    s8 = z[5]*y[5]*x[4]*z[0]+z[3]*z[2]*x[6]*y[3]+x[1]*y[5]*z[6]*z[6]+z[5]*y
+        [5]*x[7]*z[4]-z[1]*x[1]*y[2]*z[6]+z[1]*x[1]*y[6]*z[2]+2.0*z[6]*y[6]*x[7]*z[5]-z
+        [7]*y[6]*x[7]*z[2]-z[3]*y[6]*x[7]*z[2]+x[6]*y[7]*z[2]*z[2]-2.0*z[6]*y[6]*x[7]*z
+        [2]-2.0*x[6]*y[3]*z[7]*z[7]-x[6]*y[2]*z[7]*z[7]-z[5]*x[6]*y[5]*z[2]+y[6]*x[2]*z
+        [7]*z[7];
+    s6 = s8+2.0*y[6]*x[3]*z[7]*z[7]+z[6]*z[6]*x[7]*y[3]-y[6]*x[7]*z[3]*z[3]+z
+        [5]*x[5]*y[0]*z[4]+2.0*z[6]*z[6]*x[7]*y[2]-2.0*z[6]*z[6]*x[2]*y[7]-z[6]*z[6]*x
+        [3]*y[7]+z[7]*y[6]*x[7]*z[5]+z[7]*y[5]*x[7]*z[4]-2.0*z[7]*x[7]*y[3]*z[4]+2.0*z
+        [7]*x[3]*y[7]*z[4]-2.0*z[7]*x[4]*y[7]*z[3]+2.0*z[7]*x[7]*y[4]*z[3]-z[7]*y[0]*x
+        [7]*z[4]-2.0*z[7]*z[6]*x[3]*y[7]+s7;
+    s8 = s6+2.0*z[7]*z[6]*x[7]*y[3]+2.0*z[7]*x[6]*y[7]*z[3]+z[7]*x[6]*y[7]*z
+        [2]-2.0*z[7]*y[6]*x[7]*z[3]+z[7]*z[6]*x[7]*y[2]-z[7]*z[6]*x[2]*y[7]+z[5]*y[1]*x
+        [5]*z[0]-z[5]*z[1]*x[5]*y[0]+2.0*y[1]*x[6]*z[5]*z[5]-2.0*x[1]*y[6]*z[5]*z[5]+z
+        [5]*z[1]*x[0]*y[5]+z[6]*y[6]*x[3]*z[7]+2.0*z[6]*x[6]*y[7]*z[2]-z[6]*y[6]*x[7]*z
+        [3];
+    s7 = s8+2.0*z[6]*y[6]*x[2]*z[7]-z[6]*x[6]*y[3]*z[7]+z[6]*x[6]*y[7]*z[3]
+        -2.0*z[6]*x[6]*y[2]*z[7]-2.0*z[1]*y[1]*x[5]*z[2]-z[1]*y[1]*x[6]*z[2]-z[7]*z[0]*
+        x[7]*y[3]-2.0*z[6]*x[6]*y[5]*z[2]-z[2]*z[6]*x[3]*y[7]+z[2]*x[6]*y[7]*z[3]-z[2]*
+        z[6]*x[2]*y[7]+y[5]*x[6]*z[4]*z[4]+z[2]*y[6]*x[2]*z[7]+y[6]*x[7]*z[4]*z[4]+z[2]
+        *z[6]*x[7]*y[2]-2.0*x[5]*y[7]*z[4]*z[4];
+    s8 = -x[6]*y[7]*z[4]*z[4]-z[5]*y[5]*x[0]*z[4]-z[2]*x[6]*y[2]*z[7]-x[5]*y
+        [6]*z[4]*z[4]-2.0*z[5]*y[1]*x[5]*z[6]+2.0*z[5]*z[1]*x[5]*y[6]+2.0*z[5]*x[1]*y
+        [5]*z[6]-2.0*z[5]*z[1]*x[6]*y[5]-z[5]*x[5]*y[2]*z[6]+z[5]*x[5]*y[6]*z[2]+z[5]*x
+        [2]*y[5]*z[6]+z[5]*z[5]*x[4]*y[7]-y[5]*x[4]*z[7]*z[7]+x[5]*y[4]*z[7]*z[7]+z[6]*
+        z[1]*x[5]*y[6]+z[6]*y[1]*x[6]*z[5];
+    s4 = s8-z[6]*z[1]*x[6]*y[5]-z[6]*x[1]*y[6]*z[5]+z[2]*z[6]*x[7]*y[3]+2.0*z
+        [6]*x[6]*y[2]*z[5]+2.0*z[6]*x[5]*y[6]*z[2]-2.0*z[6]*x[2]*y[6]*z[5]+z[7]*z[0]*x
+        [3]*y[7]+z[7]*z[0]*x[7]*y[4]+z[3]*z[6]*x[7]*y[3]-z[3]*z[6]*x[3]*y[7]-z[3]*x[6]*
+        y[3]*z[7]+z[3]*y[6]*x[2]*z[7]-z[3]*x[6]*y[2]*z[7]+z[5]*x[5]*y[4]*z[7]+s5+s7;
+    s8 = s4+z[3]*y[6]*x[3]*z[7]-z[7]*x[0]*y[7]*z[3]+z[6]*x[5]*y[4]*z[7]+z[7]*
+        y[0]*x[7]*z[3]+z[5]*z[6]*x[4]*y[7]-2.0*z[5]*x[5]*y[6]*z[4]+2.0*z[5]*x[5]*y[4]*z
+        [6]-z[5]*x[5]*y[7]*z[4]-z[5]*y[6]*x[5]*z[7]-z[5]*z[6]*x[7]*y[4]-z[7]*z[0]*x[4]*
+        y[7]-z[5]*z[6]*x[7]*y[5]-z[5]*y[5]*x[4]*z[7]+z[7]*x[0]*y[7]*z[4];
+    s7 = s8-2.0*z[5]*y[5]*x[4]*z[6]+z[5]*z[6]*x[5]*y[7]+z[5]*x[6]*y[5]*z[7]+
+        2.0*z[5]*y[5]*x[6]*z[4]+z[6]*z[5]*x[4]*y[6]-z[6]*x[5]*y[6]*z[4]-z[6]*z[5]*x[6]*
+        y[4]-z[6]*x[6]*y[7]*z[4]-2.0*z[6]*y[6]*x[5]*z[7]+z[6]*x[6]*y[4]*z[7]-z[6]*y[5]*
+        x[4]*z[7]-z[6]*y[6]*x[4]*z[7]+z[6]*y[6]*x[7]*z[4]+z[6]*y[5]*x[6]*z[4]+2.0*z[6]*
+        x[6]*y[5]*z[7];
+    s8 = -2.0*z[6]*x[6]*y[7]*z[5]-z[2]*y[1]*x[2]*z[0]+2.0*z[7]*z[6]*x[4]*y[7]
+        -2.0*z[7]*x[6]*y[7]*z[4]-2.0*z[7]*z[6]*x[7]*y[4]+z[7]*z[5]*x[4]*y[7]-z[7]*z[5]*
+        x[7]*y[4]-z[7]*x[5]*y[7]*z[4]+2.0*z[7]*y[6]*x[7]*z[4]-z[7]*z[6]*x[7]*y[5]+z[7]*
+        z[6]*x[5]*y[7]-z[7]*x[6]*y[7]*z[5]+z[1]*z[1]*x[6]*y[2]+s7+x[1]*y[5]*z[2]*z[2];
+    s6 = s8+2.0*z[2]*y[2]*x[1]*z[3]-2.0*z[2]*y[2]*x[3]*z[1]-2.0*x[1]*y[4]*z
+        [0]*z[0]+2.0*y[1]*x[4]*z[0]*z[0]+2.0*x[2]*y[7]*z[3]*z[3]-2.0*y[2]*x[7]*z[3]*z
+        [3]-x[1]*y[5]*z[0]*z[0]+z[0]*z[0]*x[7]*y[4]+z[0]*z[0]*x[3]*y[7]+x[2]*y[3]*z[0]*
+        z[0]-2.0*y[1]*x[3]*z[0]*z[0]+y[5]*x[4]*z[0]*z[0]-2.0*z[0]*z[0]*x[4]*y[3]+x[1]*y
+        [2]*z[0]*z[0]-z[0]*z[0]*x[4]*y[7]+y[1]*x[5]*z[0]*z[0];
+    s8 = s6-y[2]*x[3]*z[0]*z[0]+y[1]*x[0]*z[3]*z[3]-2.0*x[0]*y[7]*z[3]*z[3]-x
+        [0]*y[4]*z[3]*z[3]-2.0*x[2]*y[0]*z[3]*z[3]-x[1]*y[0]*z[3]*z[3]+y[0]*x[4]*z[3]*z
+        [3]-2.0*z[0]*y[1]*x[0]*z[4]+2.0*z[0]*z[1]*x[0]*y[4]+2.0*z[0]*x[1]*y[0]*z[4]-2.0
+        *z[0]*z[1]*x[4]*y[0]-2.0*z[3]*x[2]*y[3]*z[7]-2.0*z[3]*z[2]*x[3]*y[7]+2.0*z[3]*z
+        [2]*x[7]*y[3];
+    s7 = s8+2.0*z[3]*y[2]*x[3]*z[7]+2.0*z[5]*y[5]*x[4]*z[1]+2.0*z[0]*y[1]*x
+        [0]*z[3]-z[0]*y[0]*x[3]*z[7]-2.0*z[0]*y[0]*x[3]*z[4]-z[0]*x[1]*y[0]*z[2]+z[0]*z
+        [1]*x[2]*y[0]-z[0]*y[1]*x[0]*z[5]-z[0]*z[1]*x[0]*y[2]-z[0]*x[0]*y[7]*z[3]-2.0*z
+        [0]*z[1]*x[0]*y[3]-z[5]*x[5]*y[4]*z[0]-2.0*z[0]*x[0]*y[4]*z[3]+z[0]*x[0]*y[7]*z
+        [4]-z[0]*z[2]*x[0]*y[3];
+    s8 = s7+z[0]*x[5]*y[0]*z[4]+z[0]*z[1]*x[0]*y[5]-z[0]*x[2]*y[0]*z[3]-z[0]*
+        z[1]*x[5]*y[0]-2.0*z[0]*x[1]*y[0]*z[3]+2.0*z[0]*y[0]*x[4]*z[3]-z[0]*x[0]*y[4]*z
+        [7]+z[0]*x[1]*y[0]*z[5]+z[0]*y[0]*x[7]*z[3]+z[0]*y[2]*x[0]*z[3]-z[0]*y[5]*x[0]*
+        z[4]+z[0]*z[2]*x[3]*y[0]+z[0]*x[2]*y[3]*z[1]+z[0]*x[0]*y[3]*z[7]-z[0]*x[2]*y[1]
+        *z[3];
+    s5 = s8+z[0]*y[1]*x[0]*z[2]+z[3]*x[1]*y[3]*z[0]-2.0*z[3]*y[0]*x[3]*z[7]-z
+        [3]*y[0]*x[3]*z[4]-z[3]*x[1]*y[0]*z[2]+z[3]*z[0]*x[7]*y[4]+2.0*z[3]*z[0]*x[3]*y
+        [7]+2.0*z[3]*x[2]*y[3]*z[0]-z[3]*y[1]*x[3]*z[0]-z[3]*z[1]*x[0]*y[3]-z[3]*z[0]*x
+        [4]*y[3]+z[3]*x[1]*y[2]*z[0]-z[3]*z[0]*x[4]*y[7]-2.0*z[3]*z[2]*x[0]*y[3]-z[3]*x
+        [0]*y[4]*z[7]-2.0*z[3]*y[2]*x[3]*z[0];
+    s8 = s5+2.0*z[3]*z[2]*x[3]*y[0]+z[3]*x[2]*y[3]*z[1]+2.0*z[3]*x[0]*y[3]*z
+        [7]+z[3]*y[1]*x[0]*z[2]-z[4]*y[0]*x[3]*z[7]-z[4]*x[1]*y[5]*z[0]-z[4]*y[1]*x[0]*
+        z[5]+2.0*z[4]*z[0]*x[7]*y[4]+z[4]*z[0]*x[3]*y[7]+2.0*z[4]*y[5]*x[4]*z[0]+2.0*y
+        [0]*x[7]*z[3]*z[3]+2.0*y[2]*x[0]*z[3]*z[3]-x[2]*y[1]*z[3]*z[3]-y[0]*x[3]*z[4]*z
+        [4];
+    s7 = s8-y[1]*x[0]*z[4]*z[4]+x[1]*y[0]*z[4]*z[4]+2.0*x[0]*y[7]*z[4]*z[4]+
+        2.0*x[5]*y[0]*z[4]*z[4]-2.0*y[5]*x[0]*z[4]*z[4]+2.0*z[1]*z[1]*x[2]*y[0]-2.0*z
+        [1]*z[1]*x[0]*y[2]+z[1]*z[1]*x[0]*y[4]-z[1]*z[1]*x[0]*y[3]-z[1]*z[1]*x[4]*y[0]+
+        2.0*z[1]*z[1]*x[0]*y[5]-2.0*z[1]*z[1]*x[5]*y[0]+x[2]*y[3]*z[1]*z[1]-x[5]*y[4]*z
+        [0]*z[0]-z[0]*z[0]*x[7]*y[3];
+    s8 = s7+x[7]*y[4]*z[3]*z[3]-x[4]*y[7]*z[3]*z[3]+y[2]*x[1]*z[3]*z[3]+x[0]*
+        y[3]*z[4]*z[4]-2.0*y[0]*x[7]*z[4]*z[4]+x[3]*y[7]*z[4]*z[4]-x[7]*y[3]*z[4]*z[4]-
+        y[5]*x[1]*z[4]*z[4]+x[5]*y[1]*z[4]*z[4]+z[1]*z[1]*x[3]*y[0]+y[5]*x[4]*z[1]*z[1]
+        -y[2]*x[3]*z[1]*z[1]-x[5]*y[4]*z[1]*z[1]-z[4]*x[0]*y[4]*z[3]-z[4]*z[0]*x[4]*y
+        [3];
+    s6 = s8-z[4]*z[1]*x[4]*y[0]-2.0*z[4]*z[0]*x[4]*y[7]+z[4]*y[1]*x[5]*z[0]
+        -2.0*z[5]*x[5]*y[4]*z[1]-z[4]*x[1]*y[4]*z[0]+z[4]*y[0]*x[4]*z[3]-2.0*z[4]*x[0]*
+        y[4]*z[7]+z[4]*x[1]*y[0]*z[5]-2.0*z[1]*x[1]*y[2]*z[5]+z[4]*x[0]*y[3]*z[7]+2.0*z
+        [5]*x[5]*y[1]*z[4]+z[4]*y[1]*x[4]*z[0]+z[1]*y[1]*x[0]*z[3]+z[1]*x[1]*y[3]*z[0]
+        -2.0*z[1]*x[1]*y[5]*z[0]-2.0*z[1]*x[1]*y[0]*z[2];
+    s8 = s6-2.0*z[1]*y[1]*x[0]*z[5]-z[1]*y[1]*x[0]*z[4]+2.0*z[1]*y[1]*x[2]*z
+        [5]-z[1]*y[1]*x[3]*z[0]-2.0*z[5]*y[5]*x[1]*z[4]+z[1]*y[5]*x[4]*z[0]+z[1]*x[1]*y
+        [0]*z[4]+2.0*z[1]*x[1]*y[2]*z[0]-z[1]*z[2]*x[0]*y[3]+2.0*z[1]*y[1]*x[5]*z[0]-z
+        [1]*x[1]*y[0]*z[3]-z[1]*x[1]*y[4]*z[0]+2.0*z[1]*x[1]*y[0]*z[5]-z[1]*y[2]*x[3]*z
+        [0];
+    s7 = s8+z[1]*z[2]*x[3]*y[0]-z[1]*x[2]*y[1]*z[3]+z[1]*y[1]*x[4]*z[0]+2.0*z
+        [1]*y[1]*x[0]*z[2]+2.0*z[0]*z[1]*x[3]*y[0]+2.0*z[0]*x[0]*y[3]*z[4]+z[0]*z[5]*x
+        [0]*y[4]+z[0]*y[0]*x[4]*z[7]-z[0]*y[0]*x[7]*z[4]-z[0]*x[7]*y[3]*z[4]-z[0]*z[5]*
+        x[4]*y[0]-z[0]*x[5]*y[4]*z[1]+z[3]*z[1]*x[3]*y[0]+z[3]*x[0]*y[3]*z[4]+z[3]*z[0]
+        *x[3]*y[4]+z[3]*y[0]*x[4]*z[7];
+    s8 = s7+z[3]*x[3]*y[7]*z[4]-z[3]*x[7]*y[3]*z[4]-z[3]*x[3]*y[4]*z[7]+z[3]*
+        x[4]*y[3]*z[7]-z[3]*y[2]*x[3]*z[1]+z[3]*z[2]*x[3]*y[1]-z[3]*z[2]*x[1]*y[3]-2.0*
+        z[3]*z[0]*x[7]*y[3]+z[4]*z[0]*x[3]*y[4]+2.0*z[4]*z[5]*x[0]*y[4]+2.0*z[4]*y[0]*x
+        [4]*z[7]-2.0*z[4]*x[5]*y[4]*z[0]+z[4]*y[5]*x[4]*z[1]+z[4]*x[7]*y[4]*z[3]-z[4]*x
+        [4]*y[7]*z[3];
+    s3 = s8-z[4]*x[3]*y[4]*z[7]+z[4]*x[4]*y[3]*z[7]-2.0*z[4]*z[5]*x[4]*y[0]-z
+        [4]*x[5]*y[4]*z[1]+z[4]*z[5]*x[1]*y[4]-z[4]*z[5]*x[4]*y[1]-2.0*z[1]*y[1]*x[2]*z
+        [0]+z[1]*z[5]*x[0]*y[4]-z[1]*z[5]*x[4]*y[0]-z[1]*y[5]*x[1]*z[4]+z[1]*x[5]*y[1]*
+        z[4]+z[1]*z[5]*x[1]*y[4]-z[1]*z[5]*x[4]*y[1]+z[1]*z[2]*x[3]*y[1]-z[1]*z[2]*x[1]
+        *y[3]+z[1]*y[2]*x[1]*z[3];
+    s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
+        [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
+        z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
+        +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
+    s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
+        x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
+        *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
+        [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
+    s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
+        [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
+        z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
+        -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
+    s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
+        x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
+        *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
+        [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
+    s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
+        y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
+        *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
+        [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
+    s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
+        x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
+        *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
+        [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
+    s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
+        [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
+        z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
+        +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
+    s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
+        x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
+        *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
+        [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
+    s4 = 1/s5;
+    s2 = s3*s4;
+    const double unknown2 = s1*s2;
+
+    return Point<3> (unknown0, unknown1, unknown2);
+  }
 
 
 
-template <int dim>
-double TriaObjectAccessor<1, dim>::measure () const
-{
-  return std::sqrt((vertex(1)-vertex(0)).square());
-}
+  template <int structdim, int dim, int spacedim>
+  Point<spacedim>
+  barycenter (const TriaAccessor<structdim, dim, spacedim> &)
+  {
+                                    // this function catches all the cases not
+                                    // explicitly handled above
+    Assert (false, ExcNotImplemented());
+    return Point<spacedim>();
+  }
 
 
 
-template <int dim>
-unsigned int TriaObjectAccessor<1, dim>::number_of_children () const
-{
-  if (!has_children())
-    return 1;
-  else
-    {
-      unsigned int sum = 0;
-      for (unsigned int c=0; c<2; ++c)
-       sum += child(c)->number_of_children();
-      return sum;
-    };
-}
 
+  template <int dim, int spacedim>
+  double
+  measure (const TriaAccessor<1, dim, spacedim> &accessor)
+  {
+                                    // remember that we use (dim-)linear
+                                    // mappings
+    return std::sqrt((accessor.vertex(1)-accessor.vertex(0)).square());
+  }
 
 
-/*------------------------ Functions: QuadAccessor ---------------------------*/
+#if deal_II_dimension == 2
 
-template <int dim>
-const unsigned int TriaObjectAccessor<2, dim>::objectdim;
+  double
+  measure (const TriaAccessor<2,2,2> &accessor)
+  {
+                                    // the evaluation of the formulae
+                                    // is a bit tricky when done dimension
+                                    // independently, so we write this function
+                                    // for 2D and 3D separately
+/*
+  Get the computation of the measure by this little Maple script. We
+  use the blinear mapping of the unit quad to the real quad. However,
+  every transformation mapping the unit faces to straight lines should
+  do.
 
-
-template <int dim>
-void
-TriaObjectAccessor<2, dim>::set (const internal::Triangulation::TriaObject<2> &quad) const
-{
-  objects().cells[this->present_index] = quad;
-}
-
-
-
-template <int dim>
-unsigned int TriaObjectAccessor<2, dim>::vertex_index (const unsigned int corner) const
-{
-  Assert (corner<4, ExcIndexRange(corner,0,4));
-
-                                  // table used to switch the vertices, if the
-                                  // line orientation is wrong,
-                                  //
-                                  // first index: line orientation 0: false or
-                                  // 1: true=standard
-                                  //
-                                  // second index: vertex index to be switched
-                                  // (or not)
-  
-  static const unsigned int switch_table[2][2]={{1,0},{0,1}};
-  
-  return line(corner%2)->vertex_index(switch_table[line_orientation(corner%2)][corner/2]);
-}
-
-
-
-template <int dim>
-Point<dim> &
-TriaObjectAccessor<2, dim>::vertex (const unsigned int i) const
-{
-  return const_cast<Point<dim> &> (this->tria->vertices[vertex_index(i)]);
-}
-
-
-
-template <int dim>
-void
-TriaObjectAccessor<2, dim>::set_used_flag () const
-{
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  objects().used[this->present_index] = true;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::clear_used_flag () const
-{
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  objects().used[this->present_index] = false;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::recursively_set_user_flag () const
-{
-  set_user_flag ();
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_set_user_flag ();
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::recursively_clear_user_flag () const
-{
-  clear_user_flag ();
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_clear_user_flag ();
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::clear_user_data () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().clear_user_data(this->present_index);
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::set_user_pointer (void *p) const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_pointer(this->present_index) = p;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::clear_user_pointer () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_pointer(this->present_index) = 0;
-}
-
-
-
-template <int dim>
-void * TriaObjectAccessor<2, dim>::user_pointer () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return objects().user_pointer(this->present_index);
-}
-
-
-
-template <int dim>
-void
-TriaObjectAccessor<2, dim>::recursively_set_user_pointer (void *p) const
-{
-  set_user_pointer (p);
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_set_user_pointer (p);
-}
-
-
-
-template <int dim>
-void
-TriaObjectAccessor<2, dim>::recursively_clear_user_pointer () const
-{
-  clear_user_pointer ();
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_clear_user_pointer ();
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::set_user_index (const unsigned int p) const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_index(this->present_index) = p;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::clear_user_index () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  objects().user_index(this->present_index) = 0;
-}
-
-
-
-template <int dim>
-unsigned int  TriaObjectAccessor<2, dim>::user_index () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return objects().user_index(this->present_index);
-}
-
-
-
-template <int dim>
-void
-TriaObjectAccessor<2, dim>::recursively_set_user_index (const unsigned int p) const
-{
-  set_user_index (p);
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_set_user_index (p);
-}
-
-
-
-template <int dim>
-void
-TriaObjectAccessor<2, dim>::recursively_clear_user_index () const
-{
-  clear_user_index ();
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_clear_user_index ();
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::set_children (const unsigned int i, const int index) const
-{
-  Assert (used(),
-         TriaAccessorExceptions::ExcCellNotUsed());
-  Assert (i%2==0, TriaAccessorExceptions::ExcSetOnlyEvenChildren(i));
-  Assert ((index==-1) ||
-         (i==0 && !has_children() && (index>=0)) ||
-         (i>0  &&  has_children() && (index>=0) &&
-          objects().children[2*this->present_index+i/2] == -1),
-         TriaAccessorExceptions::ExcCantSetChildren(index));
-
-  objects().children[2*this->present_index+i/2] = index;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::clear_children () const
-{
-  set_children (0, -1);
-  set_children (2, -1);
-}
-
-
-
-template <int dim>
-unsigned char TriaObjectAccessor<2, dim>::boundary_indicator () const
-{
-  Assert (dim>2, ExcImpossibleInDim(dim));
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-
-  return objects().material_id[this->present_index];
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::set_boundary_indicator (const unsigned char boundary_ind) const
-{
-  Assert (dim>2, ExcImpossibleInDim(dim));
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-
-  objects().material_id[this->present_index] = boundary_ind;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<2, dim>::set_all_boundary_indicators (const unsigned char boundary_ind) const
-{
-  set_boundary_indicator (boundary_ind);
-
-  for (unsigned int i=0; i<4; ++i)
-    this->line(i)->set_boundary_indicator (boundary_ind);
-}
-
-
-
-template <int dim>
-bool TriaObjectAccessor<2, dim>::at_boundary () const
-{
-                                  // error checking is done
-                                  // in boundary_indicator()
-  return (boundary_indicator() != 255);
-}
-
-
-
-template <int dim>
-double TriaObjectAccessor<2, dim>::diameter () const
-{
-  return std::sqrt(std::max((vertex(3)-vertex(0)).square(),
-                           (vertex(2)-vertex(1)).square()));
-}
-
-
-
-template <int dim>
-Point<dim> TriaObjectAccessor<2, dim>::center () const
-{
-  return (vertex(0)+vertex(1)+vertex(2)+vertex(3))/4.;
-}
-
-
-#if deal_II_dimension == 2
-
-template <>
-Point<2> TriaObjectAccessor<2, 2>::barycenter () const
-{
-                                  // the evaluation of the formulae
-                                  // is a bit tricky when done dimension
-                                  // independently, so we write this function
-                                  // for 2D and 3D separately
-/*
-  Get the computation of the barycenter by this little Maple script. We
-  use the bilinear mapping of the unit quad to the real quad. However,
-  every transformation mapping the unit faces to strait lines should
-  do.
-
-  Remember that the area of the quad is given by
-  |K| = \int_K 1 dx dy  = \int_{\hat K} |det J| d(xi) d(eta)
-  and that the barycenter is given by
-  \vec x_s = 1/|K| \int_K \vec x dx dy
-  = 1/|K| \int_{\hat K} \vec x(xi,eta) |det J| d(xi) d(eta)
-
-  # x and y are arrays holding the x- and y-values of the four vertices
-  # of this cell in real space. 
-  x := array(0..3);
-  y := array(0..3);
-  tphi[0] := (1-xi)*(1-eta):
-  tphi[1] :=     xi*(1-eta):
-  tphi[2] := (1-xi)*eta:
-  tphi[3] :=     xi*eta:
-  x_real := sum(x[s]*tphi[s], s=0..3):
-  y_real := sum(y[s]*tphi[s], s=0..3):
-  detJ := diff(x_real,xi)*diff(y_real,eta) - diff(x_real,eta)*diff(y_real,xi):
-
-  measure := simplify ( int ( int (detJ, xi=0..1), eta=0..1)):
-
-  xs := simplify (1/measure * int ( int (x_real * detJ, xi=0..1), eta=0..1)):
-  ys := simplify (1/measure * int ( int (y_real * detJ, xi=0..1), eta=0..1)):
-  readlib(C):
-
-  C(array(1..2, [xs, ys]), optimized);
-*/
-
-  const double x[4] = { vertex(0)(0),
-                       vertex(1)(0),
-                       vertex(2)(0),
-                       vertex(3)(0)  };
-  const double y[4] = { vertex(0)(1),
-                       vertex(1)(1),
-                       vertex(2)(1),
-                       vertex(3)(1)  };
-  const double t1 = x[0]*x[1];
-  const double t3 = x[0]*x[0];
-  const double t5 = x[1]*x[1];
-  const double t9 = y[0]*x[0];
-  const double t11 = y[1]*x[1];
-  const double t14 = x[2]*x[2];
-  const double t16 = x[3]*x[3];
-  const double t20 = x[2]*x[3];
-  const double t27 = t1*y[1]+t3*y[1]-t5*y[0]-t3*y[2]+t5*y[3]+t9*x[2]-t11*x[3]-t1*y[0]-t14*y[3]+t16*y[2]-t16*y[1]+t14*y[0]-t20*y[3]-x[0]*x[2]*y[2]+x[1]*x[3]*y[3]+t20*y[2];
-  const double t37 = 1/(-x[1]*y[0]+x[1]*y[3]+y[0]*x[2]+x[0]*y[1]-x[0]*y[2]-y[1]*x[3]-x[2]*y[3]+x[3]*y[2]);
-  const double t39 = y[2]*y[2];
-  const double t51 = y[0]*y[0];
-  const double t53 = y[1]*y[1];
-  const double t59 = y[3]*y[3];
-  const double t63 = t39*x[3]+y[2]*y[0]*x[2]+y[3]*x[3]*y[2]-y[2]*x[2]*y[3]-y[3]*y[1]*x[3]-t9*y[2]+t11*y[3]+t51*x[2]-t53*x[3]-x[1]*t51+t9*y[1]-t11*y[0]+x[0]*t53-t59*x[2]+t59*x[1]-t39*x[0];
-
-  return Point<2> (t27*t37/3, t63*t37/3);
-}
-
-
-
-template <>
-double TriaObjectAccessor<2, 2>::measure () const
-{
-                                  // the evaluation of the formulae
-                                  // is a bit tricky when done dimension
-                                  // independently, so we write this function
-                                  // for 2D and 3D separately
-/*
-  Get the computation of the measure by this little Maple script. We
-  use the blinear mapping of the unit quad to the real quad. However,
-  every transformation mapping the unit faces to straight lines should
-  do.
-
-  Remember that the area of the quad is given by
-  \int_K 1 dx dy  = \int_{\hat K} |det J| d(xi) d(eta)
+  Remember that the area of the quad is given by
+  \int_K 1 dx dy  = \int_{\hat K} |det J| d(xi) d(eta)
 
   # x and y are arrays holding the x- and y-values of the four vertices
   # of this cell in real space. 
   x := array(0..3);
   y := array(0..3);
   tphi[0] := (1-xi)*(1-eta):
-  tphi[1] :=     xi*(1-eta):
-  tphi[2] := (1-xi)*eta:
-  tphi[3] :=     xi*eta:
-  x_real := sum(x[s]*tphi[s], s=0..3):
-  y_real := sum(y[s]*tphi[s], s=0..3):
-  detJ := diff(x_real,xi)*diff(y_real,eta) - diff(x_real,eta)*diff(y_real,xi):
-
-  measure := simplify ( int ( int (detJ, xi=0..1), eta=0..1)):
-  readlib(C):
-
-  C(measure, optimized);
-
-  additional optimizaton: divide by 2 only one time
-*/
-
-  const double x[4] = { vertex(0)(0),
-                       vertex(1)(0),
-                       vertex(2)(0),
-                       vertex(3)(0)  };
-  const double y[4] = { vertex(0)(1),
-                       vertex(1)(1),
-                       vertex(2)(1),
-                       vertex(3)(1)  };
-
-  return (-x[1]*y[0]+x[1]*y[3]+y[0]*x[2]+x[0]*y[1]-x[0]*y[2]-y[1]*x[3]-x[2]*y[3]+x[3]*y[2])/2;
-}
-
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-template <>
-Point<3> TriaObjectAccessor<2, 3>::barycenter () const
-{
-                                  // the evaluation of the formulae
-                                  // is a bit tricky when done dimension
-                                  // independently, so we write this function
-                                  // for 2D and 3D separately
-/*
-  To compute the barycenter, we first have to find out the size of
-  an area element in real space; this equals the Jacobian determinant
-  at this point, then. To do so, find out the points in real space
-  belonging to
-  xi,eta
-  xi+dxi, eta
-  xi, eta+deta
-  To this end, remember that the mapping is
-  x(xi,eta) = \sum_i=0^3 x_i phi_i(xi,eta)
-  y(xi,eta) = \sum_i=0^3 y_i phi_i(xi,eta)
-  z(xi,eta) = \sum_i=0^3 z_i phi_i(xi,eta)
-  with x_i, y_i being the four vertices and the phi_i the shape functions
-  corresponding to these four vertices of this face. Now the real space
-  points belonging to the above points on the unit face are:
-  x, y, z
-  x+sum x_i \partial_xi phi_i(xi,eta) dxi,
-  y+sum y_i \partial_xi phi_i(xi,eta) dxi,
-  z+sum z_i \partial_xi phi_i(xi,eta) dxi
-  x+sum x_i \partial_eta phi_i(xi,eta) deta,
-  y+sum y_i \partial_eta phi_i(xi,eta) deta,
-  z+sum z_i \partial_eta phi_i(xi,eta) deta
-  The unit infinitesimal vectors at the point xi,eta have the direction
-  dxi, 0
-  0, deta
-  and are therefore in real space
-  sum x_i \partial_xi phi_i(xi,eta) dxi,
-  sum y_i \partial_xi phi_i(xi,eta) dxi,
-  sum z_i \partial_xi phi_i(xi,eta) dxi
-  sum x_i \partial_eta phi_i(xi,eta) deta,
-  sum y_i \partial_eta phi_i(xi,eta) deta
-  sum z_i \partial_eta phi_i(xi,eta) deta
-  or in other form:
-  \partial_xi (x,y,z) dxi
-  \partial_eta (x,y,z) deta
-  Then the area element is the length of the cross-product of these two vectors and
-  the Jacobian determinant is this expression divided by dxi deta:
-  |J| = |(\partial_xi (x,y,z) \times (\partial_eta (x,y,z)|
-
-  There is a script in the deal.II/source/fe/scripts/3d directory, which does
-  these computations in Maple.
-*/
-  Assert (false, ExcNotImplemented());
-  
-  return Point<3> ();
-}
-
-
-
-template <>
-double TriaObjectAccessor<2, 3>::measure () const
-{
-                                  // the evaluation of the formulae
-                                  // is a bit tricky when done dimension
-                                  // independently, so we write this function
-                                  // for 2D and 3D separately
-                                  //
-                                  // for documentation, see the barycenter
-                                  // function above.
-  Assert (false, ExcNotImplemented());
-  return 0;
-}
-
-#endif
-
-
-template <int dim>
-unsigned int TriaObjectAccessor<2, dim>::number_of_children () const
-{
-  if (!has_children())
-    return 1;
-  else
-    {
-      unsigned int sum = 0;
-      for (unsigned int c=0; c<n_children(); ++c)
-       sum += child(c)->number_of_children();
-      return sum;
-    };
-}
-
-
-template <int dim>
-void
-TriaObjectAccessor<2, dim>::
-set_line_orientation (const unsigned int ,
-                      const bool         ) const
-{
-  Assert(false,
-        ExcMessage("The line orientation of Quads can only be set in 3D. In 2D the lines are alway in standard orientation."));}
-
-
-
-#if deal_II_dimension == 3
-
-template <>
-void
-TriaObjectAccessor<2, 3>::
-set_line_orientation (const unsigned int line,
-                      const bool         orientation) const
-{
-  const int dim=3;
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  Assert (line<GeometryInfo<dim>::lines_per_face,
-          ExcIndexRange (line, 0, GeometryInfo<3>::lines_per_face));
-  Assert (this->present_index * GeometryInfo<dim>::lines_per_face + line
-          < this->tria->faces->quads.line_orientations.size(),
-          ExcInternalError());
-          
-  this->tria->faces
-    ->quads.line_orientations[this->present_index *
-                              GeometryInfo<dim>::lines_per_face
-                              +
-                              line]  = orientation;
-}
-
-#endif
-
-
-/*------------------------ Functions: TriaObjectAccessor ---------------------------*/
-
-
-template <int dim>
-const unsigned int TriaObjectAccessor<3, dim>::objectdim;
-
-
-#if deal_II_dimension == 3
-
-template <>
-void
-TriaObjectAccessor<3, 3>::set (const internal::Triangulation::TriaObject<3> &hex) const
-{
-  this->tria->levels[this->present_level]
-    ->cells.cells[this->present_index] = hex;
-}
-
-#endif
-
-
-template <int dim>
-unsigned int TriaObjectAccessor<3, dim>::vertex_index (const unsigned int corner) const
-{
-  Assert (corner<8, ExcIndexRange(corner,0,8));
-
-                                  // get the corner indices by asking either
-                                  // the bottom or the top face for its
-                                  // vertices. handle non-standard faces by
-                                  // calling the vertex reordering function
-                                  // from GeometryInfo
-
-                                  // bottom face (4) for first four vertices,
-                                  // top face (5) for the rest
-  const unsigned int face_index=4+corner/4;
-
-  return quad(face_index)->vertex_index(GeometryInfo<dim>
-                                       ::standard_to_real_face_vertex(corner%4,
-                                                                      face_orientation(face_index),
-                                                                      face_flip(face_index),
-                                                                      face_rotation(face_index)));
-}
-
-
-
-template <int dim>
-Point<dim> &
-TriaObjectAccessor<3, dim>::vertex (const unsigned int i) const
-{
-  return const_cast<Point<dim> &> (this->tria->vertices[vertex_index(i)]);
-}
-
-
-#if deal_II_dimension == 3
-
-template <>
-void TriaObjectAccessor<3, 3>::set_used_flag () const
-{
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  this->tria->levels[this->present_level]->cells.used[this->present_index] = true;
-}
-
-
-template <>
-void TriaObjectAccessor<3, 3>::clear_used_flag () const
-{
-  Assert (this->state() == IteratorState::valid,
-         TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  this->tria->levels[this->present_level]->cells.used[this->present_index] = false;
-}
-
-#endif
-
-
-template <int dim>
-void TriaObjectAccessor<3, dim>::recursively_set_user_flag () const
-{
-  set_user_flag ();
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_set_user_flag ();
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<3, dim>::recursively_clear_user_flag () const
-{
-  clear_user_flag ();
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_clear_user_flag ();
-}
-
-
-#if deal_II_dimension == 3
-
-template <>
-void TriaObjectAccessor<3, 3>::clear_user_data () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  this->tria->levels[this->present_level]->cells.clear_user_data(this->present_index);
-}
-
-
-
-template <>
-void TriaObjectAccessor<3, 3>::set_user_pointer (void *p) const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  this->tria->levels[this->present_level]->cells.user_pointer(this->present_index) = p;
-}
-
-
-template <>
-void TriaObjectAccessor<3, 3>::clear_user_pointer () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  this->tria->levels[this->present_level]->cells.user_pointer(this->present_index) = 0;
-}
-
-
-template <>
-void * TriaObjectAccessor<3, 3>::user_pointer () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return this->tria->levels[this->present_level]->cells.user_pointer(this->present_index);
-}
-
-
-template <>
-void TriaObjectAccessor<3, 3>::set_user_index (const unsigned int p) const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  this->tria->levels[this->present_level]->cells.user_index(this->present_index) = p;
-}
-
-
-template <>
-void TriaObjectAccessor<3, 3>::clear_user_index () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  this->tria->levels[this->present_level]->cells.user_index(this->present_index) = 0;
-}
-
-
-template <>
-unsigned int  TriaObjectAccessor<3, 3>::user_index () const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  return this->tria->levels[this->present_level]->cells.user_index(this->present_index);
-}
-
-#endif
-
-
-template <int dim>
-void
-TriaObjectAccessor<3, dim>::recursively_set_user_pointer (void *p) const
-{
-  set_user_pointer (p);
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_set_user_pointer (p);
-}
-
-
-
-template <int dim>
-void
-TriaObjectAccessor<3, dim>::recursively_clear_user_pointer () const
-{
-  clear_user_pointer ();
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_clear_user_pointer ();
-}
-
-
-template <int dim>
-void
-TriaObjectAccessor<3, dim>::recursively_set_user_index (const unsigned int p) const
-{
-  set_user_index (p);
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_set_user_index (p);
-}
-
-
-
-template <int dim>
-void
-TriaObjectAccessor<3, dim>::recursively_clear_user_index () const
-{
-  clear_user_index ();
-
-  if (has_children())
-    for (unsigned int c=0; c<n_children(); ++c)
-      child(c)->recursively_clear_user_index ();
-}
-
-
-#if deal_II_dimension == 3
-
-template <>
-void TriaObjectAccessor<3,3>::set_children (const unsigned int i, const int index) const
-{
-  Assert (used(), TriaAccessorExceptions::ExcCellNotUsed());
-  Assert (i%2==0, TriaAccessorExceptions::ExcSetOnlyEvenChildren(i));
-  Assert ((index==-1) ||
-         (i==0 && !has_children() && (index>=0)) ||
-         (i>0  &&  has_children() && (index>=0) &&
-          this->tria->levels[this->present_level]->
-          cells.children[4*this->present_index+i/2] == -1),
-         TriaAccessorExceptions::ExcCantSetChildren(index));
-
-  this->tria->levels[this->present_level]->cells.children[4*this->present_index+i/2] = index;
-}
-
-#endif
-
-
-template <int dim>
-void TriaObjectAccessor<3, dim>::clear_children () const
-{
-  set_children (0,-1);
-  set_children (2,-1);
-  set_children (4,-1);
-  set_children (6,-1);
-}
-
-
-
-template <int dim>
-unsigned char TriaObjectAccessor<3, dim>::boundary_indicator () const
-{
-  Assert (false, ExcImpossibleInDim(dim));
-  return 255;
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<3, dim>::set_boundary_indicator (const unsigned char) const
-{
-  Assert (false, ExcImpossibleInDim(dim));
-}
-
-
-
-template <int dim>
-void TriaObjectAccessor<3, dim>::set_all_boundary_indicators (const unsigned char) const
-{
-  Assert (false, ExcImpossibleInDim(dim));
-}
-
-
-
-template <int dim>
-bool TriaObjectAccessor<3, dim>::at_boundary () const
-{
-                                  // error checking is done
-                                  // in boundary_indicator()
-  return (boundary_indicator() != 255);
-}
-
-
-
-template <int dim>
-double TriaObjectAccessor<3, dim>::diameter () const
-{
-  return std::sqrt(std::max( std::max((vertex(7)-vertex(0)).square(),
-                                     (vertex(6)-vertex(1)).square()),
-                            std::max((vertex(2)-vertex(5)).square(),
-                                     (vertex(3)-vertex(4)).square()) ));
-}
-
-
-
-template <int dim>
-Point<dim> TriaObjectAccessor<3, dim>::center () const
-{
-  return (vertex(0)+vertex(1)+vertex(2)+vertex(3)+
-         vertex(4)+vertex(5)+vertex(6)+vertex(7))/8.;
-}
-
-
-#if deal_II_dimension == 3
-
-template <>
-Point<3> TriaObjectAccessor<3, 3>::barycenter () const
-{
-/*
-  Get the computation of the barycenter by this little Maple script. We
-  use the trilinear mapping of the unit hex to the real hex.
-
-  Remember that the area of the hex is given by
-  |K| = \int_K 1 dx dy dz = \int_{\hat K} |det J| d(xi) d(eta) d(zeta)
-  and that the barycenter is given by
-  \vec x_s = 1/|K| \int_K \vec x dx dy dz
-  = 1/|K| \int_{\hat K} \vec x(xi,eta,zeta) |det J| d(xi) d(eta) d(zeta)
-
-  Note, that in the ordering of the shape functions tphi[0]-tphi[7]
-  below, eta and zeta have been exchanged (zeta belongs to the y, and
-  eta to the z direction). However, the resulting Jacobian determinant
-  detJ should be the same, as a matrix and the matrix created from it
-  by exchanging two consecutive lines and two neighboring columns have
-  the same determinant.
-  
-  # x, y and z are arrays holding the x-, y- and z-values of the four vertices
-  # of this cell in real space. 
-  x := array(0..7):
-  y := array(0..7):
-  z := array(0..7):
-  tphi[0] := (1-xi)*(1-eta)*(1-zeta):
-  tphi[1] := xi*(1-eta)*(1-zeta):
-  tphi[2] := xi*eta*(1-zeta):
-  tphi[3] := (1-xi)*eta*(1-zeta):
-  tphi[4] := (1-xi)*(1-eta)*zeta:
-  tphi[5] := xi*(1-eta)*zeta:
-  tphi[6] := xi*eta*zeta:
-  tphi[7] := (1-xi)*eta*zeta:
-  x_real := sum(x[s]*tphi[s], s=0..7):
-  y_real := sum(y[s]*tphi[s], s=0..7):
-  z_real := sum(z[s]*tphi[s], s=0..7):
-  with (linalg):
-  J := matrix(3,3, [[diff(x_real, xi), diff(x_real, eta), diff(x_real, zeta)],
-  [diff(y_real, xi), diff(y_real, eta), diff(y_real, zeta)],
-  [diff(z_real, xi), diff(z_real, eta), diff(z_real, zeta)]]): 
-  detJ := det (J):
-
-  measure := simplify ( int ( int ( int (detJ, xi=0..1), eta=0..1), zeta=0..1)):
-
-  xs := simplify (1/measure * int ( int ( int (x_real * detJ, xi=0..1), eta=0..1), zeta=0..1)):
-  ys := simplify (1/measure * int ( int ( int (y_real * detJ, xi=0..1), eta=0..1), zeta=0..1)):
-  zs := simplify (1/measure * int ( int ( int (z_real * detJ, xi=0..1), eta=0..1), zeta=0..1)):
+  tphi[1] :=     xi*(1-eta):
+  tphi[2] := (1-xi)*eta:
+  tphi[3] :=     xi*eta:
+  x_real := sum(x[s]*tphi[s], s=0..3):
+  y_real := sum(y[s]*tphi[s], s=0..3):
+  detJ := diff(x_real,xi)*diff(y_real,eta) - diff(x_real,eta)*diff(y_real,xi):
 
+  measure := simplify ( int ( int (detJ, xi=0..1), eta=0..1)):
   readlib(C):
 
-  C(array(1..3, [xs, ys, zs]));
+  C(measure, optimized);
 
+  additional optimizaton: divide by 2 only one time
+*/
 
-  This script takes more than several hours when using an old version
-  of maple on an old and slow computer. Therefore, when changing to
-  the new deal.II numbering scheme (lexicographic numbering) the code
-  lines below have not been reproduced with maple but only the
-  ordering of points in the definitions of x[], y[] and z[] have been
-  changed.
+    const double x[4] = { accessor.vertex(0)(0),
+                         accessor.vertex(1)(0),
+                         accessor.vertex(2)(0),
+                         accessor.vertex(3)(0)  };
+    const double y[4] = { accessor.vertex(0)(1),
+                         accessor.vertex(1)(1),
+                         accessor.vertex(2)(1),
+                         accessor.vertex(3)(1)  };
 
-  For the case, someone is willing to rerun the maple script, he/she
-  should use following ordering of shape functions:
-  
-  tphi[0] := (1-xi)*(1-eta)*(1-zeta):
-  tphi[1] :=     xi*(1-eta)*(1-zeta):
-  tphi[2] := (1-xi)*    eta*(1-zeta):
-  tphi[3] :=     xi*    eta*(1-zeta):
-  tphi[4] := (1-xi)*(1-eta)*zeta:
-  tphi[5] :=     xi*(1-eta)*zeta:
-  tphi[6] := (1-xi)*    eta*zeta:
-  tphi[7] :=     xi*    eta*zeta:
+    return (-x[1]*y[0]+x[1]*y[3]+y[0]*x[2]+x[0]*y[1]-x[0]*y[2]-y[1]*x[3]-x[2]*y[3]+x[3]*y[2])/2;
+  }
 
-  and change the ordering of points in the definitions of x[], y[] and
-  z[] back to the standard ordering.
-*/
+#endif
 
-  const double x[8] = { vertex(0)(0),
-                       vertex(1)(0),
-                       vertex(5)(0),
-                       vertex(4)(0),
-                       vertex(2)(0),
-                       vertex(3)(0),
-                       vertex(7)(0),
-                       vertex(6)(0)   };
-  const double y[8] = { vertex(0)(1),
-                       vertex(1)(1),
-                       vertex(5)(1),
-                       vertex(4)(1),
-                       vertex(2)(1),
-                       vertex(3)(1),
-                       vertex(7)(1),
-                       vertex(6)(1)   };
-  const double z[8] = { vertex(0)(2),
-                       vertex(1)(2),
-                       vertex(5)(2),
-                       vertex(4)(2),
-                       vertex(2)(2),
-                       vertex(3)(2),
-                       vertex(7)(2),
-                       vertex(6)(2)   };
-
-  double s1, s2, s3, s4, s5, s6, s7, s8;
-  
-  s1 = 1.0/6.0;
-  s8 = -x[2]*x[2]*y[0]*z[3]-2.0*z[6]*x[7]*x[7]*y[4]-z[5]*x[7]*x[7]*y[4]-z
-       [6]*x[7]*x[7]*y[5]+2.0*y[6]*x[7]*x[7]*z[4]-z[5]*x[6]*x[6]*y[4]+x[6]*x[6]*y[4]*z
-       [7]-z[1]*x[0]*x[0]*y[2]-x[6]*x[6]*y[7]*z[4]+2.0*x[6]*x[6]*y[5]*z[7]-2.0*x[6]*x
-       [6]*y[7]*z[5]+y[5]*x[6]*x[6]*z[4]+2.0*x[5]*x[5]*y[4]*z[6]+x[0]*x[0]*y[7]*z[4]
-       -2.0*x[5]*x[5]*y[6]*z[4];
-  s7 = s8-y[6]*x[5]*x[5]*z[7]+z[6]*x[5]*x[5]*y[7]-y[1]*x[0]*x[0]*z[5]+x[7]*
-       z[5]*x[4]*y[7]-x[7]*y[6]*x[5]*z[7]-2.0*x[7]*x[6]*y[7]*z[4]+2.0*x[7]*x[6]*y[4]*z
-       [7]-x[7]*x[5]*y[7]*z[4]-2.0*x[7]*y[6]*x[4]*z[7]-x[7]*y[5]*x[4]*z[7]+x[2]*x[2]*y
-       [3]*z[0]-x[7]*x[6]*y[7]*z[5]+x[7]*x[6]*y[5]*z[7]+2.0*x[1]*x[1]*y[0]*z[5]+x[7]*z
-       [6]*x[5]*y[7];
-  s8 = -2.0*x[1]*x[1]*y[5]*z[0]+z[1]*x[0]*x[0]*y[5]+2.0*x[2]*x[2]*y[3]*z[1]
-       -z[5]*x[4]*x[4]*y[1]+y[5]*x[4]*x[4]*z[1]-2.0*x[5]*x[5]*y[4]*z[1]+2.0*x[5]*x[5]*
-       y[1]*z[4]-2.0*x[2]*x[2]*y[1]*z[3]-y[1]*x[2]*x[2]*z[0]+x[7]*y[2]*x[3]*z[7]+x[7]*
-       z[2]*x[6]*y[3]+2.0*x[7]*z[6]*x[4]*y[7]+z[5]*x[1]*x[1]*y[4]+z[1]*x[2]*x[2]*y[0]
-       -2.0*y[0]*x[3]*x[3]*z[7];
-  s6 = s8+2.0*z[0]*x[3]*x[3]*y[7]-x[7]*x[2]*y[3]*z[7]-x[7]*z[2]*x[3]*y[7]+x
-       [7]*x[2]*y[7]*z[3]-x[7]*y[2]*x[6]*z[3]+x[4]*x[5]*y[1]*z[4]-x[4]*x[5]*y[4]*z[1]+
-       x[4]*z[5]*x[1]*y[4]-x[4]*y[5]*x[1]*z[4]-2.0*x[5]*z[5]*x[4]*y[1]-2.0*x[5]*y[5]*x
-       [1]*z[4]+2.0*x[5]*z[5]*x[1]*y[4]+2.0*x[5]*y[5]*x[4]*z[1]-x[6]*z[5]*x[7]*y[4]-z
-       [2]*x[3]*x[3]*y[6]+s7;
-  s8 = -2.0*x[6]*z[6]*x[7]*y[5]-x[6]*y[6]*x[4]*z[7]+y[2]*x[3]*x[3]*z[6]+x
-       [6]*y[6]*x[7]*z[4]+2.0*y[2]*x[3]*x[3]*z[7]+x[0]*x[1]*y[0]*z[5]+x[0]*y[1]*x[5]*z
-       [0]-x[0]*z[1]*x[5]*y[0]-2.0*z[2]*x[3]*x[3]*y[7]+2.0*x[6]*z[6]*x[5]*y[7]-x[0]*x
-       [1]*y[5]*z[0]-x[6]*y[5]*x[4]*z[6]-2.0*x[3]*z[0]*x[7]*y[3]-x[6]*z[6]*x[7]*y[4]
-       -2.0*x[1]*z[1]*x[5]*y[0];
-  s7 = s8+2.0*x[1]*y[1]*x[5]*z[0]+2.0*x[1]*z[1]*x[0]*y[5]+2.0*x[3]*y[0]*x
-       [7]*z[3]+2.0*x[3]*x[0]*y[3]*z[7]-2.0*x[3]*x[0]*y[7]*z[3]-2.0*x[1]*y[1]*x[0]*z
-       [5]-2.0*x[6]*y[6]*x[5]*z[7]+s6-y[5]*x[1]*x[1]*z[4]+x[6]*z[6]*x[4]*y[7]-2.0*x[2]
-       *y[2]*x[3]*z[1]+x[6]*z[5]*x[4]*y[6]+x[6]*x[5]*y[4]*z[6]-y[6]*x[7]*x[7]*z[2]-x
-       [6]*x[5]*y[6]*z[4];
-  s8 = x[3]*x[3]*y[7]*z[4]-2.0*y[6]*x[7]*x[7]*z[3]+z[6]*x[7]*x[7]*y[2]+2.0*
-       z[6]*x[7]*x[7]*y[3]+2.0*y[1]*x[0]*x[0]*z[3]+2.0*x[0]*x[1]*y[3]*z[0]-2.0*x[0]*y
-       [0]*x[3]*z[4]-2.0*x[0]*z[1]*x[4]*y[0]-2.0*x[0]*y[1]*x[3]*z[0]+2.0*x[0]*y[0]*x
-       [4]*z[3]-2.0*x[0]*z[0]*x[4]*y[3]+2.0*x[0]*x[1]*y[0]*z[4]+2.0*x[0]*z[1]*x[3]*y
-       [0]-2.0*x[0]*x[1]*y[0]*z[3]-2.0*x[0]*x[1]*y[4]*z[0]+2.0*x[0]*y[1]*x[4]*z[0];
-  s5 = s8+2.0*x[0]*z[0]*x[3]*y[4]+x[1]*y[1]*x[0]*z[3]-x[1]*z[1]*x[4]*y[0]-x
-       [1]*y[1]*x[0]*z[4]+x[1]*z[1]*x[0]*y[4]-x[1]*y[1]*x[3]*z[0]-x[1]*z[1]*x[0]*y[3]-
-       x[0]*z[5]*x[4]*y[1]+x[0]*y[5]*x[4]*z[1]-2.0*x[4]*x[0]*y[4]*z[7]-2.0*x[4]*y[5]*x
-       [0]*z[4]+2.0*x[4]*z[5]*x[0]*y[4]-2.0*x[4]*x[5]*y[4]*z[0]-2.0*x[4]*y[0]*x[7]*z
-       [4]-x[5]*y[5]*x[0]*z[4]+s7;
-  s8 = x[5]*z[5]*x[0]*y[4]-x[5]*z[5]*x[4]*y[0]+x[1]*z[5]*x[0]*y[4]+x[5]*y
-       [5]*x[4]*z[0]-x[0]*y[0]*x[7]*z[4]-x[0]*z[5]*x[4]*y[0]-x[1]*y[5]*x[0]*z[4]+x[0]*
-       z[0]*x[7]*y[4]+x[0]*y[5]*x[4]*z[0]-x[0]*z[0]*x[4]*y[7]+x[0]*x[5]*y[0]*z[4]+x[0]
-       *y[0]*x[4]*z[7]-x[0]*x[5]*y[4]*z[0]-x[3]*x[3]*y[4]*z[7]+2.0*x[2]*z[2]*x[3]*y[1]
-       ;
-  s7 = s8-x[5]*x[5]*y[4]*z[0]+2.0*y[5]*x[4]*x[4]*z[0]-2.0*z[0]*x[4]*x[4]*y
-       [7]+2.0*y[0]*x[4]*x[4]*z[7]-2.0*z[5]*x[4]*x[4]*y[0]+x[5]*x[5]*y[4]*z[7]-x[5]*x
-       [5]*y[7]*z[4]-2.0*y[5]*x[4]*x[4]*z[7]+2.0*z[5]*x[4]*x[4]*y[7]-x[0]*x[0]*y[7]*z
-       [3]+y[2]*x[0]*x[0]*z[3]+x[0]*x[0]*y[3]*z[7]-x[5]*x[1]*y[4]*z[0]+x[5]*y[1]*x[4]*
-       z[0]-x[4]*y[0]*x[3]*z[4];
-  s8 = -x[4]*y[1]*x[0]*z[4]+x[4]*z[1]*x[0]*y[4]+x[4]*x[0]*y[3]*z[4]-x[4]*x
-       [0]*y[4]*z[3]+x[4]*x[1]*y[0]*z[4]-x[4]*x[1]*y[4]*z[0]+x[4]*z[0]*x[3]*y[4]+x[5]*
-       x[1]*y[0]*z[4]+x[1]*z[1]*x[3]*y[0]+x[1]*y[1]*x[4]*z[0]-x[5]*z[1]*x[4]*y[0]-2.0*
-       y[1]*x[0]*x[0]*z[4]+2.0*z[1]*x[0]*x[0]*y[4]+2.0*x[0]*x[0]*y[3]*z[4]-2.0*z[1]*x
-       [0]*x[0]*y[3];
-  s6 = s8-2.0*x[0]*x[0]*y[4]*z[3]+x[1]*x[1]*y[3]*z[0]+x[1]*x[1]*y[0]*z[4]-x
-       [1]*x[1]*y[0]*z[3]-x[1]*x[1]*y[4]*z[0]-z[1]*x[4]*x[4]*y[0]+y[0]*x[4]*x[4]*z[3]-
-       z[0]*x[4]*x[4]*y[3]+y[1]*x[4]*x[4]*z[0]-x[0]*x[0]*y[4]*z[7]-y[5]*x[0]*x[0]*z[4]
-       +z[5]*x[0]*x[0]*y[4]+x[5]*x[5]*y[0]*z[4]-x[0]*y[0]*x[3]*z[7]+x[0]*z[0]*x[3]*y
-       [7]+s7;
-  s8 = s6+x[0]*x[2]*y[3]*z[0]-x[0]*x[2]*y[0]*z[3]+x[0]*y[0]*x[7]*z[3]-x[0]*
-       y[2]*x[3]*z[0]+x[0]*z[2]*x[3]*y[0]-x[0]*z[0]*x[7]*y[3]+x[1]*x[2]*y[3]*z[0]-z[2]
-       *x[0]*x[0]*y[3]+x[3]*z[2]*x[6]*y[3]-x[3]*x[2]*y[3]*z[6]+x[3]*x[2]*y[6]*z[3]-x
-       [3]*y[2]*x[6]*z[3]-2.0*x[3]*y[2]*x[7]*z[3]+2.0*x[3]*z[2]*x[7]*y[3];
-  s7 = s8+2.0*x[4]*y[5]*x[7]*z[4]+2.0*x[4]*x[5]*y[4]*z[7]-2.0*x[4]*z[5]*x
-       [7]*y[4]-2.0*x[4]*x[5]*y[7]*z[4]+x[5]*y[5]*x[7]*z[4]-x[5]*z[5]*x[7]*y[4]-x[5]*y
-       [5]*x[4]*z[7]+x[5]*z[5]*x[4]*y[7]+2.0*x[3]*x[2]*y[7]*z[3]-2.0*x[2]*z[2]*x[1]*y
-       [3]+2.0*x[4]*z[0]*x[7]*y[4]+2.0*x[4]*x[0]*y[7]*z[4]+2.0*x[4]*x[5]*y[0]*z[4]-x
-       [7]*x[6]*y[2]*z[7]-2.0*x[3]*x[2]*y[3]*z[7]-x[0]*x[4]*y[7]*z[3];
-  s8 = x[0]*x[3]*y[7]*z[4]-x[0]*x[3]*y[4]*z[7]+x[0]*x[4]*y[3]*z[7]-2.0*x[7]
-       *z[6]*x[3]*y[7]+x[3]*x[7]*y[4]*z[3]-x[3]*x[4]*y[7]*z[3]-x[3]*x[7]*y[3]*z[4]+x
-       [3]*x[4]*y[3]*z[7]+2.0*x[2]*y[2]*x[1]*z[3]+y[6]*x[3]*x[3]*z[7]-z[6]*x[3]*x[3]*y
-       [7]-x[1]*z[5]*x[4]*y[1]-x[1]*x[5]*y[4]*z[1]-x[1]*z[2]*x[0]*y[3]-x[1]*x[2]*y[0]*
-       z[3]+x[1]*y[2]*x[0]*z[3];
-  s4 = s8+x[1]*x[5]*y[1]*z[4]+x[1]*y[5]*x[4]*z[1]+x[4]*y[0]*x[7]*z[3]-x[4]*
-       z[0]*x[7]*y[3]-x[4]*x[4]*y[7]*z[3]+x[4]*x[4]*y[3]*z[7]+x[3]*z[6]*x[7]*y[3]-x[3]
-       *x[6]*y[3]*z[7]+x[3]*x[6]*y[7]*z[3]-x[3]*z[6]*x[2]*y[7]-x[3]*y[6]*x[7]*z[3]+x
-       [3]*z[6]*x[7]*y[2]+x[3]*y[6]*x[2]*z[7]+2.0*x[5]*z[5]*x[4]*y[6]+s5+s7;
-  s8 = s4-2.0*x[5]*z[5]*x[6]*y[4]-x[5]*z[6]*x[7]*y[5]+x[5]*x[6]*y[5]*z[7]-x
-       [5]*x[6]*y[7]*z[5]-2.0*x[5]*y[5]*x[4]*z[6]+2.0*x[5]*y[5]*x[6]*z[4]-x[3]*y[6]*x
-       [7]*z[2]+x[4]*x[7]*y[4]*z[3]+x[4]*x[3]*y[7]*z[4]-x[4]*x[7]*y[3]*z[4]-x[4]*x[3]*
-       y[4]*z[7]-z[1]*x[5]*x[5]*y[0]+y[1]*x[5]*x[5]*z[0]+x[4]*y[6]*x[7]*z[4];
-  s7 = s8-x[4]*x[6]*y[7]*z[4]+x[4]*x[6]*y[4]*z[7]-x[4]*z[6]*x[7]*y[4]-x[5]*
-       y[6]*x[4]*z[7]-x[5]*x[6]*y[7]*z[4]+x[5]*x[6]*y[4]*z[7]+x[5]*z[6]*x[4]*y[7]-y[6]
-       *x[4]*x[4]*z[7]+z[6]*x[4]*x[4]*y[7]+x[7]*x[5]*y[4]*z[7]-y[2]*x[7]*x[7]*z[3]+z
-       [2]*x[7]*x[7]*y[3]-y[0]*x[3]*x[3]*z[4]-y[1]*x[3]*x[3]*z[0]+z[1]*x[3]*x[3]*y[0];
-  s8 = z[0]*x[3]*x[3]*y[4]-x[2]*y[1]*x[3]*z[0]+x[2]*z[1]*x[3]*y[0]+x[3]*y
-       [1]*x[0]*z[3]+x[3]*x[1]*y[3]*z[0]+x[3]*x[0]*y[3]*z[4]-x[3]*z[1]*x[0]*y[3]-x[3]*
-       x[0]*y[4]*z[3]+x[3]*y[0]*x[4]*z[3]-x[3]*z[0]*x[4]*y[3]-x[3]*x[1]*y[0]*z[3]+x[3]
-       *z[0]*x[7]*y[4]-x[3]*y[0]*x[7]*z[4]+z[0]*x[7]*x[7]*y[4]-y[0]*x[7]*x[7]*z[4];
-  s6 = s8+y[1]*x[0]*x[0]*z[2]-2.0*y[2]*x[3]*x[3]*z[0]+2.0*z[2]*x[3]*x[3]*y
-       [0]-2.0*x[1]*x[1]*y[0]*z[2]+2.0*x[1]*x[1]*y[2]*z[0]-y[2]*x[3]*x[3]*z[1]+z[2]*x
-       [3]*x[3]*y[1]-y[5]*x[4]*x[4]*z[6]+z[5]*x[4]*x[4]*y[6]+x[7]*x[0]*y[7]*z[4]-x[7]*
-       z[0]*x[4]*y[7]-x[7]*x[0]*y[4]*z[7]+x[7]*y[0]*x[4]*z[7]-x[0]*x[1]*y[0]*z[2]+x[0]
-       *z[1]*x[2]*y[0]+s7;
-  s8 = s6+x[0]*x[1]*y[2]*z[0]-x[0]*y[1]*x[2]*z[0]-x[3]*z[1]*x[0]*y[2]+2.0*x
-       [3]*x[2]*y[3]*z[0]+y[0]*x[7]*x[7]*z[3]-z[0]*x[7]*x[7]*y[3]-2.0*x[3]*z[2]*x[0]*y
-       [3]-2.0*x[3]*x[2]*y[0]*z[3]+2.0*x[3]*y[2]*x[0]*z[3]+x[3]*x[2]*y[3]*z[1]-x[3]*x
-       [2]*y[1]*z[3]-x[5]*y[1]*x[0]*z[5]+x[3]*y[1]*x[0]*z[2]+x[4]*y[6]*x[7]*z[5];
-  s7 = s8-x[5]*x[1]*y[5]*z[0]+2.0*x[1]*z[1]*x[2]*y[0]-2.0*x[1]*z[1]*x[0]*y
-       [2]+x[1]*x[2]*y[3]*z[1]-x[1]*x[2]*y[1]*z[3]+2.0*x[1]*y[1]*x[0]*z[2]-2.0*x[1]*y
-       [1]*x[2]*z[0]-z[2]*x[1]*x[1]*y[3]+y[2]*x[1]*x[1]*z[3]+y[5]*x[7]*x[7]*z[4]+y[6]*
-       x[7]*x[7]*z[5]+x[7]*x[6]*y[7]*z[2]+x[7]*y[6]*x[2]*z[7]-x[7]*z[6]*x[2]*y[7]-2.0*
-       x[7]*x[6]*y[3]*z[7];
-  s8 = s7+2.0*x[7]*x[6]*y[7]*z[3]+2.0*x[7]*y[6]*x[3]*z[7]-x[3]*z[2]*x[1]*y
-       [3]+x[3]*y[2]*x[1]*z[3]+x[5]*x[1]*y[0]*z[5]+x[4]*y[5]*x[6]*z[4]+x[5]*z[1]*x[0]*
-       y[5]-x[4]*z[6]*x[7]*y[5]-x[4]*x[5]*y[6]*z[4]+x[4]*x[5]*y[4]*z[6]-x[4]*z[5]*x[6]
-       *y[4]-x[1]*y[2]*x[3]*z[1]+x[1]*z[2]*x[3]*y[1]-x[2]*x[1]*y[0]*z[2]-x[2]*z[1]*x
-       [0]*y[2];
-  s5 = s8+x[2]*x[1]*y[2]*z[0]-x[2]*z[2]*x[0]*y[3]+x[2]*y[2]*x[0]*z[3]-x[2]*
-       y[2]*x[3]*z[0]+x[2]*z[2]*x[3]*y[0]+x[2]*y[1]*x[0]*z[2]+x[5]*y[6]*x[7]*z[5]+x[6]
-       *y[5]*x[7]*z[4]+2.0*x[6]*y[6]*x[7]*z[5]-x[7]*y[0]*x[3]*z[7]+x[7]*z[0]*x[3]*y[7]
-       -x[7]*x[0]*y[7]*z[3]+x[7]*x[0]*y[3]*z[7]+2.0*x[7]*x[7]*y[4]*z[3]-2.0*x[7]*x[7]*
-       y[3]*z[4]-2.0*x[1]*x[1]*y[2]*z[5];
-  s8 = s5-2.0*x[7]*x[4]*y[7]*z[3]+2.0*x[7]*x[3]*y[7]*z[4]-2.0*x[7]*x[3]*y
-       [4]*z[7]+2.0*x[7]*x[4]*y[3]*z[7]+2.0*x[1]*x[1]*y[5]*z[2]-x[1]*x[1]*y[2]*z[6]+x
-       [1]*x[1]*y[6]*z[2]+z[1]*x[5]*x[5]*y[2]-y[1]*x[5]*x[5]*z[2]-x[1]*x[1]*y[6]*z[5]+
-       x[1]*x[1]*y[5]*z[6]+x[5]*x[5]*y[6]*z[2]-x[5]*x[5]*y[2]*z[6]-2.0*y[1]*x[5]*x[5]*
-       z[6];
-  s7 = s8+2.0*z[1]*x[5]*x[5]*y[6]+2.0*x[1]*z[1]*x[5]*y[2]+2.0*x[1]*y[1]*x
-       [2]*z[5]-2.0*x[1]*z[1]*x[2]*y[5]-2.0*x[1]*y[1]*x[5]*z[2]-x[1]*y[1]*x[6]*z[2]-x
-       [1]*z[1]*x[2]*y[6]+x[1]*z[1]*x[6]*y[2]+x[1]*y[1]*x[2]*z[6]-x[5]*x[1]*y[2]*z[5]+
-       x[5]*y[1]*x[2]*z[5]-x[5]*z[1]*x[2]*y[5]+x[5]*x[1]*y[5]*z[2]-x[5]*y[1]*x[6]*z[2]
-       -x[5]*x[1]*y[2]*z[6];
-  s8 = s7+x[5]*x[1]*y[6]*z[2]+x[5]*z[1]*x[6]*y[2]+x[1]*x[2]*y[5]*z[6]-x[1]*
-       x[2]*y[6]*z[5]-x[1]*z[1]*x[6]*y[5]-x[1]*y[1]*x[5]*z[6]+x[1]*z[1]*x[5]*y[6]+x[1]
-       *y[1]*x[6]*z[5]-x[5]*x[6]*y[5]*z[2]+x[5]*x[2]*y[5]*z[6]-x[5]*x[2]*y[6]*z[5]+x
-       [5]*x[6]*y[2]*z[5]-2.0*x[5]*z[1]*x[6]*y[5]-2.0*x[5]*x[1]*y[6]*z[5]+2.0*x[5]*x
-       [1]*y[5]*z[6];
-  s6 = s8+2.0*x[5]*y[1]*x[6]*z[5]+2.0*x[2]*x[1]*y[6]*z[2]+2.0*x[2]*z[1]*x
-       [6]*y[2]-2.0*x[2]*x[1]*y[2]*z[6]+x[2]*x[5]*y[6]*z[2]+x[2]*x[6]*y[2]*z[5]-x[2]*x
-       [5]*y[2]*z[6]+y[1]*x[2]*x[2]*z[5]-z[1]*x[2]*x[2]*y[5]-2.0*x[2]*y[1]*x[6]*z[2]-x
-       [2]*x[6]*y[5]*z[2]-2.0*z[1]*x[2]*x[2]*y[6]+x[2]*x[2]*y[5]*z[6]-x[2]*x[2]*y[6]*z
-       [5]+2.0*y[1]*x[2]*x[2]*z[6]+x[2]*z[1]*x[5]*y[2];
-  s8 = s6-x[2]*x[1]*y[2]*z[5]+x[2]*x[1]*y[5]*z[2]-x[2]*y[1]*x[5]*z[2]+x[6]*
-       y[1]*x[2]*z[5]-x[6]*z[1]*x[2]*y[5]-z[1]*x[6]*x[6]*y[5]+y[1]*x[6]*x[6]*z[5]-y[1]
-       *x[6]*x[6]*z[2]-2.0*x[6]*x[6]*y[5]*z[2]+2.0*x[6]*x[6]*y[2]*z[5]+z[1]*x[6]*x[6]*
-       y[2]-x[6]*x[1]*y[6]*z[5]-x[6]*y[1]*x[5]*z[6]+x[6]*x[1]*y[5]*z[6];
-  s7 = s8+x[6]*z[1]*x[5]*y[6]-x[6]*z[1]*x[2]*y[6]-x[6]*x[1]*y[2]*z[6]+2.0*x
-       [6]*x[5]*y[6]*z[2]+2.0*x[6]*x[2]*y[5]*z[6]-2.0*x[6]*x[2]*y[6]*z[5]-2.0*x[6]*x
-       [5]*y[2]*z[6]+x[6]*x[1]*y[6]*z[2]+x[6]*y[1]*x[2]*z[6]-x[2]*x[2]*y[3]*z[7]+x[2]*
-       x[2]*y[7]*z[3]-x[2]*z[2]*x[3]*y[7]-x[2]*y[2]*x[7]*z[3]+x[2]*z[2]*x[7]*y[3]+x[2]
-       *y[2]*x[3]*z[7]-x[6]*x[6]*y[3]*z[7];
-  s8 = s7+x[6]*x[6]*y[7]*z[3]-x[6]*x[2]*y[3]*z[7]+x[6]*x[2]*y[7]*z[3]-x[6]*
-       y[6]*x[7]*z[3]+x[6]*y[6]*x[3]*z[7]-x[6]*z[6]*x[3]*y[7]+x[6]*z[6]*x[7]*y[3]+y[6]
-       *x[2]*x[2]*z[7]-z[6]*x[2]*x[2]*y[7]+2.0*x[2]*x[2]*y[6]*z[3]-x[2]*y[6]*x[7]*z[2]
-       -2.0*x[2]*y[2]*x[6]*z[3]-2.0*x[2]*x[2]*y[3]*z[6]+2.0*x[2]*y[2]*x[3]*z[6]-x[2]*x
-       [6]*y[2]*z[7];
-  s3 = s8+x[2]*x[6]*y[7]*z[2]+x[2]*z[6]*x[7]*y[2]+2.0*x[2]*z[2]*x[6]*y[3]
-       -2.0*x[2]*z[2]*x[3]*y[6]-y[2]*x[6]*x[6]*z[3]-2.0*x[6]*x[6]*y[2]*z[7]+2.0*x[6]*x
-       [6]*y[7]*z[2]+z[2]*x[6]*x[6]*y[3]-2.0*x[6]*y[6]*x[7]*z[2]+x[6]*y[2]*x[3]*z[6]-x
-       [6]*x[2]*y[3]*z[6]+2.0*x[6]*z[6]*x[7]*y[2]+2.0*x[6]*y[6]*x[2]*z[7]-2.0*x[6]*z
-       [6]*x[2]*y[7]+x[6]*x[2]*y[6]*z[3]-x[6]*z[2]*x[3]*y[6];
-  s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
-       [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
-       z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
-       +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
-  s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
-       x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
-       *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
-       [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
-  s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
-       [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
-       z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
-       -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
-  s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
-       x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
-       *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
-       [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
-  s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
-       y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
-       *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
-       [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
-  s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
-       x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
-       *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
-       [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
-  s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
-       [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
-       z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
-       +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
-  s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
-       x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
-       *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
-       [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
-  s4 = 1/s5;
-  s2 = s3*s4;
-  const double unknown0 = s1*s2;
-  s1 = 1.0/6.0;
-  s8 = 2.0*x[1]*y[0]*y[0]*z[4]+x[5]*y[0]*y[0]*z[4]-x[1]*y[4]*y[4]*z[0]+z[1]
-       *x[0]*y[4]*y[4]+x[1]*y[0]*y[0]*z[5]-z[1]*x[5]*y[0]*y[0]-2.0*z[1]*x[4]*y[0]*y[0]
-       +2.0*z[1]*x[3]*y[0]*y[0]+z[2]*x[3]*y[0]*y[0]+y[0]*y[0]*x[7]*z[3]+2.0*y[0]*y[0]*
-       x[4]*z[3]-2.0*x[1]*y[0]*y[0]*z[3]-2.0*x[5]*y[4]*y[4]*z[0]+2.0*z[5]*x[0]*y[4]*y
-       [4]+2.0*y[4]*y[5]*x[7]*z[4];
-  s7 = s8-x[3]*y[4]*y[4]*z[7]+x[7]*y[4]*y[4]*z[3]+z[0]*x[3]*y[4]*y[4]-2.0*x
-       [0]*y[4]*y[4]*z[7]-y[1]*x[1]*y[4]*z[0]-x[0]*y[4]*y[4]*z[3]+2.0*z[0]*x[7]*y[4]*y
-       [4]+y[4]*z[6]*x[4]*y[7]-y[0]*y[0]*x[7]*z[4]+y[0]*y[0]*x[4]*z[7]+2.0*y[4]*z[5]*x
-       [4]*y[7]-2.0*y[4]*x[5]*y[7]*z[4]-y[4]*x[6]*y[7]*z[4]-y[4]*y[6]*x[4]*z[7]-2.0*y
-       [4]*y[5]*x[4]*z[7];
-  s8 = y[4]*y[6]*x[7]*z[4]-y[7]*y[2]*x[7]*z[3]+y[7]*z[2]*x[7]*y[3]+y[7]*y
-       [2]*x[3]*z[7]+2.0*x[5]*y[4]*y[4]*z[7]-y[7]*x[2]*y[3]*z[7]-y[0]*z[0]*x[4]*y[7]+z
-       [6]*x[7]*y[3]*y[3]-y[0]*x[0]*y[4]*z[7]+y[0]*x[0]*y[7]*z[4]-2.0*x[2]*y[3]*y[3]*z
-       [7]-z[5]*x[4]*y[0]*y[0]+y[0]*z[0]*x[7]*y[4]-2.0*z[6]*x[3]*y[7]*y[7]+z[1]*x[2]*y
-       [0]*y[0];
-  s6 = s8+y[4]*y[0]*x[4]*z[3]-2.0*y[4]*z[0]*x[4]*y[7]+2.0*y[4]*x[0]*y[7]*z
-       [4]-y[4]*z[0]*x[4]*y[3]-y[4]*x[0]*y[7]*z[3]+y[4]*z[0]*x[3]*y[7]-y[4]*y[0]*x[3]*
-       z[4]+y[0]*x[4]*y[3]*z[7]-y[0]*x[7]*y[3]*z[4]-y[0]*x[3]*y[4]*z[7]+y[0]*x[7]*y[4]
-       *z[3]+x[2]*y[7]*y[7]*z[3]-z[2]*x[3]*y[7]*y[7]-2.0*z[2]*x[0]*y[3]*y[3]+2.0*y[0]*
-       z[1]*x[0]*y[4]+s7;
-  s8 = -2.0*y[0]*y[1]*x[0]*z[4]-y[0]*y[1]*x[0]*z[5]-y[0]*y[0]*x[3]*z[7]-z
-       [1]*x[0]*y[3]*y[3]-y[0]*x[1]*y[5]*z[0]-2.0*z[0]*x[7]*y[3]*y[3]+x[0]*y[3]*y[3]*z
-       [4]+2.0*x[0]*y[3]*y[3]*z[7]-z[0]*x[4]*y[3]*y[3]+2.0*x[2]*y[3]*y[3]*z[0]+x[1]*y
-       [3]*y[3]*z[0]+2.0*y[7]*z[6]*x[7]*y[3]+2.0*y[7]*y[6]*x[3]*z[7]-2.0*y[7]*y[6]*x
-       [7]*z[3]-2.0*y[7]*x[6]*y[3]*z[7];
-  s7 = s8+y[4]*x[4]*y[3]*z[7]-y[4]*x[4]*y[7]*z[3]+y[4]*x[3]*y[7]*z[4]-y[4]*
-       x[7]*y[3]*z[4]+2.0*y[4]*y[0]*x[4]*z[7]-2.0*y[4]*y[0]*x[7]*z[4]+2.0*x[6]*y[7]*y
-       [7]*z[3]+y[4]*x[0]*y[3]*z[4]+y[0]*y[1]*x[5]*z[0]+y[0]*z[1]*x[0]*y[5]-x[2]*y[0]*
-       y[0]*z[3]+x[4]*y[3]*y[3]*z[7]-x[7]*y[3]*y[3]*z[4]-x[5]*y[4]*y[4]*z[1]+y[3]*z[0]
-       *x[3]*y[4];
-  s8 = y[3]*y[0]*x[4]*z[3]+2.0*y[3]*y[0]*x[7]*z[3]+2.0*y[3]*y[2]*x[0]*z[3]
-       -2.0*y[3]*y[2]*x[3]*z[0]+2.0*y[3]*z[2]*x[3]*y[0]+y[3]*z[1]*x[3]*y[0]-2.0*y[3]*x
-       [2]*y[0]*z[3]-y[3]*x[1]*y[0]*z[3]-y[3]*y[1]*x[3]*z[0]-2.0*y[3]*x[0]*y[7]*z[3]-y
-       [3]*x[0]*y[4]*z[3]-2.0*y[3]*y[0]*x[3]*z[7]-y[3]*y[0]*x[3]*z[4]+2.0*y[3]*z[0]*x
-       [3]*y[7]+y[3]*y[1]*x[0]*z[3]+z[5]*x[1]*y[4]*y[4];
-  s5 = s8-2.0*y[0]*y[0]*x[3]*z[4]-2.0*y[0]*x[1]*y[4]*z[0]+y[3]*x[7]*y[4]*z
-       [3]-y[3]*x[4]*y[7]*z[3]+y[3]*x[3]*y[7]*z[4]-y[3]*x[3]*y[4]*z[7]+y[3]*x[0]*y[7]*
-       z[4]-y[3]*z[0]*x[4]*y[7]-2.0*y[4]*y[5]*x[0]*z[4]+s6+y[7]*x[0]*y[3]*z[7]-y[7]*z
-       [0]*x[7]*y[3]+y[7]*y[0]*x[7]*z[3]-y[7]*y[0]*x[3]*z[7]+2.0*y[0]*y[1]*x[4]*z[0]+
-       s7;
-  s8 = -2.0*y[7]*x[7]*y[3]*z[4]-2.0*y[7]*x[3]*y[4]*z[7]+2.0*y[7]*x[4]*y[3]*
-       z[7]+y[7]*y[0]*x[4]*z[7]-y[7]*y[0]*x[7]*z[4]+2.0*y[7]*x[7]*y[4]*z[3]-y[7]*x[0]*
-       y[4]*z[7]+y[7]*z[0]*x[7]*y[4]+z[5]*x[4]*y[7]*y[7]+2.0*z[6]*x[4]*y[7]*y[7]-x[5]*
-       y[7]*y[7]*z[4]-2.0*x[6]*y[7]*y[7]*z[4]+2.0*y[7]*x[6]*y[4]*z[7]-2.0*y[7]*z[6]*x
-       [7]*y[4]+2.0*y[7]*y[6]*x[7]*z[4];
-  s7 = s8-2.0*y[7]*y[6]*x[4]*z[7]-y[7]*z[5]*x[7]*y[4]-y[7]*y[5]*x[4]*z[7]-x
-       [0]*y[7]*y[7]*z[3]+z[0]*x[3]*y[7]*y[7]+y[7]*x[5]*y[4]*z[7]+y[7]*y[5]*x[7]*z[4]-
-       y[4]*x[1]*y[5]*z[0]-x[1]*y[0]*y[0]*z[2]-y[4]*y[5]*x[1]*z[4]-2.0*y[4]*z[5]*x[4]*
-       y[0]-y[4]*y[1]*x[0]*z[4]+y[4]*y[5]*x[4]*z[1]+y[0]*z[0]*x[3]*y[7]-y[0]*z[1]*x[0]
-       *y[2];
-  s8 = 2.0*y[0]*x[1]*y[3]*z[0]+y[4]*y[1]*x[4]*z[0]+2.0*y[0]*y[1]*x[0]*z[3]+
-       y[4]*x[1]*y[0]*z[5]-y[4]*z[1]*x[5]*y[0]+y[4]*z[1]*x[0]*y[5]-y[4]*z[1]*x[4]*y[0]
-       +y[4]*x[1]*y[0]*z[4]-y[4]*z[5]*x[4]*y[1]+x[5]*y[4]*y[4]*z[6]-z[5]*x[6]*y[4]*y
-       [4]+y[4]*x[5]*y[1]*z[4]-y[0]*z[2]*x[0]*y[3]+y[0]*y[5]*x[4]*z[0]+y[0]*x[1]*y[2]*
-       z[0];
-  s6 = s8-2.0*y[0]*z[0]*x[4]*y[3]-2.0*y[0]*x[0]*y[4]*z[3]-2.0*y[0]*z[1]*x
-       [0]*y[3]-y[0]*x[0]*y[7]*z[3]-2.0*y[0]*y[1]*x[3]*z[0]+y[0]*x[2]*y[3]*z[0]-y[0]*y
-       [1]*x[2]*z[0]+y[0]*y[1]*x[0]*z[2]-y[0]*x[2]*y[1]*z[3]+y[0]*x[0]*y[3]*z[7]+y[0]*
-       x[2]*y[3]*z[1]-y[0]*y[2]*x[3]*z[0]+y[0]*y[2]*x[0]*z[3]-y[0]*y[5]*x[0]*z[4]-y[4]
-       *y[5]*x[4]*z[6]+s7;
-  s8 = s6+y[4]*z[6]*x[5]*y[7]-y[4]*x[6]*y[7]*z[5]+y[4]*x[6]*y[5]*z[7]-y[4]*
-       z[6]*x[7]*y[5]-y[4]*x[5]*y[6]*z[4]+y[4]*z[5]*x[4]*y[6]+y[4]*y[5]*x[6]*z[4]-2.0*
-       y[1]*y[1]*x[0]*z[5]+2.0*y[1]*y[1]*x[5]*z[0]-2.0*y[2]*y[2]*x[6]*z[3]+x[5]*y[1]*y
-       [1]*z[4]-z[5]*x[4]*y[1]*y[1]-x[6]*y[2]*y[2]*z[7]+z[6]*x[7]*y[2]*y[2];
-  s7 = s8-x[1]*y[5]*y[5]*z[0]+z[1]*x[0]*y[5]*y[5]+y[1]*y[5]*x[4]*z[1]-y[1]*
-       y[5]*x[1]*z[4]-2.0*y[2]*z[2]*x[3]*y[6]+2.0*y[1]*z[1]*x[0]*y[5]-2.0*y[1]*z[1]*x
-       [5]*y[0]+2.0*y[1]*x[1]*y[0]*z[5]-y[2]*x[2]*y[3]*z[7]-y[2]*z[2]*x[3]*y[7]+y[2]*x
-       [2]*y[7]*z[3]+y[2]*z[2]*x[7]*y[3]-2.0*y[2]*x[2]*y[3]*z[6]+2.0*y[2]*x[2]*y[6]*z
-       [3]+2.0*y[2]*z[2]*x[6]*y[3]-y[3]*y[2]*x[6]*z[3];
-  s8 = y[3]*y[2]*x[3]*z[6]+y[3]*x[2]*y[6]*z[3]-y[3]*z[2]*x[3]*y[6]-y[2]*y
-       [2]*x[7]*z[3]+2.0*y[2]*y[2]*x[3]*z[6]+y[2]*y[2]*x[3]*z[7]-2.0*y[1]*x[1]*y[5]*z
-       [0]-x[2]*y[3]*y[3]*z[6]+z[2]*x[6]*y[3]*y[3]+2.0*y[6]*x[2]*y[5]*z[6]+2.0*y[6]*x
-       [6]*y[2]*z[5]-2.0*y[6]*x[5]*y[2]*z[6]+2.0*y[3]*x[2]*y[7]*z[3]-2.0*y[3]*z[2]*x
-       [3]*y[7]-y[0]*z[0]*x[7]*y[3]-y[0]*z[2]*x[1]*y[3];
-  s4 = s8-y[2]*y[6]*x[7]*z[2]+y[0]*z[2]*x[3]*y[1]+y[1]*z[5]*x[1]*y[4]-y[1]*
-       x[5]*y[4]*z[1]+2.0*y[0]*z[0]*x[3]*y[4]+2.0*y[0]*x[0]*y[3]*z[4]+2.0*z[2]*x[7]*y
-       [3]*y[3]-2.0*z[5]*x[7]*y[4]*y[4]+x[6]*y[4]*y[4]*z[7]-z[6]*x[7]*y[4]*y[4]+y[1]*y
-       [1]*x[0]*z[3]+y[3]*x[6]*y[7]*z[2]-y[3]*z[6]*x[2]*y[7]+2.0*y[3]*y[2]*x[3]*z[7]+
-       s5+s7;
-  s8 = s4+y[2]*x[6]*y[7]*z[2]-y[2]*y[6]*x[7]*z[3]+y[2]*y[6]*x[2]*z[7]-y[2]*
-       z[6]*x[2]*y[7]-y[2]*x[6]*y[3]*z[7]+y[2]*y[6]*x[3]*z[7]+y[2]*z[6]*x[7]*y[3]-2.0*
-       y[3]*y[2]*x[7]*z[3]-x[6]*y[3]*y[3]*z[7]+y[1]*y[1]*x[4]*z[0]-y[1]*y[1]*x[3]*z[0]
-       +x[2]*y[6]*y[6]*z[3]-z[2]*x[3]*y[6]*y[6]-y[1]*y[1]*x[0]*z[4];
-  s7 = s8+y[5]*x[1]*y[0]*z[5]+y[6]*x[2]*y[7]*z[3]-y[6]*y[2]*x[6]*z[3]+y[6]*
-       y[2]*x[3]*z[6]-y[6]*x[2]*y[3]*z[6]+y[6]*z[2]*x[6]*y[3]-y[5]*y[1]*x[0]*z[5]-y[5]
-       *z[1]*x[5]*y[0]+y[5]*y[1]*x[5]*z[0]-y[6]*z[2]*x[3]*y[7]-y[7]*y[6]*x[7]*z[2]+2.0
-       *y[6]*y[6]*x[2]*z[7]+y[6]*y[6]*x[3]*z[7]+x[6]*y[7]*y[7]*z[2]-z[6]*x[2]*y[7]*y
-       [7];
-  s8 = -x[2]*y[1]*y[1]*z[3]+2.0*y[1]*y[1]*x[0]*z[2]-2.0*y[1]*y[1]*x[2]*z[0]
-       +z[2]*x[3]*y[1]*y[1]-z[1]*x[0]*y[2]*y[2]+x[1]*y[2]*y[2]*z[0]+y[2]*y[2]*x[0]*z
-       [3]-y[2]*y[2]*x[3]*z[0]-2.0*y[2]*y[2]*x[3]*z[1]+y[1]*x[1]*y[3]*z[0]-2.0*y[6]*y
-       [6]*x[7]*z[2]+2.0*y[5]*y[5]*x[4]*z[1]-2.0*y[5]*y[5]*x[1]*z[4]-y[6]*y[6]*x[7]*z
-       [3]-2.0*y[1]*x[1]*y[0]*z[2];
-  s6 = s8+2.0*y[1]*z[1]*x[2]*y[0]-2.0*y[1]*z[1]*x[0]*y[2]+2.0*y[1]*x[1]*y
-       [2]*z[0]+y[1]*x[2]*y[3]*z[1]-y[1]*y[2]*x[3]*z[1]-y[1]*z[2]*x[1]*y[3]+y[1]*y[2]*
-       x[1]*z[3]-y[2]*x[1]*y[0]*z[2]+y[2]*z[1]*x[2]*y[0]+y[2]*x[2]*y[3]*z[0]-y[7]*x[6]
-       *y[2]*z[7]+y[7]*z[6]*x[7]*y[2]+y[7]*y[6]*x[2]*z[7]-y[6]*x[6]*y[3]*z[7]+y[6]*x
-       [6]*y[7]*z[3]+s7;
-  s8 = s6-y[6]*z[6]*x[3]*y[7]+y[6]*z[6]*x[7]*y[3]+2.0*y[2]*y[2]*x[1]*z[3]+x
-       [2]*y[3]*y[3]*z[1]-z[2]*x[1]*y[3]*y[3]+y[1]*x[1]*y[0]*z[4]+y[1]*z[1]*x[3]*y[0]-
-       y[1]*x[1]*y[0]*z[3]+2.0*y[5]*x[5]*y[1]*z[4]-2.0*y[5]*x[5]*y[4]*z[1]+2.0*y[5]*z
-       [5]*x[1]*y[4]-2.0*y[5]*z[5]*x[4]*y[1]-2.0*y[6]*x[6]*y[2]*z[7]+2.0*y[6]*x[6]*y
-       [7]*z[2];
-  s7 = s8+2.0*y[6]*z[6]*x[7]*y[2]-2.0*y[6]*z[6]*x[2]*y[7]-y[1]*z[1]*x[4]*y
-       [0]+y[1]*z[1]*x[0]*y[4]-y[1]*z[1]*x[0]*y[3]+2.0*y[6]*y[6]*x[7]*z[5]+2.0*y[5]*y
-       [5]*x[6]*z[4]-2.0*y[5]*y[5]*x[4]*z[6]+x[6]*y[5]*y[5]*z[7]-y[3]*x[2]*y[1]*z[3]-y
-       [3]*y[2]*x[3]*z[1]+y[3]*z[2]*x[3]*y[1]+y[3]*y[2]*x[1]*z[3]-y[2]*x[2]*y[0]*z[3]+
-       y[2]*z[2]*x[3]*y[0];
-  s8 = s7+2.0*y[2]*x[2]*y[3]*z[1]-2.0*y[2]*x[2]*y[1]*z[3]+y[2]*y[1]*x[0]*z
-       [2]-y[2]*y[1]*x[2]*z[0]+2.0*y[2]*z[2]*x[3]*y[1]-2.0*y[2]*z[2]*x[1]*y[3]-y[2]*z
-       [2]*x[0]*y[3]+y[5]*z[6]*x[5]*y[7]-y[5]*x[6]*y[7]*z[5]-y[5]*y[6]*x[4]*z[7]-y[5]*
-       y[6]*x[5]*z[7]-2.0*y[5]*x[5]*y[6]*z[4]+2.0*y[5]*x[5]*y[4]*z[6]-2.0*y[5]*z[5]*x
-       [6]*y[4]+2.0*y[5]*z[5]*x[4]*y[6];
-  s5 = s8-y[1]*y[5]*x[0]*z[4]-z[6]*x[7]*y[5]*y[5]+y[6]*y[6]*x[7]*z[4]-y[6]*
-       y[6]*x[4]*z[7]-2.0*y[6]*y[6]*x[5]*z[7]-x[5]*y[6]*y[6]*z[4]+z[5]*x[4]*y[6]*y[6]+
-       z[6]*x[5]*y[7]*y[7]-x[6]*y[7]*y[7]*z[5]+y[1]*y[5]*x[4]*z[0]+y[7]*y[6]*x[7]*z[5]
-       +y[6]*y[5]*x[7]*z[4]+y[5]*y[6]*x[7]*z[5]+y[6]*y[5]*x[6]*z[4]-y[6]*y[5]*x[4]*z
-       [6]+2.0*y[6]*z[6]*x[5]*y[7];
-  s8 = s5-2.0*y[6]*x[6]*y[7]*z[5]+2.0*y[6]*x[6]*y[5]*z[7]-2.0*y[6]*z[6]*x
-       [7]*y[5]-y[6]*x[5]*y[7]*z[4]-y[6]*x[6]*y[7]*z[4]+y[6]*x[6]*y[4]*z[7]-y[6]*z[6]*
-       x[7]*y[4]+y[6]*z[5]*x[4]*y[7]+y[6]*z[6]*x[4]*y[7]+y[6]*x[5]*y[4]*z[6]-y[6]*z[5]
-       *x[6]*y[4]+y[7]*x[6]*y[5]*z[7]-y[7]*z[6]*x[7]*y[5]-2.0*y[6]*x[6]*y[5]*z[2];
-  s7 = s8-y[7]*y[6]*x[5]*z[7]+2.0*y[4]*y[5]*x[4]*z[0]+2.0*x[3]*y[7]*y[7]*z
-       [4]-2.0*x[4]*y[7]*y[7]*z[3]-z[0]*x[4]*y[7]*y[7]+x[0]*y[7]*y[7]*z[4]-y[0]*z[5]*x
-       [4]*y[1]+y[0]*x[5]*y[1]*z[4]-y[0]*x[5]*y[4]*z[0]+y[0]*z[5]*x[0]*y[4]-y[5]*y[5]*
-       x[0]*z[4]+y[5]*y[5]*x[4]*z[0]+2.0*y[1]*y[1]*x[2]*z[5]-2.0*y[1]*y[1]*x[5]*z[2]+z
-       [1]*x[5]*y[2]*y[2];
-  s8 = s7-x[1]*y[2]*y[2]*z[5]-y[5]*z[5]*x[4]*y[0]+y[5]*z[5]*x[0]*y[4]-y[5]*
-       x[5]*y[4]*z[0]-y[2]*x[1]*y[6]*z[5]-y[2]*y[1]*x[5]*z[6]+y[2]*z[1]*x[5]*y[6]+y[2]
-       *y[1]*x[6]*z[5]-y[1]*z[1]*x[6]*y[5]-y[1]*x[1]*y[6]*z[5]+y[1]*x[1]*y[5]*z[6]+y
-       [1]*z[1]*x[5]*y[6]+y[5]*x[5]*y[0]*z[4]+y[2]*y[1]*x[2]*z[5]-y[2]*z[1]*x[2]*y[5];
-  s6 = s8+y[2]*x[1]*y[5]*z[2]-y[2]*y[1]*x[5]*z[2]-y[1]*y[1]*x[5]*z[6]+y[1]*
-       y[1]*x[6]*z[5]-z[1]*x[2]*y[5]*y[5]+x[1]*y[5]*y[5]*z[2]+2.0*y[1]*z[1]*x[5]*y[2]
-       -2.0*y[1]*x[1]*y[2]*z[5]-2.0*y[1]*z[1]*x[2]*y[5]+2.0*y[1]*x[1]*y[5]*z[2]-y[1]*y
-       [1]*x[6]*z[2]+y[1]*y[1]*x[2]*z[6]-2.0*y[5]*x[1]*y[6]*z[5]-2.0*y[5]*y[1]*x[5]*z
-       [6]+2.0*y[5]*z[1]*x[5]*y[6]+2.0*y[5]*y[1]*x[6]*z[5];
-  s8 = s6-y[6]*z[1]*x[6]*y[5]-y[6]*y[1]*x[5]*z[6]+y[6]*x[1]*y[5]*z[6]+y[6]*
-       y[1]*x[6]*z[5]-2.0*z[1]*x[6]*y[5]*y[5]+2.0*x[1]*y[5]*y[5]*z[6]-x[1]*y[6]*y[6]*z
-       [5]+z[1]*x[5]*y[6]*y[6]+y[5]*z[1]*x[5]*y[2]-y[5]*x[1]*y[2]*z[5]+y[5]*y[1]*x[2]*
-       z[5]-y[5]*y[1]*x[5]*z[2]-y[6]*z[1]*x[2]*y[5]+y[6]*x[1]*y[5]*z[2];
-  s7 = s8-y[1]*z[1]*x[2]*y[6]-y[1]*x[1]*y[2]*z[6]+y[1]*x[1]*y[6]*z[2]+y[1]*
-       z[1]*x[6]*y[2]+y[5]*x[5]*y[6]*z[2]-y[5]*x[2]*y[6]*z[5]+y[5]*x[6]*y[2]*z[5]-y[5]
-       *x[5]*y[2]*z[6]-x[6]*y[5]*y[5]*z[2]+x[2]*y[5]*y[5]*z[6]-y[5]*y[5]*x[4]*z[7]+y
-       [5]*y[5]*x[7]*z[4]-y[1]*x[6]*y[5]*z[2]+y[1]*x[2]*y[5]*z[6]-y[2]*x[6]*y[5]*z[2]
-       -2.0*y[2]*y[1]*x[6]*z[2];
-  s8 = s7-2.0*y[2]*z[1]*x[2]*y[6]+2.0*y[2]*x[1]*y[6]*z[2]+2.0*y[2]*y[1]*x
-       [2]*z[6]-2.0*x[1]*y[2]*y[2]*z[6]+2.0*z[1]*x[6]*y[2]*y[2]+x[6]*y[2]*y[2]*z[5]-x
-       [5]*y[2]*y[2]*z[6]+2.0*x[5]*y[6]*y[6]*z[2]-2.0*x[2]*y[6]*y[6]*z[5]-z[1]*x[2]*y
-       [6]*y[6]-y[6]*y[1]*x[6]*z[2]-y[6]*x[1]*y[2]*z[6]+y[6]*z[1]*x[6]*y[2]+y[6]*y[1]*
-       x[2]*z[6]+x[1]*y[6]*y[6]*z[2];
-  s3 = s8+y[2]*x[5]*y[6]*z[2]+y[2]*x[2]*y[5]*z[6]-y[2]*x[2]*y[6]*z[5]+y[5]*
-       z[5]*x[4]*y[7]+y[5]*x[5]*y[4]*z[7]-y[5]*z[5]*x[7]*y[4]-y[5]*x[5]*y[7]*z[4]+2.0*
-       y[4]*x[5]*y[0]*z[4]-y[3]*z[6]*x[3]*y[7]+y[3]*y[6]*x[3]*z[7]+y[3]*x[6]*y[7]*z[3]
-       -y[3]*y[6]*x[7]*z[3]-y[2]*y[1]*x[3]*z[0]-y[2]*z[1]*x[0]*y[3]+y[2]*y[1]*x[0]*z
-       [3]+y[2]*x[1]*y[3]*z[0];
-  s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
-       [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
-       z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
-       +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
-  s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
-       x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
-       *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
-       [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
-  s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
-       [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
-       z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
-       -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
-  s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
-       x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
-       *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
-       [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
-  s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
-       y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
-       *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
-       [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
-  s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
-       x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
-       *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
-       [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
-  s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
-       [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
-       z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
-       +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
-  s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
-       x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
-       *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
-       [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
-  s4 = 1/s5;
-  s2 = s3*s4;
-  const double unknown1 = s1*s2;
-  s1 = 1.0/6.0;
-  s8 = -z[2]*x[1]*y[2]*z[5]+z[2]*y[1]*x[2]*z[5]-z[2]*z[1]*x[2]*y[5]+z[2]*z
-       [1]*x[5]*y[2]+2.0*y[5]*x[7]*z[4]*z[4]-y[1]*x[2]*z[0]*z[0]+x[0]*y[3]*z[7]*z[7]
-       -2.0*z[5]*z[5]*x[4]*y[1]+2.0*z[5]*z[5]*x[1]*y[4]+z[5]*z[5]*x[0]*y[4]-2.0*z[2]*z
-       [2]*x[1]*y[3]+2.0*z[2]*z[2]*x[3]*y[1]-x[0]*y[4]*z[7]*z[7]-y[0]*x[3]*z[7]*z[7]+x
-       [1]*y[0]*z[5]*z[5];
-  s7 = s8-y[1]*x[0]*z[5]*z[5]+z[1]*y[1]*x[2]*z[6]+y[1]*x[0]*z[2]*z[2]+z[2]*
-       z[2]*x[3]*y[0]-z[2]*z[2]*x[0]*y[3]-x[1]*y[0]*z[2]*z[2]+2.0*z[5]*z[5]*x[4]*y[6]
-       -2.0*z[5]*z[5]*x[6]*y[4]-z[5]*z[5]*x[7]*y[4]-x[6]*y[7]*z[5]*z[5]+2.0*z[2]*y[1]*
-       x[2]*z[6]-2.0*z[2]*x[1]*y[2]*z[6]+2.0*z[2]*z[1]*x[6]*y[2]-y[6]*x[5]*z[7]*z[7]+
-       2.0*x[6]*y[4]*z[7]*z[7];
-  s8 = -2.0*y[6]*x[4]*z[7]*z[7]+x[6]*y[5]*z[7]*z[7]-2.0*z[2]*z[1]*x[2]*y[6]
-       +z[4]*y[6]*x[7]*z[5]+x[5]*y[4]*z[6]*z[6]+z[6]*z[6]*x[4]*y[7]-z[6]*z[6]*x[7]*y
-       [4]-2.0*z[6]*z[6]*x[7]*y[5]+2.0*z[6]*z[6]*x[5]*y[7]-y[5]*x[4]*z[6]*z[6]+2.0*z
-       [0]*z[0]*x[3]*y[4]-x[6]*y[5]*z[2]*z[2]+z[1]*z[1]*x[5]*y[6]-z[1]*z[1]*x[6]*y[5]-
-       z[5]*z[5]*x[4]*y[0];
-  s6 = s8+2.0*x[1]*y[3]*z[0]*z[0]+2.0*x[1]*y[6]*z[2]*z[2]-2.0*y[1]*x[6]*z
-       [2]*z[2]-y[1]*x[5]*z[2]*z[2]-z[1]*z[1]*x[2]*y[6]-2.0*z[1]*z[1]*x[2]*y[5]+2.0*z
-       [1]*z[1]*x[5]*y[2]+z[1]*y[1]*x[6]*z[5]+y[1]*x[2]*z[5]*z[5]+z[2]*z[1]*x[2]*y[0]+
-       z[1]*x[1]*y[5]*z[6]-z[1]*x[1]*y[6]*z[5]-z[1]*y[1]*x[5]*z[6]-z[1]*x[2]*y[6]*z[5]
-       +z[1]*x[6]*y[2]*z[5]+s7;
-  s8 = -x[1]*y[2]*z[5]*z[5]+z[1]*x[5]*y[6]*z[2]-2.0*z[2]*z[2]*x[3]*y[6]+2.0
-       *z[2]*z[2]*x[6]*y[3]+z[2]*z[2]*x[7]*y[3]-z[2]*z[2]*x[3]*y[7]-z[1]*x[6]*y[5]*z
-       [2]+2.0*z[1]*x[1]*y[5]*z[2]-2.0*x[3]*y[4]*z[7]*z[7]+2.0*x[4]*y[3]*z[7]*z[7]+x
-       [5]*y[6]*z[2]*z[2]+y[1]*x[2]*z[6]*z[6]+y[0]*x[4]*z[7]*z[7]+z[2]*x[2]*y[3]*z[0]-
-       x[1]*y[2]*z[6]*z[6];
-  s7 = s8-z[7]*z[2]*x[3]*y[7]+x[2]*y[6]*z[3]*z[3]-y[2]*x[6]*z[3]*z[3]-z[6]*
-       x[2]*y[3]*z[7]-z[2]*z[1]*x[0]*y[2]+z[6]*z[2]*x[6]*y[3]-z[6]*z[2]*x[3]*y[6]+z[6]
-       *x[2]*y[6]*z[3]+z[2]*x[1]*y[2]*z[0]+z[6]*y[2]*x[3]*z[7]-z[4]*z[5]*x[6]*y[4]+z
-       [4]*z[5]*x[4]*y[6]-z[4]*y[6]*x[5]*z[7]+z[4]*z[6]*x[4]*y[7]+z[4]*x[5]*y[4]*z[6];
-  s8 = -z[6]*y[2]*x[6]*z[3]-z[4]*y[5]*x[4]*z[6]-z[2]*y[1]*x[5]*z[6]+z[2]*x
-       [1]*y[5]*z[6]+z[4]*x[6]*y[4]*z[7]+2.0*z[4]*z[5]*x[4]*y[7]-z[4]*z[6]*x[7]*y[4]+x
-       [6]*y[7]*z[3]*z[3]-2.0*z[4]*z[5]*x[7]*y[4]-2.0*z[4]*y[5]*x[4]*z[7]-z[4]*y[6]*x
-       [4]*z[7]+z[4]*x[6]*y[5]*z[7]-z[4]*x[6]*y[7]*z[5]+2.0*z[4]*x[5]*y[4]*z[7]+z[2]*x
-       [2]*y[5]*z[6]-z[2]*x[2]*y[6]*z[5];
-  s5 = s8+z[2]*x[6]*y[2]*z[5]-z[2]*x[5]*y[2]*z[6]-z[2]*x[2]*y[3]*z[7]-x[2]*
-       y[3]*z[7]*z[7]+2.0*z[2]*x[2]*y[3]*z[1]-z[2]*y[2]*x[3]*z[0]+z[2]*y[2]*x[0]*z[3]-
-       z[2]*x[2]*y[0]*z[3]-z[7]*y[2]*x[7]*z[3]+z[7]*z[2]*x[7]*y[3]+z[7]*x[2]*y[7]*z[3]
-       +z[6]*y[1]*x[2]*z[5]-z[6]*x[1]*y[2]*z[5]+z[5]*x[1]*y[5]*z[2]+s6+s7;
-  s8 = z[5]*z[1]*x[5]*y[2]-z[5]*z[1]*x[2]*y[5]-y[6]*x[7]*z[2]*z[2]+2.0*z[2]
-       *x[2]*y[6]*z[3]-2.0*z[2]*x[2]*y[3]*z[6]+2.0*z[2]*y[2]*x[3]*z[6]+y[2]*x[3]*z[6]*
-       z[6]+y[6]*x[7]*z[5]*z[5]+z[2]*y[2]*x[3]*z[7]-z[2]*y[2]*x[7]*z[3]-2.0*z[2]*y[2]*
-       x[6]*z[3]+z[2]*x[2]*y[7]*z[3]+x[6]*y[2]*z[5]*z[5]-2.0*z[2]*x[2]*y[1]*z[3]-x[2]*
-       y[6]*z[5]*z[5];
-  s7 = s8-y[1]*x[5]*z[6]*z[6]+z[6]*x[1]*y[6]*z[2]-z[3]*z[2]*x[3]*y[6]+z[6]*
-       z[1]*x[6]*y[2]-z[6]*z[1]*x[2]*y[6]-z[6]*y[1]*x[6]*z[2]-2.0*x[5]*y[2]*z[6]*z[6]+
-       z[4]*z[1]*x[0]*y[4]-z[3]*x[2]*y[3]*z[6]-z[5]*y[1]*x[5]*z[2]+z[3]*y[2]*x[3]*z[6]
-       +2.0*x[2]*y[5]*z[6]*z[6]-z[5]*x[1]*y[5]*z[0]+y[2]*x[3]*z[7]*z[7]-x[2]*y[3]*z[6]
-       *z[6];
-  s8 = z[5]*y[5]*x[4]*z[0]+z[3]*z[2]*x[6]*y[3]+x[1]*y[5]*z[6]*z[6]+z[5]*y
-       [5]*x[7]*z[4]-z[1]*x[1]*y[2]*z[6]+z[1]*x[1]*y[6]*z[2]+2.0*z[6]*y[6]*x[7]*z[5]-z
-       [7]*y[6]*x[7]*z[2]-z[3]*y[6]*x[7]*z[2]+x[6]*y[7]*z[2]*z[2]-2.0*z[6]*y[6]*x[7]*z
-       [2]-2.0*x[6]*y[3]*z[7]*z[7]-x[6]*y[2]*z[7]*z[7]-z[5]*x[6]*y[5]*z[2]+y[6]*x[2]*z
-       [7]*z[7];
-  s6 = s8+2.0*y[6]*x[3]*z[7]*z[7]+z[6]*z[6]*x[7]*y[3]-y[6]*x[7]*z[3]*z[3]+z
-       [5]*x[5]*y[0]*z[4]+2.0*z[6]*z[6]*x[7]*y[2]-2.0*z[6]*z[6]*x[2]*y[7]-z[6]*z[6]*x
-       [3]*y[7]+z[7]*y[6]*x[7]*z[5]+z[7]*y[5]*x[7]*z[4]-2.0*z[7]*x[7]*y[3]*z[4]+2.0*z
-       [7]*x[3]*y[7]*z[4]-2.0*z[7]*x[4]*y[7]*z[3]+2.0*z[7]*x[7]*y[4]*z[3]-z[7]*y[0]*x
-       [7]*z[4]-2.0*z[7]*z[6]*x[3]*y[7]+s7;
-  s8 = s6+2.0*z[7]*z[6]*x[7]*y[3]+2.0*z[7]*x[6]*y[7]*z[3]+z[7]*x[6]*y[7]*z
-       [2]-2.0*z[7]*y[6]*x[7]*z[3]+z[7]*z[6]*x[7]*y[2]-z[7]*z[6]*x[2]*y[7]+z[5]*y[1]*x
-       [5]*z[0]-z[5]*z[1]*x[5]*y[0]+2.0*y[1]*x[6]*z[5]*z[5]-2.0*x[1]*y[6]*z[5]*z[5]+z
-       [5]*z[1]*x[0]*y[5]+z[6]*y[6]*x[3]*z[7]+2.0*z[6]*x[6]*y[7]*z[2]-z[6]*y[6]*x[7]*z
-       [3];
-  s7 = s8+2.0*z[6]*y[6]*x[2]*z[7]-z[6]*x[6]*y[3]*z[7]+z[6]*x[6]*y[7]*z[3]
-       -2.0*z[6]*x[6]*y[2]*z[7]-2.0*z[1]*y[1]*x[5]*z[2]-z[1]*y[1]*x[6]*z[2]-z[7]*z[0]*
-       x[7]*y[3]-2.0*z[6]*x[6]*y[5]*z[2]-z[2]*z[6]*x[3]*y[7]+z[2]*x[6]*y[7]*z[3]-z[2]*
-       z[6]*x[2]*y[7]+y[5]*x[6]*z[4]*z[4]+z[2]*y[6]*x[2]*z[7]+y[6]*x[7]*z[4]*z[4]+z[2]
-       *z[6]*x[7]*y[2]-2.0*x[5]*y[7]*z[4]*z[4];
-  s8 = -x[6]*y[7]*z[4]*z[4]-z[5]*y[5]*x[0]*z[4]-z[2]*x[6]*y[2]*z[7]-x[5]*y
-       [6]*z[4]*z[4]-2.0*z[5]*y[1]*x[5]*z[6]+2.0*z[5]*z[1]*x[5]*y[6]+2.0*z[5]*x[1]*y
-       [5]*z[6]-2.0*z[5]*z[1]*x[6]*y[5]-z[5]*x[5]*y[2]*z[6]+z[5]*x[5]*y[6]*z[2]+z[5]*x
-       [2]*y[5]*z[6]+z[5]*z[5]*x[4]*y[7]-y[5]*x[4]*z[7]*z[7]+x[5]*y[4]*z[7]*z[7]+z[6]*
-       z[1]*x[5]*y[6]+z[6]*y[1]*x[6]*z[5];
-  s4 = s8-z[6]*z[1]*x[6]*y[5]-z[6]*x[1]*y[6]*z[5]+z[2]*z[6]*x[7]*y[3]+2.0*z
-       [6]*x[6]*y[2]*z[5]+2.0*z[6]*x[5]*y[6]*z[2]-2.0*z[6]*x[2]*y[6]*z[5]+z[7]*z[0]*x
-       [3]*y[7]+z[7]*z[0]*x[7]*y[4]+z[3]*z[6]*x[7]*y[3]-z[3]*z[6]*x[3]*y[7]-z[3]*x[6]*
-       y[3]*z[7]+z[3]*y[6]*x[2]*z[7]-z[3]*x[6]*y[2]*z[7]+z[5]*x[5]*y[4]*z[7]+s5+s7;
-  s8 = s4+z[3]*y[6]*x[3]*z[7]-z[7]*x[0]*y[7]*z[3]+z[6]*x[5]*y[4]*z[7]+z[7]*
-       y[0]*x[7]*z[3]+z[5]*z[6]*x[4]*y[7]-2.0*z[5]*x[5]*y[6]*z[4]+2.0*z[5]*x[5]*y[4]*z
-       [6]-z[5]*x[5]*y[7]*z[4]-z[5]*y[6]*x[5]*z[7]-z[5]*z[6]*x[7]*y[4]-z[7]*z[0]*x[4]*
-       y[7]-z[5]*z[6]*x[7]*y[5]-z[5]*y[5]*x[4]*z[7]+z[7]*x[0]*y[7]*z[4];
-  s7 = s8-2.0*z[5]*y[5]*x[4]*z[6]+z[5]*z[6]*x[5]*y[7]+z[5]*x[6]*y[5]*z[7]+
-       2.0*z[5]*y[5]*x[6]*z[4]+z[6]*z[5]*x[4]*y[6]-z[6]*x[5]*y[6]*z[4]-z[6]*z[5]*x[6]*
-       y[4]-z[6]*x[6]*y[7]*z[4]-2.0*z[6]*y[6]*x[5]*z[7]+z[6]*x[6]*y[4]*z[7]-z[6]*y[5]*
-       x[4]*z[7]-z[6]*y[6]*x[4]*z[7]+z[6]*y[6]*x[7]*z[4]+z[6]*y[5]*x[6]*z[4]+2.0*z[6]*
-       x[6]*y[5]*z[7];
-  s8 = -2.0*z[6]*x[6]*y[7]*z[5]-z[2]*y[1]*x[2]*z[0]+2.0*z[7]*z[6]*x[4]*y[7]
-       -2.0*z[7]*x[6]*y[7]*z[4]-2.0*z[7]*z[6]*x[7]*y[4]+z[7]*z[5]*x[4]*y[7]-z[7]*z[5]*
-       x[7]*y[4]-z[7]*x[5]*y[7]*z[4]+2.0*z[7]*y[6]*x[7]*z[4]-z[7]*z[6]*x[7]*y[5]+z[7]*
-       z[6]*x[5]*y[7]-z[7]*x[6]*y[7]*z[5]+z[1]*z[1]*x[6]*y[2]+s7+x[1]*y[5]*z[2]*z[2];
-  s6 = s8+2.0*z[2]*y[2]*x[1]*z[3]-2.0*z[2]*y[2]*x[3]*z[1]-2.0*x[1]*y[4]*z
-       [0]*z[0]+2.0*y[1]*x[4]*z[0]*z[0]+2.0*x[2]*y[7]*z[3]*z[3]-2.0*y[2]*x[7]*z[3]*z
-       [3]-x[1]*y[5]*z[0]*z[0]+z[0]*z[0]*x[7]*y[4]+z[0]*z[0]*x[3]*y[7]+x[2]*y[3]*z[0]*
-       z[0]-2.0*y[1]*x[3]*z[0]*z[0]+y[5]*x[4]*z[0]*z[0]-2.0*z[0]*z[0]*x[4]*y[3]+x[1]*y
-       [2]*z[0]*z[0]-z[0]*z[0]*x[4]*y[7]+y[1]*x[5]*z[0]*z[0];
-  s8 = s6-y[2]*x[3]*z[0]*z[0]+y[1]*x[0]*z[3]*z[3]-2.0*x[0]*y[7]*z[3]*z[3]-x
-       [0]*y[4]*z[3]*z[3]-2.0*x[2]*y[0]*z[3]*z[3]-x[1]*y[0]*z[3]*z[3]+y[0]*x[4]*z[3]*z
-       [3]-2.0*z[0]*y[1]*x[0]*z[4]+2.0*z[0]*z[1]*x[0]*y[4]+2.0*z[0]*x[1]*y[0]*z[4]-2.0
-       *z[0]*z[1]*x[4]*y[0]-2.0*z[3]*x[2]*y[3]*z[7]-2.0*z[3]*z[2]*x[3]*y[7]+2.0*z[3]*z
-       [2]*x[7]*y[3];
-  s7 = s8+2.0*z[3]*y[2]*x[3]*z[7]+2.0*z[5]*y[5]*x[4]*z[1]+2.0*z[0]*y[1]*x
-       [0]*z[3]-z[0]*y[0]*x[3]*z[7]-2.0*z[0]*y[0]*x[3]*z[4]-z[0]*x[1]*y[0]*z[2]+z[0]*z
-       [1]*x[2]*y[0]-z[0]*y[1]*x[0]*z[5]-z[0]*z[1]*x[0]*y[2]-z[0]*x[0]*y[7]*z[3]-2.0*z
-       [0]*z[1]*x[0]*y[3]-z[5]*x[5]*y[4]*z[0]-2.0*z[0]*x[0]*y[4]*z[3]+z[0]*x[0]*y[7]*z
-       [4]-z[0]*z[2]*x[0]*y[3];
-  s8 = s7+z[0]*x[5]*y[0]*z[4]+z[0]*z[1]*x[0]*y[5]-z[0]*x[2]*y[0]*z[3]-z[0]*
-       z[1]*x[5]*y[0]-2.0*z[0]*x[1]*y[0]*z[3]+2.0*z[0]*y[0]*x[4]*z[3]-z[0]*x[0]*y[4]*z
-       [7]+z[0]*x[1]*y[0]*z[5]+z[0]*y[0]*x[7]*z[3]+z[0]*y[2]*x[0]*z[3]-z[0]*y[5]*x[0]*
-       z[4]+z[0]*z[2]*x[3]*y[0]+z[0]*x[2]*y[3]*z[1]+z[0]*x[0]*y[3]*z[7]-z[0]*x[2]*y[1]
-       *z[3];
-  s5 = s8+z[0]*y[1]*x[0]*z[2]+z[3]*x[1]*y[3]*z[0]-2.0*z[3]*y[0]*x[3]*z[7]-z
-       [3]*y[0]*x[3]*z[4]-z[3]*x[1]*y[0]*z[2]+z[3]*z[0]*x[7]*y[4]+2.0*z[3]*z[0]*x[3]*y
-       [7]+2.0*z[3]*x[2]*y[3]*z[0]-z[3]*y[1]*x[3]*z[0]-z[3]*z[1]*x[0]*y[3]-z[3]*z[0]*x
-       [4]*y[3]+z[3]*x[1]*y[2]*z[0]-z[3]*z[0]*x[4]*y[7]-2.0*z[3]*z[2]*x[0]*y[3]-z[3]*x
-       [0]*y[4]*z[7]-2.0*z[3]*y[2]*x[3]*z[0];
-  s8 = s5+2.0*z[3]*z[2]*x[3]*y[0]+z[3]*x[2]*y[3]*z[1]+2.0*z[3]*x[0]*y[3]*z
-       [7]+z[3]*y[1]*x[0]*z[2]-z[4]*y[0]*x[3]*z[7]-z[4]*x[1]*y[5]*z[0]-z[4]*y[1]*x[0]*
-       z[5]+2.0*z[4]*z[0]*x[7]*y[4]+z[4]*z[0]*x[3]*y[7]+2.0*z[4]*y[5]*x[4]*z[0]+2.0*y
-       [0]*x[7]*z[3]*z[3]+2.0*y[2]*x[0]*z[3]*z[3]-x[2]*y[1]*z[3]*z[3]-y[0]*x[3]*z[4]*z
-       [4];
-  s7 = s8-y[1]*x[0]*z[4]*z[4]+x[1]*y[0]*z[4]*z[4]+2.0*x[0]*y[7]*z[4]*z[4]+
-       2.0*x[5]*y[0]*z[4]*z[4]-2.0*y[5]*x[0]*z[4]*z[4]+2.0*z[1]*z[1]*x[2]*y[0]-2.0*z
-       [1]*z[1]*x[0]*y[2]+z[1]*z[1]*x[0]*y[4]-z[1]*z[1]*x[0]*y[3]-z[1]*z[1]*x[4]*y[0]+
-       2.0*z[1]*z[1]*x[0]*y[5]-2.0*z[1]*z[1]*x[5]*y[0]+x[2]*y[3]*z[1]*z[1]-x[5]*y[4]*z
-       [0]*z[0]-z[0]*z[0]*x[7]*y[3];
-  s8 = s7+x[7]*y[4]*z[3]*z[3]-x[4]*y[7]*z[3]*z[3]+y[2]*x[1]*z[3]*z[3]+x[0]*
-       y[3]*z[4]*z[4]-2.0*y[0]*x[7]*z[4]*z[4]+x[3]*y[7]*z[4]*z[4]-x[7]*y[3]*z[4]*z[4]-
-       y[5]*x[1]*z[4]*z[4]+x[5]*y[1]*z[4]*z[4]+z[1]*z[1]*x[3]*y[0]+y[5]*x[4]*z[1]*z[1]
-       -y[2]*x[3]*z[1]*z[1]-x[5]*y[4]*z[1]*z[1]-z[4]*x[0]*y[4]*z[3]-z[4]*z[0]*x[4]*y
-       [3];
-  s6 = s8-z[4]*z[1]*x[4]*y[0]-2.0*z[4]*z[0]*x[4]*y[7]+z[4]*y[1]*x[5]*z[0]
-       -2.0*z[5]*x[5]*y[4]*z[1]-z[4]*x[1]*y[4]*z[0]+z[4]*y[0]*x[4]*z[3]-2.0*z[4]*x[0]*
-       y[4]*z[7]+z[4]*x[1]*y[0]*z[5]-2.0*z[1]*x[1]*y[2]*z[5]+z[4]*x[0]*y[3]*z[7]+2.0*z
-       [5]*x[5]*y[1]*z[4]+z[4]*y[1]*x[4]*z[0]+z[1]*y[1]*x[0]*z[3]+z[1]*x[1]*y[3]*z[0]
-       -2.0*z[1]*x[1]*y[5]*z[0]-2.0*z[1]*x[1]*y[0]*z[2];
-  s8 = s6-2.0*z[1]*y[1]*x[0]*z[5]-z[1]*y[1]*x[0]*z[4]+2.0*z[1]*y[1]*x[2]*z
-       [5]-z[1]*y[1]*x[3]*z[0]-2.0*z[5]*y[5]*x[1]*z[4]+z[1]*y[5]*x[4]*z[0]+z[1]*x[1]*y
-       [0]*z[4]+2.0*z[1]*x[1]*y[2]*z[0]-z[1]*z[2]*x[0]*y[3]+2.0*z[1]*y[1]*x[5]*z[0]-z
-       [1]*x[1]*y[0]*z[3]-z[1]*x[1]*y[4]*z[0]+2.0*z[1]*x[1]*y[0]*z[5]-z[1]*y[2]*x[3]*z
-       [0];
-  s7 = s8+z[1]*z[2]*x[3]*y[0]-z[1]*x[2]*y[1]*z[3]+z[1]*y[1]*x[4]*z[0]+2.0*z
-       [1]*y[1]*x[0]*z[2]+2.0*z[0]*z[1]*x[3]*y[0]+2.0*z[0]*x[0]*y[3]*z[4]+z[0]*z[5]*x
-       [0]*y[4]+z[0]*y[0]*x[4]*z[7]-z[0]*y[0]*x[7]*z[4]-z[0]*x[7]*y[3]*z[4]-z[0]*z[5]*
-       x[4]*y[0]-z[0]*x[5]*y[4]*z[1]+z[3]*z[1]*x[3]*y[0]+z[3]*x[0]*y[3]*z[4]+z[3]*z[0]
-       *x[3]*y[4]+z[3]*y[0]*x[4]*z[7];
-  s8 = s7+z[3]*x[3]*y[7]*z[4]-z[3]*x[7]*y[3]*z[4]-z[3]*x[3]*y[4]*z[7]+z[3]*
-       x[4]*y[3]*z[7]-z[3]*y[2]*x[3]*z[1]+z[3]*z[2]*x[3]*y[1]-z[3]*z[2]*x[1]*y[3]-2.0*
-       z[3]*z[0]*x[7]*y[3]+z[4]*z[0]*x[3]*y[4]+2.0*z[4]*z[5]*x[0]*y[4]+2.0*z[4]*y[0]*x
-       [4]*z[7]-2.0*z[4]*x[5]*y[4]*z[0]+z[4]*y[5]*x[4]*z[1]+z[4]*x[7]*y[4]*z[3]-z[4]*x
-       [4]*y[7]*z[3];
-  s3 = s8-z[4]*x[3]*y[4]*z[7]+z[4]*x[4]*y[3]*z[7]-2.0*z[4]*z[5]*x[4]*y[0]-z
-       [4]*x[5]*y[4]*z[1]+z[4]*z[5]*x[1]*y[4]-z[4]*z[5]*x[4]*y[1]-2.0*z[1]*y[1]*x[2]*z
-       [0]+z[1]*z[5]*x[0]*y[4]-z[1]*z[5]*x[4]*y[0]-z[1]*y[5]*x[1]*z[4]+z[1]*x[5]*y[1]*
-       z[4]+z[1]*z[5]*x[1]*y[4]-z[1]*z[5]*x[4]*y[1]+z[1]*z[2]*x[3]*y[1]-z[1]*z[2]*x[1]
-       *y[3]+z[1]*y[2]*x[1]*z[3];
-  s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
-       [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
-       z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
-       +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
-  s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
-       x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
-       *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
-       [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
-  s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
-       [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
-       z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
-       -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
-  s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
-       x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
-       *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
-       [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
-  s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
-       y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
-       *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
-       [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
-  s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
-       x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
-       *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
-       [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
-  s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
-       [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
-       z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
-       +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
-  s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
-       x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
-       *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
-       [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
-  s4 = 1/s5;
-  s2 = s3*s4;
-  const double unknown2 = s1*s2;
-
-  return Point<3> (unknown0, unknown1, unknown2);
-}
+#if deal_II_dimension == 3  
 
+  double
+  measure (const TriaAccessor<3, 3, 3> &accessor)
+  {
+    unsigned int vertex_indices[GeometryInfo<3>::vertices_per_cell];
+    for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
+      vertex_indices[i] = accessor.vertex_index(i);
 
+    return GridTools::cell_measure<3>(accessor.get_triangulation().get_vertices(),
+                                     vertex_indices);
+  }
 
-template <>
-double TriaObjectAccessor<3, 3>::measure () const
-{
-  unsigned int vertex_indices[GeometryInfo<3>::vertices_per_cell];
-  for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
-    vertex_indices[i]=vertex_index(i);
+#endif
+  
 
-  return GridTools::cell_measure<3>(this->tria->vertices, vertex_indices);
+  template <int structdim, int dim, int spacedim>
+  double
+  measure (const TriaAccessor<structdim, dim, spacedim> &)
+  {
+                                    // catch-all for all cases not explicitly
+                                    // listed above
+    Assert (false, ExcNotImplemented());
+    return -1e10;
+  }
 }
 
-#endif
-
 
 
-template <int dim>
-unsigned int TriaObjectAccessor<3, dim>::number_of_children () const
-{
-  if (!has_children())
-    return 1;
-  else
-    {
-      unsigned int sum = 0;
-      for (unsigned int c=0; c<n_children(); ++c)
-       sum += child(c)->number_of_children();
-      return sum;
-    };
-}
 
 
-#if deal_II_dimension == 3 
+/*------------------------ Functions: TriaAccessor ---------------------------*/
 
-template <>
+template <int structdim, int dim, int spacedim>
 void
-TriaObjectAccessor<3, 3>::
-set_face_orientation (const unsigned int face,
-                      const bool         orientation) const
+TriaAccessor<structdim, dim, spacedim>::
+set (const internal::Triangulation::TriaObject<structdim> &object) const
 {
-  Assert (used(), TriaAccessorExceptions::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]
-          ->cells.face_orientations.size(),
-          ExcInternalError());
-          
-  this->tria->levels[this->present_level]
-    ->cells.face_orientations[this->present_index *
-                              GeometryInfo<3>::faces_per_cell
-                              +
-                              face]  = orientation;
+  this->objects().cells[this->present_index] = object;
 }
 
 
-template <>
-void
-TriaObjectAccessor<3, 3>::
-set_face_flip (const unsigned int face,
-              const bool         flip) const
-{
-  Assert (used(), TriaAccessorExceptions::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]
-          ->cells.face_flips.size(),
-          ExcInternalError());
-          
-  this->tria->levels[this->present_level]
-    ->cells.face_flips[this->present_index *
-                      GeometryInfo<3>::faces_per_cell
-                      +
-                      face]  = flip;
-}
-
 
-template <>
-void
-TriaObjectAccessor<3, 3>::
-set_face_rotation (const unsigned int face,
-                  const bool         rotation) const
+template <int structdim, int dim, int spacedim>
+Point<spacedim>
+TriaAccessor<structdim, dim, spacedim>::
+barycenter () const
 {
-  Assert (used(), TriaAccessorExceptions::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]
-          ->cells.face_rotations.size(),
-          ExcInternalError());
-          
-  this->tria->levels[this->present_level]
-    ->cells.face_rotations[this->present_index *
-                          GeometryInfo<3>::faces_per_cell
-                          +
-                          face]  = rotation;
+                                  // call the function in the anonymous
+                                  // namespace above
+  return dealii::barycenter (*this);
 }
 
-#endif
-// Remark: The following explicit instantiations needed to be moved to
-// this place here to work around a problem with gcc3.3 on Apple MacOSX.
-// The reason is that some of the functions instantiated here are used
-// further down; if they are not explicitly instantiated here, then the
-// compiler will do an implicit instantiation and give it internal linkage
-// (despite the later explicit instantiation that should make sure it
-// gets external linkage). To make sure the functions have external
-// linkage, we need to place the explicit instantiation before the first
-// use.
-//
-// For more information, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24331
-
-template class TriaObjectAccessor<1, deal_II_dimension>;
 
-#if deal_II_dimension >= 2
-template class TriaObjectAccessor<2, deal_II_dimension>;
-#endif
 
-#if deal_II_dimension >= 3
-template class TriaObjectAccessor<3, deal_II_dimension>;
-#endif
+template <int structdim, int dim, int spacedim>
+double
+TriaAccessor<structdim, dim, spacedim>::
+measure () const
+{
+                                  // call the function in the anonymous
+                                  // namespace above
+  return dealii::measure (*this);
+}
 
 
 
@@ -2065,14 +1019,6 @@ template class TriaObjectAccessor<3, deal_II_dimension>;
 
 #if deal_II_dimension == 1
 
-template <>
-bool CellAccessor<1>::at_boundary () const
-{
-  return at_boundary(0) || at_boundary(1);
-}
-
-
-
 template <>
 bool CellAccessor<1>::point_inside (const Point<1> &p) const
 {
@@ -2082,15 +1028,14 @@ bool CellAccessor<1>::point_inside (const Point<1> &p) const
 
 
 template <>
-std::pair<unsigned int, unsigned int>
-CellAccessor<1>::neighbor_of_coarser_neighbor (const unsigned int) const
+bool CellAccessor<1,2>::point_inside (const Point<2> &) const
 {
-  Assert(false, ExcImpossibleInDim(1));
-  return std::make_pair (numbers::invalid_unsigned_int,
-                        numbers::invalid_unsigned_int);
+  Assert (false, ExcNotImplemented());
+  return 0;
 }
 
 
+
 #endif
 
 
@@ -2099,14 +1044,6 @@ CellAccessor<1>::neighbor_of_coarser_neighbor (const unsigned int) const
 
 #if deal_II_dimension == 2
 
-template <>
-bool CellAccessor<2>::at_boundary () const
-{
-  return at_boundary(0) || at_boundary(1) || at_boundary(2) || at_boundary(3);
-}
-
-
-
 template <>
 bool CellAccessor<2>::point_inside (const Point<2> &p) const
 {
@@ -2162,6 +1099,14 @@ bool CellAccessor<2>::point_inside (const Point<2> &p) const
 }
 
 
+template <>
+bool CellAccessor<2,3>::point_inside (const Point<3> &) const
+{
+  Assert (false, ExcNotImplemented());
+  return 0;
+}
+
+
 #endif
 
 
@@ -2170,16 +1115,6 @@ bool CellAccessor<2>::point_inside (const Point<2> &p) const
 
 #if deal_II_dimension == 3
 
-template <>
-bool CellAccessor<3>::at_boundary () const
-{
-  return (at_boundary(0) || at_boundary(1) ||
-         at_boundary(2) || at_boundary(3) ||
-         at_boundary(4) || at_boundary(5));
-}
-
-
-
 template <>
 bool CellAccessor<3>::point_inside (const Point<3> &p) const
 {
@@ -2192,8 +1127,9 @@ bool CellAccessor<3>::point_inside (const Point<3> &p) const
                                    // transform to the unit cell, and
                                    // check there.
   const unsigned int dim = 3;
-  Point<dim> maxp = this->vertex(0);
-  Point<dim> minp = this->vertex(0);
+  const unsigned int spacedim = 3;
+  Point<spacedim> maxp = this->vertex(0);
+  Point<spacedim> minp = this->vertex(0);
 
   for (unsigned int v=1; v<GeometryInfo<dim>::vertices_per_cell; ++v)
     for (unsigned int d=0; d<dim; ++d)
@@ -2212,20 +1148,43 @@ bool CellAccessor<3>::point_inside (const Point<3> &p) const
                                   // carefully: transform to the
                                   // unit cube
                                   // and check there.
-  const TriaRawIterator<dim, CellAccessor<dim> > cell_iterator (*this);
+  const TriaRawIterator< CellAccessor<dim,spacedim> > cell_iterator (*this);
   return (GeometryInfo<dim>::is_inside_unit_cell (
-    StaticMappingQ1<dim>::mapping.transform_real_to_unit_cell(cell_iterator, p)));
+             StaticMappingQ1<dim,spacedim>::mapping.transform_real_to_unit_cell(cell_iterator, p)));
 }
 
 
 #endif
 
 
-/*------------------------ Functions: CellAccessor<dim> -----------------------*/
+/*------------------------ Functions: CellAccessor<dim,spacedim> -----------------------*/
+
+
+
+template <int dim, int spacedim>
+bool CellAccessor<dim, spacedim>::at_boundary () const
+{
+  switch (dim)
+    {
+      case 1:
+           return at_boundary(0) || at_boundary(1);
+      case 2:
+           return (at_boundary(0) || at_boundary(1) ||
+                   at_boundary(2) || at_boundary(3));
+      case 3:
+           return (at_boundary(0) || at_boundary(1) ||
+                   at_boundary(2) || at_boundary(3) ||
+                   at_boundary(4) || at_boundary(5));
+      default:
+           Assert (false, ExcNotImplemented());
+           return false;
+    }
+}
+
 
 
-template <int dim>
-unsigned char CellAccessor<dim>::material_id () const
+template <int dim, int spacedim>
+unsigned char CellAccessor<dim, spacedim>::material_id () const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
   return this->tria->levels[this->present_level]->cells.material_id[this->present_index];
@@ -2233,8 +1192,8 @@ unsigned char CellAccessor<dim>::material_id () const
 
 
 
-template <int dim>
-void CellAccessor<dim>::set_material_id (const unsigned char mat_id) const
+template <int dim, int spacedim>
+void CellAccessor<dim, spacedim>::set_material_id (const unsigned char mat_id) const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
   this->tria->levels[this->present_level]->cells.material_id[this->present_index] = mat_id;
@@ -2242,20 +1201,20 @@ void CellAccessor<dim>::set_material_id (const unsigned char mat_id) const
 
 
 
-template <int dim>
-void CellAccessor<dim>::recursively_set_material_id (const unsigned char mat_id) const
+template <int dim, int spacedim>
+void CellAccessor<dim, spacedim>::recursively_set_material_id (const unsigned char mat_id) const
 {
   set_material_id (mat_id);
 
   if (this->has_children())
     for (unsigned int c=0; c<2; ++c)
-      child(c)->recursively_set_material_id (mat_id);
+      this->child(c)->recursively_set_material_id (mat_id);
 }
 
 
 
-template <int dim>
-unsigned int CellAccessor<dim>::subdomain_id () const
+template <int dim, int spacedim>
+unsigned int CellAccessor<dim, spacedim>::subdomain_id () const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
   return this->tria->levels[this->present_level]->subdomain_ids[this->present_index];
@@ -2263,9 +1222,9 @@ unsigned int CellAccessor<dim>::subdomain_id () const
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-CellAccessor<dim>::set_subdomain_id (const unsigned int new_subdomain_id) const
+CellAccessor<dim, spacedim>::set_subdomain_id (const unsigned int new_subdomain_id) const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
   this->tria->levels[this->present_level]->subdomain_ids[this->present_index]
@@ -2274,9 +1233,9 @@ CellAccessor<dim>::set_subdomain_id (const unsigned int new_subdomain_id) const
 
 
 
-template <int dim>
-void CellAccessor<dim>::set_neighbor (const unsigned int i,
-                                     const TriaIterator<dim,CellAccessor<dim> > &pointer) const
+template <int dim, int spacedim>
+void CellAccessor<dim, spacedim>::set_neighbor (const unsigned int i,
+                                               const TriaIterator<CellAccessor<dim, spacedim> > &pointer) const
 {
   Assert (i<GeometryInfo<dim>::faces_per_cell,
          TriaAccessorExceptions::ExcInvalidNeighbor(i));
@@ -2303,8 +1262,8 @@ void CellAccessor<dim>::set_neighbor (const unsigned int i,
 
 
 
-template <int dim>
-unsigned int CellAccessor<dim>::neighbor_of_neighbor_internal (const unsigned int neighbor) const
+template <int dim, int spacedim>
+unsigned int CellAccessor<dim,spacedim>::neighbor_of_neighbor_internal (const unsigned int neighbor) const
 {
   Assert (neighbor < GeometryInfo<dim>::faces_per_cell,
          TriaAccessorExceptions::ExcInvalidNeighbor(neighbor));
@@ -2312,7 +1271,7 @@ unsigned int CellAccessor<dim>::neighbor_of_neighbor_internal (const unsigned in
   if (dim==1)
     return GeometryInfo<dim>::opposite_face[neighbor];
   
-  const TriaIterator<dim,CellAccessor<dim> > neighbor_cell = this->neighbor(neighbor);
+  const TriaIterator<CellAccessor<dim, spacedim> > neighbor_cell = this->neighbor(neighbor);
   
                                   // usually, on regular patches of
                                   // the grid, this cell is just on
@@ -2358,8 +1317,8 @@ unsigned int CellAccessor<dim>::neighbor_of_neighbor_internal (const unsigned in
 
 
 
-template <int dim>
-unsigned int CellAccessor<dim>::neighbor_of_neighbor (const unsigned int neighbor) const
+template <int dim, int spacedim>
+unsigned int CellAccessor<dim,spacedim>::neighbor_of_neighbor (const unsigned int neighbor) const
 {
   const unsigned int n2=neighbor_of_neighbor_internal(neighbor);
   Assert (n2!=numbers::invalid_unsigned_int, TriaAccessorExceptions::ExcNeighborIsCoarser());
@@ -2369,19 +1328,18 @@ unsigned int CellAccessor<dim>::neighbor_of_neighbor (const unsigned int neighbo
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 bool
-CellAccessor<dim>::neighbor_is_coarser (const unsigned int neighbor) const
+CellAccessor<dim,spacedim>::neighbor_is_coarser (const unsigned int neighbor) const
 {
   return neighbor_of_neighbor_internal(neighbor)==numbers::invalid_unsigned_int;
 }
 
 
-# if deal_II_dimension == 2
 
-template <int dim>
+template <int dim, int spacedim>
 std::pair<unsigned int, unsigned int>
-CellAccessor<dim>::neighbor_of_coarser_neighbor (const unsigned int neighbor) const
+CellAccessor<dim, spacedim>::neighbor_of_coarser_neighbor (const unsigned int neighbor) const
 {
   Assert (neighbor < GeometryInfo<dim>::faces_per_cell,
          TriaAccessorExceptions::ExcInvalidNeighbor(neighbor));
@@ -2390,159 +1348,158 @@ CellAccessor<dim>::neighbor_of_coarser_neighbor (const unsigned int neighbor) co
   Assert (neighbor_is_coarser(neighbor),
          TriaAccessorExceptions::ExcNeighborIsNotCoarser());
   
-  const int this_face_index=face_index(neighbor);
-  const TriaIterator<dim,CellAccessor<dim> > neighbor_cell = this->neighbor(neighbor);
+  switch (dim)
+    {
+      case 2:
+      {
+       const int this_face_index=face_index(neighbor);
+       const TriaIterator<CellAccessor<2,spacedim> > neighbor_cell = this->neighbor(neighbor);
   
-                                  // usually, on regular patches of
-                                  // the grid, this cell is just on
-                                  // the opposite side of the
-                                  // neighbor that the neighbor is of
-                                  // this cell. for example in 2d, if
-                                  // we want to know the
-                                  // neighbor_of_neighbor if
-                                  // neighbor==1 (the right
-                                  // neighbor), then we will get 0
-                                  // (the left neighbor) in most
-                                  // cases. look up this relationship
-                                  // in the table provided by
-                                  // GeometryInfo and try it
-  const unsigned int face_no_guess
-    = GeometryInfo<dim>::opposite_face[neighbor];
-
-  const TriaIterator<dim,TriaObjectAccessor<dim-1, dim> > face_guess
-    =neighbor_cell->face(face_no_guess);
+                                        // usually, on regular patches of
+                                        // the grid, this cell is just on
+                                        // the opposite side of the
+                                        // neighbor that the neighbor is of
+                                        // this cell. for example in 2d, if
+                                        // we want to know the
+                                        // neighbor_of_neighbor if
+                                        // neighbor==1 (the right
+                                        // neighbor), then we will get 0
+                                        // (the left neighbor) in most
+                                        // cases. look up this relationship
+                                        // in the table provided by
+                                        // GeometryInfo and try it
+       const unsigned int face_no_guess
+         = GeometryInfo<2>::opposite_face[neighbor];
+
+       const TriaIterator<TriaAccessor<1, 2, spacedim> > face_guess
+         =neighbor_cell->face(face_no_guess);
   
-  if (face_guess->has_children())
-    for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
-      if (face_guess->child_index(subface_no)==this_face_index)
-       return std::make_pair (face_no_guess, subface_no);
-
-                                    // if the guess was false, then
-                                    // we need to loop over all faces
-                                    // and subfaces and find the
-                                    // number the hard way
-  for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
-    {
-      if (face_no!=face_no_guess)
-       {
-         const TriaIterator<dim,TriaObjectAccessor<dim-1, dim> > face
-           =neighbor_cell->face(face_no);
-         if (face->has_children())
-           for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
-             if (face->child_index(subface_no)==this_face_index)
-               return std::make_pair (face_no, subface_no);
-       }
-    }
+       if (face_guess->has_children())
+         for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
+           if (face_guess->child_index(subface_no)==this_face_index)
+             return std::make_pair (face_no_guess, subface_no);
+
+                                        // if the guess was false, then
+                                        // we need to loop over all faces
+                                        // and subfaces and find the
+                                        // number the hard way
+       for (unsigned int face_no=0; face_no<GeometryInfo<2>::faces_per_cell; ++face_no)
+         {
+           if (face_no!=face_no_guess)
+             {
+               const TriaIterator<TriaAccessor<1, 2, spacedim> > face
+                 =neighbor_cell->face(face_no);
+               if (face->has_children())
+                 for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
+                   if (face->child_index(subface_no)==this_face_index)
+                     return std::make_pair (face_no, subface_no);
+             }
+         }
   
-                                  // we should never get here,
-                                  // since then we did not find
-                                  // our way back...
-  Assert (false, ExcInternalError());
-  return std::make_pair (deal_II_numbers::invalid_unsigned_int,
-                        deal_II_numbers::invalid_unsigned_int);
-}
-
-#endif
-
-#if deal_II_dimension == 3
-
-template <int dim>
-std::pair<unsigned int, unsigned int>
-CellAccessor<dim>::neighbor_of_coarser_neighbor (const unsigned int neighbor) const
-{
-  Assert (neighbor < GeometryInfo<dim>::faces_per_cell,
-         TriaAccessorExceptions::ExcInvalidNeighbor(neighbor));
-                                  // make sure that the neighbor is
-                                  // on a coarser level
-  Assert (neighbor_is_coarser(neighbor),
-         TriaAccessorExceptions::ExcNeighborIsNotCoarser());
+                                        // we should never get here,
+                                        // since then we did not find
+                                        // our way back...
+       Assert (false, ExcInternalError());
+       return std::make_pair (deal_II_numbers::invalid_unsigned_int,
+                              deal_II_numbers::invalid_unsigned_int);
+      }
 
-  const int this_face_index=face_index(neighbor);
-  const TriaIterator<dim,CellAccessor<dim> > neighbor_cell = this->neighbor(neighbor);
+      case 3:
+      {
+       const int this_face_index=face_index(neighbor);
+       const TriaIterator<CellAccessor<3, spacedim> >
+         neighbor_cell = this->neighbor(neighbor);
   
-                                  // usually, on regular patches of
-                                  // the grid, this cell is just on
-                                  // the opposite side of the
-                                  // neighbor that the neighbor is of
-                                  // this cell. for example in 2d, if
-                                  // we want to know the
-                                  // neighbor_of_neighbor if
-                                  // neighbor==1 (the right
-                                  // neighbor), then we will get 0
-                                  // (the left neighbor) in most
-                                  // cases. look up this relationship
-                                  // in the table provided by
-                                  // GeometryInfo and try it
-  const unsigned int face_no_guess
-    = GeometryInfo<dim>::opposite_face[neighbor];
-
-  const TriaIterator<dim,TriaObjectAccessor<dim-1, dim> > face_guess
-    =neighbor_cell->face(face_no_guess);
+                                        // usually, on regular patches of
+                                        // the grid, this cell is just on
+                                        // the opposite side of the
+                                        // neighbor that the neighbor is of
+                                        // this cell. for example in 2d, if
+                                        // we want to know the
+                                        // neighbor_of_neighbor if
+                                        // neighbor==1 (the right
+                                        // neighbor), then we will get 0
+                                        // (the left neighbor) in most
+                                        // cases. look up this relationship
+                                        // in the table provided by
+                                        // GeometryInfo and try it
+       const unsigned int face_no_guess
+         = GeometryInfo<3>::opposite_face[neighbor];
+
+       const TriaIterator<TriaAccessor<3-1, 3, spacedim> > face_guess
+         =neighbor_cell->face(face_no_guess);
   
-  if (face_guess->has_children())
-    for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
-      if (face_guess->child_index(subface_no)==this_face_index)
-                                            // call a helper function, that
-                                            // translates the current subface
-                                            // number to a subface number for
-                                            // the current FaceRefineCase
-       return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no));
-      else if (face_guess->child(subface_no)->has_children())
-       for (unsigned int subsub_no=0; subsub_no<face_guess->child(subface_no)->n_children(); ++subsub_no)
-         if (face_guess->child(subface_no)->child_index(subsub_no)==this_face_index)
-                                            // call a helper function, that
-                                            // translates the current subface
-                                            // number and subsubface number to
-                                            // a subface number for the current
-                                            // FaceRefineCase
-           return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no, subsub_no));
+       if (face_guess->has_children())
+         for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
+           if (face_guess->child_index(subface_no)==this_face_index)
+                                              // call a helper function, that
+                                              // translates the current subface
+                                              // number to a subface number for
+                                              // the current FaceRefineCase
+             return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no));
+           else if (face_guess->child(subface_no)->has_children())
+             for (unsigned int subsub_no=0; subsub_no<face_guess->child(subface_no)->n_children(); ++subsub_no)
+               if (face_guess->child(subface_no)->child_index(subsub_no)==this_face_index)
+                                                  // call a helper function, that
+                                                  // translates the current subface
+                                                  // number and subsubface number to
+                                                  // a subface number for the current
+                                                  // FaceRefineCase
+                 return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no, subsub_no));
          
   
 
-                                    // if the guess was false, then
-                                    // we need to loop over all faces
-                                    // and subfaces and find the
-                                    // number the hard way
-  for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
-    {
-      if (face_no!=face_no_guess)
-       {
-         const TriaIterator<dim,TriaObjectAccessor<dim-1, dim> > face
-           =neighbor_cell->face(face_no);
-         if (face->has_children())
-           for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
-             if (face->child_index(subface_no)==this_face_index)
-                                            // call a helper function, that
-                                            // translates the current subface
-                                            // number to a subface number for
-                                            // the current FaceRefineCase
-               return std::make_pair (face_no, translate_subface_no(face, subface_no));
-             else if (face->child(subface_no)->has_children())
-               for (unsigned int subsub_no=0; subsub_no<face->child(subface_no)->n_children(); ++subsub_no)
-                 if (face->child(subface_no)->child_index(subsub_no)==this_face_index)
-                                            // call a helper function, that
-                                            // translates the current subface
-                                            // number and subsubface number to
-                                            // a subface number for the current
-                                            // FaceRefineCase
-                   return std::make_pair (face_no, translate_subface_no(face, subface_no, subsub_no));
-       }
-    }
+                                        // if the guess was false, then
+                                        // we need to loop over all faces
+                                        // and subfaces and find the
+                                        // number the hard way
+       for (unsigned int face_no=0; face_no<GeometryInfo<3>::faces_per_cell; ++face_no)
+         {
+           if (face_no!=face_no_guess)
+             {
+               const TriaIterator<TriaAccessor<3-1, 3, spacedim> > face
+                 =neighbor_cell->face(face_no);
+               if (face->has_children())
+                 for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
+                   if (face->child_index(subface_no)==this_face_index)
+                                                      // call a helper function, that
+                                                      // translates the current subface
+                                                      // number to a subface number for
+                                                      // the current FaceRefineCase
+                     return std::make_pair (face_no, translate_subface_no(face, subface_no));
+                   else if (face->child(subface_no)->has_children())
+                     for (unsigned int subsub_no=0; subsub_no<face->child(subface_no)->n_children(); ++subsub_no)
+                       if (face->child(subface_no)->child_index(subsub_no)==this_face_index)
+                                                          // call a helper function, that
+                                                          // translates the current subface
+                                                          // number and subsubface number to
+                                                          // a subface number for the current
+                                                          // FaceRefineCase
+                         return std::make_pair (face_no, translate_subface_no(face, subface_no, subsub_no));
+             }
+         }
   
-                                  // we should never get here,
-                                  // since then we did not find
-                                  // our way back...
-  Assert (false, ExcInternalError());
-  return std::make_pair (numbers::invalid_unsigned_int,
-                        numbers::invalid_unsigned_int);
-}
+                                        // we should never get here,
+                                        // since then we did not find
+                                        // our way back...
+       Assert (false, ExcInternalError());
+       return std::make_pair (numbers::invalid_unsigned_int,
+                              numbers::invalid_unsigned_int);  
+      }
 
-#endif
+      default:
+      {
+       Assert(false, ExcImpossibleInDim(1));
+       return std::make_pair (numbers::invalid_unsigned_int,
+                              numbers::invalid_unsigned_int);
+      }
+    }
+}
 
 
 
-template <int dim>
-bool CellAccessor<dim>::at_boundary (const unsigned int i) const
+template <int dim, int spacedim>
+bool CellAccessor<dim, spacedim>::at_boundary (const unsigned int i) const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
   Assert (i<GeometryInfo<dim>::faces_per_cell,
@@ -2553,49 +1510,28 @@ bool CellAccessor<dim>::at_boundary (const unsigned int i) const
 
 
 
-#if deal_II_dimension == 1
-
-template <>
-bool CellAccessor<1>::has_boundary_lines () const
-{
-  return at_boundary();
-}
-
-#else
-
-template <int dim>
-bool CellAccessor<dim>::has_boundary_lines () const
+template <int dim, int spacedim>
+bool CellAccessor<dim, spacedim>::has_boundary_lines () const
 {
-  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
-    if (this->line(l)->at_boundary())
-      return true;
+  if (dim == 1)
+    return at_boundary ();
+  else
+    {
+      for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+       if (this->line(l)->at_boundary())
+         return true;
   
-  return false;
-}
-
-#endif
-
-#if deal_II_dimension == 1
-
-template <>
-TriaIterator<1,CellAccessor<1> >
-CellAccessor<1>::
-neighbor_child_on_subface (const unsigned int,
-                           const unsigned int) const
-{
-  Assert (false, ExcNotImplemented());
-  return TriaIterator<1,CellAccessor<1> >();
+      return false;
+    }
 }
 
-#endif
 
-#if deal_II_dimension == 2
 
-template <>
-TriaIterator<2,CellAccessor<2> >
-CellAccessor<2>::
+template <int dim, int spacedim>
+TriaIterator<CellAccessor<dim,spacedim> >
+CellAccessor<dim, spacedim>::
 neighbor_child_on_subface (const unsigned int face,
-                           const unsigned int subface) const
+                          const unsigned int subface) const
 {
   Assert (!this->has_children(),
           ExcMessage ("The present cell must not have children!"));
@@ -2604,389 +1540,446 @@ neighbor_child_on_subface (const unsigned int face,
   Assert (this->neighbor(face)->has_children() == true,
           ExcMessage ("The neighbor must have children!"));
 
-  const unsigned int neighbor_neighbor
-    = this->neighbor_of_neighbor (face);
-  const unsigned int neighbor_child_index
-    = GeometryInfo<2>::child_cell_on_face(
-      this->neighbor(face)->refinement_case(),neighbor_neighbor,subface);
-
-  TriaIterator<2,CellAccessor<2> > sub_neighbor = this->neighbor(face)->child(neighbor_child_index);
-                                  // the neighbors child can have children,
-                                  // which are not further refined along the
-                                  // face under consideration. as we are
-                                  // normally interested in one of this
-                                  // child's child, search for the right one.
-  while(sub_neighbor->has_children())
+  switch (dim)
     {
-      Assert ((GeometryInfo<2>::face_refinement_case(sub_neighbor->refinement_case(),
-                                                    neighbor_neighbor) ==
-              RefinementCase<2>::no_refinement),
-             ExcInternalError());
-      sub_neighbor = sub_neighbor->child(GeometryInfo<2>::child_cell_on_face(
-                                          sub_neighbor->refinement_case(),neighbor_neighbor,0));
+      case 2:
+      {
+       const unsigned int neighbor_neighbor
+         = this->neighbor_of_neighbor (face);
+       const unsigned int neighbor_child_index
+         = GeometryInfo<dim>::child_cell_on_face(
+           this->neighbor(face)->refinement_case(),neighbor_neighbor,subface);
+
+       TriaIterator<CellAccessor<dim,spacedim> > sub_neighbor
+         = this->neighbor(face)->child(neighbor_child_index);
+                                        // the neighbors child can have children,
+                                        // which are not further refined along the
+                                        // face under consideration. as we are
+                                        // normally interested in one of this
+                                        // child's child, search for the right one.
+       while(sub_neighbor->has_children())
+         {
+           Assert ((GeometryInfo<dim>::face_refinement_case(sub_neighbor->refinement_case(),
+                                                            neighbor_neighbor) ==
+                    RefinementCase<dim>::no_refinement),
+                   ExcInternalError());
+           sub_neighbor = sub_neighbor->child(GeometryInfo<dim>::child_cell_on_face(
+                                                sub_neighbor->refinement_case(),neighbor_neighbor,0));
       
-    }
+         }
   
-  return sub_neighbor;
-}
-
-#endif
+       return sub_neighbor;
+      }
 
-#if deal_II_dimension == 3
 
-template <>
-TriaIterator<3,CellAccessor<3> >
-CellAccessor<3>::
-neighbor_child_on_subface (const unsigned int face,
-                           const unsigned int subface) const
-{
-  Assert (!this->has_children(),
-          ExcMessage ("The present cell must not have children!"));
-  Assert (!this->at_boundary(face),
-          ExcMessage ("The present cell must have a valid neighbor!"));
-  Assert (this->neighbor(face)->has_children() == true,
-          ExcMessage ("The neighbor must have children!"));
-                                  // this function returns the neighbor's
-                                  // child on a given face and
-                                  // subface. 
-
-                                  // we have to consider one other aspect here:
-                                  // The face might be refined
-                                  // anisotropically. In this case, the subface
-                                  // number refers to the following, where we
-                                  // look at the face from the current cell,
-                                  // thus the subfaces are in standard
-                                  // orientation concerning the cell
-                                  //
-                                  // for isotropic refinement
-                                  //
-                                  // *---*---*
-                                  // | 2 | 3 |
-                                  // *---*---*
-                                  // | 0 | 1 |
-                                  // *---*---*
-                                  //
-                                  // for 2*anisotropic refinement
-                                  // (first cut_y, then cut_x)
-                                  //
-                                  // *---*---*
-                                  // | 2 | 3 |
-                                  // *---*---*
-                                  // | 0 | 1 |
-                                  // *---*---*
-                                  //
-                                  // for 2*anisotropic refinement
-                                  // (first cut_x, then cut_y)
-                                  //
-                                  // *---*---*
-                                  // | 1 | 3 |
-                                  // *---*---*
-                                  // | 0 | 2 |
-                                  // *---*---*
-                                  //
-                                  // for purely anisotropic refinement:
-                                  //
-                                  // *---*---*      *-------*
-                                  // |   |   |      |   1   |
-                                  // | 0 | 1 |  or  *-------* 
-                                  // |   |   |      |   0   |
-                                  // *---*---*      *-------*
-                                  //
-                                  // for "mixed" refinement:
-                                  //
-                                  // *---*---*      *---*---*      *---*---*      *-------*
-                                  // |   | 2 |      | 1 |   |      | 1 | 2 |      |   2   |
-                                  // | 0 *---*  or  *---* 2 |  or  *---*---*  or  *---*---*
-                                  // |   | 1 |      | 0 |   |      |   0   |      | 0 | 1 |
-                                  // *---*---*      *---*---*      *-------*      *---*---*
-
-  const Triangulation<3>::face_iterator mother_face=this->face(face);
-  const unsigned int total_children=mother_face->number_of_children();
-  Assert (subface<total_children,ExcIndexRange(subface,0,total_children));
-  Assert(total_children<=GeometryInfo<3>::max_children_per_face, ExcInternalError());
+      case 3:
+      {
+                                        // this function returns the neighbor's
+                                        // child on a given face and
+                                        // subface. 
+
+                                        // we have to consider one other aspect here:
+                                        // The face might be refined
+                                        // anisotropically. In this case, the subface
+                                        // number refers to the following, where we
+                                        // look at the face from the current cell,
+                                        // thus the subfaces are in standard
+                                        // orientation concerning the cell
+                                        //
+                                        // for isotropic refinement
+                                        //
+                                        // *---*---*
+                                        // | 2 | 3 |
+                                        // *---*---*
+                                        // | 0 | 1 |
+                                        // *---*---*
+                                        //
+                                        // for 2*anisotropic refinement
+                                        // (first cut_y, then cut_x)
+                                        //
+                                        // *---*---*
+                                        // | 2 | 3 |
+                                        // *---*---*
+                                        // | 0 | 1 |
+                                        // *---*---*
+                                        //
+                                        // for 2*anisotropic refinement
+                                        // (first cut_x, then cut_y)
+                                        //
+                                        // *---*---*
+                                        // | 1 | 3 |
+                                        // *---*---*
+                                        // | 0 | 2 |
+                                        // *---*---*
+                                        //
+                                        // for purely anisotropic refinement:
+                                        //
+                                        // *---*---*      *-------*
+                                        // |   |   |        |   1   |
+                                        // | 0 | 1 |  or  *-------* 
+                                        // |   |   |        |   0   |
+                                        // *---*---*        *-------*
+                                        //
+                                        // for "mixed" refinement:
+                                        //
+                                        // *---*---*      *---*---*      *---*---*      *-------*
+                                        // |   | 2 |      | 1 |   |      | 1 | 2 |      |   2   |
+                                        // | 0 *---*  or  *---* 2 |  or  *---*---*  or  *---*---*
+                                        // |   | 1 |      | 0 |   |      |   0   |      | 0 | 1 |
+                                        // *---*---*      *---*---*      *-------*      *---*---*
+
+       const typename Triangulation<3,spacedim>::face_iterator
+         mother_face = this->face(face);
+       const unsigned int total_children=mother_face->number_of_children();
+       Assert (subface<total_children,ExcIndexRange(subface,0,total_children));
+       Assert (total_children<=GeometryInfo<3>::max_children_per_face, ExcInternalError());
   
-  unsigned int neighbor_neighbor;
-  TriaIterator<3,CellAccessor<3> > neighbor_child;
-  const TriaIterator<3,CellAccessor<3> > neighbor=this->neighbor(face);
+       unsigned int neighbor_neighbor;
+       TriaIterator<CellAccessor<3,spacedim> > neighbor_child;
+       const TriaIterator<CellAccessor<3,spacedim> > neighbor
+         = this->neighbor(face);
 
   
-  const RefinementCase<2> mother_face_ref_case=mother_face->refinement_case();
-  if (mother_face_ref_case==RefinementCase<2>::cut_xy) // total_children==4
-    {
-                                      // this case is quite easy. we are sure,
-                                      // that the neighbor is not coarser.
-
-                                      // get the neighbor's number for the given
-                                      // face and the neighbor
-      neighbor_neighbor
-       = this->neighbor_of_neighbor (face);
+       const RefinementCase<2> mother_face_ref_case
+         = mother_face->refinement_case();
+       if (mother_face_ref_case==RefinementCase<2>::cut_xy) // total_children==4
+         {
+                                            // this case is quite easy. we are sure,
+                                            // that the neighbor is not coarser.
+
+                                            // get the neighbor's number for the given
+                                            // face and the neighbor
+           neighbor_neighbor
+             = this->neighbor_of_neighbor (face);
       
-                                      // now use the info provided by GeometryInfo
-                                      // to extract the neighbors child number
-      const unsigned int neighbor_child_index
-       = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
-                                             neighbor_neighbor, subface,
-                                             neighbor->face_orientation(neighbor_neighbor),
-                                             neighbor->face_flip(neighbor_neighbor),
-                                             neighbor->face_rotation(neighbor_neighbor));
-      neighbor_child=
-       neighbor->child(neighbor_child_index);
+                                            // now use the info provided by GeometryInfo
+                                            // to extract the neighbors child number
+           const unsigned int neighbor_child_index
+             = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
+                                                     neighbor_neighbor, subface,
+                                                     neighbor->face_orientation(neighbor_neighbor),
+                                                     neighbor->face_flip(neighbor_neighbor),
+                                                     neighbor->face_rotation(neighbor_neighbor));
+           neighbor_child = neighbor->child(neighbor_child_index);
       
-                                      // make sure that the neighbor child cell we
-                                      // have found shares the desired subface.
-      Assert((this->face(face)->child(subface) ==
-             neighbor_child->face(neighbor_neighbor)),
-            ExcInternalError());
-    }
-  else //-> the face is refined anisotropically
-    {
-                                          // first of all, we have to find the
-                                          // neighbor at one of the anisotropic
-                                          // children of the
-                                          // mother_face. determine, which of
-                                          // these we need.
-         unsigned int first_child_to_find;
-         unsigned int neighbor_child_index;
-         if (total_children==2)
-           first_child_to_find=subface;
-         else 
-           {
-             first_child_to_find=subface/2;
-             if (total_children==3 &&
-                 subface==1 &&
-                 !mother_face->child(0)->has_children())
-               first_child_to_find=1;
-           }
-      if (neighbor_is_coarser(face))
-       {
-         std::pair<unsigned int, unsigned int> indices=neighbor_of_coarser_neighbor(face);
-         neighbor_neighbor=indices.first;
+                                            // make sure that the neighbor child cell we
+                                            // have found shares the desired subface.
+           Assert((this->face(face)->child(subface) ==
+                   neighbor_child->face(neighbor_neighbor)),
+                  ExcInternalError());
+         }
+       else //-> the face is refined anisotropically
+         {
+                                            // first of all, we have to find the
+                                            // neighbor at one of the anisotropic
+                                            // children of the
+                                            // mother_face. determine, which of
+                                            // these we need.
+           unsigned int first_child_to_find;
+           unsigned int neighbor_child_index;
+           if (total_children==2)
+             first_child_to_find=subface;
+           else 
+             {
+               first_child_to_find=subface/2;
+               if (total_children==3 &&
+                   subface==1 &&
+                   !mother_face->child(0)->has_children())
+                 first_child_to_find=1;
+             }
+           if (neighbor_is_coarser(face))
+             {
+               std::pair<unsigned int, unsigned int> indices=neighbor_of_coarser_neighbor(face);
+               neighbor_neighbor=indices.first;
 
          
-                                          // we have to translate our
-                                          // subface_index according to the
-                                          // RefineCase and subface index of
-                                          // the coarser face (our face is an
-                                          // anisotropic child of the coarser
-                                          // face), 'a' denotes our
-                                          // subface_index 0 and 'b' denotes
-                                          // our subface_index 1, whereas 0...3
-                                          // denote isotropic subfaces of the
-                                          // coarser face
-                                          //
-                                          // cut_x and coarser_subface_index=0
-                                          //
-                                          // *---*---*
-                                          // |b=2|   |
-                                          // |   |   |
-                                          // |a=0|   |
-                                          // *---*---*
-                                          //
-                                          // cut_x and coarser_subface_index=1
-                                          //
-                                          // *---*---*
-                                          // |   |b=3|
-                                          // |   |   |
-                                          // |   |a=1|
-                                          // *---*---*
-                                          //
-                                          // cut_y and coarser_subface_index=0
-                                          //
-                                          // *-------*
-                                          // |       |
-                                          // *-------*
-                                          // |a=0 b=1|
-                                          // *-------*
-                                          //
-                                          // cut_y and coarser_subface_index=1
-                                          //
-                                          // *-------*
-                                          // |a=2 b=3|
-                                          // *-------*
-                                          // |       |
-                                          // *-------*
-         unsigned int iso_subface;
-         if (neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_x)
-           iso_subface=2*first_child_to_find + indices.second;
-         else
-           {
-             Assert(neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_y,
-                    ExcInternalError());
-             iso_subface=first_child_to_find + 2*indices.second;
-           }
-         neighbor_child_index
-           =GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
-                                                neighbor_neighbor,
-                                                iso_subface,
-                                                neighbor->face_orientation(neighbor_neighbor),
-                                                neighbor->face_flip(neighbor_neighbor),
-                                                neighbor->face_rotation(neighbor_neighbor));
-       }
-      else //neighbor is not coarser
-       {
-         neighbor_neighbor=neighbor_of_neighbor(face);
-         neighbor_child_index
-           =GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
-                                                neighbor_neighbor,
-                                                first_child_to_find,
-                                                neighbor->face_orientation(neighbor_neighbor),
-                                                neighbor->face_flip(neighbor_neighbor),
-                                                neighbor->face_rotation(neighbor_neighbor),
-                                                mother_face_ref_case);
-       }
+                                                // we have to translate our
+                                                // subface_index according to the
+                                                // RefineCase and subface index of
+                                                // the coarser face (our face is an
+                                                // anisotropic child of the coarser
+                                                // face), 'a' denotes our
+                                                // subface_index 0 and 'b' denotes
+                                                // our subface_index 1, whereas 0...3
+                                                // denote isotropic subfaces of the
+                                                // coarser face
+                                                //
+                                                // cut_x and coarser_subface_index=0
+                                                //
+                                                // *---*---*
+                                                // |b=2|   |
+                                                // |   |   |
+                                                // |a=0|   |
+                                                // *---*---*
+                                                //
+                                                // cut_x and coarser_subface_index=1
+                                                //
+                                                // *---*---*
+                                                // |   |b=3|
+                                                // |   |   |
+                                                // |   |a=1|
+                                                // *---*---*
+                                                //
+                                                // cut_y and coarser_subface_index=0
+                                                //
+                                                // *-------*
+                                                // |       |
+                                                // *-------*
+                                                // |a=0 b=1|
+                                                // *-------*
+                                                //
+                                                // cut_y and coarser_subface_index=1
+                                                //
+                                                // *-------*
+                                                // |a=2 b=3|
+                                                // *-------*
+                                                // |       |
+                                                // *-------*
+               unsigned int iso_subface;
+               if (neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_x)
+                 iso_subface=2*first_child_to_find + indices.second;
+               else
+                 {
+                   Assert(neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_y,
+                          ExcInternalError());
+                   iso_subface=first_child_to_find + 2*indices.second;
+                 }
+               neighbor_child_index
+                 = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
+                                                         neighbor_neighbor,
+                                                         iso_subface,
+                                                         neighbor->face_orientation(neighbor_neighbor),
+                                                         neighbor->face_flip(neighbor_neighbor),
+                                                         neighbor->face_rotation(neighbor_neighbor));
+             }
+           else //neighbor is not coarser
+             {
+               neighbor_neighbor=neighbor_of_neighbor(face);
+               neighbor_child_index
+                 = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
+                                                         neighbor_neighbor,
+                                                         first_child_to_find,
+                                                         neighbor->face_orientation(neighbor_neighbor),
+                                                         neighbor->face_flip(neighbor_neighbor),
+                                                         neighbor->face_rotation(neighbor_neighbor),
+                                                         mother_face_ref_case);
+             }
       
-      neighbor_child=neighbor->child(neighbor_child_index);
-                                      // it might be, that the neighbor_child
-                                      // has children, which are not refined
-                                      // along the given subface. go down that
-                                      // list and deliver the last of those.
-      while (neighbor_child->has_children() &&
-            GeometryInfo<3>::face_refinement_case(neighbor_child->refinement_case(),neighbor_neighbor)==RefinementCase<2>::no_refinement)
-       neighbor_child=neighbor_child->child(GeometryInfo<3>::child_cell_on_face(neighbor_child->refinement_case(),
-                                                                                neighbor_neighbor,0));
-
-                                      // if there are two total subfaces, we
-                                      // are finished. if there are four we
-                                      // have to get a child of our current
-                                      // neighbor_child. If there are three,
-                                      // we have to check which of the two
-                                      // possibilities applies.
-      if (total_children==3)
-       {
-         if (mother_face->child(0)->has_children())
-           {
-             if (subface<2)
-               neighbor_child=neighbor_child->child(GeometryInfo<3>::child_cell_on_face(neighbor_child->refinement_case(),
-                                                                                        neighbor_neighbor,subface,
-                                                                                        neighbor_child->face_orientation(neighbor_neighbor),
-                                                                                        neighbor_child->face_flip(neighbor_neighbor),
-                                                                                        neighbor_child->face_rotation(neighbor_neighbor),
-                                                                                        mother_face->child(0)->refinement_case()));
-           }
-         else
-           {
-             Assert(mother_face->child(1)->has_children(), ExcInternalError());
-             if (subface>0)
-               neighbor_child=neighbor_child->child(GeometryInfo<3>::child_cell_on_face(neighbor_child->refinement_case(),
-                                                                                        neighbor_neighbor,subface-1,
-                                                                                        neighbor_child->face_orientation(neighbor_neighbor),
-                                                                                        neighbor_child->face_flip(neighbor_neighbor),
-                                                                                        neighbor_child->face_rotation(neighbor_neighbor),
-                                                                                        mother_face->child(1)->refinement_case()));
-           }
-       }
-      else if (total_children==4)
-       {
-         neighbor_child=neighbor_child->child(GeometryInfo<3>::child_cell_on_face(neighbor_child->refinement_case(),
-                                                                                  neighbor_neighbor,subface%2,
-                                                                                  neighbor_child->face_orientation(neighbor_neighbor),
-                                                                                  neighbor_child->face_flip(neighbor_neighbor),
-                                                                                  neighbor_child->face_rotation(neighbor_neighbor),
-                                                                                  mother_face->child(subface/2)->refinement_case()));
-       }
-    }
-
-                                  // it might be, that the neighbor_child has
-                                  // children, which are not refined along the
-                                  // given subface. go down that list and
-                                  // deliver the last of those.
-  while (neighbor_child->has_children())
-    neighbor_child=neighbor_child->child(GeometryInfo<3>::child_cell_on_face(neighbor_child->refinement_case(),
-                                                                            neighbor_neighbor,0));
-
-#ifdef DEBUG
-                                  // check, whether the face neighbor_child
-                                  // matches the requested subface
-  Triangulation<3>::face_iterator requested;
-  switch (this->subface_case(face))
-    {
-      case internal::SubfaceCase<3>::case_x:
-      case internal::SubfaceCase<3>::case_y:
-      case internal::SubfaceCase<3>::case_xy:
-           requested=mother_face->child(subface);
-           break;
-      case internal::SubfaceCase<3>::case_x1y2y:
-      case internal::SubfaceCase<3>::case_y1x2x:
-           requested=mother_face->child(subface/2)->child(subface%2);
-           break;
-
-      case internal::SubfaceCase<3>::case_x1y:
-      case internal::SubfaceCase<3>::case_y1x:
-           switch (subface)
+           neighbor_child=neighbor->child(neighbor_child_index);
+                                            // it might be, that the neighbor_child
+                                            // has children, which are not refined
+                                            // along the given subface. go down that
+                                            // list and deliver the last of those.
+           while (neighbor_child->has_children() &&
+                  GeometryInfo<3>::face_refinement_case(neighbor_child->refinement_case(),
+                                                          neighbor_neighbor)
+                  == RefinementCase<2>::no_refinement)
+             neighbor_child =
+               neighbor_child->child(GeometryInfo<3>::
+                                     child_cell_on_face(neighbor_child->refinement_case(),
+                                                        neighbor_neighbor,
+                                                        0));
+
+                                            // if there are two total subfaces, we
+                                            // are finished. if there are four we
+                                            // have to get a child of our current
+                                            // neighbor_child. If there are three,
+                                            // we have to check which of the two
+                                            // possibilities applies.
+           if (total_children==3)
              {
-               case 0:
-               case 1:
-                     requested=mother_face->child(0)->child(subface);
-                     break;
-               case 2:
-                     requested=mother_face->child(1);
-                     break;
-               default:
-                     Assert(false, ExcInternalError());
+               if (mother_face->child(0)->has_children())
+                 {
+                   if (subface<2)
+                     neighbor_child =
+                       neighbor_child->child(GeometryInfo<3>::
+                                             child_cell_on_face(neighbor_child->refinement_case(),
+                                                                neighbor_neighbor,subface,
+                                                                neighbor_child->face_orientation(neighbor_neighbor),
+                                                                neighbor_child->face_flip(neighbor_neighbor),
+                                                                neighbor_child->face_rotation(neighbor_neighbor),
+                                                                mother_face->child(0)->refinement_case()));
+                 }
+               else
+                 {
+                   Assert(mother_face->child(1)->has_children(), ExcInternalError());
+                   if (subface>0)
+                     neighbor_child =
+                       neighbor_child->child(GeometryInfo<3>::
+                                             child_cell_on_face(neighbor_child->refinement_case(),
+                                                                neighbor_neighbor,subface-1,
+                                                                neighbor_child->face_orientation(neighbor_neighbor),
+                                                                neighbor_child->face_flip(neighbor_neighbor),
+                                                                neighbor_child->face_rotation(neighbor_neighbor),
+                                                                mother_face->child(1)->refinement_case()));
+                 }
              }
-           break;
-      case internal::SubfaceCase<3>::case_x2y:
-      case internal::SubfaceCase<3>::case_y2x:
-           switch (subface)
+           else if (total_children==4)
              {
-               case 0:
-                     requested=mother_face->child(0);
-                     break;
-               case 1:
-               case 2:
-                     requested=mother_face->child(1)->child(subface-1);
-                     break;
-               default:
-                     Assert(false, ExcInternalError());
+               neighbor_child =
+                 neighbor_child->child(GeometryInfo<3>::
+                                       child_cell_on_face(neighbor_child->refinement_case(),
+                                                          neighbor_neighbor,subface%2,
+                                                          neighbor_child->face_orientation(neighbor_neighbor),
+                                                          neighbor_child->face_flip(neighbor_neighbor),
+                                                          neighbor_child->face_rotation(neighbor_neighbor),
+                                                          mother_face->child(subface/2)->refinement_case()));
              }
-           break;
-      default:
-           Assert(false, ExcInternalError());
-           break;
-    }
-  Assert(requested==neighbor_child->face(neighbor_neighbor),
-        ExcInternalError());
+         }
+
+                                        // it might be, that the neighbor_child has
+                                        // children, which are not refined along the
+                                        // given subface. go down that list and
+                                        // deliver the last of those.
+       while (neighbor_child->has_children())
+         neighbor_child
+           = neighbor_child->child(GeometryInfo<3>::
+                                   child_cell_on_face(neighbor_child->refinement_case(),
+                                                      neighbor_neighbor,
+                                                      0));
+
+#ifdef DEBUG
+                                        // check, whether the face neighbor_child
+                                        // matches the requested subface
+       typename Triangulation<3,spacedim>::face_iterator requested;
+       switch (this->subface_case(face))
+         {
+           case internal::SubfaceCase<3>::case_x:
+           case internal::SubfaceCase<3>::case_y:
+           case internal::SubfaceCase<3>::case_xy:
+                 requested = mother_face->child(subface);
+                 break;
+           case internal::SubfaceCase<3>::case_x1y2y:
+           case internal::SubfaceCase<3>::case_y1x2x:
+                 requested = mother_face->child(subface/2)->child(subface%2);
+                 break;
+
+           case internal::SubfaceCase<3>::case_x1y:
+           case internal::SubfaceCase<3>::case_y1x:
+                 switch (subface)
+                   {
+                     case 0:
+                     case 1:
+                           requested = mother_face->child(0)->child(subface);
+                           break;
+                     case 2:
+                           requested = mother_face->child(1);
+                           break;
+                     default:
+                           Assert(false, ExcInternalError());
+                   }
+                 break;
+           case internal::SubfaceCase<3>::case_x2y:
+           case internal::SubfaceCase<3>::case_y2x:
+                 switch (subface)
+                   {
+                     case 0:
+                           requested=mother_face->child(0);
+                           break;
+                     case 1:
+                     case 2:
+                           requested=mother_face->child(1)->child(subface-1);
+                           break;
+                     default:
+                           Assert(false, ExcInternalError());
+                   }
+                 break;
+           default:
+                 Assert(false, ExcInternalError());
+                 break;
+         }
+       Assert (requested==neighbor_child->face(neighbor_neighbor),
+               ExcInternalError());
 #endif
 
-  return neighbor_child;
+       return neighbor_child;
   
+      }
+
+      default:
+                                            // 1d or more than 3d
+           Assert (false, ExcNotImplemented());
+           return TriaIterator<CellAccessor<dim,spacedim> >();      
+    }
 }
 
-#endif
 
 
-// Remark: The explicit instantiations for "TriaObjectAccessor" were moved
+// Remark: The explicit instantiations for "TriaAccessor" were moved
 // to the top of this source file. The reason is a slightly buggy version
 // of the Apple gcc v.3.3.
 // For more information, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24331
 
 // explicit instantiations
-template class TriaAccessor<1,deal_II_dimension>;
+template class TriaAccessorBase<1,deal_II_dimension>;
+#if deal_II_dimension >= 2
+template class TriaAccessorBase<2,deal_II_dimension>;
+#endif
+#if deal_II_dimension >= 3
+template class TriaAccessorBase<3,deal_II_dimension>;
+#endif
+
+template class TriaAccessor<1,deal_II_dimension,deal_II_dimension>;
 #if deal_II_dimension >= 2
-template class TriaAccessor<2,deal_II_dimension>;
+template class TriaAccessor<2,deal_II_dimension,deal_II_dimension>;
 #endif
 #if deal_II_dimension >= 3
-template class TriaAccessor<3,deal_II_dimension>;
+template class TriaAccessor<3,deal_II_dimension,deal_II_dimension>;
 #endif
 
+
 template class CellAccessor<deal_II_dimension>;
-template class TriaRawIterator<deal_II_dimension,TriaObjectAccessor<1, deal_II_dimension> >;
-template class TriaRawIterator<deal_II_dimension,CellAccessor<deal_II_dimension> >;
-template class TriaIterator<deal_II_dimension,TriaObjectAccessor<1, deal_II_dimension> >;
-template class TriaIterator<deal_II_dimension,CellAccessor<deal_II_dimension> >;
-template class TriaActiveIterator<deal_II_dimension,TriaObjectAccessor<1, deal_II_dimension> >;
-template class TriaActiveIterator<deal_II_dimension,CellAccessor<deal_II_dimension> >;
+template class TriaRawIterator<TriaAccessor<1, deal_II_dimension, deal_II_dimension> >;
+template class TriaRawIterator<CellAccessor<deal_II_dimension> >;
+template class TriaIterator<TriaAccessor<1, deal_II_dimension, deal_II_dimension> >;
+template class TriaIterator<CellAccessor<deal_II_dimension> >;
+template class TriaActiveIterator<TriaAccessor<1, deal_II_dimension, deal_II_dimension> >;
+template class TriaActiveIterator<CellAccessor<deal_II_dimension> >;
+
 
 #if deal_II_dimension >= 2
-template class TriaRawIterator<deal_II_dimension,TriaObjectAccessor<2, deal_II_dimension> >;
-template class TriaIterator<deal_II_dimension,TriaObjectAccessor<2, deal_II_dimension> >;
-template class TriaActiveIterator<deal_II_dimension,TriaObjectAccessor<2, deal_II_dimension> >;
+template class TriaRawIterator<TriaAccessor<2, deal_II_dimension, deal_II_dimension> >;
+template class TriaIterator<TriaAccessor<2, deal_II_dimension, deal_II_dimension> >;
+template class TriaActiveIterator<TriaAccessor<2, deal_II_dimension, deal_II_dimension> >;
 #endif
 
 #if deal_II_dimension >= 3
-template class TriaRawIterator<deal_II_dimension,TriaObjectAccessor<3, deal_II_dimension> >;
-template class TriaIterator<deal_II_dimension,TriaObjectAccessor<3, deal_II_dimension> >;
-template class TriaActiveIterator<deal_II_dimension,TriaObjectAccessor<3, deal_II_dimension> >;
+template class TriaRawIterator<TriaAccessor<3, deal_II_dimension, deal_II_dimension> >;
+template class TriaIterator<TriaAccessor<3, deal_II_dimension, deal_II_dimension> >;
+template class TriaActiveIterator<TriaAccessor<3, deal_II_dimension, deal_II_dimension> >;
+#endif
+
+#if deal_II_dimension == 1
+template class TriaAccessorBase<1,deal_II_dimension,2>;
+template class TriaAccessorBase<1,deal_II_dimension,3>;
+
+template class TriaAccessor<1,deal_II_dimension,2>;
+template class TriaAccessor<1,deal_II_dimension,3>;
+#endif
+#if deal_II_dimension == 2
+template class TriaAccessorBase<1,deal_II_dimension,3>;
+template class TriaAccessorBase<2,deal_II_dimension,3>;
+
+template class TriaAccessor<1,deal_II_dimension,3>;
+template class TriaAccessor<2,deal_II_dimension,3>;
+#endif
+
+#if deal_II_dimension != 3
+template class CellAccessor<deal_II_dimension, deal_II_dimension+1>;
+template class TriaRawIterator<TriaAccessor<1, deal_II_dimension, deal_II_dimension+1> >;
+template class TriaRawIterator<CellAccessor<deal_II_dimension, deal_II_dimension+1> >;
+template class TriaIterator<TriaAccessor<1, deal_II_dimension, deal_II_dimension+1> >;
+template class TriaIterator<CellAccessor<deal_II_dimension, deal_II_dimension+1> >;
+template class TriaActiveIterator<TriaAccessor<1, deal_II_dimension, deal_II_dimension+1> >;
+template class TriaActiveIterator<CellAccessor<deal_II_dimension, deal_II_dimension+1> >;
+
+
+#if deal_II_dimension == 2
+template class TriaRawIterator<TriaAccessor<2, deal_II_dimension, deal_II_dimension+1> >;
+template class TriaIterator<TriaAccessor<2, deal_II_dimension, deal_II_dimension+1> >;
+template class TriaActiveIterator<TriaAccessor<2, deal_II_dimension, deal_II_dimension+1> >;
+#endif
+
 #endif
 
 DEAL_II_NAMESPACE_CLOSE
index a1628c34cdef1500ace57371c72044c99c3b38b5..0254258eff85832f5e1ee9789252626e0d8cca6a 100644 (file)
@@ -26,113 +26,136 @@ DEAL_II_NAMESPACE_OPEN
 /* -------------------------- Boundary --------------------- */
 
 
-template <int dim>
-Boundary<dim>::~Boundary ()
+template <int dim, int spacedim>
+Boundary<dim, spacedim>::~Boundary ()
 {}
 
 
 
-template <int dim>
-Point<dim>
-Boundary<dim>::get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &) const 
+template <int dim, int spacedim>
+Point<spacedim>
+Boundary<dim, spacedim>::
+get_new_point_on_quad (const typename Triangulation<dim, spacedim>::quad_iterator &) const 
 {
   Assert (false, ExcPureFunctionCalled());
-  return Point<dim>();
+  return Point<spacedim>();
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-Boundary<dim>::
-get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &,
-                                std::vector<Point<dim> > &) const
+Boundary<dim, spacedim>::
+get_intermediate_points_on_line (const typename Triangulation<dim, spacedim>::line_iterator &,
+                                std::vector<Point<spacedim> > &) const
 {
   Assert (false, ExcPureFunctionCalled());
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-Boundary<dim>::
-get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &,
-                                std::vector<Point<dim> > &) const
+Boundary<dim, spacedim>::
+get_intermediate_points_on_quad (const typename Triangulation<dim, spacedim>::quad_iterator &,
+                                std::vector<Point<spacedim> > &) const
 {
   Assert (false, ExcPureFunctionCalled());
 }
 
-#if deal_II_dimension == 1
 
-template <>
-Point<1>
-Boundary<1>::
-get_new_point_on_face (const Triangulation<1>::face_iterator &) const
+#if deal_II_dimension > 1
+
+template <int dim, int spacedim>
+Point<spacedim>
+Boundary<dim,spacedim>::
+get_new_point_on_face (const typename Triangulation<dim,spacedim>::face_iterator &face) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return Point<1>();
+  Assert (dim>1, ExcImpossibleInDim(dim));
+
+  switch (dim)
+    {
+      case 2:
+           return get_new_point_on_line (face);
+      case 3:
+           return get_new_point_on_quad (face);
+    }
+  
+  return Point<spacedim>();
 }
 
-template <>
+
+template <int dim, int spacedim>
 void
-Boundary<1>::
-get_intermediate_points_on_face (const Triangulation<1>::face_iterator &,
-                                std::vector<Point<1> > &) const
+Boundary<dim,spacedim>::
+get_intermediate_points_on_face (const typename Triangulation<dim,spacedim>::face_iterator &face,
+                                std::vector<Point<spacedim> > &points) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-}
+  Assert (dim>1, ExcImpossibleInDim(dim));
 
-#endif
+  switch (dim)
+    {
+      case 2:
+           get_intermediate_points_on_line (face, points);
+           break;
+      case 3:
+           get_intermediate_points_on_quad (face, points);
+           break;
+      default:
+           Assert (false, ExcNotImplemented());
+    }
+}
 
-#if deal_II_dimension == 2
+#else
 
 template <>
-Point<2>
-Boundary<2>::
-get_new_point_on_face (const Triangulation<2>::face_iterator &face) const
+Point<1>
+Boundary<1,1>::
+get_new_point_on_face (const Triangulation<1,1>::face_iterator &) const
 {
-  return get_new_point_on_line(face);
+  Assert (false, ExcImpossibleInDim(1));
+  return Point<1>();
 }
 
+
 template <>
 void
-Boundary<2>::
-get_intermediate_points_on_face (const Triangulation<2>::face_iterator &face,
-                                std::vector<Point<2> > &points) const
+Boundary<1,1>::
+get_intermediate_points_on_face (const Triangulation<1,1>::face_iterator &,
+                                std::vector<Point<1> > &) const
 {
-  get_intermediate_points_on_line(face, points);
+  Assert (false, ExcImpossibleInDim(1));
 }
 
-#endif
 
 
-#if deal_II_dimension == 3
-
 template <>
-Point<3>
-Boundary<3>::
-get_new_point_on_face (const Triangulation<3>::face_iterator &face) const
+Point<2>
+Boundary<1,2>::
+get_new_point_on_face (const Triangulation<1,2>::face_iterator &) const
 {
-  return get_new_point_on_quad(face);
+  Assert (false, ExcImpossibleInDim(1));
+  return Point<2>();
 }
 
+
 template <>
 void
-Boundary<3>::
-get_intermediate_points_on_face (const Triangulation<3>::face_iterator &face,
-                                std::vector<Point<3> > &points) const
+Boundary<1,2>::
+get_intermediate_points_on_face (const Triangulation<1,2>::face_iterator &,
+                                std::vector<Point<2> > &) const
 {
-  get_intermediate_points_on_quad(face, points);
+  Assert (false, ExcImpossibleInDim(1));
 }
 
-#endif
 
 
+#endif
 
-template <int dim>
+template <int dim, int spacedim>
 void
-Boundary<dim>::
-get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &,
+Boundary<dim, spacedim>::
+get_normals_at_vertices (const typename Triangulation<dim, spacedim>::face_iterator &,
                         FaceVertexNormals                                &) const
 {
   Assert (false, ExcPureFunctionCalled());
@@ -143,84 +166,107 @@ get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &,
 /* -------------------------- StraightBoundary --------------------- */
 
 
-template <int dim>
-StraightBoundary<dim>::StraightBoundary ()
+template <int dim, int spacedim>
+StraightBoundary<dim, spacedim>::StraightBoundary ()
 {}
 
 
-
-template <int dim>
-Point<dim>
-StraightBoundary<dim>::get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const 
+template <int dim, int spacedim>
+Point<spacedim>
+StraightBoundary<dim, spacedim>::
+get_new_point_on_line (const typename Triangulation<dim, spacedim>::line_iterator &line) const 
 {
   return (line->vertex(0) + line->vertex(1)) / 2;
 }
 
 
+namespace
+{
+                                  // compute the new midpoint of a quad --
+                                  // either of a 2d cell on a manifold in 3d
+                                  // or of a face of a 3d triangulation in 3d
+  template <int dim>
+  Point<3>
+  compute_new_point_on_quad (const typename Triangulation<dim, 3>::quad_iterator &quad)
+  {
+                                    // generate a new point in the middle of
+                                    // the face based on the points on the
+                                    // edges and the vertices.
+                                    //
+                                    // there is a pathological situation when
+                                    // this face is on a straight boundary, but
+                                    // one of its edges and the face behind it
+                                    // are not; if that face is refined first,
+                                    // the new point in the middle of that edge
+                                    // may not be at the same position as
+                                    // quad->line(.)->center() would have been,
+                                    // but would have been moved to the
+                                    // non-straight boundary. We cater to that
+                                    // situation by using existing edge
+                                    // midpoints if available, or center() if
+                                    // not
+                                    //
+                                    // note that this situation can not happen
+                                    // during mesh refinement, as there the
+                                    // edges are refined first and only then
+                                    // the face. thus, the check whether a line
+                                    // has children does not lead to the
+                                    // situation where the new face midpoints
+                                    // have different positions depending on
+                                    // which of the two cells is refined first.
+                                    //
+                                    // the situation where the edges aren't
+                                    // refined happens when the a higher order
+                                    // MappingQ requests the midpoint of a
+                                    // face, though, and it is for these cases
+                                    // that we need to have the check available
+    return (quad->vertex(0) + quad->vertex(1) +
+           quad->vertex(2) + quad->vertex(3) +
+           (quad->line(0)->has_children() ?
+            quad->line(0)->child(0)->vertex(1) :
+            quad->line(0)->center()) +
+           (quad->line(1)->has_children() ?
+            quad->line(1)->child(0)->vertex(1) :
+            quad->line(1)->center()) +
+           (quad->line(2)->has_children() ?
+            quad->line(2)->child(0)->vertex(1) :
+            quad->line(2)->center()) +
+           (quad->line(3)->has_children() ?
+            quad->line(3)->child(0)->vertex(1) :
+            quad->line(3)->center())               ) / 8;
+  }
+}
+
+
 #if deal_II_dimension < 3
 
-template <int dim>
-Point<dim>
-StraightBoundary<dim>::get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &) const 
+template <int dim, int spacedim>
+Point<spacedim>
+StraightBoundary<dim, spacedim>::
+get_new_point_on_quad (const typename Triangulation<dim, spacedim>::quad_iterator &) const 
 {
   Assert (false, ExcImpossibleInDim(dim));
-  return Point<dim>();
+  return Point<spacedim>();
 }
 
+#if deal_II_dimension == 2
+template <>
+Point<3>
+StraightBoundary<2,3>::
+get_new_point_on_quad (const Triangulation<2,3>::quad_iterator &quad) const 
+{
+  return compute_new_point_on_quad<2> (quad);
+}
 
+#endif
 #else
 
-
 template <>
 Point<3>
 StraightBoundary<3>::
 get_new_point_on_quad (const Triangulation<3>::quad_iterator &quad) const 
 {
-                                   // generate a new point in the middle of
-                                   // the face based on the points on the
-                                   // edges and the vertices.
-                                   //
-                                   // there is a pathological situation when
-                                   // this face is on a straight boundary, but
-                                   // one of its edges and the face behind it
-                                   // are not; if that face is refined first,
-                                   // the new point in the middle of that edge
-                                   // may not be at the same position as
-                                   // quad->line(.)->center() would have been,
-                                   // but would have been moved to the
-                                   // non-straight boundary. We cater to that
-                                   // situation by using existing edge
-                                   // midpoints if available, or center() if
-                                   // not
-                                   //
-                                   // note that this situation can not happen
-                                   // during mesh refinement, as there the
-                                   // edges are refined first and only then
-                                   // the face. thus, the check whether a line
-                                   // has children does not lead to the
-                                   // situation where the new face midpoints
-                                   // have different positions depending on
-                                   // which of the two cells is refined first.
-                                   //
-                                   // the situation where the edges aren't
-                                   // refined happens when the a higher order
-                                   // MappingQ requests the midpoint of a
-                                   // face, though, and it is for these cases
-                                   // that we need to have the check available
-  return (quad->vertex(0) + quad->vertex(1) +
-         quad->vertex(2) + quad->vertex(3) +
-         (quad->line(0)->has_children() ?
-           quad->line(0)->child(0)->vertex(1) :
-           quad->line(0)->center()) +
-         (quad->line(1)->has_children() ?
-           quad->line(1)->child(0)->vertex(1) :
-           quad->line(1)->center()) +
-         (quad->line(2)->has_children() ?
-           quad->line(2)->child(0)->vertex(1) :
-           quad->line(2)->center()) +
-         (quad->line(3)->has_children() ?
-           quad->line(3)->child(0)->vertex(1) :
-           quad->line(3)->center())               ) / 8;
+  return compute_new_point_on_quad<3> (quad);
 }
 
 #endif
@@ -238,14 +284,22 @@ get_intermediate_points_on_line (const Triangulation<1>::line_iterator &,
 }
 
 
+template <>
+void
+StraightBoundary<1,2>::
+get_intermediate_points_on_line (const Triangulation<1,2>::line_iterator &,
+                                std::vector<Point<2> > &) const
+{
+  Assert(false, ExcImpossibleInDim(1));
+}
 #else
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-StraightBoundary<dim>::
-get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
-                                std::vector<Point<dim> > &points) const
+StraightBoundary<dim, spacedim>::
+get_intermediate_points_on_line (const typename Triangulation<dim, spacedim>::line_iterator &line,
+                                std::vector<Point<spacedim> > &points) const
 {
   const unsigned int n=points.size();
   Assert(n>0, ExcInternalError());
@@ -253,7 +307,7 @@ get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterato
   const double dx=1./(n+1);
   double x=dx;
 
-  const Point<dim> vertices[2] = { line->vertex(0),
+  const Point<spacedim> vertices[2] = { line->vertex(0),
                                   line->vertex(1) };
   
   for (unsigned int i=0; i<n; ++i, x+=dx)
@@ -266,11 +320,11 @@ get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterato
 
 #if deal_II_dimension < 3
 
-template <int dim>
+template <int dim, int spacedim>
 void
-StraightBoundary<dim>::
-get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &,
-                                std::vector<Point<dim> > &) const
+StraightBoundary<dim, spacedim>::
+get_intermediate_points_on_quad (const typename Triangulation<dim, spacedim>::quad_iterator &,
+                                std::vector<Point<spacedim> > &) const
 {
   Assert(false, ExcImpossibleInDim(dim));
 }
@@ -283,7 +337,7 @@ StraightBoundary<3>::
 get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
                                 std::vector<Point<3> > &points) const
 {
-  const unsigned int dim = 3;
+  const unsigned int spacedim = 3;
   
   const unsigned int n=points.size(),
                     m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
@@ -293,10 +347,10 @@ get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
   const double ds=1./(m+1);
   double y=ds;
 
-  const Point<dim> vertices[4] = { quad->vertex(0),
-                                  quad->vertex(1),
-                                  quad->vertex(2),
-                                  quad->vertex(3) };
+  const Point<spacedim> vertices[4] = { quad->vertex(0),
+                                       quad->vertex(1),
+                                       quad->vertex(2),
+                                       quad->vertex(3) };
 
   for (unsigned int i=0; i<m; ++i, y+=ds)
     {
@@ -324,6 +378,15 @@ get_normals_at_vertices (const Triangulation<1>::face_iterator &,
   Assert (false, ExcImpossibleInDim(1));
 }
 
+template <>
+void
+StraightBoundary<1,2>::
+get_normals_at_vertices (const Triangulation<1,2>::face_iterator &,
+                        Boundary<1,2>::FaceVertexNormals &) const
+{
+  Assert (false, ExcImpossibleInDim(1));
+}
+
 #endif
 
 
@@ -342,6 +405,20 @@ get_normals_at_vertices (const Triangulation<2>::face_iterator &face,
                                            -tangent[0]);
 }
 
+template <>
+void
+StraightBoundary<2,3>::
+get_normals_at_vertices (const Triangulation<2,3>::face_iterator &face,
+                        Boundary<2,3>::FaceVertexNormals &face_vertex_normals) const
+{
+  const Tensor<1,3> tangent = face->vertex(1) - face->vertex(0);
+  for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_face; ++vertex)
+                                    // compute normals from tangent
+    face_vertex_normals[vertex] = Point<3>(tangent[1],
+                                           -tangent[0],0);
+  Assert(false, ExcNotImplemented());
+}
+
 #endif
 
 
@@ -388,5 +465,10 @@ get_normals_at_vertices (const Triangulation<3>::face_iterator &face,
 template class Boundary<deal_II_dimension>;
 template class StraightBoundary<deal_II_dimension>;
 
+#if deal_II_dimension == 1 || deal_II_dimension == 2
+template class Boundary<deal_II_dimension, deal_II_dimension+1>;
+template class StraightBoundary<deal_II_dimension, deal_II_dimension+1>;
+#endif
+
 DEAL_II_NAMESPACE_CLOSE
 
index a1bc4609a3d8d67ee1ce4defb4b1e99a24865450..139d4540bb4b70796c9870ade03ca559e97dd6dd 100644 (file)
@@ -256,26 +256,26 @@ CylinderBoundary<dim>::get_radius () const
 
 //======================================================================//
 
-template <int dim>
-HyperBallBoundary<dim>::HyperBallBoundary (const Point<dim> p,
+template <int dim, int spacedim>
+HyperBallBoundary<dim,spacedim>::HyperBallBoundary (const Point<spacedim> p,
                                           const double     radius) :
                center(p), radius(radius), compute_radius_automatically(false)
 {}
 
 
 
-template <int dim>
-Point<dim>
-HyperBallBoundary<dim>::get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const
+template <int dim, int spacedim>
+Point<spacedim>
+HyperBallBoundary<dim,spacedim>::get_new_point_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line) const
 {
-  Point<dim> middle = StraightBoundary<dim>::get_new_point_on_line (line);
+  Point<spacedim> middle = StraightBoundary<dim,spacedim>::get_new_point_on_line (line);
   
   middle -= center;
 
   double r=0;
   if (compute_radius_automatically)
     {
-      const Point<dim> vertex_relative = line->vertex(0) - center;
+      const Point<spacedim> vertex_relative = line->vertex(0) - center;
       r = std::sqrt(vertex_relative.square());
     }
   else
@@ -293,30 +293,39 @@ HyperBallBoundary<dim>::get_new_point_on_line (const typename Triangulation<dim>
 
 template <>
 Point<1>
-HyperBallBoundary<1>::
-get_new_point_on_quad (const Triangulation<1>::quad_iterator &) const
+HyperBallBoundary<1,1>::
+get_new_point_on_quad (const Triangulation<1,1>::quad_iterator &) const
 {
   Assert (false, ExcInternalError());
   return Point<1>();
 }
 
+template <>
+Point<2>
+HyperBallBoundary<1,2>::
+get_new_point_on_quad (const Triangulation<1,2>::quad_iterator &) const
+{
+  Assert (false, ExcInternalError());
+  return Point<2>();
+}
+
 #endif
 
 
 
-template <int dim>
-Point<dim>
-HyperBallBoundary<dim>::
-get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &quad) const
+template <int dim, int spacedim>
+Point<spacedim>
+HyperBallBoundary<dim,spacedim>::
+get_new_point_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad) const
 {
-  Point<dim> middle = StraightBoundary<dim>::get_new_point_on_quad (quad);
+  Point<spacedim> middle = StraightBoundary<dim,spacedim>::get_new_point_on_quad (quad);
   
   middle -= center;
 
   double r=0;
   if (compute_radius_automatically)
     {
-      const Point<dim> vertex_relative = quad->vertex(0) - center;
+      const Point<spacedim> vertex_relative = quad->vertex(0) - center;
       r = std::sqrt(vertex_relative.square());
     }
   else
@@ -340,14 +349,14 @@ HyperBallBoundary<1>::get_intermediate_points_on_line (
   Assert (false, ExcImpossibleInDim(1));
 }
 
-#else
+#endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-HyperBallBoundary<dim>::get_intermediate_points_on_line (
-  const typename Triangulation<dim>::line_iterator &line,
-  std::vector<Point<dim> > &points) const
+HyperBallBoundary<dim,spacedim>::get_intermediate_points_on_line (
+  const typename Triangulation<dim,spacedim>::line_iterator &line,
+  std::vector<Point<spacedim> > &points) const
 {
   if (points.size()==1)
     points[0]=get_new_point_on_line(line);
@@ -356,16 +365,16 @@ HyperBallBoundary<dim>::get_intermediate_points_on_line (
 }
 
   
-template <int dim>
+template <int dim, int spacedim>
 void
-HyperBallBoundary<dim>::get_intermediate_points_between_points (
-  const Point<dim> &p0, const Point<dim> &p1,
-  std::vector<Point<dim> > &points) const
+HyperBallBoundary<dim,spacedim>::get_intermediate_points_between_points (
+  const Point<spacedim> &p0, const Point<spacedim> &p1,
+  std::vector<Point<spacedim> > &points) const
 {
   const unsigned int n=points.size();
   Assert(n>0, ExcInternalError());
 
-  const Point<dim> v0=p0-center,
+  const Point<spacedim> v0=p0-center,
                   v1=p1-center;
   const double length=std::sqrt((v1-v0).square());
   
@@ -373,7 +382,7 @@ HyperBallBoundary<dim>::get_intermediate_points_between_points (
   double r=0;
   if (compute_radius_automatically)
     {
-      const Point<dim> vertex_relative = p0 - center;
+      const Point<spacedim> vertex_relative = p0 - center;
       r = std::sqrt(vertex_relative.square());
     }
   else
@@ -386,7 +395,7 @@ HyperBallBoundary<dim>::get_intermediate_points_between_points (
   
   const double alpha=std::acos((v0*v1)/std::sqrt(v0.square()*v1.square()));
   const double d_alpha=alpha/(n+1);
-  const Point<dim> pm=0.5*(v0+v1);
+  const Point<spacedim> pm=0.5*(v0+v1);
   
   const double h=std::sqrt(pm.square());
   
@@ -435,9 +444,6 @@ HyperBallBoundary<dim>::get_intermediate_points_between_points (
     }
 }
 
-
-#endif
-
 #if deal_II_dimension == 3
 
 template <>
@@ -473,11 +479,11 @@ HyperBallBoundary<3>::get_intermediate_points_on_quad (
 #endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-HyperBallBoundary<dim>::get_intermediate_points_on_quad (
-  const typename Triangulation<dim>::quad_iterator &,
-  std::vector<Point<dim> > &) const
+HyperBallBoundary<dim,spacedim>::get_intermediate_points_on_quad (
+  const typename Triangulation<dim,spacedim>::quad_iterator &,
+  std::vector<Point<spacedim> > &) const
 {
   Assert(false, ExcImpossibleInDim(dim));
 }
@@ -495,14 +501,23 @@ get_normals_at_vertices (const Triangulation<1>::face_iterator &,
   Assert (false, ExcImpossibleInDim(1));
 }
 
+template <>
+void
+HyperBallBoundary<1,2>::
+get_normals_at_vertices (const Triangulation<1,2>::face_iterator &,
+                        Boundary<1,2>::FaceVertexNormals &) const
+{
+  Assert (false, ExcImpossibleInDim(1));
+}
+
 #endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-HyperBallBoundary<dim>::
-get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
-                        typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const
+HyperBallBoundary<dim,spacedim>::
+get_normals_at_vertices (const typename Triangulation<dim,spacedim>::face_iterator &face,
+                        typename Boundary<dim,spacedim>::FaceVertexNormals &face_vertex_normals) const
 {
   for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_face; ++vertex)
     face_vertex_normals[vertex] = face->vertex(vertex)-center;
@@ -510,18 +525,18 @@ get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
 
 
 
-template <int dim>
-Point<dim>
-HyperBallBoundary<dim>::get_center () const 
+template <int dim, int spacedim>
+Point<spacedim>
+HyperBallBoundary<dim,spacedim>::get_center () const 
 {
   return center;
 }
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 double
-HyperBallBoundary<dim>::get_radius () const 
+HyperBallBoundary<dim,spacedim>::get_radius () const 
 {
   Assert(!compute_radius_automatically, ExcRadiusNotSet());
   return radius;
@@ -847,5 +862,9 @@ template class HalfHyperBallBoundary<deal_II_dimension>;
 template class HyperShellBoundary<deal_II_dimension>;
 template class HalfHyperShellBoundary<deal_II_dimension>;
 
+#if deal_II_dimension != 3
+template class HyperBallBoundary<deal_II_dimension,deal_II_dimension+1>;
+#endif
+
 DEAL_II_NAMESPACE_CLOSE
 
index 16fe8d842f9361401e90c53a607ec5e98e73c12b..9961c1f516fca5c4806d3457dd332c1e3646f741 100644 (file)
@@ -27,9 +27,9 @@ namespace internal
   namespace Triangulation
   {    
     template <>
-    template <int dim>
-    typename dealii::Triangulation<dim>::raw_line_iterator
-    TriaObjects<TriaObject<1> >::next_free_single_line (const dealii::Triangulation<dim> &tria)
+    template <int dim, int spacedim>
+    typename dealii::Triangulation<dim,spacedim>::raw_line_iterator
+    TriaObjects<TriaObject<1> >::next_free_single_line (const dealii::Triangulation<dim,spacedim> &tria)
     {
                                       // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
       
@@ -72,15 +72,15 @@ namespace internal
            return tria.end_line();
        }
 
-      return typename dealii::Triangulation<dim>::raw_line_iterator(&tria,0,pos);
+      return typename dealii::Triangulation<dim,spacedim>::raw_line_iterator(&tria,0,pos);
     }
     
          
 
     template <>
-    template <int dim>
-    typename dealii::Triangulation<dim>::raw_line_iterator
-    TriaObjects<TriaObject<1> >::next_free_pair_line (const dealii::Triangulation<dim> &tria)
+    template <int dim, int spacedim>
+    typename dealii::Triangulation<dim,spacedim>::raw_line_iterator
+    TriaObjects<TriaObject<1> >::next_free_pair_line (const dealii::Triangulation<dim,spacedim> &tria)
     {
                                       // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
       
@@ -100,15 +100,15 @@ namespace internal
       else
        next_free_pair=pos+2;
       
-      return typename dealii::Triangulation<dim>::raw_line_iterator(&tria,0,pos);
+      return typename dealii::Triangulation<dim,spacedim>::raw_line_iterator(&tria,0,pos);
     }
 
 
     
     template <>
-    template <int dim>
-    typename dealii::Triangulation<dim>::raw_quad_iterator
-    TriaObjects<TriaObject<1> >::next_free_single_quad (const dealii::Triangulation<dim> &tria)
+    template <int dim, int spacedim>
+    typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator
+    TriaObjects<TriaObject<1> >::next_free_single_quad (const dealii::Triangulation<dim,spacedim> &tria)
     {
       Assert(false, ExcWrongIterator("quad","line"));
       return tria.end_quad();
@@ -117,9 +117,9 @@ namespace internal
 
 
     template <>
-    template <int dim>
-    typename dealii::Triangulation<dim>::raw_quad_iterator
-    TriaObjects<TriaObject<1> >::next_free_pair_quad (const dealii::Triangulation<dim> &tria)
+    template <int dim, int spacedim>
+    typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator
+    TriaObjects<TriaObject<1> >::next_free_pair_quad (const dealii::Triangulation<dim,spacedim> &tria)
     {
       Assert(false, ExcWrongIterator("quad","line"));
       return tria.end_quad();
@@ -128,9 +128,9 @@ namespace internal
 
     
     template <>
-    template <int dim>
-    typename dealii::Triangulation<dim>::raw_quad_iterator
-    TriaObjects<TriaObject<2> >::next_free_single_quad (const dealii::Triangulation<dim> &tria)
+    template <int dim, int spacedim>
+    typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator
+    TriaObjects<TriaObject<2> >::next_free_single_quad (const dealii::Triangulation<dim,spacedim> &tria)
     {
                                       // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
       
@@ -173,15 +173,15 @@ namespace internal
            return tria.end_quad();
        }
 
-      return typename dealii::Triangulation<dim>::raw_quad_iterator(&tria,0,pos);
+      return typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator(&tria,0,pos);
     }
     
          
 
     template <>
-    template <int dim>
-    typename dealii::Triangulation<dim>::raw_quad_iterator
-    TriaObjects<TriaObject<2> >::next_free_pair_quad (const dealii::Triangulation<dim> &tria)
+    template <int dim, int spacedim>
+    typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator
+    TriaObjects<TriaObject<2> >::next_free_pair_quad (const dealii::Triangulation<dim,spacedim> &tria)
     {
                                       // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
       
@@ -201,14 +201,14 @@ namespace internal
       else
        next_free_pair=pos+2;
       
-      return typename dealii::Triangulation<dim>::raw_quad_iterator(&tria,0,pos);
+      return typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator(&tria,0,pos);
     }
 
 
     template <>
-    template <int dim>
-    typename dealii::Triangulation<dim>::raw_line_iterator
-    TriaObjects<TriaObject<2> >::next_free_single_line (const dealii::Triangulation<dim> &tria)
+    template <int dim, int spacedim>
+    typename dealii::Triangulation<dim,spacedim>::raw_line_iterator
+    TriaObjects<TriaObject<2> >::next_free_single_line (const dealii::Triangulation<dim,spacedim> &tria)
     {
       Assert(false, ExcWrongIterator("line","quad"));
       return tria.end_line();
@@ -217,9 +217,9 @@ namespace internal
 
 
     template <>
-    template <int dim>
-    typename dealii::Triangulation<dim>::raw_line_iterator
-    TriaObjects<TriaObject<2> >::next_free_pair_line (const dealii::Triangulation<dim> &tria)
+    template <int dim, int spacedim>
+    typename dealii::Triangulation<dim,spacedim>::raw_line_iterator
+    TriaObjects<TriaObject<2> >::next_free_pair_line (const dealii::Triangulation<dim,spacedim> &tria)
     {
       Assert(false, ExcWrongIterator("line","quad"));
       return tria.end_line();
@@ -228,9 +228,9 @@ namespace internal
 
 
     template <>
-    template <int dim>
-    typename dealii::Triangulation<dim>::raw_hex_iterator
-    TriaObjects<TriaObject<3> >::next_free_hex (const dealii::Triangulation<dim> &tria,
+    template <int dim, int spacedim>
+    typename dealii::Triangulation<dim,spacedim>::raw_hex_iterator
+    TriaObjects<TriaObject<3> >::next_free_hex (const dealii::Triangulation<dim,spacedim> &tria,
                                            const unsigned int               level)
     {
                                       // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
@@ -250,7 +250,7 @@ namespace internal
       else
        next_free_pair=pos+2;
       
-      return typename dealii::Triangulation<dim>::raw_hex_iterator(&tria,level,pos);
+      return typename dealii::Triangulation<dim,spacedim>::raw_hex_iterator(&tria,level,pos);
     }
 
 
index 61c82c7bac6d7fb5fb9777f48ed17bc88303ccbc..f2e80d4e0c1d3a7888ed7b4f7a09f01d944b3cb4 100644 (file)
@@ -170,1350 +170,2662 @@ namespace internal
 
 namespace hp
 {
-  
-  template <int dim>
-  const unsigned int DoFHandler<dim>::dimension;
-
-  template <int dim>
-  const unsigned int DoFHandler<dim>::invalid_dof_index;
 
-  template <int dim>
-  const unsigned int DoFHandler<dim>::default_fe_index;
-  
+/**
+ * A class with the same purpose as the similarly named class of the
+ * Triangulation class. See there for more information.
+ */
+  template <int x_dim, int x_spacedim>
+  struct DoFHandler<x_dim,x_spacedim>::Implementation
+  {
+                                      /**
+                                       * Do that part of reserving
+                                       * space that pertains to
+                                       * vertices, since this is the
+                                       * same in all space
+                                       * dimensions.
+                                       */
+      template<int dim, int spacedim>
+      static
+      void
+      reserve_space_vertices (DoFHandler<dim,spacedim> &dof_handler)
+       { 
+                                          // The final step is allocating
+                                          // memory is to set up vertex dof
+                                          // information. since vertices
+                                          // are sequentially numbered,
+                                          // what we do first is to set up
+                                          // an array in which we record
+                                          // whether a vertex is associated
+                                          // with any of the given fe's, by
+                                          // setting a bit. in a later
+                                          // step, we then actually
+                                          // allocate memory for the
+                                          // required dofs
+         std::vector<std::vector<bool> >
+           vertex_fe_association (dof_handler.finite_elements->size(),
+                                  std::vector<bool> (dof_handler.tria->n_vertices(), false));
+      
+         for (active_cell_iterator cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+           for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+             vertex_fe_association[cell->active_fe_index()][cell->vertex_index(v)]
+               = true;
+      
+                                          // in debug mode, make sure
+                                          // that each vertex is
+                                          // associated with at least one
+                                          // fe (note that except for
+                                          // unused vertices, all
+                                          // vertices are actually
+                                          // active)
+#ifdef DEBUG
+         for (unsigned int v=0; v<dof_handler.tria->n_vertices(); ++v)
+           if (dof_handler.tria->vertex_used(v) == true)
+             {
+               unsigned int fe=0;
+               for (; fe<dof_handler.finite_elements->size(); ++fe)
+                 if (vertex_fe_association[fe][v] == true)
+                   break;
+               Assert (fe != dof_handler.finite_elements->size(), ExcInternalError());
+             }
+#endif
 
+                                          // next count how much memory
+                                          // we actually need. for each
+                                          // vertex, we need one slot per
+                                          // fe to store the fe_index,
+                                          // plus dofs_per_vertex for
+                                          // this fe. in addition, we
+                                          // need one slot as the end
+                                          // marker for the
+                                          // fe_indices. at the same time
+                                          // already fill the
+                                          // vertex_dofs_offsets field
+         dof_handler.vertex_dofs_offsets.resize (dof_handler.tria->n_vertices(),
+                                                 numbers::invalid_unsigned_int);
+      
+         unsigned int vertex_slots_needed = 0;
+         for (unsigned int v=0; v<dof_handler.tria->n_vertices(); ++v)
+           if (dof_handler.tria->vertex_used(v) == true)
+             {
+               dof_handler.vertex_dofs_offsets[v] = vertex_slots_needed;
+           
+               for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+                 if (vertex_fe_association[fe][v] == true)
+                   vertex_slots_needed += (*dof_handler.finite_elements)[fe].dofs_per_vertex + 1;
+               ++vertex_slots_needed;
+             }
 
-  template <int dim>
-  DoFHandler<dim>::DoFHandler (const Triangulation<dim> &tria)
-                  :
-                  tria(&tria),
-                 faces (NULL),
-                  used_dofs (0)
-  {
-    create_active_fe_table ();
-    tria.add_refinement_listener (*this);
-  }
+                                          // now allocate the space we
+                                          // have determined we need, and
+                                          // set up the linked lists for
+                                          // each of the vertices
+         dof_handler.vertex_dofs.resize (vertex_slots_needed, invalid_dof_index);
+         for (unsigned int v=0; v<dof_handler.tria->n_vertices(); ++v)
+           if (dof_handler.tria->vertex_used(v) == true)
+             {
+               unsigned int pointer = dof_handler.vertex_dofs_offsets[v];
+               for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+                 if (vertex_fe_association[fe][v] == true)
+                   {
+                                                      // if this vertex
+                                                      // uses this fe,
+                                                      // then set the
+                                                      // fe_index and
+                                                      // move the pointer
+                                                      // ahead
+                     dof_handler.vertex_dofs[pointer] = fe;
+                     pointer += (*dof_handler.finite_elements)[fe].dofs_per_vertex + 1;
+                   }
+                                                // finally place the end
+                                                // marker
+               dof_handler.vertex_dofs[pointer] = numbers::invalid_unsigned_int;
+             }
+       }
 
+      
+    
+                                       /**
+                                        * Distribute dofs on the given cell,
+                                        * with new dofs starting with index
+                                        * @p next_free_dof. Return the next
+                                        * unused index number. The finite
+                                        * element used is the one given to
+                                        * @p distribute_dofs, which is copied
+                                        * to @p selected_fe.
+                                        *
+                                        * This function is excluded from the
+                                        * @p distribute_dofs function since
+                                        * it can not be implemented dimension
+                                        * independent.
+                                        */
+      template <int spacedim>
+      static
+      unsigned int
+      distribute_dofs_on_cell (const typename DoFHandler<1,spacedim>::active_cell_iterator &cell,
+                              unsigned int          next_free_dof)
+       {
+         const FiniteElement<1> &fe       = cell->get_fe();
+         const unsigned int      fe_index = cell->active_fe_index ();
+    
+                                          // number dofs on vertices. to do
+                                          // so, check whether dofs for
+                                          // this vertex have been
+                                          // distributed and for the
+                                          // present fe (only check the
+                                          // first dof), and if this isn't
+                                          // the case distribute new ones
+                                          // there
+         if (fe.dofs_per_vertex > 0)
+           for (unsigned int vertex=0; vertex<GeometryInfo<1>::vertices_per_cell; ++vertex)
+             if (cell->vertex_dof_index(vertex, 0, fe_index) == invalid_dof_index)
+               for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
+                 cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
+    
+                                          // finally for the line. this one
+                                          // shouldn't be numbered yet
+         if (fe.dofs_per_line > 0)
+           {
+             Assert (cell->dof_index(0, fe_index) == invalid_dof_index,
+                     ExcInternalError());
+       
+             for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
+               cell->set_dof_index (d, next_free_dof, fe_index);
+           }
 
-  template <int dim>
-  DoFHandler<dim>::~DoFHandler ()
-  {
-                                     // unsubscribe as a listener to refinement
-                                     // of the underlying triangulation
-    tria->remove_refinement_listener (*this);
+                                          // note that this cell has been processed
+         cell->set_user_flag ();
   
-                                     // ...and release allocated memory
-    clear ();
-  }
-
-#if deal_II_dimension == 1
-
-  template <>
-  DoFHandler<1>::raw_cell_iterator
-  DoFHandler<1>::begin_raw (const unsigned int level) const
-  {
-    return begin_raw_line (level);
-  }
-
-
-  template <>
-  DoFHandler<1>::cell_iterator
-  DoFHandler<1>::begin (const unsigned int level) const
-  {
-    return begin_line (level);
-  }
-
-
-  template <>
-  DoFHandler<1>::active_cell_iterator
-  DoFHandler<1>::begin_active (const unsigned int level) const
-  {
-    return begin_active_line (level);
-  }
-
-
-  template <>
-  DoFHandler<1>::raw_cell_iterator
-  DoFHandler<1>::end () const
-  {
-    return end_line ();
-  }
-
-
-  template <>
-  DoFHandler<1>::raw_cell_iterator
-  DoFHandler<1>::last_raw () const
-  {
-    return last_raw_line ();
-  }
-
-
-  template <>
-  DoFHandler<1>::raw_cell_iterator
-  DoFHandler<1>::last_raw (const unsigned int level) const
-  {
-    return last_raw_line (level);
-  }
-
-
-  template <>
-  DoFHandler<1>::cell_iterator
-  DoFHandler<1>::last () const
-  {
-    return last_line ();
-  }
-
-
-  template <>
-  DoFHandler<1>::cell_iterator
-  DoFHandler<1>::last (const unsigned int level) const
-  {
-    return last_line (level);
-  }
-
-
-  template <>
-  DoFHandler<1>::active_cell_iterator
-  DoFHandler<1>::last_active () const
-  {
-    return last_active_line ();
-  }
-
-
-  template <>
-  DoFHandler<1>::active_cell_iterator
-  DoFHandler<1>::last_active (const unsigned int level) const
-  {
-    return last_active_line (level);
-  }
-
-
-  template <>
-  DoFHandler<1>::raw_face_iterator
-  DoFHandler<1>::begin_raw_face () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::face_iterator
-  DoFHandler<1>::begin_face () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::active_face_iterator
-  DoFHandler<1>::begin_active_face () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::raw_face_iterator
-  DoFHandler<1>::end_face () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::raw_face_iterator
-  DoFHandler<1>::end_raw_face () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::active_face_iterator
-  DoFHandler<1>::end_active_face () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::raw_face_iterator
-  DoFHandler<1>::last_raw_face () const 
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::face_iterator
-  DoFHandler<1>::last_face () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::active_face_iterator
-  DoFHandler<1>::last_active_face () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::raw_quad_iterator
-  DoFHandler<1>::begin_raw_quad (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::quad_iterator
-  DoFHandler<1>::begin_quad (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::active_quad_iterator
-  DoFHandler<1>::begin_active_quad (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
-
-
-  template <>
-  DoFHandler<1>::raw_quad_iterator
-  DoFHandler<1>::end_quad () const
-  {
-    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;
-  }
+         return next_free_dof;
+       }
 
 
-  template <>
-  DoFHandler<1>::raw_quad_iterator
-  DoFHandler<1>::last_raw_quad (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+      template <int spacedim>
+      static
+      unsigned int
+      distribute_dofs_on_cell (const typename DoFHandler<2,spacedim>::active_cell_iterator &cell,
+                              unsigned int          next_free_dof)
+       {
+         const FiniteElement<2> &fe       = cell->get_fe();
+         const unsigned int      fe_index = cell->active_fe_index ();
+    
+                                          // number dofs on vertices. to do
+                                          // so, check whether dofs for
+                                          // this vertex have been
+                                          // distributed and for the
+                                          // present fe (only check the
+                                          // first dof), and if this isn't
+                                          // the case distribute new ones
+                                          // there
+         if (fe.dofs_per_vertex > 0)
+           for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
+             if (cell->vertex_dof_index(vertex, 0, fe_index) == invalid_dof_index)
+               for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
+                 cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
+    
+                                          // next the sides. do the
+                                          // same as above: check whether
+                                          // the line is already numbered
+                                          // for the present fe_index, and
+                                          // if not do it
+         if (fe.dofs_per_line > 0)
+           for (unsigned int l=0; l<GeometryInfo<2>::lines_per_cell; ++l)
+             {
+               line_iterator line = cell->line(l);
 
+               if (line->dof_index(0,fe_index) == invalid_dof_index)
+                 for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
+                   line->set_dof_index (d, next_free_dof, fe_index);
+             }
 
-  template <>
-  DoFHandler<1>::quad_iterator
-  DoFHandler<1>::last_quad (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
 
+                                          // finally for the quad. this one
+                                          // shouldn't be numbered yet
+         if (fe.dofs_per_quad > 0)
+           {
+             Assert (cell->dof_index(0, fe_index) == invalid_dof_index,
+                     ExcInternalError());
+       
+             for (unsigned int d=0; d<fe.dofs_per_quad; ++d, ++next_free_dof)
+               cell->set_dof_index (d, next_free_dof, fe_index);
+           }
 
-  template <>
-  DoFHandler<1>::active_quad_iterator
-  DoFHandler<1>::last_active_quad (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+                                          // note that this cell has been processed
+         cell->set_user_flag ();
+  
+         return next_free_dof;
+       }
 
 
-  template <>
-  DoFHandler<1>::raw_quad_iterator
-  DoFHandler<1>::last_raw_quad () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+      template <int spacedim>
+      static
+      unsigned int
+      distribute_dofs_on_cell (const typename DoFHandler<3,spacedim>::active_cell_iterator &cell,
+                              unsigned int          next_free_dof)
+       {
+         const FiniteElement<3> &fe       = cell->get_fe();
+         const unsigned int      fe_index = cell->active_fe_index ();
+    
+                                          // number dofs on vertices. to do
+                                          // so, check whether dofs for
+                                          // this vertex have been
+                                          // distributed and for the
+                                          // present fe (only check the
+                                          // first dof), and if this isn't
+                                          // the case distribute new ones
+                                          // there
+         if (fe.dofs_per_vertex > 0)
+           for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
+             if (cell->vertex_dof_index(vertex, 0, fe_index) == invalid_dof_index)
+               for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
+                 cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
+    
+                                          // next the four lines. do the
+                                          // same as above: check whether
+                                          // the line is already numbered
+                                          // for the present fe_index, and
+                                          // if not do it
+         if (fe.dofs_per_line > 0)
+           for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
+             {
+               line_iterator line = cell->line(l);
 
+               if (line->dof_index(0,fe_index) == invalid_dof_index)
+                 for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
+                   line->set_dof_index (d, next_free_dof, fe_index);
+             }
 
-  template <>
-  DoFHandler<1>::quad_iterator
-  DoFHandler<1>::last_quad () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+                                          // same for quads
+         if (fe.dofs_per_quad > 0)
+           for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
+             {
+               quad_iterator quad = cell->quad(q);
 
+               if (quad->dof_index(0,fe_index) == invalid_dof_index)
+                 for (unsigned int d=0; d<fe.dofs_per_quad; ++d, ++next_free_dof)
+                   quad->set_dof_index (d, next_free_dof, fe_index);
+             }
 
-  template <>
-  DoFHandler<1>::active_quad_iterator
-  DoFHandler<1>::last_active_quad () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
 
+                                          // finally for the hex. this one
+                                          // shouldn't be numbered yet
+         if (fe.dofs_per_hex > 0)
+           {
+             Assert (cell->dof_index(0, fe_index) == invalid_dof_index,
+                     ExcInternalError());
+       
+             for (unsigned int d=0; d<fe.dofs_per_hex; ++d, ++next_free_dof)
+               cell->set_dof_index (d, next_free_dof, fe_index);
+           }
 
-  template <>
-  DoFHandler<1>::raw_hex_iterator
-  DoFHandler<1>::begin_raw_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+                                          // note that this cell has been processed
+         cell->set_user_flag ();
+  
+         return next_free_dof;
+       }
+      
+      
+                                       /**
+                                        * Reserve enough space in the 
+                                        * <tt>levels[]</tt> objects to store the
+                                        * numbers of the degrees of freedom
+                                        * needed for the given element. The
+                                        * given element is that one which
+                                        * was selected when calling
+                                        * @p distribute_dofs the last time.
+                                        */
+      template <int spacedim>
+      static
+      void
+      reserve_space (DoFHandler<1,spacedim> &dof_handler)
+       {
+         const unsigned int dim = 1;
+    
+         Assert (dof_handler.finite_elements != 0, ExcNoFESelected());
+         Assert (dof_handler.finite_elements->size() > 0, ExcNoFESelected());
+         Assert (dof_handler.tria->n_levels() > 0, ExcInvalidTriangulation());
+         Assert (dof_handler.tria->n_levels() == dof_handler.levels.size (),
+                 ExcInternalError ());
+
+                                          // Release all space except the
+                                          // active_fe_indices field which
+                                          // we have to backup before
+         {
+           std::vector<std::vector<unsigned int> >
+             active_fe_backup(dof_handler.levels.size ());
+           for (unsigned int level = 0; level<dof_handler.levels.size (); ++level)
+             std::swap (dof_handler.levels[level]->active_fe_indices, active_fe_backup[level]);
+
+                                            // delete all levels and set them up
+                                            // newly, since vectors are
+                                            // troublesome if you want to change
+                                            // their size
+           dof_handler.clear_space ();
+  
+           for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level) 
+             {
+               dof_handler.levels.push_back (new internal::hp::DoFLevel<dim>);
+               std::swap (active_fe_backup[level],
+                          dof_handler.levels[level]->active_fe_indices);
+             }
+         }
 
+                                          // LINE (CELL) DOFs
+    
+                                          // count how much space we need
+                                          // on each level for the cell
+                                          // dofs and set the
+                                          // dof_*_offsets
+                                          // data. initially set the latter
+                                          // to an invalid index, and only
+                                          // later set it to something
+                                          // reasonable for active dof_handler.cells
+                                          //
+                                          // note that for dof_handler.cells, the
+                                          // situation is simpler than for
+                                          // other (lower dimensional)
+                                          // objects since exactly one
+                                          // finite element is used for it
+         for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level) 
+           {
+             dof_handler.levels[level]->lines.dof_offsets
+               = std::vector<unsigned int> (dof_handler.tria->n_raw_lines(level),
+                                            invalid_dof_index);
+
+             unsigned int next_free_dof = 0;
+             for (active_cell_iterator cell=dof_handler.begin_active(level);
+                  cell!=dof_handler.end_active(level); ++cell)
+               if (!cell->has_children())
+                 {
+                   dof_handler.levels[level]->lines.dof_offsets[cell->index()] = next_free_dof;
+                   next_free_dof += cell->get_fe().dofs_per_line;
+                 }
 
-  template <>
-  DoFHandler<1>::hex_iterator
-  DoFHandler<1>::begin_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+             dof_handler.levels[level]->lines.dofs
+               = std::vector<unsigned int> (next_free_dof, invalid_dof_index);
+           }
 
+                                          // safety check: make sure that
+                                          // the number of DoFs we
+                                          // allocated is actually correct
+                                          // (above we have also set the
+                                          // dof_*_offsets field, so
+                                          // we couldn't use this simpler
+                                          // algorithm)
+#ifdef DEBUG
+         for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+           {
+             unsigned int counter = 0;
+             for (cell_iterator cell=dof_handler.begin_active(level);
+                  cell!=dof_handler.end_active(level); ++cell)
+               if (!cell->has_children())
+                 counter += cell->get_fe().dofs_per_line;
+        
+             Assert (dof_handler.levels[level]->lines.dofs.size() == counter,
+                     ExcInternalError());
+             Assert (static_cast<unsigned int>
+                     (std::count (dof_handler.levels[level]->lines.dof_offsets.begin(),
+                                  dof_handler.levels[level]->lines.dof_offsets.end(),
+                                  invalid_dof_index))
+                     ==
+                     dof_handler.tria->n_raw_lines(level) - dof_handler.tria->n_active_lines(level),
+                     ExcInternalError());
+           }
+#endif
+    
+    
+                                          // VERTEX DOFS
+         reserve_space_vertices (dof_handler);
+       }
+      
 
-  template <>
-  DoFHandler<1>::active_hex_iterator
-  DoFHandler<1>::begin_active_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+      template <int spacedim>
+      static
+      void
+      reserve_space (DoFHandler<2,spacedim> &dof_handler)
+       {
+         const unsigned int dim = 2;
+    
+         Assert (dof_handler.finite_elements != 0, ExcNoFESelected());
+         Assert (dof_handler.finite_elements->size() > 0, ExcNoFESelected());
+         Assert (dof_handler.tria->n_levels() > 0, ExcInvalidTriangulation());
+         Assert (dof_handler.tria->n_levels() == dof_handler.levels.size (),
+                 ExcInternalError ());
+
+                                          // Release all space except the
+                                          // active_fe_indices field which
+                                          // we have to backup before
+         {
+           std::vector<std::vector<unsigned int> >
+             active_fe_backup(dof_handler.levels.size ());
+           for (unsigned int level = 0; level<dof_handler.levels.size (); ++level)
+             std::swap (dof_handler.levels[level]->active_fe_indices,
+                        active_fe_backup[level]);
+
+                                            // delete all levels and set them up
+                                            // newly, since vectors are
+                                            // troublesome if you want to change
+                                            // their size
+           dof_handler.clear_space ();
+  
+           for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level) 
+             {
+               dof_handler.levels.push_back (new internal::hp::DoFLevel<dim>);
+               std::swap (active_fe_backup[level],
+                          dof_handler.levels[level]->active_fe_indices);
+             }
+           dof_handler.faces = new internal::hp::DoFFaces<2>;
+         }
 
+    
+                                          // QUAD (CELL) DOFs
+    
+                                          // count how much space we need
+                                          // on each level for the cell
+                                          // dofs and set the
+                                          // dof_*_offsets
+                                          // data. initially set the latter
+                                          // to an invalid index, and only
+                                          // later set it to something
+                                          // reasonable for active dof_handler.cells
+                                          //
+                                          // note that for dof_handler.cells, the
+                                          // situation is simpler than for
+                                          // other (lower dimensional)
+                                          // objects since exactly one
+                                          // finite element is used for it
+         for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level) 
+           {
+             dof_handler.levels[level]->quads.dof_offsets
+               = std::vector<unsigned int> (dof_handler.tria->n_raw_quads(level),
+                                            invalid_dof_index);
+
+             unsigned int next_free_dof = 0;
+             for (active_cell_iterator cell=dof_handler.begin_active(level);
+                  cell!=dof_handler.end_active(level); ++cell)
+               if (!cell->has_children())
+                 {
+                   dof_handler.levels[level]->quads.dof_offsets[cell->index()] = next_free_dof;
+                   next_free_dof += cell->get_fe().dofs_per_quad;
+                 }
 
-  template <>
-  DoFHandler<1>::raw_hex_iterator
-  DoFHandler<1>::end_hex () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+             dof_handler.levels[level]->quads.dofs
+               = std::vector<unsigned int> (next_free_dof, invalid_dof_index);
+           }
 
+                                          // safety check: make sure that
+                                          // the number of DoFs we
+                                          // allocated is actually correct
+                                          // (above we have also set the
+                                          // dof_*_offsets field, so
+                                          // we couldn't use this simpler
+                                          // algorithm)
+#ifdef DEBUG
+         for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+           {
+             unsigned int counter = 0;
+             for (cell_iterator cell=dof_handler.begin_active(level);
+                  cell!=dof_handler.end_active(level); ++cell)
+               if (!cell->has_children())
+                 counter += cell->get_fe().dofs_per_quad;
+        
+             Assert (dof_handler.levels[level]->quads.dofs.size() == counter,
+                     ExcInternalError());
+             Assert (static_cast<unsigned int>
+                     (std::count (dof_handler.levels[level]->quads.dof_offsets.begin(),
+                                  dof_handler.levels[level]->quads.dof_offsets.end(),
+                                  invalid_dof_index))
+                     ==
+                     dof_handler.tria->n_raw_quads(level) - dof_handler.tria->n_active_quads(level),
+                     ExcInternalError());
+           }
+#endif
+    
+    
+                                          // LINE DOFS
+                                          //
+                                          // same here: count line dofs,
+                                          // then allocate as much space as
+                                          // we need and prime the linked
+                                          // list for lines (see the
+                                          // description in hp::DoFLevels)
+                                          // with the indices we will
+                                          // need. note that our task is
+                                          // more complicated since two
+                                          // adjacent dof_handler.cells may have
+                                          // different active_fe_indices,
+                                          // in which case we need to
+                                          // allocate *two* sets of line
+                                          // dofs for the same line
+                                          //
+                                          // the way we do things is that
+                                          // we loop over all active dof_handler.cells
+                                          // (these are the ones that have
+                                          // DoFs only anyway) and all
+                                          // their dof_handler.faces. We note in the
+                                          // user flags whether we have
+                                          // previously visited a face and
+                                          // if so skip it (consequently,
+                                          // we have to save and later
+                                          // restore the line flags)
+         {
+           std::vector<bool> saved_line_user_flags;
+           const_cast<Triangulation<dim,spacedim>&>(*dof_handler.tria)
+             .save_user_flags_line (saved_line_user_flags);
+           const_cast<Triangulation<dim,spacedim>&>(*dof_handler.tria).clear_user_flags_line ();
+
+                                            // an array to hold how many
+                                            // slots (see the hp::DoFLevel
+                                            // class) we will have to store
+                                            // on each level
+           unsigned int n_line_slots = 0;
+    
+           for (active_cell_iterator cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+             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 it. let's
+                                                    // see how much we need: we need
+                                                    // one set if a) there is no
+                                                    // neighbor behind this face, or
+                                                    // b) the neighbor is either
+                                                    // coarser or finer than we are,
+                                                    // or c) the neighbor is neither
+                                                    // coarser nor finer, but has
+                                                    // happens to have the same
+                                                    // active_fe_index:
+                   if (cell->at_boundary(face)
+                       ||
+                       cell->face(face)->has_children()
+                       ||
+                       cell->neighbor_is_coarser(face)
+                       ||
+                       (!cell->at_boundary(face)
+                        &&
+                        (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+                                                      // ok, one set of
+                                                      // dofs. that makes
+                                                      // one index, 1 times
+                                                      // dofs_per_line
+                                                      // dofs, and one stop
+                                                      // index
+                     n_line_slots
+                       += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line + 2;
+
+                                                    // otherwise we do
+                                                    // indeed need two
+                                                    // sets, i.e. two
+                                                    // indices, two sets of
+                                                    // dofs, and one stop
+                                                    // index:
+                   else
+                     n_line_slots
+                       += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line
+                           +
+                           (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
+                           .dofs_per_line
+                           +
+                           3);
+            
+                                                    // mark this face as
+                                                    // visited
+                   cell->face(face)->set_user_flag ();
+                 }
 
-  template <>
-  DoFHandler<1>::hex_iterator
-  DoFHandler<1>::end_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+                                            // now that we know how many
+                                            // line dofs we will have to
+                                            // have on each level, allocate
+                                            // the memory. note that we
+                                            // allocate offsets for all
+                                            // lines, though only the
+                                            // active ones will have a
+                                            // non-invalid value later on
+           dof_handler.faces->lines.dof_offsets
+             = std::vector<unsigned int> (dof_handler.tria->n_raw_lines(),
+                                          invalid_dof_index);
+           dof_handler.faces->lines.dofs
+             = std::vector<unsigned int> (n_line_slots,
+                                          invalid_dof_index);
+      
+                                            // with the memory now
+                                            // allocated, loop over the
+                                            // dof_handler.cells again and prime the
+                                            // _offset values as well as
+                                            // the fe_index fields
+           const_cast<Triangulation<dim,spacedim>&>(*dof_handler.tria).clear_user_flags_line ();
+
+           unsigned int next_free_line_slot = 0;
+      
+           for (active_cell_iterator cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+             for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+               if (! cell->face(face)->user_flag_set())
+                 {
+                                                    // same decision tree
+                                                    // as before
+                   if (cell->at_boundary(face)
+                       ||
+                       cell->face(face)->has_children()
+                       ||
+                       cell->neighbor_is_coarser(face)
+                       ||
+                       (!cell->at_boundary(face)
+                        &&
+                        (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+                     {
+                       dof_handler.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
+                       dof_handler.faces
+                         ->lines.dofs[next_free_line_slot]
+                         = cell->active_fe_index();
+
+                                                        // the next
+                                                        // dofs_per_line
+                                                        // indices remain
+                                                        // unset for the
+                                                        // moment (i.e. at
+                                                        // invalid_dof_index).
+                                                        // 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
+                         += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line + 2;
+                     }
+                   else
+                     {
+                       dof_handler.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
+                       dof_handler.faces
+                         ->lines.dofs[next_free_line_slot]
+                         = cell->active_fe_index();
+
+                                                        // the next
+                                                        // dofs_per_line
+                                                        // indices remain
+                                                        // unset for the
+                                                        // moment (i.e. at
+                                                        // invalid_dof_index).
+                                                        // 
+                                                        // then comes the
+                                                        // fe_index for the
+                                                        // neighboring
+                                                        // cell:
+                       dof_handler.faces
+                         ->lines.dofs[next_free_line_slot
+                                      +
+                                      (*dof_handler.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
+                         += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line
+                             +
+                             (*dof_handler.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
+           Assert (next_free_line_slot == n_line_slots,
+                   ExcInternalError());
+      
+                                            // at the end, restore the user
+                                            // flags for the lines
+           const_cast<Triangulation<dim,spacedim>&>(*dof_handler.tria)
+             .load_user_flags_line (saved_line_user_flags);
+         }
+    
 
+                                          // VERTEX DOFS
+         reserve_space_vertices (dof_handler);
+       }
+      
 
-  template <>
-  DoFHandler<1>::raw_hex_iterator
-  DoFHandler<1>::end_raw_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+      template <int spacedim>
+      static
+      void
+      reserve_space (DoFHandler<3,spacedim> &dof_handler)
+       {
+         const unsigned int dim = 3;
+    
+         Assert (dof_handler.finite_elements != 0, ExcNoFESelected());
+         Assert (dof_handler.finite_elements->size() > 0, ExcNoFESelected());
+         Assert (dof_handler.tria->n_levels() > 0, ExcInvalidTriangulation());
+         Assert (dof_handler.tria->n_levels() == dof_handler.levels.size (),
+                 ExcInternalError ());
+
+                                          // Release all space except the
+                                          // active_fe_indices field which
+                                          // we have to backup before
+         {
+           std::vector<std::vector<unsigned int> >
+             active_fe_backup(dof_handler.levels.size ());
+           for (unsigned int level = 0; level<dof_handler.levels.size (); ++level)
+             std::swap (dof_handler.levels[level]->active_fe_indices,
+                        active_fe_backup[level]);
+
+                                            // delete all levels and set them up
+                                            // newly, since vectors are
+                                            // troublesome if you want to change
+                                            // their size
+           dof_handler.clear_space ();
+  
+           for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level) 
+             {
+               dof_handler.levels.push_back (new internal::hp::DoFLevel<dim>);
+               std::swap (active_fe_backup[level],
+                          dof_handler.levels[level]->active_fe_indices);
+             }
+           dof_handler.faces = new internal::hp::DoFFaces<3>;
+         }
 
+    
+                                          // HEX (CELL) DOFs
+    
+                                          // count how much space we need
+                                          // on each level for the cell
+                                          // dofs and set the
+                                          // dof_*_offsets
+                                          // data. initially set the latter
+                                          // to an invalid index, and only
+                                          // later set it to something
+                                          // reasonable for active dof_handler.cells
+                                          //
+                                          // note that for dof_handler.cells, the
+                                          // situation is simpler than for
+                                          // other (lower dimensional)
+                                          // objects since exactly one
+                                          // finite element is used for it
+         for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level) 
+           {
+             dof_handler.levels[level]->hexes.dof_offsets
+               = std::vector<unsigned int> (dof_handler.tria->n_raw_hexs(level),
+                                            invalid_dof_index);
+
+             unsigned int next_free_dof = 0;
+             for (active_cell_iterator cell=dof_handler.begin_active(level);
+                  cell!=dof_handler.end_active(level); ++cell)
+               if (!cell->has_children())
+                 {
+                   dof_handler.levels[level]->hexes.dof_offsets[cell->index()] = next_free_dof;
+                   next_free_dof += cell->get_fe().dofs_per_hex;
+                 }
 
-  template <>
-  DoFHandler<1>::active_hex_iterator
-  DoFHandler<1>::end_active_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+             dof_handler.levels[level]->hexes.dofs
+               = std::vector<unsigned int> (next_free_dof, invalid_dof_index);
+           }
 
+                                          // safety check: make sure that
+                                          // the number of DoFs we
+                                          // allocated is actually correct
+                                          // (above we have also set the
+                                          // dof_*_offsets field, so
+                                          // we couldn't use this simpler
+                                          // algorithm)
+#ifdef DEBUG
+         for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+           {
+             unsigned int counter = 0;
+             for (cell_iterator cell=dof_handler.begin_active(level);
+                  cell!=dof_handler.end_active(level); ++cell)
+               if (!cell->has_children())
+                 counter += cell->get_fe().dofs_per_hex;
+        
+             Assert (dof_handler.levels[level]->hexes.dofs.size() == counter,
+                     ExcInternalError());
+             Assert (static_cast<unsigned int>
+                     (std::count (dof_handler.levels[level]->hexes.dof_offsets.begin(),
+                                  dof_handler.levels[level]->hexes.dof_offsets.end(),
+                                  invalid_dof_index))
+                     ==
+                     dof_handler.tria->n_raw_hexs(level) - dof_handler.tria->n_active_hexs(level),
+                     ExcInternalError());
+           }
+#endif
+    
+    
+                                          // QUAD DOFS
+                                          //
+                                          // same here: count quad dofs,
+                                          // then allocate as much space as
+                                          // we need and prime the linked
+                                          // list for quad (see the
+                                          // description in hp::DoFLevels)
+                                          // with the indices we will
+                                          // need. note that our task is
+                                          // more complicated since two
+                                          // adjacent dof_handler.cells may have
+                                          // different active_fe_indices,
+                                          // in which case we need to
+                                          // allocate *two* sets of line
+                                          // dofs for the same line
+                                          //
+                                          // the way we do things is that
+                                          // we loop over all active dof_handler.cells
+                                          // (these are the ones that have
+                                          // DoFs only anyway) and all
+                                          // their dof_handler.faces. We note in the
+                                          // user flags whether we have
+                                          // previously visited a face and
+                                          // if so skip it (consequently,
+                                          // we have to save and later
+                                          // restore the line flags)
+         {
+           std::vector<bool> saved_quad_user_flags;
+           const_cast<Triangulation<dim,spacedim>&>(*dof_handler.tria)
+             .save_user_flags_quad (saved_quad_user_flags);
+           const_cast<Triangulation<dim,spacedim>&>(*dof_handler.tria).clear_user_flags_quad ();
+
+                                            // 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=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+             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
+                                                    // it. let's see how much
+                                                    // we need: we need one
+                                                    // set if a) there is no
+                                                    // neighbor behind this
+                                                    // face, or b) the
+                                                    // neighbor is not on the
+                                                    // same level or further
+                                                    // refined, or c) the
+                                                    // neighbor is on the
+                                                    // same level, but
+                                                    // happens to have the
+                                                    // same active_fe_index:
+                   if (cell->at_boundary(face)
+                       ||
+                       cell->face(face)->has_children()
+                       ||
+                       cell->neighbor_is_coarser(face)
+                       ||
+                       (!cell->at_boundary(face)
+                        &&
+                        (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+                                                      // ok, one set of
+                                                      // dofs. that makes
+                                                      // one index, 1 times
+                                                      // dofs_per_quad
+                                                      // dofs, and one stop
+                                                      // index
+                     n_quad_slots
+                       += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad + 2;
+
+                                                    // otherwise we do
+                                                    // indeed need two
+                                                    // sets, i.e. two
+                                                    // indices, two sets of
+                                                    // dofs, and one stop
+                                                    // index:
+                   else
+                     n_quad_slots
+                       += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad
+                           +
+                           (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
+                           .dofs_per_quad
+                           +
+                           3);
+            
+                                                    // mark this face as
+                                                    // visited
+                   cell->face(face)->set_user_flag ();
+                 }
 
-  template <>
-  DoFHandler<1>::raw_hex_iterator
-  DoFHandler<1>::last_raw_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+                                            // now that we know how many
+                                            // quad dofs we will have to
+                                            // 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
+           if (true) 
+             {
+               dof_handler.faces->quads.dof_offsets
+                 = std::vector<unsigned int> (dof_handler.tria->n_raw_quads(),
+                                              invalid_dof_index);
+               dof_handler.faces->quads.dofs
+                 = std::vector<unsigned int> (n_quad_slots,
+                                              invalid_dof_index);        
+             }
 
+                                            // with the memory now
+                                            // allocated, loop over the
+                                            // dof_handler.cells again and prime the
+                                            // _offset values as well as
+                                            // the fe_index fields
+           const_cast<Triangulation<dim,spacedim>&>(*dof_handler.tria).clear_user_flags_quad ();
 
-  template <>
-  DoFHandler<1>::raw_hex_iterator
-  DoFHandler<1>::last_raw_hex () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+           unsigned int next_free_quad_slot = 0;
+      
+           for (active_cell_iterator cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+             for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+               if (! cell->face(face)->user_flag_set())
+                 {
+                                                    // same decision tree
+                                                    // as before
+                   if (cell->at_boundary(face)
+                       ||
+                       cell->face(face)->has_children()
+                       ||
+                       cell->neighbor_is_coarser(face)
+                       ||
+                       (!cell->at_boundary(face)
+                        &&
+                        (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+                     {
+                       dof_handler.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
+                       dof_handler.faces
+                         ->quads.dofs[next_free_quad_slot]
+                         = cell->active_fe_index();
+
+                                                        // the next
+                                                        // dofs_per_quad
+                                                        // indices remain
+                                                        // unset for the
+                                                        // moment (i.e. at
+                                                        // invalid_dof_index).
+                                                        // 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_quad_slot
+                         += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad + 2;
+                     }
+                   else
+                     {
+                       dof_handler.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
+                       dof_handler.faces
+                         ->quads.dofs[next_free_quad_slot]
+                         = cell->active_fe_index();
+
+                                                        // the next
+                                                        // dofs_per_quad
+                                                        // indices remain
+                                                        // unset for the
+                                                        // moment (i.e. at
+                                                        // invalid_dof_index).
+                                                        // 
+                                                        // then comes the
+                                                        // fe_index for the
+                                                        // neighboring
+                                                        // cell:
+                       dof_handler.faces
+                         ->quads.dofs[next_free_quad_slot
+                                      +
+                                      (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad
+                                      +
+                                      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_quad_slot
+                         += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad
+                             +
+                             (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
+                             .dofs_per_quad
+                             +
+                             3);
+                     }
+              
+                                                    // mark this face as
+                                                    // visited
+                   cell->face(face)->set_user_flag ();
+                 }
 
+                                            // we should have moved the
+                                            // 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
+           const_cast<Triangulation<dim,spacedim>&>(*dof_handler.tria)
+             .load_user_flags_quad (saved_quad_user_flags);
+         }
 
-  template <>
-  DoFHandler<1>::hex_iterator
-  DoFHandler<1>::last_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
 
+                                          // LINE DOFS
 
-  template <>
-  DoFHandler<1>::hex_iterator
-  DoFHandler<1>::last_hex () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+                                          // the situation here is pretty
+                                          // much like with vertices: there
+                                          // can be an arbitrary number of
+                                          // finite elements associated
+                                          // with each line. 
+                                          //
+                                          // the algorithm we use is
+                                          // somewhat similar to what we do
+                                          // in reserve_space_vertices()
+         if (true)
+           {
+                                              // what we do first is to set up
+                                              // an array in which we record
+                                              // whether a line is associated
+                                              // with any of the given fe's, by
+                                              // setting a bit. in a later
+                                              // step, we then actually
+                                              // allocate memory for the
+                                              // required dofs
+             std::vector<std::vector<bool> >
+               line_fe_association (dof_handler.finite_elements->size(),
+                                    std::vector<bool> (dof_handler.tria->n_raw_lines(),
+                                                       false));
+      
+             for (active_cell_iterator cell=dof_handler.begin_active();
+                  cell!=dof_handler.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;
+
+                                              // first check which of the
+                                              // lines is used at all,
+                                              // i.e. is associated with a
+                                              // finite element. we do this
+                                              // since not all lines may
+                                              // actually be used, in which
+                                              // case we do not have to
+                                              // allocate any memory at
+                                              // all
+             std::vector<bool> line_is_used (dof_handler.tria->n_raw_lines(), false);
+             for (unsigned int line=0; line<dof_handler.tria->n_raw_lines(); ++line)
+               for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+                 if (line_fe_association[fe][line] == true)
+                   {
+                     line_is_used[line] = true;
+                     break;
+                   }
+       
+                                              // next count how much memory
+                                              // we actually need. for each
+                                              // line, we need one slot per
+                                              // fe to store the fe_index,
+                                              // plus dofs_per_line for
+                                              // this fe. in addition, we
+                                              // need one slot as the end
+                                              // marker for the
+                                              // fe_indices. at the same
+                                              // time already fill the
+                                              // line_dofs_offsets field
+             dof_handler.faces->lines.dof_offsets
+               .resize (dof_handler.tria->n_raw_lines(),
+                        numbers::invalid_unsigned_int);
+       
+             unsigned int line_slots_needed = 0;
+             for (unsigned int line=0; line<dof_handler.tria->n_raw_lines(); ++line)
+               if (line_is_used[line] == true)
+                 {
+                   dof_handler.faces->lines.dof_offsets[line] = line_slots_needed;
+           
+                   for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+                     if (line_fe_association[fe][line] == true)
+                       line_slots_needed += (*dof_handler.finite_elements)[fe].dofs_per_line + 1;
+                   ++line_slots_needed;
+                 }
 
+                                              // now allocate the space we
+                                              // have determined we need, and
+                                              // set up the linked lists for
+                                              // each of the lines
+             dof_handler.faces->lines.dofs.resize (line_slots_needed, invalid_dof_index);
+             for (unsigned int line=0; line<dof_handler.tria->n_raw_lines(); ++line)
+               if (line_is_used[line] == true)
+                 {
+                   unsigned int pointer = dof_handler.faces->lines.dof_offsets[line];
+                   for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+                     if (line_fe_association[fe][line] == true)
+                       {
+                                                          // if this line
+                                                          // uses this fe,
+                                                          // then set the
+                                                          // fe_index and
+                                                          // move the
+                                                          // pointer ahead
+                         dof_handler.faces->lines.dofs[pointer] = fe;
+                         pointer += (*dof_handler.finite_elements)[fe].dofs_per_line + 1;
+                       }
+                                                    // finally place the end
+                                                    // marker
+                   dof_handler.faces->lines.dofs[pointer] = numbers::invalid_unsigned_int;
+                 }
+           }
 
-  template <>
-  DoFHandler<1>::active_hex_iterator
-  DoFHandler<1>::last_active_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
+    
 
+                                          // VERTEX DOFS
+         reserve_space_vertices (dof_handler);
+       }
 
-  template <>
-  DoFHandler<1>::active_hex_iterator
-  DoFHandler<1>::last_active_hex () const
-  {
-    Assert (false, ExcImpossibleInDim(1));
-    return 0;
-  }
 
-#endif
+                                      /**
+                                       * Implement the function of same name
+                                       * in the mother class.
+                                       */
+      template <int spacedim>
+      static
+      unsigned int
+      max_couplings_between_dofs (const DoFHandler<1,spacedim> &dof_handler)
+       {
+         return std::min(3*dof_handler.finite_elements->max_dofs_per_vertex() +
+                         2*dof_handler.finite_elements->max_dofs_per_line(), dof_handler.n_dofs());
+       }
 
 
-#if deal_II_dimension == 2
 
-  template <>
-  DoFHandler<2>::raw_cell_iterator
-  DoFHandler<2>::begin_raw (const unsigned int level) const
-  {
-    return begin_raw_quad (level);
-  }
+      template <int spacedim>
+      static
+      unsigned int
+      max_couplings_between_dofs (const DoFHandler<2,spacedim> &dof_handler)
+       {
+                                          // get these numbers by drawing pictures
+                                          // and counting...
+                                          // example:
+                                          //   |     |     |
+                                          // --x-----x--x--X--
+                                          //   |     |  |  |
+                                          //   |     x--x--x
+                                          //   |     |  |  |
+                                          // --x--x--*--x--x--
+                                          //   |  |  |     |
+                                          //   x--x--x     |
+                                          //   |  |  |     |
+                                          // --X--x--x-----x--
+                                          //   |     |     |
+                                          // x = vertices connected with center vertex *;
+                                          //   = total of 19
+                                          // (the X vertices are connected with * if
+                                          // the vertices adjacent to X are hanging
+                                          // nodes)
+                                          // count lines -> 28 (don't forget to count
+                                          // mother and children separately!)
+         unsigned int max_couplings;
+         switch (dof_handler.tria->max_adjacent_cells())
+           {
+             case 4:
+                   max_couplings=19*dof_handler.finite_elements->max_dofs_per_vertex() +
+                                 28*dof_handler.finite_elements->max_dofs_per_line() +
+                                 8*dof_handler.finite_elements->max_dofs_per_quad();
+                   break;
+             case 5:
+                   max_couplings=21*dof_handler.finite_elements->max_dofs_per_vertex() +
+                                 31*dof_handler.finite_elements->max_dofs_per_line() +
+                                 9*dof_handler.finite_elements->max_dofs_per_quad();
+                   break;
+             case 6:
+                   max_couplings=28*dof_handler.finite_elements->max_dofs_per_vertex() +
+                                 42*dof_handler.finite_elements->max_dofs_per_line() +
+                                 12*dof_handler.finite_elements->max_dofs_per_quad();
+                   break;
+             case 7:
+                   max_couplings=30*dof_handler.finite_elements->max_dofs_per_vertex() +
+                                 45*dof_handler.finite_elements->max_dofs_per_line() +
+                                 13*dof_handler.finite_elements->max_dofs_per_quad();
+                   break;
+             case 8:
+                   max_couplings=37*dof_handler.finite_elements->max_dofs_per_vertex() +
+                                 56*dof_handler.finite_elements->max_dofs_per_line() +
+                                 16*dof_handler.finite_elements->max_dofs_per_quad();
+                   break;
+             default:
+                   Assert (false, ExcNotImplemented());
+                   max_couplings=0;
+           };
+         return std::min(max_couplings,dof_handler.n_dofs());
+       }
 
 
-  template <>
-  DoFHandler<2>::cell_iterator
-  DoFHandler<2>::begin (const unsigned int level) const
-  {
-    return begin_quad (level);
-  }
+      template <int spacedim>
+      static
+      unsigned int
+      max_couplings_between_dofs (const DoFHandler<3,spacedim> &dof_handler)
+       {
+//TODO:[?] Invent significantly better estimates than the ones in this function  
+                                          // doing the same thing here is a rather
+                                          // complicated thing, compared to the 2d
+                                          // case, since it is hard to draw pictures
+                                          // with several refined hexahedra :-) so I
+                                          // presently only give a coarse estimate
+                                          // for the case that at most 8 hexes meet
+                                          // at each vertex
+                                          //
+                                          // can anyone give better estimate here?
+         const unsigned int max_adjacent_cells = dof_handler.tria->max_adjacent_cells();
+
+         unsigned int max_couplings;
+         if (max_adjacent_cells <= 8)
+           max_couplings=7*7*7*dof_handler.finite_elements->max_dofs_per_vertex() +
+                         7*6*7*3*dof_handler.finite_elements->max_dofs_per_line() +
+                         9*4*7*3*dof_handler.finite_elements->max_dofs_per_quad() +
+                         27*dof_handler.finite_elements->max_dofs_per_hex();
+         else
+           {
+             Assert (false, ExcNotImplemented());
+             max_couplings=0;
+           }
+  
+         return std::min(max_couplings,dof_handler.n_dofs());
+       }
+      
+// xxx      
+  };
 
 
-  template <>
-  DoFHandler<2>::active_cell_iterator
-  DoFHandler<2>::begin_active (const unsigned int level) const
-  {
-    return begin_active_quad (level);
-  }
+  
+  template<int dim, int spacedim>
+  const unsigned int DoFHandler<dim,spacedim>::dimension;
 
+  template<int dim, int spacedim>
+  const unsigned int DoFHandler<dim,spacedim>::invalid_dof_index;
 
-  template <>
-  DoFHandler<2>::raw_cell_iterator
-  DoFHandler<2>::end () const
-  {
-    return end_quad ();
-  }
+  template<int dim, int spacedim>
+  const unsigned int DoFHandler<dim,spacedim>::default_fe_index;
+  
 
 
-  template <>
-  DoFHandler<2>::raw_cell_iterator
-  DoFHandler<2>::last_raw () const
+  template<int dim, int spacedim>
+  DoFHandler<dim,spacedim>::DoFHandler (const Triangulation<dim,spacedim> &tria)
+                  :
+                  tria(&tria),
+                 faces (NULL),
+                  used_dofs (0)
   {
-    return last_raw_quad ();
+    create_active_fe_table ();
+    tria.add_refinement_listener (*this);
   }
 
 
-  template <>
-  DoFHandler<2>::raw_cell_iterator
-  DoFHandler<2>::last_raw (const unsigned int level) const
+  template<int dim, int spacedim>
+  DoFHandler<dim,spacedim>::~DoFHandler ()
   {
-    return last_raw_quad (level);
+                                     // unsubscribe as a listener to refinement
+                                     // of the underlying triangulation
+    tria->remove_refinement_listener (*this);
+  
+                                     // ...and release allocated memory
+    clear ();
   }
 
 
-  template <>
-  DoFHandler<2>::cell_iterator
-  DoFHandler<2>::last () const
-  {
-    return last_quad ();
-  }
-
 
-  template <>
-  DoFHandler<2>::cell_iterator
-  DoFHandler<2>::last (const unsigned int level) const
-  {
-    return last_quad (level);
-  }
+/*------------------------ Cell iterator functions ------------------------*/
 
 
-  template <>
-  DoFHandler<2>::active_cell_iterator
-  DoFHandler<2>::last_active () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_cell_iterator
+  DoFHandler<dim,spacedim>::begin_raw (const unsigned int level) const
   {
-    return last_active_quad ();
+    switch (dim)
+      {
+       case 1:
+             return begin_raw_line (level);
+       case 2:
+             return begin_raw_quad (level);
+       case 3:
+             return begin_raw_hex (level);
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::active_cell_iterator
-  DoFHandler<2>::last_active (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::cell_iterator
+  DoFHandler<dim,spacedim>::begin (const unsigned int level) const
   {
-    return last_active_quad (level);
+    switch (dim)
+      {
+       case 1:
+             return begin_line (level);
+       case 2:
+             return begin_quad (level);
+       case 3:
+             return begin_hex (level);
+       default:
+             Assert (false, ExcImpossibleInDim(dim));
+             return cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::raw_face_iterator
-  DoFHandler<2>::begin_raw_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::active_cell_iterator
+  DoFHandler<dim,spacedim>::begin_active (const unsigned int level) const
   {
-    return begin_raw_line ();
+    switch (dim)
+      {
+       case 1:
+             return begin_active_line (level);
+       case 2:
+             return begin_active_quad (level);
+       case 3:
+             return begin_active_hex (level);
+       default:
+             Assert (false, ExcNotImplemented());
+             return active_cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::face_iterator
-  DoFHandler<2>::begin_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_cell_iterator
+  DoFHandler<dim,spacedim>::last_raw () const
   {
-    return begin_line ();
+    switch (dim)
+      {
+       case 1:
+             return last_raw_line ();
+       case 2:
+             return last_raw_quad ();
+       case 3:
+             return last_raw_hex ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::active_face_iterator
-  DoFHandler<2>::begin_active_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_cell_iterator
+  DoFHandler<dim,spacedim>::last_raw (const unsigned int level) const
   {
-    return begin_active_line ();
+    switch (dim)
+      {
+       case 1:
+             return last_raw_line (level);
+       case 2:
+             return last_raw_quad (level);
+       case 3:
+             return last_raw_hex (level);
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::raw_face_iterator
-  DoFHandler<2>::end_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::cell_iterator
+  DoFHandler<dim,spacedim>::last () const
   {
-    return end_line ();
+    switch (dim)
+      {
+       case 1:
+             return last_line ();
+       case 2:
+             return last_quad ();
+       case 3:
+             return last_hex ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::raw_face_iterator
-  DoFHandler<2>::end_raw_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::cell_iterator
+  DoFHandler<dim,spacedim>::last (const unsigned int level) const
   {
-    return end_line ();
+    switch (dim)
+      {
+       case 1:
+             return last_line (level);
+       case 2:
+             return last_quad (level);
+       case 3:
+             return last_hex (level);
+       default:
+             Assert (false, ExcNotImplemented());
+             return cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::active_face_iterator
-  DoFHandler<2>::end_active_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::active_cell_iterator
+  DoFHandler<dim,spacedim>::last_active () const
   {
-    return end_line ();
+    switch (dim)
+      {
+       case 1:
+             return last_active_line ();
+       case 2:
+             return last_active_quad ();
+       case 3:
+             return last_active_hex ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return active_cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::raw_face_iterator
-  DoFHandler<2>::last_raw_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::active_cell_iterator
+  DoFHandler<dim,spacedim>::last_active (const unsigned int level) const
   {
-    return last_raw_line ();
+    switch (dim)
+      {
+       case 1:
+             return last_active_line (level);
+       case 2:
+             return last_active_quad (level);
+       case 3:
+             return last_active_hex (level);
+       default:
+             Assert (false, ExcNotImplemented());
+             return active_cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::face_iterator
-  DoFHandler<2>::last_face () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_cell_iterator
+  DoFHandler<dim,spacedim>::end () const
   {
-    return last_line ();
+    switch (dim)
+      {
+       case 1:
+             return end_line();
+       case 2:
+             return end_quad();
+       case 3:
+             return end_hex();
+       default:
+             Assert (false, ExcImpossibleInDim(dim));
+             return raw_cell_iterator();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::active_face_iterator
-  DoFHandler<2>::last_active_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_cell_iterator
+  DoFHandler<dim, spacedim>::end_raw (const unsigned int level) const
   {
-    return last_active_line ();
+    return (level == tria->n_levels()-1 ?
+           end() :
+           begin_raw (level+1));
   }
 
 
-  template <>
-  DoFHandler<2>::raw_hex_iterator
-  DoFHandler<2>::begin_raw_hex (const unsigned int) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::cell_iterator
+  DoFHandler<dim, spacedim>::end (const unsigned int level) const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    return (level == tria->n_levels()-1 ?
+           cell_iterator(end()) :
+           begin (level+1));
   }
 
 
-  template <>
-  DoFHandler<2>::hex_iterator
-  DoFHandler<2>::begin_hex (const unsigned int) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_cell_iterator
+  DoFHandler<dim, spacedim>::end_active (const unsigned int level) const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    return (level == tria->n_levels()-1 ?
+           active_cell_iterator(end()) :
+           begin_active (level+1));
   }
 
 
-  template <>
-  DoFHandler<2>::active_hex_iterator
-  DoFHandler<2>::begin_active_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
-  }
+/*------------------------ Face iterator functions ------------------------*/
 
 
-  template <>
-  DoFHandler<2>::raw_hex_iterator
-  DoFHandler<2>::end_hex () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_face_iterator
+  DoFHandler<dim,spacedim>::begin_raw_face () const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    switch (dim)
+      {
+       case 1:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_face_iterator();
+       case 2:
+             return begin_raw_line ();
+       case 3:
+             return begin_raw_quad ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_face_iterator ();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::hex_iterator
-  DoFHandler<2>::end_hex (const unsigned int) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::face_iterator
+  DoFHandler<dim,spacedim>::begin_face () const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    switch (dim)
+      {
+       case 1:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_face_iterator();
+       case 2:
+             return begin_line ();
+       case 3:
+             return begin_quad ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return face_iterator ();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::raw_hex_iterator
-  DoFHandler<2>::end_raw_hex (const unsigned int) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::active_face_iterator
+  DoFHandler<dim,spacedim>::begin_active_face () const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    switch (dim)
+      {
+       case 1:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_face_iterator();
+       case 2:
+             return begin_active_line ();
+       case 3:
+             return begin_active_quad ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return active_face_iterator ();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::active_hex_iterator
-  DoFHandler<2>::end_active_hex (const unsigned int) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_face_iterator
+  DoFHandler<dim, spacedim>::end_raw_face () const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    return end_face();
   }
 
 
-  template <>
-  DoFHandler<2>::raw_hex_iterator
-  DoFHandler<2>::last_raw_hex (const unsigned int) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_face_iterator
+  DoFHandler<dim,spacedim>::end_face () const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    switch (dim)
+      {
+       case 1:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_face_iterator();
+       case 2:
+             return end_line ();
+       case 3:
+             return end_quad ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_face_iterator ();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::raw_hex_iterator
-  DoFHandler<2>::last_raw_hex () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_face_iterator
+  DoFHandler<dim, spacedim>::end_active_face () const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    return active_face_iterator(end_face());
   }
 
 
-  template <>
-  DoFHandler<2>::hex_iterator
-  DoFHandler<2>::last_hex (const unsigned int) const
-  {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
-  }
 
 
-  template <>
-  DoFHandler<2>::hex_iterator
-  DoFHandler<2>::last_hex () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_face_iterator
+  DoFHandler<dim,spacedim>::last_raw_face () const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    switch (dim)
+      {
+       case 1:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_face_iterator();
+       case 2:
+             return last_raw_line ();
+       case 3:
+             return last_raw_quad ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_face_iterator ();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::active_hex_iterator
-  DoFHandler<2>::last_active_hex (const unsigned int) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::face_iterator
+  DoFHandler<dim,spacedim>::last_face () const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    switch (dim)
+      {
+       case 1:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_face_iterator();
+       case 2:
+             return last_line ();
+       case 3:
+             return last_quad ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_face_iterator ();
+      }
   }
 
 
-  template <>
-  DoFHandler<2>::active_hex_iterator
-  DoFHandler<2>::last_active_hex () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::active_face_iterator
+  DoFHandler<dim,spacedim>::last_active_face () const
   {
-    Assert (false, ExcImpossibleInDim(2));
-    return 0;
+    switch (dim)
+      {
+       case 1:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_face_iterator();
+       case 2:
+             return last_active_line ();
+       case 3:
+             return last_active_quad ();
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_face_iterator ();
+      }
   }
 
 
-#endif
+/*------------------------ Line iterator functions ------------------------*/
 
 
-#if deal_II_dimension == 3
 
-  template <>
-  DoFHandler<3>::raw_cell_iterator
-  DoFHandler<3>::begin_raw (const unsigned int level) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_line_iterator
+  DoFHandler<dim, spacedim>::begin_raw_line (const unsigned int level) const
   {
-    return begin_raw_hex (level);
+    switch (dim)
+      {
+       case 1:
+             Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+
+             if (tria->n_raw_lines(level) == 0)
+               return end_line ();
+
+             return raw_line_iterator (tria,
+                                       level,
+                                       0,
+                                       this);
+
+       default:
+             Assert (level == 0, ExcFacesHaveNoLevel());
+             return raw_line_iterator (tria,
+                                       0,
+                                       0,
+                                       this);
+      }
   }
 
 
-  template <>
-  DoFHandler<3>::cell_iterator
-  DoFHandler<3>::begin (const unsigned int level) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::line_iterator
+  DoFHandler<dim, spacedim>::begin_line (const unsigned int level) const
   {
-    return begin_hex (level);
+                                    // level is checked in begin_raw
+    raw_line_iterator ri = begin_raw_line (level);
+    if (ri.state() != IteratorState::valid)
+      return ri;
+    while (ri->used() == false)
+      if ((++ri).state() != IteratorState::valid)
+       return ri;
+    return ri;
   }
 
 
-  template <>
-  DoFHandler<3>::active_cell_iterator
-  DoFHandler<3>::begin_active (const unsigned int level) const
-  {
-    return begin_active_hex (level);
-  }
-
 
-  template <>
-  DoFHandler<3>::raw_cell_iterator
-  DoFHandler<3>::end () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_line_iterator
+  DoFHandler<dim, spacedim>::begin_active_line (const unsigned int level) const
   {
-    return end_hex ();
+                                    // level is checked in begin_raw
+    line_iterator i = begin_line (level);
+    if (i.state() != IteratorState::valid)
+      return i;
+    while (i->has_children())
+      if ((++i).state() != IteratorState::valid)
+       return i;
+    return i;
   }
 
 
-  template <>
-  DoFHandler<3>::raw_cell_iterator
-  DoFHandler<3>::last_raw () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_line_iterator
+  DoFHandler<dim, spacedim>::end_line () const
   {
-    return last_raw_hex ();
+    return raw_line_iterator (tria,
+                             -1,
+                             -1,
+                             this);
   }
 
 
-  template <>
-  DoFHandler<3>::raw_cell_iterator
-  DoFHandler<3>::last_raw (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_line_iterator
+  DoFHandler<dim, spacedim>::last_raw_line (const unsigned int level) const
   {
-    return last_raw_hex (level);
+    switch (dim)
+      {
+       case 1:
+             Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+             Assert (tria->n_raw_lines(level) != 0,
+                     ExcEmptyLevel (level));
+
+             return raw_line_iterator (tria,
+                                       level,
+                                       tria->n_raw_lines(level)-1,
+                                       this);
+
+       default:
+             Assert (level == 0, ExcFacesHaveNoLevel());
+             return raw_line_iterator (tria,
+                                       0,
+                                       tria->n_raw_lines()-1,
+                                       this);
+      }
   }
 
 
-  template <>
-  DoFHandler<3>::cell_iterator
-  DoFHandler<3>::last () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_line_iterator
+  DoFHandler<dim, spacedim>::last_raw_line () const
   {
-    return last_hex ();
+    if (dim == 1)
+      return last_raw_line (tria->n_levels()-1);
+    else
+      return last_raw_line (0);
   }
 
 
-  template <>
-  DoFHandler<3>::cell_iterator
-  DoFHandler<3>::last (const unsigned int level) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::line_iterator
+  DoFHandler<dim, spacedim>::last_line (const unsigned int level) const
   {
-    return last_hex (level);
+                                    // level is checked in last_raw
+    raw_line_iterator ri = last_raw_line(level);
+    if (ri->used()==true)
+      return ri;
+    while ((--ri).state() == IteratorState::valid)
+      if (ri->used()==true)
+       return ri;
+    return ri;
   }
 
 
-  template <>
-  DoFHandler<3>::active_cell_iterator
-  DoFHandler<3>::last_active () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::line_iterator
+  DoFHandler<dim, spacedim>::last_line () const
   {
-    return last_active_hex ();
+    if (dim == 1)
+      return last_line (tria->n_levels()-1);
+    else
+      return last_line (0);
   }
 
 
-  template <>
-  DoFHandler<3>::active_cell_iterator
-  DoFHandler<3>::last_active (const unsigned int level) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_line_iterator
+  DoFHandler<dim, spacedim>::last_active_line (const unsigned int level) const
   {
-    return last_active_hex (level);
+                                    // level is checked in last_raw
+    line_iterator i = last_line(level);
+    if (i->has_children()==false)
+      return i;
+    while ((--i).state() == IteratorState::valid)
+      if (i->has_children()==false)
+       return i;
+    return i;
   }
 
 
-  template <>
-  DoFHandler<3>::raw_face_iterator
-  DoFHandler<3>::begin_raw_face () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_line_iterator
+  DoFHandler<dim, spacedim>::last_active_line () const
   {
-    return begin_raw_quad ();
+    if (dim == 1)
+      return last_active_line (tria->n_levels()-1);
+    else
+      return last_active_line (0);
   }
 
 
-  template <>
-  DoFHandler<3>::face_iterator
-  DoFHandler<3>::begin_face () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_line_iterator
+  DoFHandler<dim, spacedim>::end_raw_line (const unsigned int level) const
   {
-    return begin_quad ();
+    Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
+    if (dim == 1)
+      return (level == tria->n_levels()-1 ?
+             end_line() :
+             begin_raw_line (level+1));
+    else
+      return end_line();
   }
 
 
-  template <>
-  DoFHandler<3>::active_face_iterator
-  DoFHandler<3>::begin_active_face () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::line_iterator
+  DoFHandler<dim, spacedim>::end_line (const unsigned int level) const
   {
-    return begin_active_quad ();
+    Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
+    if (dim == 1)
+      return (level == tria->n_levels()-1 ?
+             line_iterator(end_line()) :
+             begin_line (level+1));
+    else
+      return line_iterator(end_line());
   }
 
 
-  template <>
-  DoFHandler<3>::raw_face_iterator
-  DoFHandler<3>::end_face () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_line_iterator
+  DoFHandler<dim, spacedim>::end_active_line (const unsigned int level) const
   {
-    return end_quad ();
+    Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
+    if (dim == 1)
+      return (level == tria->n_levels()-1 ?
+             active_line_iterator(end_line()) :
+             begin_active_line (level+1));
+    else
+      return active_line_iterator(end_line());
   }
 
 
-  template <>
-  DoFHandler<3>::raw_face_iterator
-  DoFHandler<3>::end_raw_face () const
-  {
-    return end_quad ();
-  }
 
+/*------------------------ Quad iterator functions ------------------------*/
 
-  template <>
-  DoFHandler<3>::active_face_iterator
-  DoFHandler<3>::end_active_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_quad_iterator
+  DoFHandler<dim,spacedim>::begin_raw_quad (const unsigned int level) const
   {
-    return end_quad ();
-  }
+    switch (dim)
+      {
+       case 1:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_hex_iterator();
+       case 2:
+       {
+         Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+
+         if (tria->n_raw_quads(level) == 0)
+           return end_quad();
+  
+         return raw_quad_iterator (tria,
+                                   level,
+                                   0,
+                                   this);
+       }
 
+       case 3:
+       {
+         Assert (level == 0, ExcFacesHaveNoLevel());
 
-  template <>
-  DoFHandler<3>::raw_face_iterator
-  DoFHandler<3>::last_raw_face () const
-  {
-    return last_raw_quad ();
+         return raw_quad_iterator (tria,
+                                   0,
+                                   0,
+                                   this);
+       }
+      
+      
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_hex_iterator();            
+      }
   }
 
 
-  template <>
-  DoFHandler<3>::face_iterator
-  DoFHandler<3>::last_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::quad_iterator
+  DoFHandler<dim,spacedim>::begin_quad (const unsigned int level) const
   {
-    return last_quad ();
+                                    // level is checked in begin_raw
+    raw_quad_iterator ri = begin_raw_quad (level);
+    if (ri.state() != IteratorState::valid)
+      return ri;
+    while (ri->used() == false)
+      if ((++ri).state() != IteratorState::valid)
+       return ri;
+    return ri;
   }
 
 
-  template <>
-  DoFHandler<3>::active_face_iterator
-  DoFHandler<3>::last_active_face () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::active_quad_iterator
+  DoFHandler<dim,spacedim>::begin_active_quad (const unsigned int level) const
   {
-    return last_active_quad ();
+                                    // level is checked in begin_raw
+    quad_iterator i = begin_quad (level);
+    if (i.state() != IteratorState::valid)
+      return i;
+    while (i->has_children())
+      if ((++i).state() != IteratorState::valid)
+       return i;
+    return i;
   }
 
 
-#endif
-
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_line_iterator
-  DoFHandler<dim>::begin_raw_line (const unsigned int level) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_quad_iterator
+  DoFHandler<dim, spacedim>::end_raw_quad (const unsigned int level) const
   {
-    Assert (dim==1 || level == 0,
-           typename Triangulation<dim>::ExcFacesHaveNoLevel());
-    return raw_line_iterator (tria,
-                              dim==1 ? tria->begin_raw_line(level)->level() : 0,
-                              tria->begin_raw_line(level)->index(),
-                              this);
+    Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
+    if (dim == 2)
+      return (level == tria->n_levels()-1 ?
+             end_quad() :
+             begin_raw_quad (level+1));
+    else
+      return end_quad();
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::line_iterator
-  DoFHandler<dim>::begin_line (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::quad_iterator
+  DoFHandler<dim, spacedim>::end_quad (const unsigned int level) const
   {
-    Assert (dim==1 || level == 0,
-           typename Triangulation<dim>::ExcFacesHaveNoLevel());
-    return line_iterator (tria,
-                          dim==1 ? tria->begin_line(level)->level() : 0,
-                          tria->begin_line(level)->index(),
-                          this);
+    Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
+    if (dim == 2)
+      return (level == tria->n_levels()-1 ?
+             quad_iterator(end_quad()) :
+             begin_quad (level+1));
+    else
+      return quad_iterator(end_quad());  
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_line_iterator
-  DoFHandler<dim>::begin_active_line (const unsigned int level) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_quad_iterator
+  DoFHandler<dim, spacedim>::end_active_quad (const unsigned int level) const
   {
-    Assert (dim==1 || level == 0,
-           typename Triangulation<dim>::ExcFacesHaveNoLevel());
-    return active_line_iterator (tria,
-                                 dim==1 ? tria->begin_active_line(level)->level() : 0,
-                                 tria->begin_active_line(level)->index(),
-                                 this);
+    Assert(dim == 2 || level == 0, ExcFacesHaveNoLevel());
+    if (dim == 2)
+      return (level == tria->n_levels()-1 ?
+             active_quad_iterator(end_quad()) :
+             begin_active_quad (level+1));
+    else
+      return active_quad_iterator(end_quad());
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_quad_iterator
-  DoFHandler<dim>::begin_raw_quad (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_quad_iterator
+  DoFHandler<dim,spacedim>::end_quad () const
   {
-    Assert (dim==2 || level == 0,
-           typename Triangulation<dim>::ExcFacesHaveNoLevel());  
     return raw_quad_iterator (tria,
-                              dim==2 ? tria->begin_raw_quad(level)->level() : 0,
-                              tria->begin_raw_quad(level)->index(),
-                              this);
+                             -1,
+                             -1,
+                             this);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::quad_iterator
-  DoFHandler<dim>::begin_quad (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_quad_iterator
+  DoFHandler<dim,spacedim>::last_raw_quad (const unsigned int level) const
   {
-    Assert (dim==2 || level == 0,
-           typename Triangulation<dim>::ExcFacesHaveNoLevel());  
-    return quad_iterator (tria,
-                          dim==2 ? tria->begin_quad(level)->level() : 0,
-                          tria->begin_quad(level)->index(),
-                          this);
+    switch (dim)
+      {
+       case 1:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_quad_iterator();
+       case 2:
+             Assert (level<tria->n_levels(),
+                     ExcInvalidLevel(level));
+             Assert (tria->n_raw_quads(level) != 0,
+                     ExcEmptyLevel (level));
+             return raw_quad_iterator (tria,
+                                       level,
+                                       tria->n_raw_quads(level)-1,
+                                       this);
+       case 3:
+             Assert (level == 0, ExcFacesHaveNoLevel());
+             return raw_quad_iterator (tria,
+                                       0,
+                                       tria->n_raw_quads()-1,
+                                       this);
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_quad_iterator();
+      }      
+  }
+
+
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_quad_iterator
+  DoFHandler<dim,spacedim>::last_raw_quad () const
+  {
+    if (dim == 2)
+      return last_raw_quad (tria->n_levels()-1);
+    else
+      return last_raw_quad (0);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_quad_iterator
-  DoFHandler<dim>::begin_active_quad (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::quad_iterator
+  DoFHandler<dim,spacedim>::last_quad (const unsigned int level) const
   {
-    Assert (dim==2 || level == 0,
-           typename Triangulation<dim>::ExcFacesHaveNoLevel());  
-    return active_quad_iterator (tria,
-                                 dim==2 ? tria->begin_active_quad(level)->level() : 0,
-                                 tria->begin_active_quad(level)->index(),
-                                 this);
+                                    // level is checked in last_raw
+    raw_quad_iterator ri = last_raw_quad(level);
+    if (ri->used()==true)
+      return ri;
+    while ((--ri).state() == IteratorState::valid)
+      if (ri->used()==true)
+       return ri;
+    return ri;
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_hex_iterator
-  DoFHandler<dim>::begin_raw_hex (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::quad_iterator
+  DoFHandler<dim,spacedim>::last_quad () const
   {
-    return raw_hex_iterator (tria,
-                             tria->begin_raw_hex(level)->level(),
-                             tria->begin_raw_hex(level)->index(),
-                             this);
+    if (dim == 2)
+      return last_quad (tria->n_levels()-1);
+    else
+      return last_quad (0);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::hex_iterator
-  DoFHandler<dim>::begin_hex (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::active_quad_iterator
+  DoFHandler<dim,spacedim>::last_active_quad (const unsigned int level) const
   {
-    return hex_iterator (tria,
-                         tria->begin_hex(level)->level(),
-                         tria->begin_hex(level)->index(),
-                         this);
+                                    // level is checked in last_raw
+    quad_iterator i = last_quad(level);
+    if (i->has_children()==false)
+      return i;
+    while ((--i).state() == IteratorState::valid)
+      if (i->has_children()==false)
+       return i;
+    return i;
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_hex_iterator
-  DoFHandler<dim>::begin_active_hex (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::active_quad_iterator
+  DoFHandler<dim,spacedim>::last_active_quad () const
   {
-    return active_hex_iterator (tria,
-                                tria->begin_active_hex(level)->level(),
-                                tria->begin_active_hex(level)->index(),
-                                this);
+    if (dim == 2)
+      return last_active_quad (tria->n_levels()-1);
+    else
+      return last_active_quad (0);
   }
 
 
-                                  // 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
-  {
-    return raw_line_iterator (tria, -1, -1, this);
-  }
+/*------------------------ Hex iterator functions ------------------------*/
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_quad_iterator
-  DoFHandler<dim>::end_quad () const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::raw_hex_iterator
+  DoFHandler<dim,spacedim>::begin_raw_hex (const unsigned int level) const
   {
-    return raw_quad_iterator (tria, -1, -1, this);
+    switch (dim)
+      {
+       case 1:
+       case 2:
+             Assert (false, ExcImpossibleInDim(1));
+             return raw_hex_iterator();
+       case 3:
+       {
+         Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+
+         if (tria->n_raw_hexs(level) == 0)
+           return end_hex();
+  
+         return raw_hex_iterator (tria,
+                                  level,
+                                  0,
+                                  this);
+       }
+      
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_hex_iterator();            
+      }
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_hex_iterator
-  DoFHandler<dim>::end_hex () const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim,spacedim>::hex_iterator
+  DoFHandler<dim,spacedim>::begin_hex (const unsigned int level) const
   {
-    return raw_hex_iterator (tria, -1, -1, this);
+                                    // level is checked in begin_raw
+    raw_hex_iterator ri = begin_raw_hex (level);
+    if (ri.state() != IteratorState::valid)
+      return ri;
+    while (ri->used() == false)
+      if ((++ri).state() != IteratorState::valid)
+       return ri;
+    return ri;
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_cell_iterator
-  DoFHandler<dim>::end_raw (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_hex_iterator
+  DoFHandler<dim, spacedim>::begin_active_hex (const unsigned int level) const
   {
-    return (level == levels.size()-1 ?
-            end() :
-            begin_raw (level+1));
+                                    // level is checked in begin_raw
+    hex_iterator i = begin_hex (level);
+    if (i.state() != IteratorState::valid)
+      return i;
+    while (i->has_children())
+      if ((++i).state() != IteratorState::valid)
+       return i;
+    return i;
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::cell_iterator
-  DoFHandler<dim>::end (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_hex_iterator
+  DoFHandler<dim, spacedim>::end_raw_hex (const unsigned int level) const
   {
-    return (level == levels.size()-1 ?
-            cell_iterator(end()) :
-            begin (level+1));
+    return (level == tria->n_levels()-1 ?
+           end_hex() :
+           begin_raw_hex (level+1));
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_cell_iterator
-  DoFHandler<dim>::end_active (const unsigned int level) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::hex_iterator
+  DoFHandler<dim, spacedim>::end_hex (const unsigned int level) const
   {
-    return (level == levels.size()-1 ?
-            active_cell_iterator(end()) :
-            begin_active (level+1));
+    return (level == tria->n_levels()-1 ?
+           hex_iterator(end_hex()) :
+           begin_hex (level+1));
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_line_iterator
-  DoFHandler<dim>::end_raw_line (const unsigned int level) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_hex_iterator
+  DoFHandler<dim, spacedim>::end_active_hex (const unsigned int level) const
   {
-    return raw_line_iterator(tria,
-                            tria->end_raw_line(level)->level(),
-                            tria->end_raw_line(level)->index(),
-                            this);
+    return (level == tria->n_levels()-1 ?
+           active_hex_iterator(end_hex()) :
+           begin_active_hex (level+1));
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::line_iterator
-  DoFHandler<dim>::end_line (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_hex_iterator
+  DoFHandler<dim, spacedim>::end_hex () const
   {
-    return line_iterator(tria,
-                        tria->end_line(level)->level(),
-                        tria->end_line(level)->index(),
-                        this);
+    return raw_hex_iterator (tria,
+                            -1,
+                            -1,
+                            this);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_line_iterator
-  DoFHandler<dim>::end_active_line (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_hex_iterator
+  DoFHandler<dim, spacedim>::last_raw_hex (const unsigned int level) const
   {
-    return active_line_iterator(tria,
-                               tria->end_active_line(level)->level(),
-                               tria->end_active_line(level)->index(),
-                               this);
+    switch (dim)
+      {
+       case 1:
+       case 2:
+             Assert (false, ExcImpossibleInDim(dim));
+             return raw_hex_iterator();
+
+       case 3:
+             Assert (level<tria->n_levels(),
+                     ExcInvalidLevel(level));
+             Assert (tria->n_raw_hexs(level) != 0,
+                     ExcEmptyLevel (level));
+
+             return raw_hex_iterator (tria,
+                                      level,
+                                      tria->n_raw_hexs(level)-1,
+                                      this);
+       default:
+             Assert (false, ExcNotImplemented());
+             return raw_hex_iterator();
+      }
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_quad_iterator
-  DoFHandler<dim>::end_raw_quad (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::raw_hex_iterator
+  DoFHandler<dim, spacedim>::last_raw_hex () const
   {
-    return raw_quad_iterator(tria,
-                            tria->end_raw_quad(level)->level(),
-                            tria->end_raw_quad(level)->index(),
-                            this);
+    return last_raw_hex (tria->n_levels()-1);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::quad_iterator
-  DoFHandler<dim>::end_quad (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::hex_iterator
+  DoFHandler<dim, spacedim>::last_hex (const unsigned int level) const
   {
-    return quad_iterator(tria,
-                        tria->end_quad(level)->level(),
-                        tria->end_quad(level)->index(),
-                        this);
+                                    // level is checked in last_raw
+    raw_hex_iterator ri = last_raw_hex(level);
+    if (ri->used()==true)
+      return ri;
+    while ((--ri).state() == IteratorState::valid)
+      if (ri->used()==true)
+       return ri;
+    return ri;
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_quad_iterator
-  DoFHandler<dim>::end_active_quad (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::hex_iterator
+  DoFHandler<dim, spacedim>::last_hex () const
   {
-    return active_quad_iterator(tria,
-                               tria->end_active_quad(level)->level(),
-                               tria->end_active_quad(level)->index(),
-                               this);
+    return last_hex (tria->n_levels()-1);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_hex_iterator
-  DoFHandler<dim>::end_raw_hex (const unsigned int level) const
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_hex_iterator
+  DoFHandler<dim, spacedim>::last_active_hex (const unsigned int level) const
   {
-    return raw_hex_iterator(tria,
-                           tria->end_raw_hex(level)->level(),
-                           tria->end_raw_hex(level)->index(),
-                           this);
+                                    // level is checked in last_raw
+    hex_iterator i = last_hex(level);
+    if (i->has_children()==false)
+      return i;
+    while ((--i).state() == IteratorState::valid)
+      if (i->has_children()==false)
+       return i;
+    return i;
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::hex_iterator
-  DoFHandler<dim>::end_hex (const unsigned int level) const
+
+  template <int dim, int spacedim>
+  typename DoFHandler<dim, spacedim>::active_hex_iterator
+  DoFHandler<dim, spacedim>::last_active_hex () const
   {
-    return hex_iterator(tria,
-                       tria->end_hex(level)->level(),
-                       tria->end_hex(level)->index(),
-                       this);
+    return last_active_hex (tria->n_levels()-1);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_hex_iterator
-  DoFHandler<dim>::end_active_hex (const unsigned int level) const
-  {
-    return active_hex_iterator(tria,
-                              tria->end_active_hex(level)->level(),
-                              tria->end_active_hex(level)->index(),
-                              this);
-  }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_line_iterator
-  DoFHandler<dim>::last_raw_line (const unsigned int level) const
+
+//------------------------------------------------------------------
+#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 raw_line_iterator (tria,
-                              tria->last_raw_line(level)->level(),
-                              tria->last_raw_line(level)->index(),
-                              this);
+    return this->levels[obj_level]->lines.
+      get_dof_index (*this,
+                    obj_index,
+                    fe_index,
+                    local_index,
+                    obj_level);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::line_iterator
-  DoFHandler<dim>::last_line (const unsigned int level) const
+  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
   {
-    return line_iterator (tria,
-                          tria->last_line(level)->level(),
-                          tria->last_line(level)->index(),
-                          this);
+    this->levels[obj_level]->lines.
+      set_dof_index (*this,
+                    obj_index,
+                    fe_index,
+                    local_index,
+                    global_index,
+                    obj_level);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_line_iterator
-  DoFHandler<dim>::last_active_line (const unsigned int level) const
+  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 active_line_iterator (tria,
-                                 tria->last_active_line(level)->level(),
-                                 tria->last_active_line(level)->index(),
-                                 this);
+    return this->levels[obj_level]->lines.fe_index_is_active(*this,
+                                                            obj_index,
+                                                            fe_index,
+                                                            obj_level);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_quad_iterator
-  DoFHandler<dim>::last_raw_quad (const unsigned int level) const
+  template <>
+  template <>
+  unsigned int
+  DoFHandler<1>::n_active_fe_indices<1> (const unsigned int obj_level,
+                                        const unsigned int obj_index) const
   {
-    return raw_quad_iterator (tria,
-                              tria->last_raw_quad(level)->level(),
-                              tria->last_raw_quad(level)->index(),
-                              this);
+    return this->levels[obj_level]->lines.n_active_fe_indices (*this,
+                                                              obj_index);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::quad_iterator
-  DoFHandler<dim>::last_quad (const unsigned int level) const
-  {
-    return quad_iterator (tria,
-                          tria->last_quad(level)->level(),
-                          tria->last_quad(level)->index(),
-                          this);
-  }
-
 
-  template <int dim>
-  typename DoFHandler<dim>::active_quad_iterator
-  DoFHandler<dim>::last_active_quad (const unsigned int level) const
+  template <>
+  template <>
+  unsigned int
+  DoFHandler<1>::nth_active_fe_index<1> (const unsigned int obj_level,
+                                        const unsigned int obj_index,
+                                        const unsigned int n) const
   {
-    return active_quad_iterator (tria,
-                                 tria->last_active_quad(level)->level(),
-                                 tria->last_active_quad(level)->index(),
-                                 this);
+    return this->levels[obj_level]->lines.nth_active_fe_index (*this,
+                                                              obj_level,
+                                                              obj_index,
+                                                              n);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_hex_iterator
-  DoFHandler<dim>::last_raw_hex (const unsigned int level) const
-  {
-    return raw_hex_iterator (tria,
-                             tria->last_raw_hex(level)->level(),
-                             tria->last_raw_hex(level)->index(),
-                             this);
-  }
-
 
-  template <int dim>
-  typename DoFHandler<dim>::hex_iterator
-  DoFHandler<dim>::last_hex (const unsigned int level) const
+  template <>
+  template <>
+  unsigned int
+  DoFHandler<1,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 hex_iterator (tria,
-                         tria->last_hex(level)->level(),
-                         tria->last_hex(level)->index(),
-                         this);
+    return this->levels[obj_level]->lines.
+      get_dof_index (*this,
+                    obj_index,
+                    fe_index,
+                    local_index,
+                    obj_level);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_hex_iterator
-  DoFHandler<dim>::last_active_hex (const unsigned int level) const
+  template <>
+  template <>
+  void
+  DoFHandler<1,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
   {
-    return active_hex_iterator (tria,
-                                tria->last_active_hex(level)->level(),
-                                tria->last_active_hex(level)->index(),
-                                this);
+    this->levels[obj_level]->lines.
+      set_dof_index (*this,
+                    obj_index,
+                    fe_index,
+                    local_index,
+                    global_index,
+                    obj_level);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_line_iterator
-  DoFHandler<dim>::last_raw_line () const
+  template <>
+  template <>
+  bool
+  DoFHandler<1,2>::fe_index_is_active<1> (const unsigned int obj_level,
+                                       const unsigned int obj_index,
+                                       const unsigned int fe_index) const
   {
-    return raw_line_iterator (tria,
-                             tria->last_raw_line()->level(),
-                             tria->last_raw_line()->index(),
-                             this);
+    return this->levels[obj_level]->lines.fe_index_is_active(*this,
+                                                            obj_index,
+                                                            fe_index,
+                                                            obj_level);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_quad_iterator
-  DoFHandler<dim>::last_raw_quad () const
+  template <>
+  template <>
+  unsigned int
+  DoFHandler<1,2>::n_active_fe_indices<1> (const unsigned int obj_level,
+                                        const unsigned int obj_index) const
   {
-    return raw_quad_iterator (tria,
-                             tria->last_raw_quad()->level(),
-                             tria->last_raw_quad()->index(),
-                             this);
+    return this->levels[obj_level]->lines.n_active_fe_indices (*this,
+                                                              obj_index);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::raw_hex_iterator
-  DoFHandler<dim>::last_raw_hex () const
-  {
-    return raw_hex_iterator (tria,
-                            tria->last_raw_hex()->level(),
-                            tria->last_raw_hex()->index(),
-                            this);
-  }
-
 
-  template <int dim>
-  typename DoFHandler<dim>::line_iterator
-  DoFHandler<dim>::last_line () const
+  template <>
+  template <>
+  unsigned int
+  DoFHandler<1,2>::nth_active_fe_index<1> (const unsigned int obj_level,
+                                        const unsigned int obj_index,
+                                        const unsigned int n) const
   {
-    return line_iterator (tria,
-                         tria->last_line()->level(),
-                         tria->last_line()->index(),
-                         this);
+    return this->levels[obj_level]->lines.nth_active_fe_index (*this,
+                                                              obj_level,
+                                                              obj_index,
+                                                              n);
   }
 
+#endif
+
 
-  template <int dim>
-  typename DoFHandler<dim>::quad_iterator
-  DoFHandler<dim>::last_quad () const
+#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 quad_iterator (tria,
-                         tria->last_quad()->level(),
-                         tria->last_quad()->index(),
-                         this);
+    return this->faces->lines.
+      get_dof_index (*this,
+                    obj_index,
+                    fe_index,
+                    local_index,
+                    obj_level);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::hex_iterator
-  DoFHandler<dim>::last_hex () const
+  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
   {
-    return hex_iterator (tria,
-                        tria->last_hex()->level(),
-                        tria->last_hex()->index(),
-                        this);
+    this->faces->lines.
+      set_dof_index (*this,
+                    obj_index,
+                    fe_index,
+                    local_index,
+                    global_index,
+                    obj_level);
+  
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_line_iterator
-  DoFHandler<dim>::last_active_line () const
+  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 active_line_iterator (tria,
-                                tria->last_active_line()->level(),
-                                tria->last_active_line()->index(),
-                                this);
+    return this->faces->lines.fe_index_is_active(*this,
+                                                obj_index,
+                                                fe_index,
+                                                obj_level);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_quad_iterator
-  DoFHandler<dim>::last_active_quad () const
+  template <>
+  template <>
+  unsigned int
+  DoFHandler<2>::n_active_fe_indices<1> (const unsigned int ,
+                                        const unsigned int obj_index) const
   {
-    return active_quad_iterator (tria,
-                                tria->last_active_quad()->level(),
-                                tria->last_active_quad()->index(),
-                                this);
+    return this->faces->lines.n_active_fe_indices (*this,
+                                                  obj_index);
   }
 
 
-  template <int dim>
-  typename DoFHandler<dim>::active_hex_iterator
-  DoFHandler<dim>::last_active_hex () const
+  template <>
+  template <>
+  unsigned int
+  DoFHandler<2>::nth_active_fe_index<1> (const unsigned int obj_level,
+                                        const unsigned int obj_index,
+                                        const unsigned int n) const
   {
-    return active_hex_iterator (tria,
-                               tria->last_active_hex()->level(),
-                               tria->last_active_hex()->index(),
-                               this);
+    return this->faces->lines.nth_active_fe_index (*this,
+                                                  obj_level,
+                                                  obj_index,
+                                                  n);
   }
 
+  
 
-//------------------------------------------------------------------
-#if deal_II_dimension == 1 
   template <>
   template <>
   unsigned int
-  DoFHandler<1>::get_dof_index<1> (const unsigned int       obj_level,
+  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]->lines.
+    return this->levels[obj_level]->quads.
       get_dof_index (*this,
                     obj_index,
                     fe_index,
@@ -1525,30 +2837,31 @@ namespace hp
   template <>
   template <>
   void
-  DoFHandler<1>::set_dof_index<1> (const unsigned int       obj_level,
+  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]->lines.
+    this->levels[obj_level]->quads.
       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,
+  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]->lines.fe_index_is_active(*this,
+    return this->levels[obj_level]->quads.fe_index_is_active(*this,
                                                             obj_index,
                                                             fe_index,
                                                             obj_level);
@@ -1558,10 +2871,10 @@ namespace hp
   template <>
   template <>
   unsigned int
-  DoFHandler<1>::n_active_fe_indices<1> (const unsigned int obj_level,
+  DoFHandler<2>::n_active_fe_indices<2> (const unsigned int obj_level,
                                         const unsigned int obj_index) const
   {
-    return this->levels[obj_level]->lines.n_active_fe_indices (*this,
+    return this->levels[obj_level]->quads.n_active_fe_indices (*this,
                                                               obj_index);
   }
 
@@ -1570,23 +2883,21 @@ namespace hp
   template <>
   template <>
   unsigned int
-  DoFHandler<1>::nth_active_fe_index<1> (const unsigned int obj_level,
+  DoFHandler<2>::nth_active_fe_index<2> (const unsigned int obj_level,
                                         const unsigned int obj_index,
                                         const unsigned int n) const
   {
-    return this->levels[obj_level]->lines.nth_active_fe_index (*this,
+    return this->levels[obj_level]->quads.nth_active_fe_index (*this,
                                                               obj_level,
                                                               obj_index,
                                                               n);
   }
-#endif
 
 
-#if deal_II_dimension == 2
   template <>
   template <>
   unsigned int
-  DoFHandler<2>::get_dof_index<1> (const unsigned int       obj_level,
+  DoFHandler<2,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
@@ -1603,7 +2914,7 @@ namespace hp
   template <>
   template <>
   void
-  DoFHandler<2>::set_dof_index<1> (const unsigned int       obj_level,
+  DoFHandler<2,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,
@@ -1623,7 +2934,7 @@ namespace hp
   template <>
   template <>
   bool
-  DoFHandler<2>::fe_index_is_active<1> (const unsigned int obj_level,
+  DoFHandler<2,3>::fe_index_is_active<1> (const unsigned int obj_level,
                                        const unsigned int obj_index,
                                        const unsigned int fe_index) const
   {
@@ -1637,7 +2948,7 @@ namespace hp
   template <>
   template <>
   unsigned int
-  DoFHandler<2>::n_active_fe_indices<1> (const unsigned int ,
+  DoFHandler<2,3>::n_active_fe_indices<1> (const unsigned int ,
                                         const unsigned int obj_index) const
   {
     return this->faces->lines.n_active_fe_indices (*this,
@@ -1648,7 +2959,7 @@ namespace hp
   template <>
   template <>
   unsigned int
-  DoFHandler<2>::nth_active_fe_index<1> (const unsigned int obj_level,
+  DoFHandler<2,3>::nth_active_fe_index<1> (const unsigned int obj_level,
                                         const unsigned int obj_index,
                                         const unsigned int n) const
   {
@@ -1663,7 +2974,7 @@ namespace hp
   template <>
   template <>
   unsigned int
-  DoFHandler<2>::get_dof_index<2> (const unsigned int       obj_level,
+  DoFHandler<2,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
@@ -1680,7 +2991,7 @@ namespace hp
   template <>
   template <>
   void
-  DoFHandler<2>::set_dof_index<2> (const unsigned int       obj_level,
+  DoFHandler<2,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,
@@ -1700,7 +3011,7 @@ namespace hp
   template <>
   template <>
   bool
-  DoFHandler<2>::fe_index_is_active<2> (const unsigned int obj_level,
+  DoFHandler<2,3>::fe_index_is_active<2> (const unsigned int obj_level,
                                        const unsigned int obj_index,
                                        const unsigned int fe_index) const
   {
@@ -1714,7 +3025,7 @@ namespace hp
   template <>
   template <>
   unsigned int
-  DoFHandler<2>::n_active_fe_indices<2> (const unsigned int obj_level,
+  DoFHandler<2,3>::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,
@@ -1726,7 +3037,7 @@ namespace hp
   template <>
   template <>
   unsigned int
-  DoFHandler<2>::nth_active_fe_index<2> (const unsigned int obj_level,
+  DoFHandler<2,3>::nth_active_fe_index<2> (const unsigned int obj_level,
                                         const unsigned int obj_index,
                                         const unsigned int n) const
   {
@@ -1735,6 +3046,8 @@ namespace hp
                                                               obj_index,
                                                               n);
   }
+
+
 #endif
 
 #if deal_II_dimension == 3
@@ -2076,11 +3389,35 @@ namespace hp
     return n;
   }
 
+
+  template <>
+  unsigned int DoFHandler<1,2>::n_boundary_dofs () const
+  {
+    Assert(false,ExcNotImplemented());
+    return 0;
+  }
+
+  template <>
+  unsigned int DoFHandler<1,2>::n_boundary_dofs (const FunctionMap &) const
+  {
+    Assert(false,ExcNotImplemented());
+    return 0;
+  }
+
+  template <>
+  unsigned int DoFHandler<1,2>::n_boundary_dofs (const std::set<unsigned char> &) const
+  {
+    Assert(false,ExcNotImplemented());
+    return 0;
+  }
+
+
+
 #endif
 
 
-  template <int dim>
-  unsigned int DoFHandler<dim>::n_boundary_dofs () const
+  template<int dim, int spacedim>
+  unsigned int DoFHandler<dim,spacedim>::n_boundary_dofs () const
   {
     Assert (finite_elements != 0, ExcNoFESelected());
 
@@ -2098,7 +3435,7 @@ namespace hp
                                      // boundaries of dimension dim-2,
                                      // and so every boundary line is
                                      // also part of a boundary face.
-    typename DoFHandler<dim>::active_cell_iterator cell = this->begin_active (),
+    typename DoFHandler<dim,spacedim>::active_cell_iterator cell = this->begin_active (),
                                                    endc = this->end();
     for (; cell!=endc; ++cell)
       for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
@@ -2117,9 +3454,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   unsigned int
-  DoFHandler<dim>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
+  DoFHandler<dim,spacedim>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
   {
     Assert (finite_elements != 0, ExcNoFESelected());
     Assert (boundary_indicators.find(255) == boundary_indicators.end(),
@@ -2132,7 +3469,7 @@ namespace hp
     std::vector<unsigned int> dofs_on_face;
     dofs_on_face.reserve (this->get_fe ().max_dofs_per_face());
 
-    typename DoFHandler<dim>::active_cell_iterator cell = this->begin_active (),
+    typename DoFHandler<dim,spacedim>::active_cell_iterator cell = this->begin_active (),
                                                    endc = this->end();
     for (; cell!=endc; ++cell)
       for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
@@ -2153,9 +3490,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   unsigned int
-  DoFHandler<dim>::n_boundary_dofs (const std::set<unsigned char> &boundary_indicators) const
+  DoFHandler<dim,spacedim>::n_boundary_dofs (const std::set<unsigned char> &boundary_indicators) const
   {
     Assert (finite_elements != 0, ExcNoFESelected());
     Assert (boundary_indicators.find (255) == boundary_indicators.end(),
@@ -2168,7 +3505,7 @@ namespace hp
     std::vector<unsigned int> dofs_on_face;
     dofs_on_face.reserve (this->get_fe ().max_dofs_per_face());
 
-    typename DoFHandler<dim>::active_cell_iterator cell = this->begin_active (),
+    typename DoFHandler<dim,spacedim>::active_cell_iterator cell = this->begin_active (),
                                                    endc = this->end();
     for (; cell!=endc; ++cell)
       for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
@@ -2187,9 +3524,34 @@ namespace hp
   }
 
 
-  template <int dim>
+  template <>
+  unsigned int DoFHandler<2,3>::n_boundary_dofs () const
+  {
+    Assert(false,ExcNotImplemented());
+    return 0;
+  }
+
+  template <>
+  unsigned int DoFHandler<2,3>::n_boundary_dofs (const FunctionMap &) const
+  {
+    Assert(false,ExcNotImplemented());
+    return 0;
+  }
+
+  template <>
+  unsigned int DoFHandler<2,3>::n_boundary_dofs (const std::set<unsigned char> &) const
+  {
+    Assert(false,ExcNotImplemented());
+    return 0;
+  }
+
+
+
+
+
+  template<int dim, int spacedim>
   unsigned int
-  DoFHandler<dim>::memory_consumption () const
+  DoFHandler<dim,spacedim>::memory_consumption () const
   {
     unsigned int mem = (MemoryConsumption::memory_consumption (tria) +
                         MemoryConsumption::memory_consumption (finite_elements) +
@@ -2207,9 +3569,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template<int dim, int spacedim>
   void
-  DoFHandler<dim>::
+  DoFHandler<dim,spacedim>::
   compute_vertex_dof_identities (std::vector<unsigned int> &new_dof_indices) const
   {
                                      // Note: we may wish to have
@@ -2321,9 +3683,9 @@ namespace hp
 
 #endif
 
-  template <int dim>
+  template<int dim, int spacedim>
   void
-  DoFHandler<dim>::
+  DoFHandler<dim,spacedim>::
   compute_line_dof_identities (std::vector<unsigned int> &new_dof_indices) const
   {
                                      // An implementation of the
@@ -2542,6 +3904,12 @@ namespace hp
   compute_quad_dof_identities (std::vector<unsigned int> &) const
   {}
 
+  template <>
+  void
+  DoFHandler<1,2>::
+  compute_quad_dof_identities (std::vector<unsigned int> &) const
+  {}
+
 #endif
 
 
@@ -2553,12 +3921,20 @@ namespace hp
   compute_quad_dof_identities (std::vector<unsigned int> &) const
   {}
 
+
+  template <>
+  void
+  DoFHandler<2,3>::
+  compute_quad_dof_identities (std::vector<unsigned int> &) const
+  {}
+
+
 #endif
 
   
-  template <int dim>
+  template<int dim, int spacedim>
   void
-  DoFHandler<dim>::
+  DoFHandler<dim,spacedim>::
   compute_quad_dof_identities (std::vector<unsigned int> &new_dof_indices) const
   {
                                      // An implementation of the
@@ -2641,8 +4017,8 @@ namespace hp
   
 
   
-  template <int dim>
-  void DoFHandler<dim>::distribute_dofs (const hp::FECollection<dim> &ff)
+  template<int dim, int spacedim>
+  void DoFHandler<dim,spacedim>::distribute_dofs (const hp::FECollection<dim,spacedim> &ff)
   {
     Assert (tria->n_levels() > 0, ExcInvalidTriangulation());
 
@@ -2665,7 +4041,7 @@ namespace hp
 
                                      // then allocate space for all
                                      // the other tables
-    reserve_space ();
+    Implementation::reserve_space (*this);
 
                                      // Clear user flags because we will
                                      // need them. But first we save
@@ -2677,7 +4053,7 @@ namespace hp
                                      // beginning of this function.
     std::vector<bool> user_flags;
     tria->save_user_flags(user_flags);
-    const_cast<Triangulation<dim> &>(*tria).clear_user_flags ();
+    const_cast<Triangulation<dim,spacedim> &>(*tria).clear_user_flags ();
 
 
                                     /////////////////////////////////
@@ -2690,7 +4066,9 @@ namespace hp
                           endc = end();
 
       for (; cell != endc; ++cell) 
-       next_free_dof = distribute_dofs_on_cell (cell, next_free_dof);
+       next_free_dof
+         = Implementation::template distribute_dofs_on_cell<spacedim> (cell,
+                                                              next_free_dof);
 
       used_dofs = next_free_dof;
     }
@@ -2754,13 +4132,13 @@ namespace hp
     
     
                                      // finally restore the user flags
-    const_cast<Triangulation<dim> &>(*tria).load_user_flags(user_flags);
+    const_cast<Triangulation<dim,spacedim> &>(*tria).load_user_flags(user_flags);
   }
 
 
 
-  template <int dim>
-  void DoFHandler<dim>::clear ()
+  template<int dim, int spacedim>
+  void DoFHandler<dim,spacedim>::clear ()
   {
                                      // release lock to old fe
     finite_elements = 0;
@@ -2770,183 +4148,9 @@ namespace hp
   }
 
 
-#if deal_II_dimension == 1
-
-  template <>
-  unsigned int
-  DoFHandler<1>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                         unsigned int          next_free_dof)
-  {
-    const FiniteElement<1> &fe       = cell->get_fe();
-    const unsigned int      fe_index = cell->active_fe_index ();
-    
-                                    // number dofs on vertices. to do
-                                    // so, check whether dofs for
-                                    // this vertex have been
-                                    // distributed and for the
-                                    // present fe (only check the
-                                    // first dof), and if this isn't
-                                    // the case distribute new ones
-                                    // there
-    if (fe.dofs_per_vertex > 0)
-      for (unsigned int vertex=0; vertex<GeometryInfo<1>::vertices_per_cell; ++vertex)
-        if (cell->vertex_dof_index(vertex, 0, fe_index) == invalid_dof_index)
-          for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
-            cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
-    
-                                     // finally for the line. this one
-                                     // shouldn't be numbered yet
-    if (fe.dofs_per_line > 0)
-      {
-       Assert (cell->dof_index(0, fe_index) == invalid_dof_index,
-               ExcInternalError());
-       
-       for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
-         cell->set_dof_index (d, next_free_dof, fe_index);
-      }
-
-                                     // note that this cell has been processed
-    cell->set_user_flag ();
-  
-    return next_free_dof;
-  }
-
-#endif
-
-
-#if deal_II_dimension == 2
-
-  template <>
-  unsigned int
-  DoFHandler<2>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                         unsigned int          next_free_dof)
-  {
-    const FiniteElement<2> &fe       = cell->get_fe();
-    const unsigned int      fe_index = cell->active_fe_index ();
-    
-                                    // number dofs on vertices. to do
-                                    // so, check whether dofs for
-                                    // this vertex have been
-                                    // distributed and for the
-                                    // present fe (only check the
-                                    // first dof), and if this isn't
-                                    // the case distribute new ones
-                                    // there
-    if (fe.dofs_per_vertex > 0)
-      for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
-        if (cell->vertex_dof_index(vertex, 0, fe_index) == invalid_dof_index)
-          for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
-            cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
-    
-                                     // next the sides. do the
-                                     // same as above: check whether
-                                     // the line is already numbered
-                                     // for the present fe_index, and
-                                     // if not do it
-    if (fe.dofs_per_line > 0)
-      for (unsigned int l=0; l<GeometryInfo<2>::lines_per_cell; ++l)
-        {
-          line_iterator line = cell->line(l);
-
-          if (line->dof_index(0,fe_index) == invalid_dof_index)
-            for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
-              line->set_dof_index (d, next_free_dof, fe_index);
-        }
-
-
-                                     // finally for the quad. this one
-                                     // shouldn't be numbered yet
-    if (fe.dofs_per_quad > 0)
-      {
-       Assert (cell->dof_index(0, fe_index) == invalid_dof_index,
-               ExcInternalError());
-       
-       for (unsigned int d=0; d<fe.dofs_per_quad; ++d, ++next_free_dof)
-         cell->set_dof_index (d, next_free_dof, fe_index);
-      }
-
-                                     // note that this cell has been processed
-    cell->set_user_flag ();
-  
-    return next_free_dof;
-  }
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-  template <>
-  unsigned int
-  DoFHandler<3>::distribute_dofs_on_cell (active_cell_iterator &cell,
-                                         unsigned int          next_free_dof)
-  {
-    const FiniteElement<3> &fe       = cell->get_fe();
-    const unsigned int      fe_index = cell->active_fe_index ();
-    
-                                    // number dofs on vertices. to do
-                                    // so, check whether dofs for
-                                    // this vertex have been
-                                    // distributed and for the
-                                    // present fe (only check the
-                                    // first dof), and if this isn't
-                                    // the case distribute new ones
-                                    // there
-    if (fe.dofs_per_vertex > 0)
-      for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
-        if (cell->vertex_dof_index(vertex, 0, fe_index) == invalid_dof_index)
-          for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
-            cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
-    
-                                     // next the four lines. do the
-                                     // same as above: check whether
-                                     // the line is already numbered
-                                     // for the present fe_index, and
-                                     // if not do it
-    if (fe.dofs_per_line > 0)
-      for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
-        {
-          line_iterator line = cell->line(l);
-
-          if (line->dof_index(0,fe_index) == invalid_dof_index)
-            for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
-              line->set_dof_index (d, next_free_dof, fe_index);
-        }
-
-                                    // same for quads
-    if (fe.dofs_per_quad > 0)
-      for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
-        {
-          quad_iterator quad = cell->quad(q);
-
-          if (quad->dof_index(0,fe_index) == invalid_dof_index)
-            for (unsigned int d=0; d<fe.dofs_per_quad; ++d, ++next_free_dof)
-              quad->set_dof_index (d, next_free_dof, fe_index);
-        }
-
-
-                                     // finally for the hex. this one
-                                     // shouldn't be numbered yet
-    if (fe.dofs_per_hex > 0)
-      {
-       Assert (cell->dof_index(0, fe_index) == invalid_dof_index,
-               ExcInternalError());
-       
-       for (unsigned int d=0; d<fe.dofs_per_hex; ++d, ++next_free_dof)
-         cell->set_dof_index (d, next_free_dof, fe_index);
-      }
-
-                                     // note that this cell has been processed
-    cell->set_user_flag ();
-  
-    return next_free_dof;
-  }
-
-#endif
-
 
-  template <int dim>
-  void DoFHandler<dim>::renumber_dofs (const std::vector<unsigned int> &new_numbers)
+  template<int dim, int spacedim>
+  void DoFHandler<dim,spacedim>::renumber_dofs (const std::vector<unsigned int> &new_numbers)
   {
     Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
 #ifdef DEBUG
@@ -2964,1320 +4168,187 @@ namespace hp
 #endif
 
     renumber_dofs_internal (new_numbers, internal::int2type<dim>());
-  }
-
-
-
-  template <int dim>
-  void
-  DoFHandler<dim>::
-  renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
-                         internal::int2type<0>)
-  {
-    Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
-
-    for (unsigned int vertex_index=0; vertex_index<get_tria().n_vertices();
-        ++vertex_index)
-      {
-       const unsigned int n_active_fe_indices
-         = n_active_vertex_fe_indices (vertex_index);
-
-       for (unsigned int f=0; f<n_active_fe_indices; ++f)
-         {
-           const unsigned int fe_index
-             = nth_active_vertex_fe_index (vertex_index, f);
-
-           for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_vertex; ++d)
-             set_vertex_dof_index (vertex_index,
-                                   fe_index,
-                                   d,
-                                   new_numbers[get_vertex_dof_index(vertex_index,
-                                                                    fe_index,
-                                                                    d)]);
-         }
-      }
-  }
-
-
-
-  template <int dim>
-  void
-  DoFHandler<dim>::
-  renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
-                         internal::int2type<1>)
-  {
-    Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
-
-    renumber_dofs_internal (new_numbers, internal::int2type<0>());
-    
-    for (line_iterator line=begin_line(); line!=end_line(); ++line)
-      {
-       const unsigned int n_active_fe_indices
-         = line->n_active_fe_indices ();
-
-       for (unsigned int f=0; f<n_active_fe_indices; ++f)
-         {
-           const unsigned int fe_index
-             = line->nth_active_fe_index (f);
-
-           for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_line; ++d)
-             line->set_dof_index (d,
-                                  new_numbers[line->dof_index(d,fe_index)],
-                                  fe_index);
-         }
-      }
-  }
-
-
-#if deal_II_dimension >= 2
-
-  template <int dim>
-  void
-  DoFHandler<dim>::
-  renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
-                         internal::int2type<2>)
-  {
-    Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
-
-    renumber_dofs_internal (new_numbers, internal::int2type<1>());
-    
-    for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad)
-      {
-       const unsigned int n_active_fe_indices
-         = quad->n_active_fe_indices ();
-
-       for (unsigned int f=0; f<n_active_fe_indices; ++f)
-         {
-           const unsigned int fe_index
-             = quad->nth_active_fe_index (f);
-
-           for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_quad; ++d)
-             quad->set_dof_index (d,
-                                  new_numbers[quad->dof_index(d,fe_index)],
-                                  fe_index);
-         }
-      }
-  }
-
-#endif
-
-#if deal_II_dimension >= 3
-
-  template <int dim>
-  void
-  DoFHandler<dim>::
-  renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
-                         internal::int2type<3>)
-  {
-    Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
-
-    renumber_dofs_internal (new_numbers, internal::int2type<2>());
-    
-    for (hex_iterator hex=begin_hex(); hex!=end_hex(); ++hex)
-      {
-       const unsigned int n_active_fe_indices
-         = hex->n_active_fe_indices ();
-
-       for (unsigned int f=0; f<n_active_fe_indices; ++f)
-         {
-           const unsigned int fe_index
-             = hex->nth_active_fe_index (f);
-
-           for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_hex; ++d)
-             hex->set_dof_index (d,
-                                 new_numbers[hex->dof_index(d,fe_index)],
-                                 fe_index);
-         }
-      }
-  }
-
-#endif
-
-
-#if deal_II_dimension == 1
-
-  template <>
-  unsigned int
-  DoFHandler<1>::max_couplings_between_dofs () const
-  {
-    Assert (finite_elements != 0, ExcNoFESelected());
-    return std::min(3*finite_elements->max_dofs_per_vertex() +
-                    2*finite_elements->max_dofs_per_line(), n_dofs());
-  }
-
-
-
-  template <>
-  unsigned int
-  DoFHandler<1>::max_couplings_between_boundary_dofs () const
-  {
-    Assert (finite_elements != 0, ExcNoFESelected());
-    return finite_elements->max_dofs_per_vertex();
-  }
-
-#endif
-
-
-#if deal_II_dimension == 2
-
-  template <>
-  unsigned int
-  DoFHandler<2>::max_couplings_between_dofs () const
-  {
-    Assert (finite_elements != 0, ExcNoFESelected());
-
-                                     // get these numbers by drawing pictures
-                                     // and counting...
-                                     // example:
-                                     //   |     |     |
-                                     // --x-----x--x--X--
-                                     //   |     |  |  |
-                                     //   |     x--x--x
-                                     //   |     |  |  |
-                                     // --x--x--*--x--x--
-                                     //   |  |  |     |
-                                     //   x--x--x     |
-                                     //   |  |  |     |
-                                     // --X--x--x-----x--
-                                     //   |     |     |
-                                     // x = vertices connected with center vertex *;
-                                     //   = total of 19
-                                     // (the X vertices are connected with * if
-                                     // the vertices adjacent to X are hanging
-                                     // nodes)
-                                     // count lines -> 28 (don't forget to count
-                                     // mother and children separately!)
-    unsigned int max_couplings;
-    switch (tria->max_adjacent_cells())
-      {
-        case 4:
-              max_couplings=19*finite_elements->max_dofs_per_vertex() +
-                            28*finite_elements->max_dofs_per_line() +
-                            8*finite_elements->max_dofs_per_quad();
-              break;
-        case 5:
-              max_couplings=21*finite_elements->max_dofs_per_vertex() +
-                            31*finite_elements->max_dofs_per_line() +
-                            9*finite_elements->max_dofs_per_quad();
-              break;
-        case 6:
-              max_couplings=28*finite_elements->max_dofs_per_vertex() +
-                            42*finite_elements->max_dofs_per_line() +
-                            12*finite_elements->max_dofs_per_quad();
-              break;
-        case 7:
-              max_couplings=30*finite_elements->max_dofs_per_vertex() +
-                            45*finite_elements->max_dofs_per_line() +
-                            13*finite_elements->max_dofs_per_quad();
-              break;
-        case 8:
-              max_couplings=37*finite_elements->max_dofs_per_vertex() +
-                            56*finite_elements->max_dofs_per_line() +
-                            16*finite_elements->max_dofs_per_quad();
-              break;
-        default:
-              Assert (false, ExcNotImplemented());
-              max_couplings=0;
-      };
-    return std::min(max_couplings,n_dofs());
-  }
-
-
-
-  template <>
-  unsigned int
-  DoFHandler<2>::max_couplings_between_boundary_dofs () const
-  {
-    Assert (finite_elements != 0, ExcNoFESelected());
-    return (3*finite_elements->max_dofs_per_vertex()
-            +
-            2*finite_elements->max_dofs_per_line());
-  }
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-  template <>
-  unsigned int
-  DoFHandler<3>::max_couplings_between_dofs () const
-  {
-//TODO:[?] Invent significantly better estimates than the ones in this function  
-    Assert (finite_elements != 0, ExcNoFESelected());
-
-                                     // doing the same thing here is a rather
-                                     // complicated thing, compared to the 2d
-                                     // case, since it is hard to draw pictures
-                                     // with several refined hexahedra :-) so I
-                                     // presently only give a coarse estimate
-                                     // for the case that at most 8 hexes meet
-                                     // at each vertex
-                                     //
-                                     // can anyone give better estimate here?
-    const unsigned int max_adjacent_cells = tria->max_adjacent_cells();
-
-    unsigned int max_couplings;
-    if (max_adjacent_cells <= 8)
-      max_couplings=7*7*7*finite_elements->max_dofs_per_vertex() +
-                    7*6*7*3*finite_elements->max_dofs_per_line() +
-                    9*4*7*3*finite_elements->max_dofs_per_quad() +
-                    27*finite_elements->max_dofs_per_hex();
-    else
-      {
-        Assert (false, ExcNotImplemented());
-        max_couplings=0;
-      }
-  
-    return std::min(max_couplings,n_dofs());
-  }
-
-
-  template <>
-  unsigned int
-  DoFHandler<3>::max_couplings_between_boundary_dofs () const
-  {
-    Assert (finite_elements != 0, ExcNoFESelected());
-                                     // we need to take refinement of
-                                     // one boundary face into consideration
-                                     // here; in fact, this function returns
-                                     // what #max_coupling_between_dofs<2>
-                                     // returns
-                                     //
-                                     // we assume here, that only four faces
-                                     // meet at the boundary; this assumption
-                                     // is not justified and needs to be
-                                     // fixed some time. fortunately, ommitting
-                                     // it for now does no harm since the
-                                     // matrix will cry foul if its requirements
-                                     // are not satisfied
-    return (19*finite_elements->max_dofs_per_vertex() +
-            28*finite_elements->max_dofs_per_line() +
-            8*finite_elements->max_dofs_per_quad());
-  }
-
-
-#endif
-
+  }
 
 
-#if deal_II_dimension == 1
 
-  template <>
-  void DoFHandler<1>::reserve_space ()
+  template<int dim, int spacedim>
+  void
+  DoFHandler<dim,spacedim>::
+  renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
+                         internal::int2type<0>)
   {
-    const unsigned int dim = 1;
-    
-    Assert (finite_elements != 0, ExcNoFESelected());
-    Assert (finite_elements->size() > 0, ExcNoFESelected());
-    Assert (tria->n_levels() > 0, ExcInvalidTriangulation());
-    Assert (tria->n_levels() == levels.size (), ExcInternalError ());
-
-                                     // Release all space except the
-                                     // active_fe_indices field which
-                                     // we have to backup before
-    {
-      std::vector<std::vector<unsigned int> > active_fe_backup(levels.size ());
-      for (unsigned int level = 0; level<levels.size (); ++level)
-        std::swap (levels[level]->active_fe_indices, active_fe_backup[level]);
-
-                                       // delete all levels and set them up
-                                       // newly, since vectors are
-                                       // troublesome if you want to change
-                                       // their size
-      clear_space ();
-  
-      for (unsigned int level=0; level<tria->n_levels(); ++level) 
-        {
-          levels.push_back (new internal::hp::DoFLevel<dim>);
-          std::swap (active_fe_backup[level],
-                     levels[level]->active_fe_indices);
-        }
-    }
+    Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
 
-                                     // LINE (CELL) DOFs
-    
-                                     // count how much space we need
-                                     // on each level for the cell
-                                     // dofs and set the
-                                     // dof_*_offsets
-                                     // data. initially set the latter
-                                     // to an invalid index, and only
-                                     // later set it to something
-                                     // reasonable for active cells
-                                    //
-                                    // note that for cells, the
-                                    // situation is simpler than for
-                                    // other (lower dimensional)
-                                    // objects since exactly one
-                                    // finite element is used for it
-    for (unsigned int level=0; level<tria->n_levels(); ++level) 
+    for (unsigned int vertex_index=0; vertex_index<get_tria().n_vertices();
+        ++vertex_index)
       {
-        levels[level]->lines.dof_offsets
-          = std::vector<unsigned int> (tria->n_raw_lines(level),
-                                       invalid_dof_index);
-
-        unsigned int next_free_dof = 0;
-        for (active_cell_iterator cell=begin_active(level);
-             cell!=end_active(level); ++cell)
-          if (!cell->has_children())
-           {
-             levels[level]->lines.dof_offsets[cell->index()] = next_free_dof;
-             next_free_dof += cell->get_fe().dofs_per_line;
-           }
+       const unsigned int n_active_fe_indices
+         = n_active_vertex_fe_indices (vertex_index);
 
-        levels[level]->lines.dofs
-          = std::vector<unsigned int> (next_free_dof, invalid_dof_index);
-      }
+       for (unsigned int f=0; f<n_active_fe_indices; ++f)
+         {
+           const unsigned int fe_index
+             = nth_active_vertex_fe_index (vertex_index, f);
 
-                                     // safety check: make sure that
-                                     // the number of DoFs we
-                                     // allocated is actually correct
-                                     // (above we have also set the
-                                     // dof_*_offsets field, so
-                                     // we couldn't use this simpler
-                                     // algorithm)
-#ifdef DEBUG
-    for (unsigned int level=0; level<tria->n_levels(); ++level)
-      {
-        unsigned int counter = 0;
-        for (cell_iterator cell=begin_active(level);
-            cell!=end_active(level); ++cell)
-          if (!cell->has_children())
-            counter += cell->get_fe().dofs_per_line;
-        
-        Assert (levels[level]->lines.dofs.size() == counter, ExcInternalError());
-        Assert (static_cast<unsigned int>
-                (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),
-                ExcInternalError());
+           for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_vertex; ++d)
+             set_vertex_dof_index (vertex_index,
+                                   fe_index,
+                                   d,
+                                   new_numbers[get_vertex_dof_index(vertex_index,
+                                                                    fe_index,
+                                                                    d)]);
+         }
       }
-#endif
-    
-    
-                                    // VERTEX DOFS
-    reserve_space_vertices ();
   }
 
-#endif
-
 
-#if deal_II_dimension == 2
 
-  template <>
-  void DoFHandler<2>::reserve_space ()
+  template<int dim, int spacedim>
+  void
+  DoFHandler<dim,spacedim>::
+  renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
+                         internal::int2type<1>)
   {
-    const unsigned int dim = 2;
-    
-    Assert (finite_elements != 0, ExcNoFESelected());
-    Assert (finite_elements->size() > 0, ExcNoFESelected());
-    Assert (tria->n_levels() > 0, ExcInvalidTriangulation());
-    Assert (tria->n_levels() == levels.size (), ExcInternalError ());
-
-                                     // Release all space except the
-                                     // active_fe_indices field which
-                                     // we have to backup before
-    {
-      std::vector<std::vector<unsigned int> > active_fe_backup(levels.size ());
-      for (unsigned int level = 0; level<levels.size (); ++level)
-        std::swap (levels[level]->active_fe_indices, active_fe_backup[level]);
-
-                                       // delete all levels and set them up
-                                       // newly, since vectors are
-                                       // troublesome if you want to change
-                                       // their size
-      clear_space ();
-  
-      for (unsigned int level=0; level<tria->n_levels(); ++level) 
-        {
-          levels.push_back (new internal::hp::DoFLevel<dim>);
-          std::swap (active_fe_backup[level],
-                     levels[level]->active_fe_indices);
-        }
-      faces = new internal::hp::DoFFaces<2>;
-    }
+    Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
 
+    renumber_dofs_internal (new_numbers, internal::int2type<0>());
     
-                                     // QUAD (CELL) DOFs
-    
-                                     // count how much space we need
-                                     // on each level for the cell
-                                     // dofs and set the
-                                     // dof_*_offsets
-                                     // data. initially set the latter
-                                     // to an invalid index, and only
-                                     // later set it to something
-                                     // reasonable for active cells
-                                    //
-                                    // note that for cells, the
-                                    // situation is simpler than for
-                                    // other (lower dimensional)
-                                    // objects since exactly one
-                                    // finite element is used for it
-    for (unsigned int level=0; level<tria->n_levels(); ++level) 
+    for (line_iterator line=begin_line(); line!=end_line(); ++line)
       {
-        levels[level]->quads.dof_offsets
-          = std::vector<unsigned int> (tria->n_raw_quads(level),
-                                       invalid_dof_index);
-
-        unsigned int next_free_dof = 0;
-        for (active_cell_iterator cell=begin_active(level);
-             cell!=end_active(level); ++cell)
-          if (!cell->has_children())
-           {
-             levels[level]->quads.dof_offsets[cell->index()] = next_free_dof;
-             next_free_dof += cell->get_fe().dofs_per_quad;
-           }
+       const unsigned int n_active_fe_indices
+         = line->n_active_fe_indices ();
 
-        levels[level]->quads.dofs
-          = std::vector<unsigned int> (next_free_dof, invalid_dof_index);
-      }
+       for (unsigned int f=0; f<n_active_fe_indices; ++f)
+         {
+           const unsigned int fe_index
+             = line->nth_active_fe_index (f);
 
-                                     // safety check: make sure that
-                                     // the number of DoFs we
-                                     // allocated is actually correct
-                                     // (above we have also set the
-                                     // dof_*_offsets field, so
-                                     // we couldn't use this simpler
-                                     // algorithm)
-#ifdef DEBUG
-    for (unsigned int level=0; level<tria->n_levels(); ++level)
-      {
-        unsigned int counter = 0;
-        for (cell_iterator cell=begin_active(level);
-            cell!=end_active(level); ++cell)
-          if (!cell->has_children())
-            counter += cell->get_fe().dofs_per_quad;
-        
-        Assert (levels[level]->quads.dofs.size() == counter, ExcInternalError());
-        Assert (static_cast<unsigned int>
-                (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),
-                ExcInternalError());
+           for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_line; ++d)
+             line->set_dof_index (d,
+                                  new_numbers[line->dof_index(d,fe_index)],
+                                  fe_index);
+         }
       }
-#endif
-    
-    
-                                     // LINE DOFS
-                                     //
-                                     // same here: count line dofs,
-                                     // then allocate as much space as
-                                     // we need and prime the linked
-                                     // list for lines (see the
-                                     // description in hp::DoFLevels)
-                                     // with the indices we will
-                                     // need. note that our task is
-                                     // more complicated since two
-                                     // adjacent cells may have
-                                     // different active_fe_indices,
-                                     // in which case we need to
-                                     // allocate *two* sets of line
-                                     // dofs for the same line
-                                     //
-                                     // the way we do things is that
-                                     // we loop over all active cells
-                                     // (these are the ones that have
-                                     // DoFs only anyway) and all
-                                     // their faces. We note in the
-                                     // user flags whether we have
-                                     // previously visited a face and
-                                     // if so skip it (consequently,
-                                     // we have to save and later
-                                     // restore the line flags)
-    {
-      std::vector<bool> saved_line_user_flags;
-      const_cast<Triangulation<dim>&>(*tria)
-        .save_user_flags_line (saved_line_user_flags);
-      const_cast<Triangulation<dim>&>(*tria).clear_user_flags_line ();
-
-                                       // an array to hold how many
-                                       // slots (see the hp::DoFLevel
-                                       // class) we will have to store
-                                       // on each level
-      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)
-          if (! cell->face(face)->user_flag_set())
-            {
-                                               // ok, face has not been
-                                               // visited. so we need to
-                                               // allocate space for it. let's
-                                               // see how much we need: we need
-                                               // one set if a) there is no
-                                               // neighbor behind this face, or
-                                               // b) the neighbor is either
-                                               // coarser or finer than we are,
-                                               // or c) the neighbor is neither
-                                               // coarser nor finer, but has
-                                               // happens to have the same
-                                               // active_fe_index:
-              if (cell->at_boundary(face)
-                  ||
-                  cell->face(face)->has_children()
-                  ||
-                 cell->neighbor_is_coarser(face)
-                 ||
-                 (!cell->at_boundary(face)
-                  &&
-                  (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
-                                                 // ok, one set of
-                                                 // dofs. that makes
-                                                 // one index, 1 times
-                                                 // dofs_per_line
-                                                 // dofs, and one stop
-                                                 // index
-                n_line_slots
-                  += (*finite_elements)[cell->active_fe_index()].dofs_per_line + 2;
-
-                                               // otherwise we do
-                                               // indeed need two
-                                               // sets, i.e. two
-                                               // indices, two sets of
-                                               // dofs, and one stop
-                                               // index:
-              else
-                n_line_slots
-                  += ((*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 ();
-            }
-
-                                       // now that we know how many
-                                       // line dofs we will have to
-                                       // have on each level, allocate
-                                       // the memory. note that we
-                                       // allocate offsets for all
-                                       // lines, though only the
-                                       // active ones will have a
-                                       // non-invalid value later on
-      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
-                                       // _offset values as well as
-                                       // the fe_index fields
-      const_cast<Triangulation<dim>&>(*tria).clear_user_flags_line ();
-
-      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)
-          if (! cell->face(face)->user_flag_set())
-            {
-                                               // same decision tree
-                                               // as before
-              if (cell->at_boundary(face)
-                  ||
-                  cell->face(face)->has_children()
-                  ||
-                 cell->neighbor_is_coarser(face)
-                 ||
-                 (!cell->at_boundary(face)
-                  &&
-                  (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
-                {
-                  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
-                  faces
-                    ->lines.dofs[next_free_line_slot]
-                    = cell->active_fe_index();
-
-                                                   // the next
-                                                   // dofs_per_line
-                                                   // indices remain
-                                                   // unset for the
-                                                   // moment (i.e. at
-                                                   // invalid_dof_index).
-                                                   // 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
-                    += (*finite_elements)[cell->active_fe_index()].dofs_per_line + 2;
-                }
-              else
-                {
-                  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
-                  faces
-                    ->lines.dofs[next_free_line_slot]
-                    = cell->active_fe_index();
-
-                                                   // the next
-                                                   // dofs_per_line
-                                                   // indices remain
-                                                   // unset for the
-                                                   // moment (i.e. at
-                                                   // invalid_dof_index).
-                                                   // 
-                                                   // then comes the
-                                                   // fe_index for the
-                                                   // neighboring
-                                                   // cell:
-                  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
-                   += ((*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
-      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);
-    }
-    
-
-                                    // VERTEX DOFS
-    reserve_space_vertices ();
   }
 
-#endif
-
 
-#if deal_II_dimension == 3
+#if deal_II_dimension >= 2
 
-  template <>
-  void DoFHandler<3>::reserve_space ()
+  template<int dim, int spacedim>
+  void
+  DoFHandler<dim,spacedim>::
+  renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
+                         internal::int2type<2>)
   {
-    const unsigned int dim = 3;
-    
-    Assert (finite_elements != 0, ExcNoFESelected());
-    Assert (finite_elements->size() > 0, ExcNoFESelected());
-    Assert (tria->n_levels() > 0, ExcInvalidTriangulation());
-    Assert (tria->n_levels() == levels.size (), ExcInternalError ());
-
-                                     // Release all space except the
-                                     // active_fe_indices field which
-                                     // we have to backup before
-    {
-      std::vector<std::vector<unsigned int> > active_fe_backup(levels.size ());
-      for (unsigned int level = 0; level<levels.size (); ++level)
-        std::swap (levels[level]->active_fe_indices, active_fe_backup[level]);
-
-                                       // delete all levels and set them up
-                                       // newly, since vectors are
-                                       // troublesome if you want to change
-                                       // their size
-      clear_space ();
-  
-      for (unsigned int level=0; level<tria->n_levels(); ++level) 
-        {
-          levels.push_back (new internal::hp::DoFLevel<dim>);
-          std::swap (active_fe_backup[level],
-                     levels[level]->active_fe_indices);
-        }
-      faces = new internal::hp::DoFFaces<3>;
-    }
+    Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
 
+    renumber_dofs_internal (new_numbers, internal::int2type<1>());
     
-                                     // HEX (CELL) DOFs
-    
-                                     // count how much space we need
-                                     // on each level for the cell
-                                     // dofs and set the
-                                     // dof_*_offsets
-                                     // data. initially set the latter
-                                     // to an invalid index, and only
-                                     // later set it to something
-                                     // reasonable for active cells
-                                    //
-                                    // note that for cells, the
-                                    // situation is simpler than for
-                                    // other (lower dimensional)
-                                    // objects since exactly one
-                                    // finite element is used for it
-    for (unsigned int level=0; level<tria->n_levels(); ++level) 
+    for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad)
       {
-        levels[level]->hexes.dof_offsets
-          = std::vector<unsigned int> (tria->n_raw_hexs(level),
-                                       invalid_dof_index);
-
-        unsigned int next_free_dof = 0;
-        for (active_cell_iterator cell=begin_active(level);
-             cell!=end_active(level); ++cell)
-          if (!cell->has_children())
-           {
-             levels[level]->hexes.dof_offsets[cell->index()] = next_free_dof;
-             next_free_dof += cell->get_fe().dofs_per_hex;
-           }
+       const unsigned int n_active_fe_indices
+         = quad->n_active_fe_indices ();
 
-        levels[level]->hexes.dofs
-          = std::vector<unsigned int> (next_free_dof, invalid_dof_index);
-      }
+       for (unsigned int f=0; f<n_active_fe_indices; ++f)
+         {
+           const unsigned int fe_index
+             = quad->nth_active_fe_index (f);
 
-                                     // safety check: make sure that
-                                     // the number of DoFs we
-                                     // allocated is actually correct
-                                     // (above we have also set the
-                                     // dof_*_offsets field, so
-                                     // we couldn't use this simpler
-                                     // algorithm)
-#ifdef DEBUG
-    for (unsigned int level=0; level<tria->n_levels(); ++level)
-      {
-        unsigned int counter = 0;
-        for (cell_iterator cell=begin_active(level);
-            cell!=end_active(level); ++cell)
-          if (!cell->has_children())
-            counter += cell->get_fe().dofs_per_hex;
-        
-        Assert (levels[level]->hexes.dofs.size() == counter, ExcInternalError());
-        Assert (static_cast<unsigned int>
-                (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),
-                ExcInternalError());
+           for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_quad; ++d)
+             quad->set_dof_index (d,
+                                  new_numbers[quad->dof_index(d,fe_index)],
+                                  fe_index);
+         }
       }
-#endif
-    
-    
-                                     // QUAD DOFS
-                                     //
-                                     // same here: count quad dofs,
-                                     // then allocate as much space as
-                                     // we need and prime the linked
-                                     // list for quad (see the
-                                     // description in hp::DoFLevels)
-                                     // with the indices we will
-                                     // need. note that our task is
-                                     // more complicated since two
-                                     // adjacent cells may have
-                                     // different active_fe_indices,
-                                     // in which case we need to
-                                     // allocate *two* sets of line
-                                     // dofs for the same line
-                                     //
-                                     // the way we do things is that
-                                     // we loop over all active cells
-                                     // (these are the ones that have
-                                     // DoFs only anyway) and all
-                                     // their faces. We note in the
-                                     // user flags whether we have
-                                     // previously visited a face and
-                                     // if so skip it (consequently,
-                                     // we have to save and later
-                                     // restore the line flags)
-    {
-      std::vector<bool> saved_quad_user_flags;
-      const_cast<Triangulation<dim>&>(*tria)
-        .save_user_flags_quad (saved_quad_user_flags);
-      const_cast<Triangulation<dim>&>(*tria).clear_user_flags_quad ();
-
-                                      // 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())
-           {
-                                               // ok, face has not been
-                                               // visited. so we need to
-                                               // allocate space for
-                                               // it. let's see how much
-                                               // we need: we need one
-                                               // set if a) there is no
-                                               // neighbor behind this
-                                               // face, or b) the
-                                               // neighbor is not on the
-                                               // same level or further
-                                               // refined, or c) the
-                                               // neighbor is on the
-                                               // same level, but
-                                               // happens to have the
-                                               // same active_fe_index:
-              if (cell->at_boundary(face)
-                  ||
-                  cell->face(face)->has_children()
-                  ||
-                 cell->neighbor_is_coarser(face)
-                 ||
-                 (!cell->at_boundary(face)
-                  &&
-                  (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
-                                                 // ok, one set of
-                                                 // dofs. that makes
-                                                 // one index, 1 times
-                                                 // dofs_per_quad
-                                                 // dofs, and one stop
-                                                 // index
-                n_quad_slots
-                  += (*finite_elements)[cell->active_fe_index()].dofs_per_quad + 2;
-
-                                               // otherwise we do
-                                               // indeed need two
-                                               // sets, i.e. two
-                                               // indices, two sets of
-                                               // dofs, and one stop
-                                               // index:
-              else
-                n_quad_slots
-                  += ((*finite_elements)[cell->active_fe_index()].dofs_per_quad
-                      +
-                      (*finite_elements)[cell->neighbor(face)->active_fe_index()]
-                      .dofs_per_quad
-                      +
-                      3);
-            
-                                               // mark this face as
-                                               // visited
-              cell->face(face)->set_user_flag ();
-            }
-
-                                       // now that we know how many
-                                       // quad dofs we will have to
-                                       // 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
-      if (true) 
-        {
-          faces->quads.dof_offsets
-            = std::vector<unsigned int> (tria->n_raw_quads(),
-                                         invalid_dof_index);
-          faces->quads.dofs
-            = std::vector<unsigned int> (n_quad_slots,
-                                         invalid_dof_index);        
-        }
-
-                                       // with the memory now
-                                       // allocated, loop over the
-                                       // cells again and prime the
-                                       // _offset values as well as
-                                       // the fe_index fields
-      const_cast<Triangulation<dim>&>(*tria).clear_user_flags_quad ();
+  }
 
-      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)
-          if (! cell->face(face)->user_flag_set())
-            {
-                                               // same decision tree
-                                               // as before
-              if (cell->at_boundary(face)
-                  ||
-                  cell->face(face)->has_children()
-                  ||
-                 cell->neighbor_is_coarser(face)
-                 ||
-                 (!cell->at_boundary(face)
-                  &&
-                  (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
-                {
-                  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
-                  faces
-                    ->quads.dofs[next_free_quad_slot]
-                    = cell->active_fe_index();
-
-                                                   // the next
-                                                   // dofs_per_quad
-                                                   // indices remain
-                                                   // unset for the
-                                                   // moment (i.e. at
-                                                   // invalid_dof_index).
-                                                   // 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_quad_slot
-                    += (*finite_elements)[cell->active_fe_index()].dofs_per_quad + 2;
-                }
-              else
-                {
-                  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
-                  faces
-                    ->quads.dofs[next_free_quad_slot]
-                    = cell->active_fe_index();
-
-                                                   // the next
-                                                   // dofs_per_quad
-                                                   // indices remain
-                                                   // unset for the
-                                                   // moment (i.e. at
-                                                   // invalid_dof_index).
-                                                   // 
-                                                   // then comes the
-                                                   // fe_index for the
-                                                   // neighboring
-                                                   // cell:
-                  faces
-                    ->quads.dofs[next_free_quad_slot
-                                +
-                                (*finite_elements)[cell->active_fe_index()].dofs_per_quad
-                                +
-                                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_quad_slot
-                    += ((*finite_elements)[cell->active_fe_index()].dofs_per_quad
-                        +
-                        (*finite_elements)[cell->neighbor(face)->active_fe_index()]
-                        .dofs_per_quad
-                        +
-                        3);
-                }
-              
-                                               // mark this face as
-                                               // visited
-              cell->face(face)->set_user_flag ();
-            }
-
-                                       // we should have moved the
-                                       // 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
-      const_cast<Triangulation<dim>&>(*tria)
-        .load_user_flags_quad (saved_quad_user_flags);
-    }
+#endif
 
+#if deal_II_dimension >= 3
 
-                                    // LINE DOFS
+  template<int dim, int spacedim>
+  void
+  DoFHandler<dim,spacedim>::
+  renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
+                         internal::int2type<3>)
+  {
+    Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
 
-                                    // the situation here is pretty
-                                    // much like with vertices: there
-                                    // can be an arbitrary number of
-                                    // finite elements associated
-                                    // with each line. 
-                                    //
-                                    // the algorithm we use is
-                                    // somewhat similar to what we do
-                                    // in reserve_space_vertices()
-    if (true)
+    renumber_dofs_internal (new_numbers, internal::int2type<2>());
+    
+    for (hex_iterator hex=begin_hex(); hex!=end_hex(); ++hex)
       {
-                                        // what we do first is to set up
-                                        // an array in which we record
-                                        // whether a line is associated
-                                        // with any of the given fe's, by
-                                        // setting a bit. in a later
-                                        // step, we then actually
-                                        // allocate memory for the
-                                        // required dofs
-       std::vector<std::vector<bool> >
-         line_fe_association (finite_elements->size(),
-                              std::vector<bool> (tria->n_raw_lines(),
-                                                 false));
-      
-       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;
-
-                                        // first check which of the
-                                        // lines is used at all,
-                                        // i.e. is associated with a
-                                        // finite element. we do this
-                                        // since not all lines may
-                                        // actually be used, in which
-                                        // case we do not have to
-                                        // allocate any memory at
-                                        // all
-       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)
-             {
-               line_is_used[line] = true;
-               break;
-             }
-       
-                                        // next count how much memory
-                                        // we actually need. for each
-                                        // line, we need one slot per
-                                        // fe to store the fe_index,
-                                        // plus dofs_per_line for
-                                        // this fe. in addition, we
-                                        // need one slot as the end
-                                        // marker for the
-                                        // fe_indices. at the same
-                                        // time already fill the
-                                        // line_dofs_offsets field
-       faces->lines.dof_offsets
-         .resize (tria->n_raw_lines(),
-                  numbers::invalid_unsigned_int);
-       
-       unsigned int line_slots_needed = 0;
-       for (unsigned int line=0; line<tria->n_raw_lines(); ++line)
-         if (line_is_used[line] == true)
-           {
-             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)
-                 line_slots_needed += (*finite_elements)[fe].dofs_per_line + 1;
-             ++line_slots_needed;
-           }
-
-                                        // now allocate the space we
-                                        // have determined we need, and
-                                        // set up the linked lists for
-                                        // each of the lines
-       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 = faces->lines.dof_offsets[line];
-             for (unsigned int fe=0; fe<finite_elements->size(); ++fe)
-               if (line_fe_association[fe][line] == true)
-                 {
-                                                    // if this line
-                                                    // uses this fe,
-                                                    // then set the
-                                                    // fe_index and
-                                                    // move the
-                                                    // pointer ahead
-                   faces->lines.dofs[pointer] = fe;
-                   pointer += (*finite_elements)[fe].dofs_per_line + 1;
-                 }
-                                              // finally place the end
-                                              // marker
-             faces->lines.dofs[pointer] = numbers::invalid_unsigned_int;
-           }
-      }
+       const unsigned int n_active_fe_indices
+         = hex->n_active_fe_indices ();
 
-    
+       for (unsigned int f=0; f<n_active_fe_indices; ++f)
+         {
+           const unsigned int fe_index
+             = hex->nth_active_fe_index (f);
 
-                                    // VERTEX DOFS
-    reserve_space_vertices ();
+           for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_hex; ++d)
+             hex->set_dof_index (d,
+                                 new_numbers[hex->dof_index(d,fe_index)],
+                                 fe_index);
+         }
+      }
   }
 
 #endif
 
 
+  template <int dim, int spacedim>
+  unsigned int
+  DoFHandler<dim, spacedim>::max_couplings_between_dofs () const
+  {
+    Assert (finite_elements != 0, ExcNoFESelected());
+    return Implementation::max_couplings_between_dofs (*this);
+  }
 
 
-  template <int dim>
-  void
-  DoFHandler<dim>::reserve_space_vertices ()
-  { 
-                                    // The final step is allocating
-                                    // memory is to set up vertex dof
-                                    // information. since vertices
-                                    // are sequentially numbered,
-                                    // what we do first is to set up
-                                    // an array in which we record
-                                    // whether a vertex is associated
-                                    // with any of the given fe's, by
-                                    // setting a bit. in a later
-                                    // step, we then actually
-                                    // allocate memory for the
-                                    // required dofs
-    std::vector<std::vector<bool> >
-      vertex_fe_association (finite_elements->size(),
-                            std::vector<bool> (tria->n_vertices(), false));
-      
-    for (active_cell_iterator cell=begin_active(); cell!=end(); ++cell)
-      for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
-       vertex_fe_association[cell->active_fe_index()][cell->vertex_index(v)]
-         = true;
-      
-                                    // in debug mode, make sure
-                                    // that each vertex is
-                                    // associated with at least one
-                                    // fe (note that except for
-                                    // unused vertices, all
-                                    // vertices are actually
-                                    // active)
-#ifdef DEBUG
-    for (unsigned int v=0; v<tria->n_vertices(); ++v)
-      if (tria->vertex_used(v) == true)
-       {
-         unsigned int fe=0;
-         for (; fe<finite_elements->size(); ++fe)
-           if (vertex_fe_association[fe][v] == true)
-             break;
-         Assert (fe != finite_elements->size(), ExcInternalError());
-       }
-#endif
 
-                                    // next count how much memory
-                                    // we actually need. for each
-                                    // vertex, we need one slot per
-                                    // fe to store the fe_index,
-                                    // plus dofs_per_vertex for
-                                    // this fe. in addition, we
-                                    // need one slot as the end
-                                    // marker for the
-                                    // fe_indices. at the same time
-                                    // already fill the
-                                    // vertex_dofs_offsets field
-    vertex_dofs_offsets.resize (tria->n_vertices(),
-                               numbers::invalid_unsigned_int);
-      
-    unsigned int vertex_slots_needed = 0;
-    for (unsigned int v=0; v<tria->n_vertices(); ++v)
-      if (tria->vertex_used(v) == true)
-       {
-         vertex_dofs_offsets[v] = vertex_slots_needed;
-           
-         for (unsigned int fe=0; fe<finite_elements->size(); ++fe)
-           if (vertex_fe_association[fe][v] == true)
-             vertex_slots_needed += (*finite_elements)[fe].dofs_per_vertex + 1;
-         ++vertex_slots_needed;
-       }
+  template <int dim, int spacedim>
+  unsigned int
+  DoFHandler<dim,spacedim>::max_couplings_between_boundary_dofs () const
+  {
+    Assert (finite_elements != 0, ExcNoFESelected());
 
-                                    // now allocate the space we
-                                    // have determined we need, and
-                                    // set up the linked lists for
-                                    // each of the vertices
-    vertex_dofs.resize (vertex_slots_needed, invalid_dof_index);
-    for (unsigned int v=0; v<tria->n_vertices(); ++v)
-      if (tria->vertex_used(v) == true)
-       {
-         unsigned int pointer = vertex_dofs_offsets[v];
-         for (unsigned int fe=0; fe<finite_elements->size(); ++fe)
-           if (vertex_fe_association[fe][v] == true)
-             {
-                                                // if this vertex
-                                                // uses this fe,
-                                                // then set the
-                                                // fe_index and
-                                                // move the pointer
-                                                // ahead
-               vertex_dofs[pointer] = fe;
-               pointer += (*finite_elements)[fe].dofs_per_vertex + 1;
-             }
-                                          // finally place the end
-                                          // marker
-         vertex_dofs[pointer] = numbers::invalid_unsigned_int;
-       }
-  }    
-  
+    switch (dim)
+      {
+       case 1:
+             return finite_elements->max_dofs_per_vertex();
+       case 2:
+             return (3*finite_elements->max_dofs_per_vertex()
+                     +
+                     2*finite_elements->max_dofs_per_line());
+       case 3:
+                                              // we need to take refinement of
+                                              // one boundary face into consideration
+                                              // here; in fact, this function returns
+                                              // what #max_coupling_between_dofs<2>
+                                              // returns
+                                              //
+                                              // we assume here, that only four faces
+                                              // meet at the boundary; this assumption
+                                              // is not justified and needs to be
+                                              // fixed some time. fortunately, ommitting
+                                              // it for now does no harm since the
+                                              // matrix will cry foul if its requirements
+                                              // are not satisfied
+             return (19*finite_elements->max_dofs_per_vertex() +
+                     28*finite_elements->max_dofs_per_line() +
+                     8*finite_elements->max_dofs_per_quad());
+       default:
+             Assert (false, ExcNotImplemented());
+             return 0;
+      }
+  }
 
 
-  template <int dim>
-  void DoFHandler<dim>::create_active_fe_table ()
+  
+  template<int dim, int spacedim>
+  void DoFHandler<dim,spacedim>::create_active_fe_table ()
   {
                                      // Create sufficiently many
                                      // hp::DoFLevels.
@@ -4312,9 +4383,8 @@ namespace hp
   }
 
 
-
-  template <int dim>
-  void DoFHandler<dim>::pre_refinement_notification (const Triangulation<dim> &tria)
+  template <int dim, int spacedim>
+  void DoFHandler<dim,spacedim>::pre_refinement_notification (const Triangulation<dim,spacedim> &tria)
   {
     create_active_fe_table ();
 
@@ -4373,11 +4443,39 @@ namespace hp
        has_children.push_back (has_children_level);
       }
   }
+
+
+
+  template <>
+  void DoFHandler<1,2>::pre_refinement_notification (const Triangulation<1,2> &tria)
+  {
+    create_active_fe_table ();
+
+                                     // Remember if the cells have already
+                                     // children. That will make the transfer
+                                     // of the active_fe_index to the finer
+                                     // levels easier.
+    Assert (has_children.size () == 0, ExcInternalError ());
+    for (unsigned int i=0; i<levels.size(); ++i)
+      {
+       const unsigned int lines_on_level = tria.n_raw_lines(i);
+       std::vector<bool> *has_children_level =
+          new std::vector<bool> (lines_on_level);
+
+                                         // Check for each cell, if it has children.
+       std::transform (tria.levels[i]->cells.children.begin (),
+                       tria.levels[i]->cells.children.end (),
+                       has_children_level->begin (),
+                       std::bind2nd (std::not_equal_to<int>(), -1));
+
+       has_children.push_back (has_children_level);
+      }
+  }
 #endif
 
 
-  template <int dim>
-  void DoFHandler<dim>::post_refinement_notification (const Triangulation<dim> &tria)
+  template<int dim, int spacedim>
+  void DoFHandler<dim,spacedim>::post_refinement_notification (const Triangulation<dim,spacedim> &tria)
   {
     Assert (has_children.size () == levels.size (), ExcInternalError ());
 
@@ -4461,8 +4559,8 @@ namespace hp
   }
 
 
-  template <int dim>
-  void DoFHandler<dim>::clear_space ()
+  template<int dim, int spacedim>
+  void DoFHandler<dim,spacedim>::clear_space ()
   {  
     for (unsigned int i=0; i<levels.size(); ++i)
       delete levels[i];
@@ -4484,6 +4582,12 @@ namespace hp
 
 /*-------------- Explicit Instantiations -------------------------------*/
   template class DoFHandler<deal_II_dimension>;
+
+#if deal_II_dimension != 3
+  //  template class DoFHandler<deal_II_dimension, deal_II_dimension+1>;
+#endif
+
+
 }
 
 DEAL_II_NAMESPACE_CLOSE
index 7400de54d9b753f8778b6a67a649b05bcff7302f..8593aa19740f4769a223f0e5263e4589d6ca953e 100644 (file)
@@ -18,23 +18,23 @@ DEAL_II_NAMESPACE_OPEN
 
 namespace hp
 {
-  template <int dim>
-  FECollection<dim>::FECollection ()
+  template <int dim, int spacedim>
+  FECollection<dim,spacedim>::FECollection ()
   {}
   
 
   
-  template <int dim>
-  FECollection<dim>::FECollection (const FiniteElement<dim> &fe)
+  template <int dim, int spacedim>
+  FECollection<dim,spacedim>::FECollection (const FiniteElement<dim,spacedim> &fe)
   {
     push_back (fe);
   }
   
 
   
-  template <int dim>
-  FECollection<dim>::
-  FECollection (const FECollection<dim> &fe_collection)
+  template <int dim, int spacedim>
+  FECollection<dim,spacedim>::
+  FECollection (const FECollection<dim,spacedim> &fe_collection)
                   :
                   Subscriptor (),
                                                    // copy the array
@@ -53,8 +53,8 @@ namespace hp
 
 
 
-  template <int dim>
-  void FECollection<dim>::push_back (const FiniteElement<dim> &new_fe)
+  template <int dim, int spacedim>
+  void FECollection<dim,spacedim>::push_back (const FiniteElement<dim,spacedim> &new_fe)
   {
                                      // check that the new element has the right
                                      // number of components. only check with
@@ -67,14 +67,14 @@ namespace hp
                           "same number of vector components!"));
   
     finite_elements
-      .push_back (boost::shared_ptr<const FiniteElement<dim> >(new_fe.clone()));
+      .push_back (boost::shared_ptr<const FiniteElement<dim,spacedim> >(new_fe.clone()));
   }
 
 
 
-  template <int dim>
+  template <int dim, int spacedim> 
   unsigned int
-  FECollection<dim>::memory_consumption () const
+  FECollection<dim,spacedim>::memory_consumption () const
   {
     unsigned int mem
       = (sizeof(*this) +
@@ -88,6 +88,10 @@ namespace hp
 
 // explicit instantiations
   template class FECollection<deal_II_dimension>;
+
+#if deal_II_dimension != 3
+  template class FECollection<deal_II_dimension, deal_II_dimension+1>;
+#endif
   
 }
 
index b73be928e427993d66c5d089d7f985c9b7627b96..13a2d535e32642ddbd64d4ecbb5ffe98e33708d2 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2003, 2006, 2007 by the deal.II authors
+//    Copyright (C) 2003, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -26,8 +26,8 @@ namespace internal
 
     template <int dim, int q_dim, class FEValues>
     FEValuesBase<dim,q_dim,FEValues>::
-    FEValuesBase (const dealii::hp::MappingCollection<dim> &mapping_collection,
-                  const dealii::hp::FECollection<dim>      &fe_collection,
+    FEValuesBase (const dealii::hp::MappingCollection<dim,FEValues::space_dimension> &mapping_collection,
+                  const dealii::hp::FECollection<dim,FEValues::space_dimension>      &fe_collection,
                   const dealii::hp::QCollection<q_dim>     &q_collection,
                   const UpdateFlags                   update_flags)
                     :
@@ -46,12 +46,13 @@ namespace internal
 
     template <int dim, int q_dim, class FEValues>
     FEValuesBase<dim,q_dim,FEValues>::
-    FEValuesBase (const dealii::hp::FECollection<dim>      &fe_collection,
-                  const dealii::hp::QCollection<q_dim> &q_collection,
-                  const UpdateFlags         update_flags)
+    FEValuesBase (const dealii::hp::FECollection<dim,FEValues::space_dimension>      &fe_collection,
+                 const dealii::hp::QCollection<q_dim> &q_collection,
+                 const UpdateFlags         update_flags)
                     :
-                    fe_collection (&fe_collection),
-                    mapping_collection (&dealii::hp::StaticMappingQ1<dim>::mapping_collection),
+                 fe_collection (&fe_collection),
+                 mapping_collection (&dealii::hp::StaticMappingQ1<dim,FEValues::space_dimension>::
+                                     mapping_collection),
                     q_collection (q_collection),
                     fe_values_table (fe_collection.size(),
                                      1,
@@ -112,36 +113,36 @@ namespace hp
 // -------------------------- FEValues -------------------------
 
 
-  template <int dim>
-  FEValues<dim>::FEValues (const hp::MappingCollection<dim> &mapping,
-                           const hp::FECollection<dim>      &fe_collection,
-                           const hp::QCollection<dim>       &q_collection,
-                           const UpdateFlags                 update_flags)
+  template <int dim, int spacedim>
+  FEValues<dim,spacedim>::FEValues (const hp::MappingCollection<dim,spacedim> &mapping,
+                                   const hp::FECollection<dim,spacedim>      &fe_collection,
+                                   const hp::QCollection<dim>       &q_collection,
+                                   const UpdateFlags                 update_flags)
                   :
-                  internal::hp::FEValuesBase<dim,dim,dealii::FEValues<dim> > (mapping,
+    internal::hp::FEValuesBase<dim,dim,dealii::FEValues<dim,spacedim> > (mapping,
                                                                        fe_collection,
                                                                        q_collection,
                                                                        update_flags)
   {}
 
 
-  template <int dim>
-  FEValues<dim>::FEValues (const hp::FECollection<dim> &fe_collection,
-                           const hp::QCollection<dim>      &q_collection,
-                           const UpdateFlags            update_flags)
+  template <int dim, int spacedim>
+  FEValues<dim,spacedim>::FEValues (const hp::FECollection<dim,spacedim> &fe_collection,
+                                   const hp::QCollection<dim>      &q_collection,
+                                   const UpdateFlags            update_flags)
                   :
-                  internal::hp::FEValuesBase<dim,dim,dealii::FEValues<dim> > (fe_collection,
+    internal::hp::FEValuesBase<dim,dim,dealii::FEValues<dim,spacedim> > (fe_collection,
                                                                        q_collection,
                                                                        update_flags)
   {}
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   void
-  FEValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iterator &cell,
-                         const unsigned int q_index,
-                         const unsigned int mapping_index,
-                         const unsigned int fe_index)
+  FEValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
+                                 const unsigned int q_index,
+                                 const unsigned int mapping_index,
+                                 const unsigned int fe_index)
   {
                                      // determine which indices we
                                      // should actually use
@@ -186,12 +187,12 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   void
-  FEValues<dim>::reinit (const typename dealii::DoFHandler<dim>::cell_iterator &cell,
-                         const unsigned int q_index,
-                         const unsigned int mapping_index,
-                         const unsigned int fe_index)
+  FEValues<dim,spacedim>::reinit (const typename dealii::DoFHandler<dim,spacedim>::cell_iterator &cell,
+                                 const unsigned int q_index,
+                                 const unsigned int mapping_index,
+                                 const unsigned int fe_index)
   {
                                      // determine which indices we
                                      // should actually use
@@ -226,9 +227,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   void
-  FEValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterator &cell,
+  FEValues<dim,spacedim>::reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
                          const unsigned int q_index,
                          const unsigned int mapping_index,
                          const unsigned int fe_index)
@@ -266,9 +267,9 @@ namespace hp
 
 
 
-  template <int dim>
+  template <int dim, int spacedim>
   void
-  FEValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator &cell,
+  FEValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                          const unsigned int q_index,
                          const unsigned int mapping_index,
                          const unsigned int fe_index)
@@ -735,4 +736,38 @@ namespace hp
 #endif
 }
 
+
+
+#if deal_II_dimension != 3
+
+namespace internal
+{
+  namespace hp
+  {
+    template class FEValuesBase<deal_II_dimension,deal_II_dimension,
+                                dealii::FEValues<deal_II_dimension,deal_II_dimension+1> >;
+// not yet implemented:  
+// #if deal_II_dimension == 2
+//     template class FEValuesBase<deal_II_dimension,deal_II_dimension-1,
+//                                 dealii::FEFaceValues<deal_II_dimension> >;
+//     template class FEValuesBase<deal_II_dimension,deal_II_dimension-1,
+//                                 dealii::FESubfaceValues<deal_II_dimension> >;
+// #endif
+  }
+}
+
+namespace hp
+{
+  template class FEValues<deal_II_dimension, deal_II_dimension+1>;
+
+// not yet implemented:  
+//#if deal_II_dimension == 2
+//   template class FEFaceValues<deal_II_dimension, deal_II_dimension+1>;
+//   template class FESubfaceValues<deal_II_dimension, deal_II_dimension+1>;
+//#endif
+}
+#endif
+
+
+
 DEAL_II_NAMESPACE_CLOSE
index 2d35df2b6712995d49633ffebb0fda0bb65f1017..29fc3080bcc146ed9a007f6acf3d8f92f6dfbd98 100644 (file)
@@ -20,25 +20,25 @@ DEAL_II_NAMESPACE_OPEN
 namespace hp
 {
 
-  template <int dim>
-  MappingCollection<dim>::MappingCollection ()
+  template<int dim, int spacedim>
+  MappingCollection<dim,spacedim>::MappingCollection ()
   {}
 
 
   
-  template <int dim>
-  MappingCollection<dim>::
-  MappingCollection (const Mapping<dim> &mapping)
+  template<int dim, int spacedim>
+  MappingCollection<dim,spacedim>::
+  MappingCollection (const Mapping<dim,spacedim> &mapping)
   {
     mappings
-      .push_back (boost::shared_ptr<const Mapping<dim> >(mapping.clone()));
+      .push_back (boost::shared_ptr<const Mapping<dim,spacedim> >(mapping.clone()));
   }
 
 
 
-  template <int dim>
-  MappingCollection<dim>::
-  MappingCollection (const MappingCollection<dim> &mapping_collection)
+  template<int dim, int spacedim>
+  MappingCollection<dim,spacedim>::
+  MappingCollection (const MappingCollection<dim,spacedim> &mapping_collection)
                   :
                   Subscriptor (),
                                                    // copy the array
@@ -57,9 +57,9 @@ namespace hp
   
   
 
-  template <int dim>
+  template<int dim, int spacedim>
   unsigned int
-  MappingCollection<dim>::memory_consumption () const
+  MappingCollection<dim,spacedim>::memory_consumption () const
   {
     return (sizeof(*this) +
            MemoryConsumption::memory_consumption (mappings));
@@ -67,31 +67,37 @@ namespace hp
 
   
 
-  template <int dim>
+  template<int dim, int spacedim>
   void
-  MappingCollection<dim>::push_back (const Mapping<dim> &new_mapping)
+  MappingCollection<dim,spacedim>::push_back (const Mapping<dim,spacedim> &new_mapping)
   {
     mappings
-      .push_back (boost::shared_ptr<const Mapping<dim> >(new_mapping.clone()));
+      .push_back (boost::shared_ptr<const Mapping<dim,spacedim> >(new_mapping.clone()));
   }
 
 //---------------------------------------------------------------------------
 
 
 
-  template <int dim>
-  MappingQ1<dim>
-  StaticMappingQ1<dim>::mapping_q1;
+  template<int dim, int spacedim>
+  MappingQ1<dim,spacedim>
+  StaticMappingQ1<dim,spacedim>::mapping_q1;
   
 
-  template <int dim>
-  MappingCollection<dim>
-  StaticMappingQ1<dim>::mapping_collection
-  = MappingCollection<dim>(mapping_q1);
+  template<int dim, int spacedim>
+  MappingCollection<dim,spacedim>
+  StaticMappingQ1<dim,spacedim>::mapping_collection
+  = MappingCollection<dim,spacedim>(mapping_q1);
 
 // explicit instantiations
   template class MappingCollection<deal_II_dimension>;
   template struct StaticMappingQ1<deal_II_dimension>;
+
+#if deal_II_dimension != 3
+  template class MappingCollection<deal_II_dimension,deal_II_dimension+1>;
+  template struct StaticMappingQ1<deal_II_dimension,deal_II_dimension+1>;
+
+#endif
   
 }
 
index 71c7e24afcde54c0abe8e3b75a25745d08517e6b..f72032f54ea8f7bcea2095f094467051c62d5890 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
 DEAL_II_NAMESPACE_OPEN
 
 
-//TODO:[GK] Inline simple functions in 1d and 3d
+//TODO:[GK] Inline simple functions
 
 /* ------------------------ MGDoFAccessor --------------------------- */
 
 
-template <int structdim, int dim>
-MGDoFAccessor<structdim, dim>::MGDoFAccessor ()
+template <int structdim, int dim, int spacedim>
+MGDoFAccessor<structdim, dim, spacedim>::MGDoFAccessor ()
                :
-               BaseClass (0,
-                          static_cast<int>(numbers::invalid_unsigned_int),
-                          static_cast<int>(numbers::invalid_unsigned_int),
-                          0),
-               mg_dof_handler(0)
+               BaseClass (0, -1, -1, 0)
 {
   Assert (false, ExcInvalidObject());
 }
 
 
 
-template <int structdim, int dim>
-MGDoFAccessor<structdim, dim>::MGDoFAccessor (const Triangulation<dim> *tria,
+template <int structdim, int dim, int spacedim>
+MGDoFAccessor<structdim, dim, spacedim>::MGDoFAccessor (const Triangulation<dim,spacedim> *tria,
                                              const int                 level,
                                              const int                 index,
                                              const AccessorData       *local_data)
                :
                BaseClass (tria, level, index, local_data),
-               mg_dof_handler (const_cast<MGDoFHandler<dim>*>(local_data))
+               mg_dof_handler (const_cast<MGDoFHandler<dim,spacedim>*>(local_data))
 {}
 
 
+template <int structdim, int dim, int spacedim>
+template <int structdim2, int dim2, int spacedim2>
+MGDoFAccessor<structdim,dim,spacedim>::
+MGDoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+               :
+               BaseClass (0, -1, -1, 0)
+{
+  Assert (false, ExcInvalidObject());
+}
+
 
-template <int structdim, int dim>
+
+template <int structdim, int dim, int spacedim>
+template <int structdim2, int dim2, int spacedim2>
+MGDoFAccessor<structdim,dim,spacedim>::
+MGDoFAccessor (const MGDoFAccessor<structdim2,dim2,spacedim2> &)
+               :
+               BaseClass (0, -1, -1, 0)
+{
+  Assert (false, ExcInvalidObject());
+}
+
+
+
+template <int structdim, int dim, int spacedim>
 void
-MGDoFAccessor<structdim, dim>::set_mg_dof_handler (MGDoFHandler<dim> *dh)
+MGDoFAccessor<structdim, dim, spacedim>::set_mg_dof_handler (MGDoFHandler<dim,spacedim> *dh)
 {
   typedef DoFAccessor<dim,DoFHandler<dim> > BaseClass;
   Assert (dh != 0, typename BaseClass::ExcInvalidObject());
@@ -69,9 +88,9 @@ MGDoFAccessor<structdim, dim>::set_mg_dof_handler (MGDoFHandler<dim> *dh)
 
 
 
-template <int structdim, int dim>
-MGDoFAccessor<structdim, dim> &
-MGDoFAccessor<structdim, dim>::operator = (const MGDoFAccessor &da)
+template <int structdim, int dim, int spacedim>
+MGDoFAccessor<structdim, dim, spacedim> &
+MGDoFAccessor<structdim, dim, spacedim>::operator = (const MGDoFAccessor &da)
 {
   BaseClass::operator= (*this);
   
@@ -81,9 +100,9 @@ MGDoFAccessor<structdim, dim>::operator = (const MGDoFAccessor &da)
 
 
 
-template <int structdim,int dim>
+template <int structdim,int dim, int spacedim>
 unsigned int
-MGDoFAccessor<structdim, dim>::mg_vertex_dof_index (const int level,
+MGDoFAccessor<structdim, dim, spacedim>::mg_vertex_dof_index (const int level,
                                                    const unsigned int vertex,
                                                    const unsigned int i) const
 {
@@ -103,9 +122,9 @@ MGDoFAccessor<structdim, dim>::mg_vertex_dof_index (const int level,
 }
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 void
-MGDoFAccessor<structdim, dim>::set_mg_vertex_dof_index (const int level,
+MGDoFAccessor<structdim, dim, spacedim>::set_mg_vertex_dof_index (const int level,
                                                        const unsigned int vertex,
                                                        const unsigned int i,
                                                        const unsigned int index) const
@@ -127,9 +146,9 @@ MGDoFAccessor<structdim, dim>::set_mg_vertex_dof_index (const int level,
 
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 unsigned int
-MGDoFAccessor<structdim, dim>::mg_dof_index (const int level,
+MGDoFAccessor<structdim, dim, spacedim>::mg_dof_index (const int level,
                                             const unsigned int i) const
 {
   return this->mg_dof_handler
@@ -140,8 +159,8 @@ MGDoFAccessor<structdim, dim>::mg_dof_index (const int level,
 }
 
 
-template <int structdim, int dim>
-void MGDoFAccessor<structdim, dim>::set_mg_dof_index (const int level,
+template <int structdim, int dim, int spacedim>
+void MGDoFAccessor<structdim, dim, spacedim>::set_mg_dof_index (const int level,
                                                      const unsigned int i,
                                                      const unsigned int index) const
 {
@@ -155,11 +174,11 @@ void MGDoFAccessor<structdim, dim>::set_mg_dof_index (const int level,
 
 
 
-template <int structdim, int dim>
-TriaIterator<dim,MGDoFObjectAccessor<structdim, dim> >
-MGDoFAccessor<structdim, dim>::child (const unsigned int i) const
+template <int structdim, int dim, int spacedim>
+TriaIterator<MGDoFAccessor<structdim,dim,spacedim> >
+MGDoFAccessor<structdim, dim, spacedim>::child (const unsigned int i) const
 {
-  const TriaIterator<dim,MGDoFObjectAccessor<structdim, dim> >
+  const TriaIterator<MGDoFAccessor<structdim,dim,spacedim> >
     q (this->tria,
        (structdim == dim ?
        this->level() + 1 :
@@ -180,264 +199,263 @@ MGDoFAccessor<structdim, dim>::child (const unsigned int i) const
 
 
 
-template <int structdim, int dim>
+template <int structdim, int dim, int spacedim>
 void
-MGDoFAccessor<structdim, dim>::copy_from (const MGDoFAccessor &a)
+MGDoFAccessor<structdim, dim, spacedim>::copy_from (const MGDoFAccessor &a)
 {
-  DoFObjectAccessor<structdim, DoFHandler<dim> >::copy_from (a);
+  DoFAccessor<structdim, DoFHandler<dim> >::copy_from (a);
   this->set_mg_dof_handler (a.mg_dof_handler);
 }
 
 
 
-/* ------------------------ MGDoFObjectAccessor<0> --------------------------- */
-
-template <int dim>
-MGDoFObjectAccessor<0,dim>::MGDoFObjectAccessor (const Triangulation<dim> *,
-                                                const int                 ,
-                                                const int                 ,
-                                                const AccessorData       *)
-{
-  Assert (false, ExcInternalError());
-}
-  
-
-
-/* ------------------------ MGDoFObjectAccessor<0> --------------------------- */
-
-
-template <int dim>
-MGDoFObjectAccessor<1, dim>::MGDoFObjectAccessor (const Triangulation<dim> *tria,
-                                                 const int                 level,
-                                                 const int                 index,
-                                                 const AccessorData       *local_data)
-               :
-               MGDoFAccessor<1,dim> (tria,level,index,local_data)
-{}
-
-
-
-template <int dim>
-void
-MGDoFObjectAccessor<1, dim>::get_mg_dof_indices (const int level,
-                                                std::vector<unsigned int> &dof_indices) const
-{
-  Assert (this->dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (this->mg_dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (&this->dof_handler->get_fe() != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (dof_indices.size() == (2*this->dof_handler->get_fe().dofs_per_vertex +
-                                this->dof_handler->get_fe().dofs_per_line),
-         typename BaseClass::ExcVectorDoesNotMatch());
-
-  const unsigned int dofs_per_vertex = this->dof_handler->get_fe().dofs_per_vertex,
-                    dofs_per_line   = this->dof_handler->get_fe().dofs_per_line;
-  std::vector<unsigned int>::iterator next = dof_indices.begin();
-  for (unsigned int vertex=0; vertex<2; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next++ = this->mg_vertex_dof_index(level,vertex,d);
-  for (unsigned int d=0; d<dofs_per_line; ++d)
-    *next++ = this->mg_dof_index(level,d);
-  
-  Assert (next == dof_indices.end(),
-         ExcInternalError());
-}
-
-
-template <int dim>
-template <typename number>
-void
-MGDoFObjectAccessor<1,dim>::get_mg_dof_values (const int level,
-                                              const Vector<number> &values,
-                                              Vector<number>       &dof_values) const
-{
-  Assert (this->dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (this->mg_dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (&this->dof_handler->get_fe() != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (dof_values.size() == this->dof_handler->get_fe().dofs_per_cell,
-         typename BaseClass::ExcVectorDoesNotMatch());
-  Assert (values.size() == this->dof_handler->n_dofs(),
-         typename BaseClass::ExcVectorDoesNotMatch());
-
-  const unsigned int dofs_per_vertex = this->dof_handler->get_fe().dofs_per_vertex,
-                    dofs_per_line   = this->dof_handler->get_fe().dofs_per_line;
-  typename Vector<number>::iterator next_dof_value=dof_values.begin();
-  for (unsigned int vertex=0; vertex<2; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next_dof_value++ = values(this->mg_vertex_dof_index(level,vertex,d));
-  for (unsigned int d=0; d<dofs_per_line; ++d)
-    *next_dof_value++ = values(this->mg_dof_index(level,d));
-  
-  Assert (next_dof_value == dof_values.end(),
-         ExcInternalError());
-}
-
-
-
-/* ------------------------ MGDoFObjectAccessor<2> --------------------------- */
-
-template <int dim>
-MGDoFObjectAccessor<2, dim>::MGDoFObjectAccessor (const Triangulation<dim> *tria,
-                                                 const int                 level,
-                                                 const int                 index,
-                                                 const AccessorData       *local_data)
-               :
-               MGDoFAccessor<2,dim> (tria,level,index,local_data)
-{}
-
-
-
-
-template <int dim>
-void
-MGDoFObjectAccessor<2, dim>::get_mg_dof_indices (const int level,
-                                                std::vector<unsigned int> &dof_indices) const
+template <int structdim, int dim, int spacedim>
+inline
+typename internal::MGDoFHandler::Iterators<dim,spacedim>::line_iterator
+MGDoFAccessor<structdim,dim,spacedim>::line (const unsigned int i) const
 {
-  Assert (this->dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (this->mg_dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (&this->dof_handler->get_fe() != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (dof_indices.size() == (4*this->dof_handler->get_fe().dofs_per_vertex +
-                                4*this->dof_handler->get_fe().dofs_per_line +
-                                this->dof_handler->get_fe().dofs_per_quad),
-         typename BaseClass::ExcVectorDoesNotMatch());
-
-  const unsigned int dofs_per_vertex = this->dof_handler->get_fe().dofs_per_vertex,
-                    dofs_per_line   = this->dof_handler->get_fe().dofs_per_line,
-                    dofs_per_quad   = this->dof_handler->get_fe().dofs_per_quad;
-  std::vector<unsigned int>::iterator next = dof_indices.begin();
-  for (unsigned int vertex=0; vertex<4; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next++ = this->mg_vertex_dof_index(level,vertex,d);
-  for (unsigned int line=0; line<4; ++line)
-    for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next++ = this->line(line)->mg_dof_index(level,d);
-  for (unsigned int d=0; d<dofs_per_quad; ++d)
-    *next++ = this->mg_dof_index(level,d);
+  Assert (structdim > 1, ExcImpossibleInDim(structdim));
+                                  // checking of 'i' happens in
+                                  // line_index(i)
   
-  Assert (next == dof_indices.end(),
-         ExcInternalError());
-}
-
-
-template <int dim>
-template <typename number>
-void
-MGDoFObjectAccessor<2,dim>::get_mg_dof_values (const int level,
-                                              const Vector<number> &values,
-                                              Vector<number>       &dof_values) const
-{
-  Assert (this->dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (this->mg_dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (&this->dof_handler->get_fe() != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (dof_values.size() == this->dof_handler->get_fe().dofs_per_cell,
-         typename BaseClass::ExcVectorDoesNotMatch());
-  Assert (values.size() == this->mg_dof_handler->n_dofs(level),
-         typename BaseClass::ExcVectorDoesNotMatch());
-
-  const unsigned int dofs_per_vertex = this->dof_handler->get_fe().dofs_per_vertex,
-                    dofs_per_line   = this->dof_handler->get_fe().dofs_per_line,
-                    dofs_per_quad   = this->dof_handler->get_fe().dofs_per_quad;
-  typename Vector<number>::iterator next_dof_value=dof_values.begin();
-  for (unsigned int vertex=0; vertex<4; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next_dof_value++ = values(this->mg_vertex_dof_index(level,vertex,d));
-  for (unsigned int line=0; line<4; ++line)
-    for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next_dof_value++ = values(this->line(line)->mg_dof_index(level,d));
-  for (unsigned int d=0; d<dofs_per_quad; ++d)
-    *next_dof_value++ = values(this->mg_dof_index(level,d));
-  
-  Assert (next_dof_value == dof_values.end(),
-         ExcInternalError());
+  return typename internal::MGDoFHandler::Iterators<dim,spacedim>::line_iterator
+    (
+      this->tria,
+      0,  // only sub-objects are allowed, which have no level
+      this->line_index(i),
+      this->mg_dof_handler
+    );
 }
 
 
-template <int dim>
-TriaIterator<dim,MGDoFObjectAccessor<1, dim> >
-MGDoFObjectAccessor<2, dim>::line (const unsigned int i) const
+template <int structdim, int dim, int spacedim>
+inline
+typename internal::MGDoFHandler::Iterators<dim,spacedim>::quad_iterator
+MGDoFAccessor<structdim,dim,spacedim>::quad (const unsigned int i) const
 {
-  Assert (i<4, ExcIndexRange (i, 0, 4));
+  Assert (structdim > 2, ExcImpossibleInDim(structdim));
+                                  // checking of 'i' happens in
+                                  // quad_index(i)
 
-  return TriaIterator<dim,MGDoFObjectAccessor<1, dim> >
+  return typename internal::MGDoFHandler::Iterators<dim,spacedim>::quad_iterator
     (
       this->tria,
-      0,
-      this->line_index (i),
+      0,  // only sub-objects are allowed, which have no level
+      this->quad_index (i),
       this->mg_dof_handler
     );
 }
 
 
-/* ------------------------ MGDoFObjectAccessor<3> --------------------------- */
-
-template <int dim>
-MGDoFObjectAccessor<3, dim>::MGDoFObjectAccessor (const Triangulation<dim> *tria,
-                                                 const int                 level,
-                                                 const int                 index,
-                                                 const AccessorData       *local_data)
-               :
-               MGDoFAccessor<3,dim> (tria,level,index,local_data)
-{}
 
+namespace internal
+{
+  namespace MGDoFAccessor
+  {
+    template <int dim, int spacedim>
+    void
+    get_mg_dof_indices (const dealii::MGDoFAccessor<1, dim, spacedim> &accessor,
+                       const int level,
+                       std::vector<unsigned int> &dof_indices)
+    {
+      const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
+                        dofs_per_line   = accessor.get_dof_handler().get_fe().dofs_per_line;
+      std::vector<unsigned int>::iterator next = dof_indices.begin();
+      for (unsigned int vertex=0; vertex<2; ++vertex)
+       for (unsigned int d=0; d<dofs_per_vertex; ++d)
+         *next++ = accessor.mg_vertex_dof_index(level,vertex,d);
+      for (unsigned int d=0; d<dofs_per_line; ++d)
+       *next++ = accessor.mg_dof_index(level,d);
+  
+      Assert (next == dof_indices.end(),
+             ExcInternalError());
+    }
+
+
+    template <int dim, int spacedim, typename number>
+    void
+    get_mg_dof_values (const dealii::MGDoFAccessor<1, dim, spacedim> &accessor,
+                      const int level,
+                      const Vector<number> &values,
+                      Vector<number>       &dof_values)
+    {
+      const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
+                        dofs_per_line   = accessor.get_dof_handler().get_fe().dofs_per_line;
+      typename Vector<number>::iterator next_dof_value=dof_values.begin();
+      for (unsigned int vertex=0; vertex<2; ++vertex)
+       for (unsigned int d=0; d<dofs_per_vertex; ++d)
+         *next_dof_value++ = values(accessor.mg_vertex_dof_index(level,vertex,d));
+      for (unsigned int d=0; d<dofs_per_line; ++d)
+       *next_dof_value++ = values(accessor.mg_dof_index(level,d));
+  
+      Assert (next_dof_value == dof_values.end(),
+             ExcInternalError());
+    }
+
+
+
+
+    template <int dim, int spacedim>
+    void
+    get_mg_dof_indices (const dealii::MGDoFAccessor<2, dim, spacedim> &accessor,
+                       const int level,
+                       std::vector<unsigned int> &dof_indices)
+    {
+      const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
+                        dofs_per_line   = accessor.get_dof_handler().get_fe().dofs_per_line,
+                        dofs_per_quad   = accessor.get_dof_handler().get_fe().dofs_per_quad;
+      std::vector<unsigned int>::iterator next = dof_indices.begin();
+      for (unsigned int vertex=0; vertex<4; ++vertex)
+       for (unsigned int d=0; d<dofs_per_vertex; ++d)
+         *next++ = accessor.mg_vertex_dof_index(level,vertex,d);
+      for (unsigned int line=0; line<4; ++line)
+       for (unsigned int d=0; d<dofs_per_line; ++d)
+         *next++ = accessor.line(line)->mg_dof_index(level,d);
+      for (unsigned int d=0; d<dofs_per_quad; ++d)
+       *next++ = accessor.mg_dof_index(level,d);
+  
+      Assert (next == dof_indices.end(),
+             ExcInternalError());
+    }
+
+
+    template <int dim, int spacedim, typename number>
+    void
+    get_mg_dof_values (const dealii::MGDoFAccessor<2, dim, spacedim> &accessor,
+                      const int level,
+                      const Vector<number> &values,
+                      Vector<number>       &dof_values)
+    {
+      const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
+                        dofs_per_line   = accessor.get_dof_handler().get_fe().dofs_per_line,
+                        dofs_per_quad   = accessor.get_dof_handler().get_fe().dofs_per_quad;
+      typename Vector<number>::iterator next_dof_value=dof_values.begin();
+      for (unsigned int vertex=0; vertex<4; ++vertex)
+       for (unsigned int d=0; d<dofs_per_vertex; ++d)
+         *next_dof_value++ = values(accessor.mg_vertex_dof_index(level,vertex,d));
+      for (unsigned int line=0; line<4; ++line)
+       for (unsigned int d=0; d<dofs_per_line; ++d)
+         *next_dof_value++ = values(accessor.line(line)->mg_dof_index(level,d));
+      for (unsigned int d=0; d<dofs_per_quad; ++d)
+       *next_dof_value++ = values(accessor.mg_dof_index(level,d));
+  
+      Assert (next_dof_value == dof_values.end(),
+             ExcInternalError());
+    }
+
+
+    template <int dim, int spacedim>
+    void
+    get_mg_dof_indices (const dealii::MGDoFAccessor<3, dim, spacedim> &accessor,
+                       const int level,
+                       std::vector<unsigned int> &dof_indices)
+    {
+      const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
+                        dofs_per_line   = accessor.get_dof_handler().get_fe().dofs_per_line,
+                        dofs_per_quad   = accessor.get_dof_handler().get_fe().dofs_per_quad,
+                        dofs_per_hex    = accessor.get_dof_handler().get_fe().dofs_per_hex;
+      std::vector<unsigned int>::iterator next = dof_indices.begin();
+      for (unsigned int vertex=0; vertex<8; ++vertex)
+       for (unsigned int d=0; d<dofs_per_vertex; ++d)
+         *next++ = accessor.mg_vertex_dof_index(level,vertex,d);
+      for (unsigned int line=0; line<12; ++line)
+       for (unsigned int d=0; d<dofs_per_line; ++d)
+         *next++ = accessor.line(line)->mg_dof_index(level,d);
+      for (unsigned int quad=0; quad<6; ++quad)
+       for (unsigned int d=0; d<dofs_per_quad; ++d)
+         *next++ = accessor.quad(quad)->mg_dof_index(level,d);
+      for (unsigned int d=0; d<dofs_per_hex; ++d)
+       *next++ = accessor.mg_dof_index(level,d);
+  
+      Assert (next == dof_indices.end(),
+             ExcInternalError());
+    }
+
+
+    template <int dim, int spacedim, typename number>
+    void
+    get_mg_dof_values (const dealii::MGDoFAccessor<3, dim, spacedim> &accessor,
+                      const int level,
+                      const Vector<number> &values,
+                      Vector<number>       &dof_values)
+    {
+      const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
+                        dofs_per_line   = accessor.get_dof_handler().get_fe().dofs_per_line,
+                        dofs_per_quad   = accessor.get_dof_handler().get_fe().dofs_per_quad,
+                        dofs_per_hex    = accessor.get_dof_handler().get_fe().dofs_per_hex;
+      typename Vector<number>::iterator next_dof_value=dof_values.begin();
+      for (unsigned int vertex=0; vertex<8; ++vertex)
+       for (unsigned int d=0; d<dofs_per_vertex; ++d)
+         *next_dof_value++ = values(accessor.mg_vertex_dof_index(level,vertex,d));
+      for (unsigned int line=0; line<12; ++line)
+       for (unsigned int d=0; d<dofs_per_line; ++d)
+         *next_dof_value++ = values(accessor.line(line)->mg_dof_index(level,d));
+      for (unsigned int quad=0; quad<6; ++quad)
+       for (unsigned int d=0; d<dofs_per_quad; ++d)
+         *next_dof_value++ = values(accessor.quad(quad)->mg_dof_index(level,d));
+      for (unsigned int d=0; d<dofs_per_hex; ++d)
+       *next_dof_value++ = values(accessor.dof_index(d));
+  
+      Assert (next_dof_value == dof_values.end(),
+             ExcInternalError());
+    }
+  }
+}
 
 
 
-template <int dim>
+template <int structdim, int dim, int spacedim>
 void
-MGDoFObjectAccessor<3, dim>::get_mg_dof_indices (const int level,
-                                                std::vector<unsigned int> &dof_indices) const
+MGDoFAccessor<structdim, dim, spacedim>::
+get_mg_dof_indices (const int level,
+                   std::vector<unsigned int> &dof_indices) const
 {
   Assert (this->dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
+         ExcInvalidObject());
   Assert (this->mg_dof_handler != 0,
-         typename BaseClass::ExcInvalidObject());
+         ExcInvalidObject());
   Assert (&this->dof_handler->get_fe() != 0,
-         typename BaseClass::ExcInvalidObject());
-  Assert (dof_indices.size() == (8*this->dof_handler->get_fe().dofs_per_vertex +
-                                12*this->dof_handler->get_fe().dofs_per_line +
-                                6*this->dof_handler->get_fe().dofs_per_quad +
-                                this->dof_handler->get_fe().dofs_per_hex),
-         typename BaseClass::ExcVectorDoesNotMatch());
-
-  const unsigned int dofs_per_vertex = this->dof_handler->get_fe().dofs_per_vertex,
-                    dofs_per_line   = this->dof_handler->get_fe().dofs_per_line,
-                    dofs_per_quad   = this->dof_handler->get_fe().dofs_per_quad,
-                    dofs_per_hex    = this->dof_handler->get_fe().dofs_per_hex;
-  std::vector<unsigned int>::iterator next = dof_indices.begin();
-  for (unsigned int vertex=0; vertex<8; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next++ = this->mg_vertex_dof_index(level,vertex,d);
-  for (unsigned int line=0; line<12; ++line)
-    for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next++ = this->line(line)->mg_dof_index(level,d);
-  for (unsigned int quad=0; quad<6; ++quad)
-    for (unsigned int d=0; d<dofs_per_quad; ++d)
-      *next++ = this->quad(quad)->mg_dof_index(level,d);
-  for (unsigned int d=0; d<dofs_per_hex; ++d)
-    *next++ = this->mg_dof_index(level,d);
-  
-  Assert (next == dof_indices.end(),
-         ExcInternalError());
+         ExcInvalidObject());
+  switch (structdim)
+    {
+      case 1:
+           Assert (dof_indices.size() ==
+                   (2*this->dof_handler->get_fe().dofs_per_vertex +
+                    this->dof_handler->get_fe().dofs_per_line),
+                   typename BaseClass::ExcVectorDoesNotMatch());
+           break;
+      case 2:
+           Assert (dof_indices.size() ==
+                   (4*this->dof_handler->get_fe().dofs_per_vertex +
+                    4*this->dof_handler->get_fe().dofs_per_line +
+                    this->dof_handler->get_fe().dofs_per_quad),
+                   typename BaseClass::ExcVectorDoesNotMatch());
+           break;
+      case 3:
+           Assert (dof_indices.size() ==
+                   (8*this->dof_handler->get_fe().dofs_per_vertex +
+                    12*this->dof_handler->get_fe().dofs_per_line +
+                    6*this->dof_handler->get_fe().dofs_per_quad +
+                    this->dof_handler->get_fe().dofs_per_hex),
+                   typename BaseClass::ExcVectorDoesNotMatch());
+
+           break;
+      default:
+           Assert (false, ExcNotImplemented());
+    }
+
+  internal::MGDoFAccessor::get_mg_dof_indices (*this, level, dof_indices);
 }
 
 
-template <int dim>
+
+template <int structdim, int dim, int spacedim>
 template <typename number>
 void
-MGDoFObjectAccessor<3,dim>::get_mg_dof_values (const int level,
-                                              const Vector<number> &values,
-                                              Vector<number>       &dof_values) const
+MGDoFAccessor<structdim,dim,spacedim>::
+get_mg_dof_values (const int level,
+                  const Vector<number> &values,
+                  Vector<number>       &dof_values) const
 {
   Assert (this->dof_handler != 0,
          typename BaseClass::ExcInvalidObject());
@@ -450,97 +468,52 @@ MGDoFObjectAccessor<3,dim>::get_mg_dof_values (const int level,
   Assert (values.size() == this->mg_dof_handler->n_dofs(level),
          typename BaseClass::ExcVectorDoesNotMatch());
 
-  const unsigned int dofs_per_vertex = this->dof_handler->get_fe().dofs_per_vertex,
-                    dofs_per_line   = this->dof_handler->get_fe().dofs_per_line,
-                    dofs_per_quad   = this->dof_handler->get_fe().dofs_per_quad,
-                    dofs_per_hex    = this->dof_handler->get_fe().dofs_per_hex;
-  typename Vector<number>::iterator next_dof_value=dof_values.begin();
-  for (unsigned int vertex=0; vertex<8; ++vertex)
-    for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next_dof_value++ = values(this->mg_vertex_dof_index(level,vertex,d));
-  for (unsigned int line=0; line<12; ++line)
-    for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next_dof_value++ = values(this->line(line)->mg_dof_index(level,d));
-  for (unsigned int quad=0; quad<6; ++quad)
-    for (unsigned int d=0; d<dofs_per_quad; ++d)
-      *next_dof_value++ = values(this->quad(quad)->mg_dof_index(level,d));
-  for (unsigned int d=0; d<dofs_per_hex; ++d)
-    *next_dof_value++ = values(this->dof_index(d));
-  
-  Assert (next_dof_value == dof_values.end(),
-         ExcInternalError());
+  internal::MGDoFAccessor::get_mg_dof_values (*this, level, values, dof_values);
 }
 
 
-template <int dim>
-TriaIterator<dim,MGDoFObjectAccessor<1, dim> >
-MGDoFObjectAccessor<3, dim>::line (const unsigned int i) const
-{
-  Assert (i<12, ExcIndexRange (i, 0, 12));
 
-  return TriaIterator<dim,MGDoFObjectAccessor<1, dim> >
-    (
-      this->tria,
-      0,
-      this->line_index (i),
-      this->mg_dof_handler
-    );
-}
 
 
-template <int dim>
-TriaIterator<dim,MGDoFObjectAccessor<2, dim> >
-MGDoFObjectAccessor<3, dim>::quad (const unsigned int i) const
-{
-  Assert (i<6, ExcIndexRange (i, 0, 6));
-
-  return TriaIterator<dim,MGDoFObjectAccessor<2, dim> >
-    (
-      this->tria,
-      0,
-      this->quad_index (i),
-      this->mg_dof_handler
-    );
-}
 
 
 
 /*------------------------- Functions: MGDoFCellAccessor -----------------------*/
 
-template <int dim>
-MGDoFCellAccessor<dim>::MGDoFCellAccessor (const Triangulation<dim> *tria,
+template <int dim, int spacedim>
+MGDoFCellAccessor<dim,spacedim>::MGDoFCellAccessor (const Triangulation<dim,spacedim> *tria,
                                           const int                 level,
                                           const int                 index,
                                           const AccessorData       *local_data)
                :
-               MGDoFObjectAccessor<dim, dim> (tria,level,index,local_data)
+               MGDoFAccessor<dim, dim, spacedim> (tria,level,index,local_data)
 {}
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-MGDoFCellAccessor<dim>::get_mg_dof_indices (std::vector<unsigned int> &dof_indices) const
+MGDoFCellAccessor<dim,spacedim>::get_mg_dof_indices (std::vector<unsigned int> &dof_indices) const
 {
-  MGDoFObjectAccessor<dim, dim>::get_mg_dof_indices (this->level(), dof_indices);
+  MGDoFAccessor<dim,dim,spacedim>::get_mg_dof_indices (this->level(), dof_indices);
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename number>
 void
-MGDoFCellAccessor<dim>::get_mg_dof_values (const Vector<number> &values,
+MGDoFCellAccessor<dim,spacedim>::get_mg_dof_values (const Vector<number> &values,
                                           Vector<number>       &dof_values) const
 {
-  MGDoFObjectAccessor<dim, dim>::get_mg_dof_values (this->level(), values, dof_values);
+  MGDoFAccessor<dim,dim,spacedim>::get_mg_dof_values (this->level(), values, dof_values);
 }
 
 
 
-template <int dim>
-TriaIterator<dim,MGDoFCellAccessor<dim> >
-MGDoFCellAccessor<dim>::neighbor (const unsigned int i) const
+template <int dim, int spacedim>
+TriaIterator<MGDoFCellAccessor<dim,spacedim> >
+MGDoFCellAccessor<dim,spacedim>::neighbor (const unsigned int i) const
 {
-  TriaIterator<dim,MGDoFCellAccessor<dim> > q (this->tria,
+  TriaIterator<MGDoFCellAccessor<dim,spacedim> > q (this->tria,
                                               this->neighbor_level (i),
                                               this->neighbor_index (i),
                                               this->mg_dof_handler);
@@ -553,11 +526,11 @@ MGDoFCellAccessor<dim>::neighbor (const unsigned int i) const
 }
 
 
-template <int dim>
-TriaIterator<dim,MGDoFCellAccessor<dim> >
-MGDoFCellAccessor<dim>::child (const unsigned int i) const
+template <int dim, int spacedim>
+TriaIterator<MGDoFCellAccessor<dim,spacedim> >
+MGDoFCellAccessor<dim,spacedim>::child (const unsigned int i) const
 {
-  TriaIterator<dim,MGDoFCellAccessor<dim> > q (this->tria,
+  TriaIterator<MGDoFCellAccessor<dim,spacedim> > q (this->tria,
                                               this->present_level+1,
                                               this->child_index (i),
                                               this->mg_dof_handler);
@@ -570,53 +543,36 @@ MGDoFCellAccessor<dim>::child (const unsigned int i) const
 }
 
 
-#if deal_II_dimension == 1
-
-template <>
-MGDoFCellAccessor<1>::face_iterator
-MGDoFCellAccessor<1>::face (const unsigned int) const
+template <int dim, int spacedim>
+typename internal::MGDoFHandler::Iterators<dim,spacedim>::face_iterator
+MGDoFCellAccessor<dim,spacedim>::face (const unsigned int i) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return face_iterator();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return
+             typename internal::MGDoFHandler::Iterators<dim,spacedim>::face_iterator();
+      case 2:
+           return this->line(i);
+      case 3:
+           return this->quad(i);
+      default:
+           Assert (false, ExcNotImplemented());
+    }
 }
 
-#endif
-
-
-#if deal_II_dimension == 2
-
-template <>
-MGDoFCellAccessor<2>::face_iterator
-MGDoFCellAccessor<2>::face (const unsigned int i) const
-{
-  return this->line(i);
-}
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-template <>
-MGDoFCellAccessor<3>::face_iterator
-MGDoFCellAccessor<3>::face (const unsigned int i) const
-{
-  return this->quad(i);
-}
-
-#endif
-
 
 
-template <int dim>
-TriaIterator<dim,MGDoFCellAccessor<dim> >
-MGDoFCellAccessor<dim>::
+template <int dim, int spacedim>
+typename internal::MGDoFHandler::Iterators<dim,spacedim>::cell_iterator
+MGDoFCellAccessor<dim,spacedim>::
 neighbor_child_on_subface (const unsigned int face,
                            const unsigned int subface) const
 {
-  const TriaIterator<dim,CellAccessor<dim> > q
-    = CellAccessor<dim>::neighbor_child_on_subface (face, subface);
-  return TriaIterator<dim,MGDoFCellAccessor<dim> > (this->tria,
+  const TriaIterator<CellAccessor<dim,spacedim> > q
+    = CellAccessor<dim,spacedim>::neighbor_child_on_subface (face, subface);
+  return TriaIterator<MGDoFCellAccessor<dim,spacedim> > (this->tria,
                                                    q->level (),
                                                    q->index (),
                                                    this->mg_dof_handler);
@@ -629,14 +585,14 @@ neighbor_child_on_subface (const unsigned int face,
 
 template
 void
-MGDoFObjectAccessor<1,deal_II_dimension>::
+MGDoFAccessor<1,deal_II_dimension>::
 get_mg_dof_values (const int level,
                   const Vector<double> &values,
                   Vector<double>       &dof_values) const;
 
 template
 void
-MGDoFObjectAccessor<1,deal_II_dimension>::
+MGDoFAccessor<1,deal_II_dimension>::
 get_mg_dof_values (const int level,
                   const Vector<float> &values,
                   Vector<float>       &dof_values) const;
@@ -646,14 +602,14 @@ get_mg_dof_values (const int level,
 
 template
 void
-MGDoFObjectAccessor<2,deal_II_dimension>::
+MGDoFAccessor<2,deal_II_dimension>::
 get_mg_dof_values (const int level,
                   const Vector<double> &values,
                   Vector<double>       &dof_values) const;
 
 template
 void
-MGDoFObjectAccessor<2,deal_II_dimension>::
+MGDoFAccessor<2,deal_II_dimension>::
 get_mg_dof_values (const int level,
                   const Vector<float> &values,
                   Vector<float>       &dof_values) const;
@@ -665,14 +621,14 @@ get_mg_dof_values (const int level,
 
 template
 void
-MGDoFObjectAccessor<3,deal_II_dimension>::
+MGDoFAccessor<3,deal_II_dimension>::
 get_mg_dof_values (const int level,
                   const Vector<double> &values,
                   Vector<double>       &dof_values) const;
 
 template
 void
-MGDoFObjectAccessor<3,deal_II_dimension>::
+MGDoFAccessor<3,deal_II_dimension>::
 get_mg_dof_values (const int level,
                   const Vector<float> &values,
                   Vector<float>       &dof_values) const;
@@ -695,29 +651,26 @@ get_mg_dof_values (const Vector<float> &values,
 #if deal_II_dimension == 1
 template class MGDoFAccessor<1, 1>;
 
-template class MGDoFObjectAccessor<1, 1>;
 template class MGDoFCellAccessor<1>;
 
-template class TriaRawIterator<1,MGDoFCellAccessor<1> >;
-template class TriaIterator<1,MGDoFCellAccessor<1> >;
-template class TriaActiveIterator<1,MGDoFCellAccessor<1> >;
+template class TriaRawIterator<MGDoFCellAccessor<1> >;
+template class TriaIterator<MGDoFCellAccessor<1> >;
+template class TriaActiveIterator<MGDoFCellAccessor<1> >;
 #endif
 
 #if deal_II_dimension == 2
 template class MGDoFAccessor<1, 2>;
 template class MGDoFAccessor<2, 2>;
 
-template class MGDoFObjectAccessor<1, 2>;
-template class MGDoFObjectAccessor<2, 2>;
 template class MGDoFCellAccessor<2>;
 
-template class TriaRawIterator   <2,MGDoFObjectAccessor<1, 2> >;
-template class TriaIterator      <2,MGDoFObjectAccessor<1, 2> >;
-template class TriaActiveIterator<2,MGDoFObjectAccessor<1, 2> >;
+template class TriaRawIterator   <MGDoFAccessor<1, 2> >;
+template class TriaIterator      <MGDoFAccessor<1, 2> >;
+template class TriaActiveIterator<MGDoFAccessor<1, 2> >;
 
-template class TriaRawIterator   <2,MGDoFCellAccessor<2> >;
-template class TriaIterator      <2,MGDoFCellAccessor<2> >;
-template class TriaActiveIterator<2,MGDoFCellAccessor<2> >;
+template class TriaRawIterator   <MGDoFCellAccessor<2> >;
+template class TriaIterator      <MGDoFCellAccessor<2> >;
+template class TriaActiveIterator<MGDoFCellAccessor<2> >;
 #endif
 
 
@@ -726,22 +679,19 @@ template class MGDoFAccessor<1, 3>;
 template class MGDoFAccessor<2, 3>;
 template class MGDoFAccessor<3, 3>;
 
-template class MGDoFObjectAccessor<1, 3>;
-template class MGDoFObjectAccessor<2, 3>;
-template class MGDoFObjectAccessor<3, 3>;
 template class MGDoFCellAccessor<3>;
 
-template class TriaRawIterator   <3,MGDoFObjectAccessor<1, 3> >;
-template class TriaIterator      <3,MGDoFObjectAccessor<1, 3> >;
-template class TriaActiveIterator<3,MGDoFObjectAccessor<1, 3> >;
+template class TriaRawIterator   <MGDoFAccessor<1, 3> >;
+template class TriaIterator      <MGDoFAccessor<1, 3> >;
+template class TriaActiveIterator<MGDoFAccessor<1, 3> >;
 
-template class TriaRawIterator   <3,MGDoFObjectAccessor<2, 3> >;
-template class TriaIterator      <3,MGDoFObjectAccessor<2, 3> >;
-template class TriaActiveIterator<3,MGDoFObjectAccessor<2, 3> >;
+template class TriaRawIterator   <MGDoFAccessor<2, 3> >;
+template class TriaIterator      <MGDoFAccessor<2, 3> >;
+template class TriaActiveIterator<MGDoFAccessor<2, 3> >;
 
-template class TriaRawIterator   <3,MGDoFCellAccessor<3> >;
-template class TriaIterator      <3,MGDoFCellAccessor<3> >;
-template class TriaActiveIterator<3,MGDoFCellAccessor<3> >;
+template class TriaRawIterator   <MGDoFCellAccessor<3> >;
+template class TriaIterator      <MGDoFCellAccessor<3> >;
+template class TriaActiveIterator<MGDoFCellAccessor<3> >;
 #endif
 
 DEAL_II_NAMESPACE_CLOSE
index 03f935e065413260e5ba3ab20a06cb060c25e7db..ad9996744cea1ff02b8bb7096d4658f20d7351d0 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
+//TODO[WB]: this class is currently only implemented for dim==spacedim. to
+//make the general case happen it should undergo a similar transformation as
+//the ::DoFHandler class, i.e. much of the functions here that are dimension
+//dependent should be moved into a local Implementation class.
+
 
 /* ------------------------ MGVertexDoFs ----------------------------------- */
 //TODO: This seems horrible memory fragmentation!
 
-template <int dim>
-MGDoFHandler<dim>::MGVertexDoFs::MGVertexDoFs ()
+template <int dim, int spacedim>
+MGDoFHandler<dim,spacedim>::MGVertexDoFs::MGVertexDoFs ()
                :
                coarsest_level (numbers::invalid_unsigned_int),
                finest_level (0),
@@ -44,8 +49,8 @@ MGDoFHandler<dim>::MGVertexDoFs::MGVertexDoFs ()
 {}
 
 
-template <int dim>
-void MGDoFHandler<dim>::MGVertexDoFs::init (const unsigned int cl,
+template <int dim, int spacedim>
+void MGDoFHandler<dim,spacedim>::MGVertexDoFs::init (const unsigned int cl,
                                            const unsigned int fl,
                                            const unsigned int dofs_per_vertex)
 {
@@ -74,16 +79,16 @@ void MGDoFHandler<dim>::MGVertexDoFs::init (const unsigned int cl,
 }
 
 
-template <int dim>
-MGDoFHandler<dim>::MGVertexDoFs::~MGVertexDoFs ()
+template <int dim, int spacedim>
+MGDoFHandler<dim,spacedim>::MGVertexDoFs::~MGVertexDoFs ()
 {
   delete[] indices;
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::MGVertexDoFs &
-MGDoFHandler<dim>::MGVertexDoFs::operator = (const MGVertexDoFs &)
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::MGVertexDoFs &
+MGDoFHandler<dim,spacedim>::MGVertexDoFs::operator = (const MGVertexDoFs &)
 {
   Assert (false,
          ExcMessage ("We don't know how many dofs per vertex there are, so there's "
@@ -93,41 +98,41 @@ MGDoFHandler<dim>::MGVertexDoFs::operator = (const MGVertexDoFs &)
 
 
 
-template <int dim>
-unsigned int MGDoFHandler<dim>::MGVertexDoFs::get_coarsest_level () const {
+template <int dim, int spacedim>
+unsigned int MGDoFHandler<dim,spacedim>::MGVertexDoFs::get_coarsest_level () const {
   return coarsest_level;
 }
 
 
-template <int dim>
-unsigned int MGDoFHandler<dim>::MGVertexDoFs::get_finest_level () const {
+template <int dim, int spacedim>
+unsigned int MGDoFHandler<dim,spacedim>::MGVertexDoFs::get_finest_level () const {
   return finest_level;
 }
 
 
 /* ------------------------ MGDoFHandler ------------------------------------- */
 
-template <int dim>
-const unsigned int MGDoFHandler<dim>::dimension;
+template <int dim, int spacedim>
+const unsigned int MGDoFHandler<dim,spacedim>::dimension;
 
 
-template <int dim>
-MGDoFHandler<dim>::MGDoFHandler (const Triangulation<dim> &tria) :
+template <int dim, int spacedim>
+MGDoFHandler<dim,spacedim>::MGDoFHandler (const Triangulation<dim,spacedim> &tria) :
                DoFHandler<dim> (tria),
                mg_faces (NULL)
 {}
 
 
-template <int dim>
-MGDoFHandler<dim>::~MGDoFHandler ()
+template <int dim, int spacedim>
+MGDoFHandler<dim,spacedim>::~MGDoFHandler ()
 {
   clear ();
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 unsigned int
-MGDoFHandler<dim>::memory_consumption() const
+MGDoFHandler<dim,spacedim>::memory_consumption() const
 {
   unsigned int mem = DoFHandler<dim>::memory_consumption();
   for (unsigned int l=0;l<mg_levels.size();++l)
@@ -144,1330 +149,1042 @@ MGDoFHandler<dim>::memory_consumption() const
 }
 
 
-#if deal_II_dimension == 1
-
-template <>
-MGDoFHandler<1>::raw_cell_iterator
-MGDoFHandler<1>::begin_raw (const unsigned int level) const
-{
-  return begin_raw_line (level);
-}
-
-
-template <>
-MGDoFHandler<1>::cell_iterator
-MGDoFHandler<1>::begin (const unsigned int level) const
-{
-  return begin_line (level);
-}
-
-
-template <>
-MGDoFHandler<1>::active_cell_iterator
-MGDoFHandler<1>::begin_active (const unsigned int level) const
-{
-  return begin_active_line (level);
-}
-
-
-template <>
-MGDoFHandler<1>::raw_cell_iterator
-MGDoFHandler<1>::end () const
-{
-  return end_line ();
-}
-
-
-template <>
-MGDoFHandler<1>::raw_cell_iterator
-MGDoFHandler<1>::last_raw () const
-{
-  return last_raw_line ();
-}
-
-
-template <>
-MGDoFHandler<1>::raw_cell_iterator
-MGDoFHandler<1>::last_raw (const unsigned int level) const
-{
-  return last_raw_line (level);
-}
-
-
-template <>
-MGDoFHandler<1>::cell_iterator
-MGDoFHandler<1>::last () const
-{
-  return last_line ();
-}
-
-
-template <>
-MGDoFHandler<1>::cell_iterator
-MGDoFHandler<1>::last (const unsigned int level) const
-{
-  return last_line (level);
-}
-
-
-template <>
-MGDoFHandler<1>::active_cell_iterator
-MGDoFHandler<1>::last_active () const
-{
-  return last_active_line ();
-}
-
-
-template <>
-MGDoFHandler<1>::active_cell_iterator
-MGDoFHandler<1>::last_active (const unsigned int level) const
-{
-  return last_active_line (level);
-}
-
-
-template <>
-internal::MGDoFHandler::Iterators<1>::raw_face_iterator
-MGDoFHandler<1>::begin_raw_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-internal::MGDoFHandler::Iterators<1>::face_iterator
-MGDoFHandler<1>::begin_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-internal::MGDoFHandler::Iterators<1>::active_face_iterator
-MGDoFHandler<1>::begin_active_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-internal::MGDoFHandler::Iterators<1>::raw_face_iterator
-MGDoFHandler<1>::end_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-internal::MGDoFHandler::Iterators<1>::raw_face_iterator
-MGDoFHandler<1>::end_raw_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-internal::MGDoFHandler::Iterators<1>::active_face_iterator
-MGDoFHandler<1>::end_active_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-internal::MGDoFHandler::Iterators<1>::raw_face_iterator
-MGDoFHandler<1>::last_raw_face () const 
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-internal::MGDoFHandler::Iterators<1>::face_iterator
-MGDoFHandler<1>::last_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-internal::MGDoFHandler::Iterators<1>::active_face_iterator
-MGDoFHandler<1>::last_active_face () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-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;
-}
+/*------------------------ Cell iterator functions ------------------------*/
 
 
-template <>
-MGDoFHandler<1>::raw_quad_iterator
-MGDoFHandler<1>::end_quad () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_cell_iterator
+MGDoFHandler<dim,spacedim>::begin_raw (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-MGDoFHandler<1>::quad_iterator
-MGDoFHandler<1>::end_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-MGDoFHandler<1>::raw_quad_iterator
-MGDoFHandler<1>::end_raw_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-MGDoFHandler<1>::active_quad_iterator
-MGDoFHandler<1>::end_active_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-MGDoFHandler<1>::raw_quad_iterator
-MGDoFHandler<1>::last_raw_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
-
-template <>
-MGDoFHandler<1>::quad_iterator
-MGDoFHandler<1>::last_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return begin_raw_line (level);
+      case 2:
+           return begin_raw_quad (level);
+      case 3:
+           return begin_raw_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_cell_iterator();
+    }
 }
 
 
-template <>
-MGDoFHandler<1>::active_quad_iterator
-MGDoFHandler<1>::last_active_quad (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
 
-template <>
-MGDoFHandler<1>::raw_quad_iterator
-MGDoFHandler<1>::last_raw_quad () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::cell_iterator
+MGDoFHandler<dim,spacedim>::begin (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return begin_line (level);
+      case 2:
+           return begin_quad (level);
+      case 3:
+           return begin_hex (level);
+      default:
+           Assert (false, ExcImpossibleInDim(dim));
+           return cell_iterator();
+    }
 }
 
 
-template <>
-MGDoFHandler<1>::quad_iterator
-MGDoFHandler<1>::last_quad () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
 
-template <>
-MGDoFHandler<1>::active_quad_iterator
-MGDoFHandler<1>::last_active_quad () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::active_cell_iterator
+MGDoFHandler<dim,spacedim>::begin_active (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return begin_active_line (level);
+      case 2:
+           return begin_active_quad (level);
+      case 3:
+           return begin_active_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_cell_iterator();
+    }
 }
 
 
-template <>
-MGDoFHandler<1>::raw_hex_iterator
-MGDoFHandler<1>::begin_raw_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
 
-template <>
-MGDoFHandler<1>::hex_iterator
-MGDoFHandler<1>::begin_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_cell_iterator
+MGDoFHandler<dim,spacedim>::last_raw () const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_raw_line ();
+      case 2:
+           return last_raw_quad ();
+      case 3:
+           return last_raw_hex ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_cell_iterator();
+    }
 }
 
 
-template <>
-MGDoFHandler<1>::active_hex_iterator
-MGDoFHandler<1>::begin_active_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
 
-template <>
-MGDoFHandler<1>::raw_hex_iterator
-MGDoFHandler<1>::end_hex () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_cell_iterator
+MGDoFHandler<dim,spacedim>::last_raw (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_raw_line (level);
+      case 2:
+           return last_raw_quad (level);
+      case 3:
+           return last_raw_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_cell_iterator();
+    }
 }
 
 
-template <>
-MGDoFHandler<1>::hex_iterator
-MGDoFHandler<1>::end_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
 
-template <>
-MGDoFHandler<1>::raw_hex_iterator
-MGDoFHandler<1>::end_raw_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::cell_iterator
+MGDoFHandler<dim,spacedim>::last () const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_line ();
+      case 2:
+           return last_quad ();
+      case 3:
+           return last_hex ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return cell_iterator();
+    }
 }
 
 
-template <>
-MGDoFHandler<1>::active_hex_iterator
-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
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::cell_iterator
+MGDoFHandler<dim,spacedim>::last (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_line (level);
+      case 2:
+           return last_quad (level);
+      case 3:
+           return last_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return cell_iterator();
+    }
 }
 
 
-template <>
-MGDoFHandler<1>::raw_hex_iterator
-MGDoFHandler<1>::last_raw_hex () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
 
-template <>
-MGDoFHandler<1>::hex_iterator
-MGDoFHandler<1>::last_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::active_cell_iterator
+MGDoFHandler<dim,spacedim>::last_active () const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_active_line ();
+      case 2:
+           return last_active_quad ();
+      case 3:
+           return last_active_hex ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_cell_iterator();
+    }
 }
 
 
-template <>
-MGDoFHandler<1>::hex_iterator
-MGDoFHandler<1>::last_hex () const
-{
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
-}
-
 
-template <>
-MGDoFHandler<1>::active_hex_iterator
-MGDoFHandler<1>::last_active_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::active_cell_iterator
+MGDoFHandler<dim,spacedim>::last_active (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return last_active_line (level);
+      case 2:
+           return last_active_quad (level);
+      case 3:
+           return last_active_hex (level);
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_cell_iterator();
+    }
 }
 
 
-template <>
-MGDoFHandler<1>::active_hex_iterator
-MGDoFHandler<1>::last_active_hex () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_cell_iterator
+MGDoFHandler<dim,spacedim>::end () const
 {
-  Assert (false, ExcImpossibleInDim(1));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           return end_line();
+      case 2:
+           return end_quad();
+      case 3:
+           return end_hex();
+      default:
+           Assert (false, ExcImpossibleInDim(dim));
+           return raw_cell_iterator();
+    }
 }
 
-#endif
-
 
-#if deal_II_dimension == 2
 
-template <>
-MGDoFHandler<2>::raw_cell_iterator
-MGDoFHandler<2>::begin_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_cell_iterator
+MGDoFHandler<dim, spacedim>::end_raw (const unsigned int level) const
 {
-  return begin_raw_quad (level);
+  return (level == this->tria->n_levels()-1 ?
+         end() :
+         begin_raw (level+1));
 }
 
 
-template <>
-MGDoFHandler<2>::cell_iterator
-MGDoFHandler<2>::begin (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::cell_iterator
+MGDoFHandler<dim, spacedim>::end (const unsigned int level) const
 {
-  return begin_quad (level);
+  return (level == this->tria->n_levels()-1 ?
+         cell_iterator(end()) :
+         begin (level+1));
 }
 
 
-template <>
-MGDoFHandler<2>::active_cell_iterator
-MGDoFHandler<2>::begin_active (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_cell_iterator
+MGDoFHandler<dim, spacedim>::end_active (const unsigned int level) const
 {
-  return begin_active_quad (level);
+  return (level == this->tria->n_levels()-1 ?
+         active_cell_iterator(end()) :
+         begin_active (level+1));
 }
 
 
-template <>
-MGDoFHandler<2>::raw_cell_iterator
-MGDoFHandler<2>::end () const
-{
-  return end_quad ();
-}
+/*------------------------ Face iterator functions ------------------------*/
 
 
-template <>
-MGDoFHandler<2>::raw_cell_iterator
-MGDoFHandler<2>::last_raw () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_face_iterator
+MGDoFHandler<dim,spacedim>::begin_raw_face () const
 {
-  return last_raw_quad ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return begin_raw_line ();
+      case 3:
+           return begin_raw_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-MGDoFHandler<2>::raw_cell_iterator
-MGDoFHandler<2>::last_raw (const unsigned int level) const
-{
-  return last_raw_quad (level);
-}
-
 
-template <>
-MGDoFHandler<2>::cell_iterator
-MGDoFHandler<2>::last () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::face_iterator
+MGDoFHandler<dim,spacedim>::begin_face () const
 {
-  return last_quad ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return begin_line ();
+      case 3:
+           return begin_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return face_iterator ();
+    }
 }
 
 
-template <>
-MGDoFHandler<2>::cell_iterator
-MGDoFHandler<2>::last (const unsigned int level) const
-{
-  return last_quad (level);
-}
-
 
-template <>
-MGDoFHandler<2>::active_cell_iterator
-MGDoFHandler<2>::last_active () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::active_face_iterator
+MGDoFHandler<dim,spacedim>::begin_active_face () const
 {
-  return last_active_quad ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return begin_active_line ();
+      case 3:
+           return begin_active_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return active_face_iterator ();
+    }
 }
 
 
-template <>
-MGDoFHandler<2>::active_cell_iterator
-MGDoFHandler<2>::last_active (const unsigned int level) const
-{
-  return last_active_quad (level);
-}
-
 
-template <>
-internal::MGDoFHandler::Iterators<2>::raw_face_iterator
-MGDoFHandler<2>::begin_raw_face () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_face_iterator
+MGDoFHandler<dim, spacedim>::end_raw_face () const
 {
-  return begin_raw_line ();
+  return end_face();
 }
 
 
-template <>
-internal::MGDoFHandler::Iterators<2>::face_iterator
-MGDoFHandler<2>::begin_face () const
-{
-  return begin_line ();
-}
-
 
-template <>
-internal::MGDoFHandler::Iterators<2>::active_face_iterator
-MGDoFHandler<2>::begin_active_face () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_face_iterator
+MGDoFHandler<dim,spacedim>::end_face () const
 {
-  return begin_active_line ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return end_line ();
+      case 3:
+           return end_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-internal::MGDoFHandler::Iterators<2>::raw_face_iterator
-MGDoFHandler<2>::end_face () const
-{
-  return end_line ();
-}
-
 
-template <>
-internal::MGDoFHandler::Iterators<2>::raw_face_iterator
-MGDoFHandler<2>::end_raw_face () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_face_iterator
+MGDoFHandler<dim, spacedim>::end_active_face () const
 {
-  return end_line ();
+  return active_face_iterator(end_face());
 }
 
 
-template <>
-internal::MGDoFHandler::Iterators<2>::active_face_iterator
-MGDoFHandler<2>::end_active_face () const
-{
-  return end_line ();
-}
-
 
-template <>
-internal::MGDoFHandler::Iterators<2>::raw_face_iterator
-MGDoFHandler<2>::last_raw_face () const
-{
-  return last_raw_line ();
-}
 
 
-template <>
-internal::MGDoFHandler::Iterators<2>::face_iterator
-MGDoFHandler<2>::last_face () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_face_iterator
+MGDoFHandler<dim,spacedim>::last_raw_face () const
 {
-  return last_line ();
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return last_raw_line ();
+      case 3:
+           return last_raw_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-internal::MGDoFHandler::Iterators<2>::active_face_iterator
-MGDoFHandler<2>::last_active_face () const
-{
-  return last_active_line ();
-}
-
 
-template <>
-MGDoFHandler<2>::raw_hex_iterator
-MGDoFHandler<2>::begin_raw_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::face_iterator
+MGDoFHandler<dim,spacedim>::last_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return last_line ();
+      case 3:
+           return last_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-MGDoFHandler<2>::hex_iterator
-MGDoFHandler<2>::begin_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
-
 
-template <>
-MGDoFHandler<2>::active_hex_iterator
-MGDoFHandler<2>::begin_active_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::active_face_iterator
+MGDoFHandler<dim,spacedim>::last_active_face () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_face_iterator();
+      case 2:
+           return last_active_line ();
+      case 3:
+           return last_active_quad ();
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_face_iterator ();
+    }
 }
 
 
-template <>
-MGDoFHandler<2>::raw_hex_iterator
-MGDoFHandler<2>::end_hex () const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
+/*------------------------ Line iterator functions ------------------------*/
 
 
-template <>
-MGDoFHandler<2>::hex_iterator
-MGDoFHandler<2>::end_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
 
-
-template <>
-MGDoFHandler<2>::raw_hex_iterator
-MGDoFHandler<2>::end_raw_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_line_iterator
+MGDoFHandler<dim, spacedim>::begin_raw_line (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (level<this->tria->n_levels(), ExcInvalidLevel(level));
+
+           if (this->tria->n_raw_lines(level) == 0)
+             return end_line ();
+
+           return raw_line_iterator (this->tria,
+                                     level,
+                                     0,
+                                     this);
+
+      default:
+           Assert (level == 0, ExcFacesHaveNoLevel());
+           return raw_line_iterator (this->tria,
+                                     0,
+                                     0,
+                                     this);
+    }
 }
 
 
-template <>
-MGDoFHandler<2>::active_hex_iterator
-MGDoFHandler<2>::end_active_hex (const unsigned int) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::line_iterator
+MGDoFHandler<dim, spacedim>::begin_line (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+                                  // level is checked in begin_raw
+  raw_line_iterator ri = begin_raw_line (level);
+  if (ri.state() != IteratorState::valid)
+    return ri;
+  while (ri->used() == false)
+    if ((++ri).state() != IteratorState::valid)
+      return ri;
+  return ri;
 }
 
 
-template <>
-MGDoFHandler<2>::raw_hex_iterator
-MGDoFHandler<2>::last_raw_hex (const unsigned int) const
-{
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
-}
-
 
-template <>
-MGDoFHandler<2>::raw_hex_iterator
-MGDoFHandler<2>::last_raw_hex () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_line_iterator
+MGDoFHandler<dim, spacedim>::begin_active_line (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+                                  // level is checked in begin_raw
+  line_iterator i = begin_line (level);
+  if (i.state() != IteratorState::valid)
+    return i;
+  while (i->has_children())
+    if ((++i).state() != IteratorState::valid)
+      return i;
+  return i;
 }
 
 
-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
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_line_iterator
+MGDoFHandler<dim, spacedim>::end_line () const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  return raw_line_iterator (this->tria,
+                           -1,
+                           -1,
+                           this);
 }
 
 
-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
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_line_iterator
+MGDoFHandler<dim, spacedim>::last_raw_line (const unsigned int level) const
 {
-  Assert (false, ExcImpossibleInDim(2));
-  return 0;
+  switch (dim)
+    {
+      case 1:
+           Assert (level<this->tria->n_levels(), ExcInvalidLevel(level));
+           Assert (this->tria->n_raw_lines(level) != 0,
+                   ExcEmptyLevel (level));
+
+           return raw_line_iterator (this->tria,
+                                     level,
+                                     this->tria->n_raw_lines(level)-1,
+                                     this);
+
+      default:
+           Assert (level == 0, ExcFacesHaveNoLevel());
+           return raw_line_iterator (this->tria,
+                                     0,
+                                     this->tria->n_raw_lines()-1,
+                                     this);
+    }
 }
 
 
-#endif
-
-
-#if deal_II_dimension == 3
 
-template <>
-MGDoFHandler<3>::raw_cell_iterator
-MGDoFHandler<3>::begin_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_line_iterator
+MGDoFHandler<dim, spacedim>::last_raw_line () const
 {
-  return begin_raw_hex (level);
+  if (dim == 1)
+    return last_raw_line (this->tria->n_levels()-1);
+  else
+    return last_raw_line (0);
 }
 
 
-template <>
-MGDoFHandler<3>::cell_iterator
-MGDoFHandler<3>::begin (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::line_iterator
+MGDoFHandler<dim, spacedim>::last_line (const unsigned int level) const
 {
-  return begin_hex (level);
+                                  // level is checked in last_raw
+  raw_line_iterator ri = last_raw_line(level);
+  if (ri->used()==true)
+    return ri;
+  while ((--ri).state() == IteratorState::valid)
+    if (ri->used()==true)
+      return ri;
+  return ri;
 }
 
 
-template <>
-MGDoFHandler<3>::active_cell_iterator
-MGDoFHandler<3>::begin_active (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::line_iterator
+MGDoFHandler<dim, spacedim>::last_line () const
 {
-  return begin_active_hex (level);
+  if (dim == 1)
+    return last_line (this->tria->n_levels()-1);
+  else
+    return last_line (0);
 }
 
 
-template <>
-MGDoFHandler<3>::raw_cell_iterator
-MGDoFHandler<3>::end () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_line_iterator
+MGDoFHandler<dim, spacedim>::last_active_line (const unsigned int level) const
 {
-  return end_hex ();
+                                  // level is checked in last_raw
+  line_iterator i = last_line(level);
+  if (i->has_children()==false)
+    return i;
+  while ((--i).state() == IteratorState::valid)
+    if (i->has_children()==false)
+      return i;
+  return i;
 }
 
 
-template <>
-MGDoFHandler<3>::raw_cell_iterator
-MGDoFHandler<3>::last_raw () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_line_iterator
+MGDoFHandler<dim, spacedim>::last_active_line () const
 {
-  return last_raw_hex ();
+  if (dim == 1)
+    return last_active_line (this->tria->n_levels()-1);
+  else
+    return last_active_line (0);
 }
 
 
-template <>
-MGDoFHandler<3>::raw_cell_iterator
-MGDoFHandler<3>::last_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_line_iterator
+MGDoFHandler<dim, spacedim>::end_raw_line (const unsigned int level) const
 {
-  return last_raw_hex (level);
+  Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 1)
+    return (level == this->tria->n_levels()-1 ?
+           end_line() :
+           begin_raw_line (level+1));
+  else
+    return end_line();
 }
 
 
-template <>
-MGDoFHandler<3>::cell_iterator
-MGDoFHandler<3>::last () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::line_iterator
+MGDoFHandler<dim, spacedim>::end_line (const unsigned int level) const
 {
-  return last_hex ();
+  Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 1)
+    return (level == this->tria->n_levels()-1 ?
+           line_iterator(end_line()) :
+           begin_line (level+1));
+  else
+    return line_iterator(end_line());
 }
 
 
-template <>
-MGDoFHandler<3>::cell_iterator
-MGDoFHandler<3>::last (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_line_iterator
+MGDoFHandler<dim, spacedim>::end_active_line (const unsigned int level) const
 {
-  return last_hex (level);
+  Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 1)
+    return (level == this->tria->n_levels()-1 ?
+           active_line_iterator(end_line()) :
+           begin_active_line (level+1));
+  else
+    return active_line_iterator(end_line());
 }
 
 
-template <>
-MGDoFHandler<3>::active_cell_iterator
-MGDoFHandler<3>::last_active () const
-{
-  return last_active_hex ();
-}
 
-
-template <>
-MGDoFHandler<3>::active_cell_iterator
-MGDoFHandler<3>::last_active (const unsigned int level) const
-{
-  return last_active_hex (level);
-}
+/*------------------------ Quad iterator functions ------------------------*/
 
 
-template <>
-internal::MGDoFHandler::Iterators<3>::raw_face_iterator
-MGDoFHandler<3>::begin_raw_face () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_quad_iterator
+MGDoFHandler<dim,spacedim>::begin_raw_quad (const unsigned int level) const
 {
-  return begin_raw_quad ();
-}
-
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_hex_iterator();
+      case 2:
+      {
+       Assert (level<this->tria->n_levels(), ExcInvalidLevel(level));
 
-template <>
-internal::MGDoFHandler::Iterators<3>::face_iterator
-MGDoFHandler<3>::begin_face () const
-{
-  return begin_quad ();
-}
+       if (this->tria->n_raw_quads(level) == 0)
+         return end_quad();
+  
+       return raw_quad_iterator (this->tria,
+                                 level,
+                                 0,
+                                 this);
+      }
 
+      case 3:
+      {
+       Assert (level == 0, ExcFacesHaveNoLevel());
 
-template <>
-internal::MGDoFHandler::Iterators<3>::active_face_iterator
-MGDoFHandler<3>::begin_active_face () const
-{
-  return begin_active_quad ();
+       return raw_quad_iterator (this->tria,
+                                 0,
+                                 0,
+                                 this);
+      }
+      
+      
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_hex_iterator();      
+    }
 }
 
 
-template <>
-internal::MGDoFHandler::Iterators<3>::raw_face_iterator
-MGDoFHandler<3>::end_face () const
-{
-  return end_quad ();
-}
-
 
-template <>
-internal::MGDoFHandler::Iterators<3>::raw_face_iterator
-MGDoFHandler<3>::end_raw_face () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::quad_iterator
+MGDoFHandler<dim,spacedim>::begin_quad (const unsigned int level) const
 {
-  return end_quad ();
+                                  // level is checked in begin_raw
+  raw_quad_iterator ri = begin_raw_quad (level);
+  if (ri.state() != IteratorState::valid)
+    return ri;
+  while (ri->used() == false)
+    if ((++ri).state() != IteratorState::valid)
+      return ri;
+  return ri;
 }
 
 
-template <>
-internal::MGDoFHandler::Iterators<3>::active_face_iterator
-MGDoFHandler<3>::end_active_face () const
-{
-  return end_quad ();
-}
-
 
-template <>
-internal::MGDoFHandler::Iterators<3>::raw_face_iterator
-MGDoFHandler<3>::last_raw_face () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::active_quad_iterator
+MGDoFHandler<dim,spacedim>::begin_active_quad (const unsigned int level) const
 {
-  return last_raw_quad ();
+                                  // level is checked in begin_raw
+  quad_iterator i = begin_quad (level);
+  if (i.state() != IteratorState::valid)
+    return i;
+  while (i->has_children())
+    if ((++i).state() != IteratorState::valid)
+      return i;
+  return i;
 }
 
 
-template <>
-internal::MGDoFHandler::Iterators<3>::face_iterator
-MGDoFHandler<3>::last_face () const
-{
-  return last_quad ();
-}
 
-
-template <>
-internal::MGDoFHandler::Iterators<3>::active_face_iterator
-MGDoFHandler<3>::last_active_face () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_quad_iterator
+MGDoFHandler<dim, spacedim>::end_raw_quad (const unsigned int level) const
 {
-  return last_active_quad ();
+  Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 2)
+    return (level == this->tria->n_levels()-1 ?
+           end_quad() :
+           begin_raw_quad (level+1));
+  else
+    return end_quad();
 }
 
 
-#endif
-
 
-template <int dim>
-typename MGDoFHandler<dim>::raw_line_iterator
-MGDoFHandler<dim>::begin_raw_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::quad_iterator
+MGDoFHandler<dim, spacedim>::end_quad (const unsigned int level) const
 {
-  Assert (dim==1 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());
-  return raw_line_iterator (this->tria,
-                           dim==1 ? this->tria->begin_raw_line(level)->level() : 0,
-                           this->tria->begin_raw_line(level)->index(),
-                           this);
+  Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 2)
+    return (level == this->tria->n_levels()-1 ?
+           quad_iterator(end_quad()) :
+           begin_quad (level+1));
+  else
+    return quad_iterator(end_quad());  
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::line_iterator
-MGDoFHandler<dim>::begin_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_quad_iterator
+MGDoFHandler<dim, spacedim>::end_active_quad (const unsigned int level) const
 {
-  Assert (dim==1 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());
-  return line_iterator (this->tria,
-                       dim==1 ? this->tria->begin_line(level)->level() : 0,
-                       this->tria->begin_line(level)->index(),
-                       this);
+  Assert(dim == 2 || level == 0, ExcFacesHaveNoLevel());
+  if (dim == 2)
+    return (level == this->tria->n_levels()-1 ?
+           active_quad_iterator(end_quad()) :
+           begin_active_quad (level+1));
+  else
+    return active_quad_iterator(end_quad());
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::active_line_iterator
-MGDoFHandler<dim>::begin_active_line (const unsigned int level) const
-{
-  Assert (dim==1 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());
-  return active_line_iterator (this->tria,
-                              dim==1 ? this->tria->begin_active_line(level)->level() : 0,
-                              this->tria->begin_active_line(level)->index(),
-                              this);
-}
-
 
-template <int dim>
-typename MGDoFHandler<dim>::raw_quad_iterator
-MGDoFHandler<dim>::begin_raw_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_quad_iterator
+MGDoFHandler<dim,spacedim>::end_quad () const
 {
-  Assert (dim==2 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());  
   return raw_quad_iterator (this->tria,
-                           dim==2 ? this->tria->begin_raw_quad(level)->level() : 0,
-                           this->tria->begin_raw_quad(level)->index(),
+                           -1,
+                           -1,
                            this);
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::quad_iterator
-MGDoFHandler<dim>::begin_quad (const unsigned int level) const
-{
-  Assert (dim==2 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());  
-  return quad_iterator (this->tria,
-                       dim==2 ? this->tria->begin_quad(level)->level() : 0,
-                       this->tria->begin_quad(level)->index(),
-                       this);
-}
-
-
-template <int dim>
-typename MGDoFHandler<dim>::active_quad_iterator
-MGDoFHandler<dim>::begin_active_quad (const unsigned int level) const
-{
-  Assert (dim==2 || level == 0,
-         typename Triangulation<dim>::ExcFacesHaveNoLevel());  
-  return active_quad_iterator (this->tria,
-                              dim==2 ? this->tria->begin_active_quad(level)->level() : 0,
-                              this->tria->begin_active_quad(level)->index(),
-                              this);
-}
-
 
-template <int dim>
-typename MGDoFHandler<dim>::raw_hex_iterator
-MGDoFHandler<dim>::begin_raw_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_quad_iterator
+MGDoFHandler<dim,spacedim>::last_raw_quad (const unsigned int level) const
 {
-  return raw_hex_iterator (this->tria,
-                          this->tria->begin_raw_hex(level)->level(),
-                          this->tria->begin_raw_hex(level)->index(),
-                          this);
-}
-
-
-template <int dim>
-typename MGDoFHandler<dim>::hex_iterator
-MGDoFHandler<dim>::begin_hex (const unsigned int level) const
-{
-  return hex_iterator (this->tria,
-                      this->tria->begin_hex(level)->level(),
-                      this->tria->begin_hex(level)->index(),
-                      this);
-}
-
-
-template <int dim>
-typename MGDoFHandler<dim>::active_hex_iterator
-MGDoFHandler<dim>::begin_active_hex (const unsigned int level) const
+  switch (dim)
+    {
+      case 1:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_quad_iterator();
+      case 2:
+           Assert (level<this->tria->n_levels(),
+                   ExcInvalidLevel(level));
+           Assert (this->tria->n_raw_quads(level) != 0,
+                   ExcEmptyLevel (level));
+           return raw_quad_iterator (this->tria,
+                                     level,
+                                     this->tria->n_raw_quads(level)-1,
+                                     this);
+      case 3:
+           Assert (level == 0, ExcFacesHaveNoLevel());
+           return raw_quad_iterator (this->tria,
+                                     0,
+                                     this->tria->n_raw_quads()-1,
+                                     this);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_quad_iterator();
+    }      
+}
+
+
+
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_quad_iterator
+MGDoFHandler<dim,spacedim>::last_raw_quad () const
 {
-  return active_hex_iterator (this->tria,
-                             this->tria->begin_active_hex(level)->level(),
-                             this->tria->begin_active_hex(level)->index(),
-                             this);
+  if (dim == 2)
+    return last_raw_quad (this->tria->n_levels()-1);
+  else
+    return last_raw_quad (0);
 }
 
 
 
-                                // 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 that return past the
-                                // end iterators, namely all functions end_*()
-template <int dim>
-typename MGDoFHandler<dim>::raw_line_iterator
-MGDoFHandler<dim>::end_line () const
-{
-  return raw_line_iterator (this->tria, -1, -1, this);
-}
-
-
-template <int dim>
-typename MGDoFHandler<dim>::raw_quad_iterator
-MGDoFHandler<dim>::end_quad () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::quad_iterator
+MGDoFHandler<dim,spacedim>::last_quad (const unsigned int level) const
 {
-  return raw_quad_iterator (this->tria, -1, -1, this);
+                                  // level is checked in last_raw
+  raw_quad_iterator ri = last_raw_quad(level);
+  if (ri->used()==true)
+    return ri;
+  while ((--ri).state() == IteratorState::valid)
+    if (ri->used()==true)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::raw_hex_iterator
-MGDoFHandler<dim>::end_hex () const
-{
-  return raw_hex_iterator (this->tria, -1, -1, this);
-}
-
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::raw_cell_iterator
-MGDoFHandler<dim>::end_raw (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::quad_iterator
+MGDoFHandler<dim,spacedim>::last_quad () const
 {
-  return (level == mg_levels.size()-1 ?
-         end() :
-         begin_raw (level+1));
+  if (dim == 2)
+    return last_quad (this->tria->n_levels()-1);
+  else
+    return last_quad (0);
 }
 
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::cell_iterator
-MGDoFHandler<dim>::end (const unsigned int level) const
-{
-  return (level == mg_levels.size()-1 ?
-         cell_iterator(end()) :
-         begin (level+1));
-}
-
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::active_cell_iterator
-MGDoFHandler<dim>::end_active (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::active_quad_iterator
+MGDoFHandler<dim,spacedim>::last_active_quad (const unsigned int level) const
 {
-  return (level == mg_levels.size()-1 ?
-         active_cell_iterator(end()) :
-         begin_active (level+1));
+                                  // level is checked in last_raw
+  quad_iterator i = last_quad(level);
+  if (i->has_children()==false)
+    return i;
+  while ((--i).state() == IteratorState::valid)
+    if (i->has_children()==false)
+      return i;
+  return i;
 }
 
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::raw_line_iterator
-MGDoFHandler<dim>::end_raw_line (const unsigned int level) const
-{
-  return raw_line_iterator(this->tria,
-                          this->tria->end_raw_line(level)->level(),
-                          this->tria->end_raw_line(level)->index(),
-                          this);
-}
-
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::line_iterator
-MGDoFHandler<dim>::end_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::active_quad_iterator
+MGDoFHandler<dim,spacedim>::last_active_quad () const
 {
-  return line_iterator(this->tria,
-                      this->tria->end_line(level)->level(),
-                      this->tria->end_line(level)->index(),
-                      this);
+  if (dim == 2)
+    return last_active_quad (this->tria->n_levels()-1);
+  else
+    return last_active_quad (0);
 }
 
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::active_line_iterator
-MGDoFHandler<dim>::end_active_line (const unsigned int level) const
-{
-  return active_line_iterator(this->tria,
-                             this->tria->end_active_line(level)->level(),
-                             this->tria->end_active_line(level)->index(),
-                             this);
-}
+/*------------------------ Hex iterator functions ------------------------*/
 
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::raw_quad_iterator
-MGDoFHandler<dim>::end_raw_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::raw_hex_iterator
+MGDoFHandler<dim,spacedim>::begin_raw_hex (const unsigned int level) const
 {
-  return raw_quad_iterator(this->tria,
-                          this->tria->end_raw_quad(level)->level(),
-                          this->tria->end_raw_quad(level)->index(),
-                          this);
-}
-
-
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::quad_iterator
-MGDoFHandler<dim>::end_quad (const unsigned int level) const
-{
-  return quad_iterator(this->tria,
-                      this->tria->end_quad(level)->level(),
-                      this->tria->end_quad(level)->index(),
-                      this);
-}
-
+  switch (dim)
+    {
+      case 1:
+      case 2:
+           Assert (false, ExcImpossibleInDim(1));
+           return raw_hex_iterator();
+      case 3:
+      {
+       Assert (level<this->tria->n_levels(), ExcInvalidLevel(level));
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::active_quad_iterator
-MGDoFHandler<dim>::end_active_quad (const unsigned int level) const
-{
-  return active_quad_iterator(this->tria,
-                             this->tria->end_active_quad(level)->level(),
-                             this->tria->end_active_quad(level)->index(),
-                             this);
+       if (this->tria->n_raw_hexs(level) == 0)
+         return end_hex();
+  
+       return raw_hex_iterator (this->tria,
+                                level,
+                                0,
+                                this);
+      }
+      
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_hex_iterator();      
+    }
 }
 
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::raw_hex_iterator
-MGDoFHandler<dim>::end_raw_hex (const unsigned int level) const
-{
-  return raw_hex_iterator(this->tria,
-                         this->tria->end_raw_hex(level)->level(),
-                         this->tria->end_raw_hex(level)->index(),
-                         this);
-}
-
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::hex_iterator
-MGDoFHandler<dim>::end_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim,spacedim>::hex_iterator
+MGDoFHandler<dim,spacedim>::begin_hex (const unsigned int level) const
 {
-  return hex_iterator(this->tria,
-                     this->tria->end_hex(level)->level(),
-                     this->tria->end_hex(level)->index(),
-                     this);
+                                  // level is checked in begin_raw
+  raw_hex_iterator ri = begin_raw_hex (level);
+  if (ri.state() != IteratorState::valid)
+    return ri;
+  while (ri->used() == false)
+    if ((++ri).state() != IteratorState::valid)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename internal::MGDoFHandler::Iterators<dim>::active_hex_iterator
-MGDoFHandler<dim>::end_active_hex (const unsigned int level) const
-{
-  return active_hex_iterator(this->tria,
-                            this->tria->end_active_hex(level)->level(),
-                            this->tria->end_active_hex(level)->index(),
-                            this);
-}
 
-
-template <int dim>
-typename MGDoFHandler<dim>::raw_line_iterator
-MGDoFHandler<dim>::last_raw_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_hex_iterator
+MGDoFHandler<dim, spacedim>::begin_active_hex (const unsigned int level) const
 {
-  return raw_line_iterator (this->tria,
-                           this->tria->last_raw_line(level)->level(),
-                           this->tria->last_raw_line(level)->index(),
-                           this);
+                                  // level is checked in begin_raw
+  hex_iterator i = begin_hex (level);
+  if (i.state() != IteratorState::valid)
+    return i;
+  while (i->has_children())
+    if ((++i).state() != IteratorState::valid)
+      return i;
+  return i;
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::line_iterator
-MGDoFHandler<dim>::last_line (const unsigned int level) const
-{
-  return line_iterator (this->tria,
-                       this->tria->last_line(level)->level(),
-                       this->tria->last_line(level)->index(),
-                       this);
-}
-
 
-template <int dim>
-typename MGDoFHandler<dim>::active_line_iterator
-MGDoFHandler<dim>::last_active_line (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_hex_iterator
+MGDoFHandler<dim, spacedim>::end_raw_hex (const unsigned int level) const
 {
-  return active_line_iterator (this->tria,
-                              this->tria->last_active_line(level)->level(),
-                              this->tria->last_active_line(level)->index(),
-                              this);
+  return (level == this->tria->n_levels()-1 ?
+         end_hex() :
+         begin_raw_hex (level+1));
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::raw_quad_iterator
-MGDoFHandler<dim>::last_raw_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::hex_iterator
+MGDoFHandler<dim, spacedim>::end_hex (const unsigned int level) const
 {
-  return raw_quad_iterator (this->tria,
-                           this->tria->last_raw_quad(level)->level(),
-                           this->tria->last_raw_quad(level)->index(),
-                           this);
+  return (level == this->tria->n_levels()-1 ?
+         hex_iterator(end_hex()) :
+         begin_hex (level+1));
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::quad_iterator
-MGDoFHandler<dim>::last_quad (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_hex_iterator
+MGDoFHandler<dim, spacedim>::end_active_hex (const unsigned int level) const
 {
-  return quad_iterator (this->tria,
-                       this->tria->last_quad(level)->level(),
-                       this->tria->last_quad(level)->index(),
-                       this);
+  return (level == this->tria->n_levels()-1 ?
+         active_hex_iterator(end_hex()) :
+         begin_active_hex (level+1));
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::active_quad_iterator
-MGDoFHandler<dim>::last_active_quad (const unsigned int level) const
-{
-  return active_quad_iterator (this->tria,
-                              this->tria->last_active_quad(level)->level(),
-                              this->tria->last_active_quad(level)->index(),
-                              this);
-}
 
-
-template <int dim>
-typename MGDoFHandler<dim>::raw_hex_iterator
-MGDoFHandler<dim>::last_raw_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_hex_iterator
+MGDoFHandler<dim, spacedim>::end_hex () const
 {
   return raw_hex_iterator (this->tria,
-                          this->tria->last_raw_hex(level)->level(),
-                          this->tria->last_raw_hex(level)->index(),
+                          -1,
+                          -1,
                           this);
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::hex_iterator
-MGDoFHandler<dim>::last_hex (const unsigned int level) const
-{
-  return hex_iterator (this->tria,
-                      this->tria->last_hex(level)->level(),
-                      this->tria->last_hex(level)->index(),
-                      this);
-}
 
-
-template <int dim>
-typename MGDoFHandler<dim>::active_hex_iterator
-MGDoFHandler<dim>::last_active_hex (const unsigned int level) const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_hex_iterator
+MGDoFHandler<dim, spacedim>::last_raw_hex (const unsigned int level) const
 {
-  return active_hex_iterator (this->tria,
-                             this->tria->last_active_hex(level)->level(),
-                             this->tria->last_active_hex(level)->index(),
-                             this);
+  switch (dim)
+    {
+      case 1:
+      case 2:
+           Assert (false, ExcImpossibleInDim(dim));
+           return raw_hex_iterator();
+
+      case 3:
+           Assert (level<this->tria->n_levels(),
+                   ExcInvalidLevel(level));
+           Assert (this->tria->n_raw_hexs(level) != 0,
+                   ExcEmptyLevel (level));
+
+           return raw_hex_iterator (this->tria,
+                                    level,
+                                    this->tria->n_raw_hexs(level)-1,
+                                    this);
+      default:
+           Assert (false, ExcNotImplemented());
+           return raw_hex_iterator();
+    }
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::raw_line_iterator
-MGDoFHandler<dim>::last_raw_line () const
-{
-  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);
-}
-
 
-template <int dim>
-typename MGDoFHandler<dim>::raw_quad_iterator
-MGDoFHandler<dim>::last_raw_quad () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::raw_hex_iterator
+MGDoFHandler<dim, spacedim>::last_raw_hex () const
 {
-  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);
+  return last_raw_hex (this->tria->n_levels()-1);
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::raw_hex_iterator
-MGDoFHandler<dim>::last_raw_hex () const
-{
-  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);
-}
 
-
-template <int dim>
-typename MGDoFHandler<dim>::line_iterator
-MGDoFHandler<dim>::last_line () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::hex_iterator
+MGDoFHandler<dim, spacedim>::last_hex (const unsigned int level) const
 {
-  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);
+                                  // level is checked in last_raw
+  raw_hex_iterator ri = last_raw_hex(level);
+  if (ri->used()==true)
+    return ri;
+  while ((--ri).state() == IteratorState::valid)
+    if (ri->used()==true)
+      return ri;
+  return ri;
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::quad_iterator
-MGDoFHandler<dim>::last_quad () const
-{
-  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);
-}
-
 
-template <int dim>
-typename MGDoFHandler<dim>::hex_iterator
-MGDoFHandler<dim>::last_hex () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::hex_iterator
+MGDoFHandler<dim, spacedim>::last_hex () const
 {
-  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);
+  return last_hex (this->tria->n_levels()-1);
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::active_line_iterator
-MGDoFHandler<dim>::last_active_line () const
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_hex_iterator
+MGDoFHandler<dim, spacedim>::last_active_hex (const unsigned int level) const
 {
-  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);
+                                  // level is checked in last_raw
+  hex_iterator i = last_hex(level);
+  if (i->has_children()==false)
+    return i;
+  while ((--i).state() == IteratorState::valid)
+    if (i->has_children()==false)
+      return i;
+  return i;
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::active_quad_iterator
-MGDoFHandler<dim>::last_active_quad () const
+
+template <int dim, int spacedim>
+typename MGDoFHandler<dim, spacedim>::active_hex_iterator
+MGDoFHandler<dim, spacedim>::last_active_hex () const
 {
-  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);
+  return last_active_hex (this->tria->n_levels()-1);
 }
 
 
-template <int dim>
-typename MGDoFHandler<dim>::active_hex_iterator
-MGDoFHandler<dim>::last_active_hex () const
-{
-  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);
-}
 
 
 //---------------------------------------------------------------------------
@@ -1687,8 +1404,8 @@ MGDoFHandler<3>::set_dof_index<3> (const unsigned int       obj_level,
 #endif
 
 
-template <int dim>
-void MGDoFHandler<dim>::distribute_dofs (const FiniteElement<dim> &fe,
+template <int dim, int spacedim>
+void MGDoFHandler<dim,spacedim>::distribute_dofs (const FiniteElement<dim,spacedim> &fe,
                                         const unsigned int        offset)
 {
                                   // first distribute global dofs
@@ -1709,7 +1426,7 @@ void MGDoFHandler<dim>::distribute_dofs (const FiniteElement<dim> &fe,
                                   // beginning of this function.
   std::vector<bool> user_flags;
   this->tria->save_user_flags(user_flags);
-  const_cast<Triangulation<dim> &>(*(this->tria)).clear_user_flags ();
+  const_cast<Triangulation<dim,spacedim> &>(*(this->tria)).clear_user_flags ();
 
                                   // now distribute indices on each level
                                   // separately
@@ -1726,7 +1443,7 @@ void MGDoFHandler<dim>::distribute_dofs (const FiniteElement<dim> &fe,
     };
   
                                   // finally restore the user flags
-  const_cast<Triangulation<dim> &>(*(this->tria)).load_user_flags(user_flags);
+  const_cast<Triangulation<dim,spacedim> &>(*(this->tria)).load_user_flags(user_flags);
 }
 
 
@@ -1895,9 +1612,9 @@ MGDoFHandler<3>::distribute_dofs_on_cell (cell_iterator &cell,
 #endif
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-MGDoFHandler<dim>::clear ()
+MGDoFHandler<dim,spacedim>::clear ()
 {
                                   // release own memory
   clear_space ();
@@ -1908,8 +1625,8 @@ MGDoFHandler<dim>::clear ()
 }
 
 
-template <int dim>
-unsigned int MGDoFHandler<dim>::n_dofs (const unsigned int level) const {
+template <int dim, int spacedim>
+unsigned int MGDoFHandler<dim,spacedim>::n_dofs (const unsigned int level) const {
   Assert (level < mg_used_dofs.size(), ExcInvalidLevel(level));
   
   return mg_used_dofs[level];
@@ -2123,6 +1840,7 @@ void MGDoFHandler<3>::renumber_dofs (const unsigned int  level,
 template <>
 void MGDoFHandler<1>::reserve_space () {
   const unsigned int dim = 1;
+  const unsigned int spacedim = 1;
   
   Assert (this->selected_fe != 0, DoFHandler<dim>::ExcNoFESelected());
   Assert (this->tria->n_levels() > 0, DoFHandler<dim>::ExcInvalidTriangulation());
@@ -2162,7 +1880,7 @@ void MGDoFHandler<1>::reserve_space () {
   std::vector<unsigned int> min_level (this->tria->n_vertices(), this->tria->n_levels());
   std::vector<unsigned int> max_level (this->tria->n_vertices(), 0);
 
-  Triangulation<dim>::cell_iterator cell = this->tria->begin(),
+  Triangulation<dim,spacedim>::cell_iterator cell = this->tria->begin(),
                                    endc = this->tria->end();
   for (; cell!=endc; ++cell)
     for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
@@ -2204,6 +1922,7 @@ void MGDoFHandler<1>::reserve_space () {
 template <>
 void MGDoFHandler<2>::reserve_space () {
   const unsigned int dim = 2;
+  const unsigned int spacedim = 2;
   
   Assert (this->selected_fe != 0, DoFHandler<dim>::ExcNoFESelected());
   Assert (this->tria->n_levels() > 0, DoFHandler<2>::ExcInvalidTriangulation());
@@ -2252,7 +1971,7 @@ void MGDoFHandler<2>::reserve_space () {
                                       this->tria->n_levels());
   std::vector<unsigned int> max_level (this->tria->n_vertices(), 0);
 
-  Triangulation<dim>::cell_iterator cell = this->tria->begin(),
+  Triangulation<dim,spacedim>::cell_iterator cell = this->tria->begin(),
                                    endc = this->tria->end();
   for (; cell!=endc; ++cell)
     for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
@@ -2294,7 +2013,9 @@ void MGDoFHandler<2>::reserve_space () {
 
 template <>
 void MGDoFHandler<3>::reserve_space () {
+
   const unsigned int dim = 3;
+  const unsigned int spacedim = 3;
   
   Assert (this->selected_fe != 0, DoFHandler<3>::ExcNoFESelected());
   Assert (this->tria->n_levels() > 0, DoFHandler<3>::ExcInvalidTriangulation());
@@ -2343,7 +2064,7 @@ void MGDoFHandler<3>::reserve_space () {
   std::vector<unsigned int> min_level (this->tria->n_vertices(), this->tria->n_levels());
   std::vector<unsigned int> max_level (this->tria->n_vertices(), 0);
 
-  Triangulation<dim>::cell_iterator cell = this->tria->begin(),
+  Triangulation<dim,spacedim>::cell_iterator cell = this->tria->begin(),
                                    endc = this->tria->end();
   for (; cell!=endc; ++cell)
     for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
@@ -2381,8 +2102,8 @@ void MGDoFHandler<3>::reserve_space () {
 #endif
 
 
-template <int dim>
-void MGDoFHandler<dim>::clear_space ()
+template <int dim, int spacedim>
+void MGDoFHandler<dim,spacedim>::clear_space ()
 {
                                    // delete all levels and set them up
                                    // newly, since vectors are
index 40cc8022a748e2fe3a93b223735f2cb9565102ab..8d04955e8c35bf673ace8a4ebf1e828dbc0510b9 100644 (file)
@@ -40,10 +40,10 @@ DEAL_II_NAMESPACE_OPEN
 
 #if deal_II_dimension == 1
 
-template <int dim>
+template <int dim, int spacedim>
 void
 MGTools::compute_row_length_vector(
-  const MGDoFHandler<dim>&,
+  const MGDoFHandler<dim,spacedim>&,
   const unsigned int,
   std::vector<unsigned int>&,
   const DoFTools::Coupling)
@@ -52,10 +52,10 @@ MGTools::compute_row_length_vector(
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 MGTools::compute_row_length_vector(
-  const MGDoFHandler<dim>&,
+  const MGDoFHandler<dim,spacedim>&,
   const unsigned int,
   std::vector<unsigned int>&,
   const Table<2,DoFTools::Coupling>&,
@@ -68,10 +68,10 @@ MGTools::compute_row_length_vector(
 #else
 
 // Template for 2D and 3D. For 1D see specialization above
-template <int dim>
+template <int dim, int spacedim>
 void
 MGTools::compute_row_length_vector(
-  const MGDoFHandler<dim>& dofs,
+  const MGDoFHandler<dim,spacedim>& dofs,
   const unsigned int level,
   std::vector<unsigned int>& row_lengths,
   const DoFTools::Coupling             flux_coupling)
@@ -89,13 +89,13 @@ MGTools::compute_row_length_vector(
                                   // triangulation for the user
                                   // flags. Since we restore them in
                                   // the end, this cast is safe.
-  Triangulation<dim>& user_flags_triangulation =
-    const_cast<Triangulation<dim>&> (dofs.get_tria());
+  Triangulation<dim,spacedim>& user_flags_triangulation =
+    const_cast<Triangulation<dim,spacedim>&> (dofs.get_tria());
   user_flags_triangulation.save_user_flags(old_flags);
   user_flags_triangulation.clear_user_flags();
   
-  const typename MGDoFHandler<dim>::cell_iterator end = dofs.end(level);
-  typename MGDoFHandler<dim>::active_cell_iterator cell;
+  const typename MGDoFHandler<dim,spacedim>::cell_iterator end = dofs.end(level);
+  typename MGDoFHandler<dim,spacedim>::active_cell_iterator cell;
   std::vector<unsigned int> cell_indices;
   std::vector<unsigned int> neighbor_indices;
 
@@ -178,7 +178,7 @@ MGTools::compute_row_length_vector(
       for (unsigned int iface=0;iface<GeometryInfo<dim>::faces_per_cell;++iface)
        {
          bool level_boundary = cell->at_boundary(iface);
-         typename MGDoFHandler<dim>::cell_iterator neighbor;
+         typename MGDoFHandler<dim,spacedim>::cell_iterator neighbor;
          if (!level_boundary)
            {
              neighbor = cell->neighbor(iface);
@@ -194,7 +194,7 @@ MGTools::compute_row_length_vector(
            }
          
          const FiniteElement<dim>& nfe = neighbor->get_fe();
-         typename MGDoFHandler<dim>::face_iterator face = cell->face(iface);
+         typename MGDoFHandler<dim,spacedim>::face_iterator face = cell->face(iface);
          
                                           // Flux couplings are
                                           // computed from both sides
@@ -241,10 +241,10 @@ MGTools::compute_row_length_vector(
 
 
 // This is the template for 2D and 3D. See version for 1D above
-template <int dim>
+template <int dim, int spacedim>
 void
 MGTools::compute_row_length_vector(
-  const MGDoFHandler<dim>& dofs,
+  const MGDoFHandler<dim,spacedim>& dofs,
   const unsigned int level,
   std::vector<unsigned int>& row_lengths,
   const Table<2,DoFTools::Coupling>& couplings,
@@ -263,13 +263,13 @@ MGTools::compute_row_length_vector(
                                   // triangulation for the user
                                   // flags. Since we restore them in
                                   // the end, this cast is safe.
-  Triangulation<dim>& user_flags_triangulation =
-    const_cast<Triangulation<dim>&> (dofs.get_tria());
+  Triangulation<dim,spacedim>& user_flags_triangulation =
+    const_cast<Triangulation<dim,spacedim>&> (dofs.get_tria());
   user_flags_triangulation.save_user_flags(old_flags);
   user_flags_triangulation.clear_user_flags();
   
-  const typename MGDoFHandler<dim>::cell_iterator end = dofs.end(level);
-  typename MGDoFHandler<dim>::active_cell_iterator cell;
+  const typename MGDoFHandler<dim,spacedim>::cell_iterator end = dofs.end(level);
+  typename MGDoFHandler<dim,spacedim>::active_cell_iterator cell;
   std::vector<unsigned int> cell_indices;
   std::vector<unsigned int> neighbor_indices;
   
@@ -416,7 +416,7 @@ MGTools::compute_row_length_vector(
       for (unsigned int iface=0;iface<GeometryInfo<dim>::faces_per_cell;++iface)
        {
          bool level_boundary = cell->at_boundary(iface);
-         typename MGDoFHandler<dim>::cell_iterator neighbor;
+         typename MGDoFHandler<dim,spacedim>::cell_iterator neighbor;
          if (!level_boundary)
            {
              neighbor = cell->neighbor(iface);
@@ -432,7 +432,7 @@ MGTools::compute_row_length_vector(
            }
          
          const FiniteElement<dim>& nfe = neighbor->get_fe();
-         typename MGDoFHandler<dim>::face_iterator face = cell->face(iface);
+         typename MGDoFHandler<dim,spacedim>::face_iterator face = cell->face(iface);
          
                                           // Flux couplings are
                                           // computed from both sides
@@ -502,9 +502,9 @@ MGTools::compute_row_length_vector(
 #endif
 
 
-template <int dim, class SparsityPattern>
+template <int dim, class SparsityPattern, int spacedim>
 void MGTools::make_sparsity_pattern (
-  const MGDoFHandler<dim> &dof,
+  const MGDoFHandler<dim,spacedim> &dof,
   SparsityPattern         &sparsity,
   const unsigned int       level)
 {
@@ -517,7 +517,7 @@ void MGTools::make_sparsity_pattern (
 
   const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell;
   std::vector<unsigned int> dofs_on_this_cell(dofs_per_cell);
-  typename MGDoFHandler<dim>::cell_iterator cell = dof.begin(level),
+  typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
                                            endc = dof.end(level);
   for (; cell!=endc; ++cell) 
     {
@@ -532,10 +532,10 @@ void MGTools::make_sparsity_pattern (
 
 
 
-template<int dim, class SparsityPattern>
+template <int dim, class SparsityPattern, int spacedim>
 void
 MGTools::make_flux_sparsity_pattern (
-  const MGDoFHandler<dim> &dof,
+  const MGDoFHandler<dim,spacedim> &dof,
   SparsityPattern       &sparsity,
   const unsigned int level)
 {
@@ -549,7 +549,7 @@ MGTools::make_flux_sparsity_pattern (
   const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell;
   std::vector<unsigned int> dofs_on_this_cell(dofs_per_cell);
   std::vector<unsigned int> dofs_on_other_cell(dofs_per_cell);
-  typename MGDoFHandler<dim>::cell_iterator cell = dof.begin(level),
+  typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
                                            endc = dof.end(level);
   for (; cell!=endc; ++cell)
     {
@@ -568,7 +568,7 @@ MGTools::make_flux_sparsity_pattern (
          if ( (! cell->at_boundary(face)) &&
               (static_cast<unsigned int>(cell->neighbor_level(face)) == level) )
            {
-             typename MGDoFHandler<dim>::cell_iterator
+             typename MGDoFHandler<dim,spacedim>::cell_iterator
                neighbor = cell->neighbor(face);
              neighbor->get_mg_dof_indices (dofs_on_other_cell);
                                               // only add one direction
@@ -589,10 +589,10 @@ MGTools::make_flux_sparsity_pattern (
 
 
 
-template<int dim, class SparsityPattern>
+template <int dim, class SparsityPattern, int spacedim>
 void
 MGTools::make_flux_sparsity_pattern_edge (
-  const MGDoFHandler<dim> &dof,
+  const MGDoFHandler<dim,spacedim> &dof,
   SparsityPattern       &sparsity,
   const unsigned int level)
 {
@@ -612,7 +612,7 @@ MGTools::make_flux_sparsity_pattern_edge (
   const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell;
   std::vector<unsigned int> dofs_on_this_cell(dofs_per_cell);
   std::vector<unsigned int> dofs_on_other_cell(dofs_per_cell);
-  typename MGDoFHandler<dim>::cell_iterator cell = dof.begin(level),
+  typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
                                            endc = dof.end(level);
   for (; cell!=endc; ++cell)
     {
@@ -627,7 +627,7 @@ MGTools::make_flux_sparsity_pattern_edge (
          if ( (! cell->at_boundary(face)) &&
               (static_cast<unsigned int>(cell->neighbor_level(face)) != level) )
            {
-             typename MGDoFHandler<dim>::cell_iterator
+             typename MGDoFHandler<dim,spacedim>::cell_iterator
                neighbor = cell->neighbor(face);
              neighbor->get_mg_dof_indices (dofs_on_other_cell);
 
@@ -651,10 +651,10 @@ MGTools::make_flux_sparsity_pattern_edge (
 
 
 
-template<int dim, class SparsityPattern>
+template <int dim, class SparsityPattern, int spacedim>
 void
 MGTools::make_flux_sparsity_pattern (
-  const MGDoFHandler<dim> &dof,
+  const MGDoFHandler<dim,spacedim> &dof,
   SparsityPattern       &sparsity,
   const unsigned int level,
   const Table<2,DoFTools::Coupling> &int_mask,
@@ -682,7 +682,7 @@ MGTools::make_flux_sparsity_pattern (
   std::vector<unsigned int> dofs_on_other_cell(total_dofs);
   Table<2,bool> support_on_face(total_dofs, GeometryInfo<dim>::faces_per_cell);
   
-  typename MGDoFHandler<dim>::cell_iterator cell = dof.begin(level),
+  typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
                                            endc = dof.end(level);
 
   Table<2,DoFTools::Coupling> int_dof_mask(total_dofs, total_dofs);
@@ -705,7 +705,7 @@ MGTools::make_flux_sparsity_pattern (
                                   // beginning of this function.
   std::vector<bool> user_flags;
   dof.get_tria().save_user_flags(user_flags);
-  const_cast<Triangulation<dim> &>(dof.get_tria()).clear_user_flags ();
+  const_cast<Triangulation<dim,spacedim> &>(dof.get_tria()).clear_user_flags ();
   
   for (; cell!=endc; ++cell)
     {
@@ -722,7 +722,7 @@ MGTools::make_flux_sparsity_pattern (
           face < GeometryInfo<dim>::faces_per_cell;
           ++face)
        {
-         typename MGDoFHandler<dim>::face_iterator cell_face = cell->face(face);
+         typename MGDoFHandler<dim,spacedim>::face_iterator cell_face = cell->face(face);
          if (cell_face->user_flag_set ())
            continue;
 
@@ -747,7 +747,7 @@ MGTools::make_flux_sparsity_pattern (
            }
          else
            {
-             typename MGDoFHandler<dim>::cell_iterator
+             typename MGDoFHandler<dim,spacedim>::cell_iterator
                neighbor = cell->neighbor(face);
              
              if (neighbor->level() < cell->level())
@@ -825,15 +825,15 @@ MGTools::make_flux_sparsity_pattern (
     }
   
                                   // finally restore the user flags
-  const_cast<Triangulation<dim> &>(dof.get_tria()).load_user_flags(user_flags);
+  const_cast<Triangulation<dim,spacedim> &>(dof.get_tria()).load_user_flags(user_flags);
 }
 
 
 
-template<int dim, class SparsityPattern>
+template <int dim, class SparsityPattern, int spacedim>
 void
 MGTools::make_flux_sparsity_pattern_edge (
-  const MGDoFHandler<dim> &dof,
+  const MGDoFHandler<dim,spacedim> &dof,
   SparsityPattern       &sparsity,
   const unsigned int level,
   const Table<2,DoFTools::Coupling> &flux_mask)
@@ -863,7 +863,7 @@ MGTools::make_flux_sparsity_pattern_edge (
   std::vector<unsigned int> dofs_on_other_cell(dofs_per_cell);
   Table<2,bool> support_on_face(dofs_per_cell, GeometryInfo<dim>::faces_per_cell);
   
-  typename MGDoFHandler<dim>::cell_iterator cell = dof.begin(level),
+  typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
                                            endc = dof.end(level);
 
    Table<2,DoFTools::Coupling> flux_dof_mask(dofs_per_cell, dofs_per_cell);
@@ -887,7 +887,7 @@ MGTools::make_flux_sparsity_pattern_edge (
          if ( (! cell->at_boundary(face)) &&
               (static_cast<unsigned int>(cell->neighbor_level(face)) != level) )
            {
-             typename MGDoFHandler<dim>::cell_iterator
+             typename MGDoFHandler<dim,spacedim>::cell_iterator
                neighbor = cell->neighbor(face);
              neighbor->get_mg_dof_indices (dofs_on_other_cell);
 
@@ -911,10 +911,10 @@ MGTools::make_flux_sparsity_pattern_edge (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 MGTools::count_dofs_per_component (
-  const MGDoFHandler<dim> &dof_handler,
+  const MGDoFHandler<dim,spacedim> &dof_handler,
   std::vector<std::vector<unsigned int> > &result,
   bool only_once,
   std::vector<unsigned int> target_component)
@@ -963,7 +963,7 @@ MGTools::count_dofs_per_component (
          for (unsigned int i=0; i<n_components; ++i)
            {
              void (*fun_ptr) (const unsigned int       level,
-                              const MGDoFHandler<dim>    &,
+                              const MGDoFHandler<dim,spacedim>    &,
                               const std::vector<bool>    &,
                               std::vector<bool>          &,
                               bool)
@@ -1009,10 +1009,10 @@ MGTools::count_dofs_per_component (
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 MGTools::count_dofs_per_component (
-  const MGDoFHandler<dim> &dof_handler,
+  const MGDoFHandler<dim,spacedim> &dof_handler,
   std::vector<std::vector<unsigned int> > &result,
   std::vector<unsigned int> target_component)
 {
@@ -1020,10 +1020,10 @@ MGTools::count_dofs_per_component (
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 MGTools::count_dofs_per_block (
-  const MGDoFHandler<dim>&     dof_handler,
+  const MGDoFHandler<dim,spacedim>&     dof_handler,
   std::vector<std::vector<unsigned int> >& dofs_per_block,
   std::vector<unsigned int>  target_block)
 {
@@ -1074,7 +1074,7 @@ MGTools::count_dofs_per_block (
       for (unsigned int i=0; i<n_blocks; ++i)
        {
          void (*fun_ptr) (const unsigned int level,
-                          const MGDoFHandler<dim>&,
+                          const MGDoFHandler<dim,spacedim>&,
                           const std::vector<bool>&,
                           std::vector<bool>&,
                           bool)
@@ -1097,10 +1097,10 @@ MGTools::count_dofs_per_block (
 
 #if deal_II_dimension == 1
 
-template <int dim>
+template <int dim, int spacedim>
 void
 MGTools::make_boundary_list(
-  const MGDoFHandler<dim>&,
+  const MGDoFHandler<dim,spacedim>&,
   const typename FunctionMap<dim>::type&,
   std::vector<std::set<unsigned int> >&,
   const std::vector<bool>&)
@@ -1111,10 +1111,10 @@ MGTools::make_boundary_list(
 
 #else
 
-template <int dim>
+template <int dim, int spacedim>
 void
 MGTools::make_boundary_list(
-  const MGDoFHandler<dim>& dof,
+  const MGDoFHandler<dim,spacedim>& dof,
   const typename FunctionMap<dim>::type& function_map,
   std::vector<std::set<unsigned int> >& boundary_indices,
   const std::vector<bool>& component_mask_)
@@ -1150,7 +1150,7 @@ MGTools::make_boundary_list(
   face_dofs.reserve (DoFTools::max_dofs_per_face(dof));
   std::fill (face_dofs.begin (), face_dofs.end (), DoFHandler<dim>::invalid_dof_index);
   
-  typename MGDoFHandler<dim>::cell_iterator cell = dof.begin(),
+  typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(),
                                            endc = dof.end();
   for (; cell!=endc; ++cell)
     for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
@@ -1183,7 +1183,7 @@ MGTools::make_boundary_list(
                                     "elements"));
           }
 
-        typename MGDoFHandler<dim>::face_iterator face = cell->face(face_no);
+        typename MGDoFHandler<dim,spacedim>::face_iterator face = cell->face(face_no);
         const unsigned char boundary_component = face->boundary_indicator();
         if (function_map.find(boundary_component) != function_map.end())
                                            // face is of the right component
@@ -1297,9 +1297,9 @@ MGTools::make_boundary_list(
 
 
   
-template<int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
-MGTools::reinit_vector (const MGDoFHandler<dim> &mg_dof,
+MGTools::reinit_vector (const MGDoFHandler<dim,spacedim> &mg_dof,
                        MGLevelObject<Vector<number> > &v)
 {
   for (unsigned int level=v.get_minlevel();
@@ -1312,9 +1312,9 @@ MGTools::reinit_vector (const MGDoFHandler<dim> &mg_dof,
 }
 
 
-template<int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
-MGTools::reinit_vector (const MGDoFHandler<dim> &mg_dof,
+MGTools::reinit_vector (const MGDoFHandler<dim,spacedim> &mg_dof,
                        MGLevelObject<BlockVector<number> > &v)
 {
   const unsigned int n_blocks = mg_dof.get_fe().n_blocks();
@@ -1331,10 +1331,10 @@ MGTools::reinit_vector (const MGDoFHandler<dim> &mg_dof,
 }
 
 
-template<int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
 MGTools::reinit_vector_by_components (
-  const MGDoFHandler<dim> &mg_dof,
+  const MGDoFHandler<dim,spacedim> &mg_dof,
   MGLevelObject<BlockVector<number> > &v,
   const std::vector<bool> &sel,
   const std::vector<unsigned int> &target_comp,
@@ -1405,10 +1405,10 @@ MGTools::reinit_vector_by_components (
 }
 
 
-template<int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
 MGTools::reinit_vector_by_components (
-  const MGDoFHandler<dim> &mg_dof,
+  const MGDoFHandler<dim,spacedim> &mg_dof,
   MGLevelObject<Vector<number> > &v,
   const std::vector<bool> &selected,
   const std::vector<unsigned int> &target_component,
@@ -1447,10 +1447,10 @@ MGTools::reinit_vector_by_components (
 }
 
 
-template<int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
 MGTools::reinit_vector_by_blocks (
-  const MGDoFHandler<dim> &mg_dof,
+  const MGDoFHandler<dim,spacedim> &mg_dof,
   MGLevelObject<BlockVector<number> > &v,
   const std::vector<bool> &sel,
   std::vector<std::vector<unsigned int> >& ndofs)
@@ -1488,10 +1488,10 @@ MGTools::reinit_vector_by_blocks (
 }
 
 
-template<int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
 MGTools::reinit_vector_by_blocks (
-  const MGDoFHandler<dim> &mg_dof,
+  const MGDoFHandler<dim,spacedim> &mg_dof,
   MGLevelObject<Vector<number> > &v,
   const unsigned int selected_block,
   std::vector<std::vector<unsigned int> >& ndofs)
index 94bc6f4acf5b57e54b19abccb41439fd930e3f7e..34399ec465acf36382c1b07a32718abd45d082b6 100644 (file)
@@ -52,9 +52,9 @@ MGSmootherContinuous<VECTOR>::MGSmootherContinuous (
 #if deal_II_dimension > 1
 
 template <class VECTOR>
-template <int dim>
+template <int dim, int spacedim>
 MGSmootherContinuous<VECTOR>::MGSmootherContinuous (
-  const MGDoFHandler<dim> &mg_dof,
+  const MGDoFHandler<dim,spacedim> &mg_dof,
   const unsigned int steps)
                :
                steps(steps)
@@ -85,7 +85,7 @@ MGSmootherContinuous<VECTOR>::MGSmootherContinuous (
                                       // at the boundary of this level's
                                       // cells and if so add the dofs
                                       // to the interior boundary dofs
-      for (typename MGDoFHandler<dim>::cell_iterator cell=mg_dof.begin(level);
+      for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
           cell != mg_dof.end(level); ++cell)
        for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
          if ((cell->neighbor(face).state() == IteratorState::valid) &&
index 8d815b14992c84b8d33ad99d30d52c35dd8f1371..b7f6423fe47a84da64635dc51584571a996c52ac 100644 (file)
@@ -34,10 +34,10 @@ DEAL_II_NAMESPACE_OPEN
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void MGTransferBlockBase::build_matrices (
-  const DoFHandler<dim>&,
-  const MGDoFHandler<dim>& mg_dof)
+  const DoFHandler<dim,spacedim>&,
+  const MGDoFHandler<dim,spacedim>& mg_dof)
 {
   const FiniteElement<dim>& fe = mg_dof.get_fe();
   const unsigned int n_blocks  = fe.n_blocks();
@@ -78,7 +78,7 @@ void MGTransferBlockBase::build_matrices (
     }
   
   block_start.resize(n_blocks);
-  DoFTools::count_dofs_per_block (static_cast<const DoFHandler<dim>&>(mg_dof), block_start);
+  DoFTools::count_dofs_per_block (static_cast<const DoFHandler<dim,spacedim>&>(mg_dof), block_start);
 
   unsigned int k=0;
   for (unsigned int i=0;i<block_start.size();++i)
@@ -160,7 +160,7 @@ void MGTransferBlockBase::build_matrices (
 
       prolongation_sparsities[level]->collect_sizes();
       
-      for (typename MGDoFHandler<dim>::cell_iterator cell=mg_dof.begin(level);
+      for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
           cell != mg_dof.end(level); ++cell)
        if (cell->has_children())
          {
@@ -199,7 +199,7 @@ void MGTransferBlockBase::build_matrices (
 
       prolongation_matrices[level]->reinit (*prolongation_sparsities[level]);
                                       // now actually build the matrices
-      for (typename MGDoFHandler<dim>::cell_iterator cell=mg_dof.begin(level);
+      for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
           cell != mg_dof.end(level); ++cell)
        if (cell->has_children())
          {
@@ -238,10 +238,10 @@ void MGTransferBlockBase::build_matrices (
 
 
 template <typename number>
-template <int dim>
+template <int dim, int spacedim>
 void MGTransferBlockSelect<number>::build_matrices (
-  const DoFHandler<dim> &dof,
-  const MGDoFHandler<dim> &mg_dof,
+  const DoFHandler<dim,spacedim> &dof,
+  const MGDoFHandler<dim,spacedim> &mg_dof,
   unsigned int select)
 {
   const FiniteElement<dim>& fe = mg_dof.get_fe();
@@ -257,16 +257,16 @@ void MGTransferBlockSelect<number>::build_matrices (
   std::vector<unsigned int> level_dof_indices  (fe.dofs_per_cell);
   for (int level=dof.get_tria().n_levels()-1; level>=0; --level)
     {
-      typename MGDoFHandler<dim>::active_cell_iterator
+      typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_cell = mg_dof.begin_active(level);
-      const typename MGDoFHandler<dim>::active_cell_iterator
+      const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_end  = mg_dof.end_active(level);
       
                                       // Compute coarse level right hand side
                                       // by restricting from fine level.
       for (; level_cell!=level_end; ++level_cell)
        {
-         DoFObjectAccessor<dim, DoFHandler<dim> >& global_cell = *level_cell;
+         DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
                                           // get the dof numbers of
                                           // this cell for the global
                                           // and the level-wise
@@ -290,10 +290,10 @@ void MGTransferBlockSelect<number>::build_matrices (
 
 
 template <typename number>
-template <int dim>
+template <int dim, int spacedim>
 void MGTransferBlock<number>::build_matrices (
-  const DoFHandler<dim> &dof,
-  const MGDoFHandler<dim> &mg_dof,
+  const DoFHandler<dim,spacedim> &dof,
+  const MGDoFHandler<dim,spacedim> &mg_dof,
   const std::vector<bool>& sel)
 {
   const FiniteElement<dim>& fe = mg_dof.get_fe();
@@ -314,16 +314,16 @@ void MGTransferBlock<number>::build_matrices (
   std::vector<unsigned int> level_dof_indices  (fe.dofs_per_cell);
   for (int level=dof.get_tria().n_levels()-1; level>=0; --level)
     {
-      typename MGDoFHandler<dim>::active_cell_iterator
+      typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_cell = mg_dof.begin_active(level);
-      const typename MGDoFHandler<dim>::active_cell_iterator
+      const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_end  = mg_dof.end_active(level);
       
                                       // Compute coarse level right hand side
                                       // by restricting from fine level.
       for (; level_cell!=level_end; ++level_cell)
        {
-         DoFObjectAccessor<dim, DoFHandler<dim> >& global_cell = *level_cell;
+         DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
                                           // get the dof numbers of
                                           // this cell for the global
                                           // and the level-wise
index 506a233f6483cae66d4b109562ca4fb5653bda89..f068b66e8af2157a4ec7145161b7fd4e178b0bfc 100644 (file)
@@ -33,10 +33,10 @@ DEAL_II_NAMESPACE_OPEN
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void MGTransferComponentBase::build_matrices (
-  const DoFHandler<dim>&,
-  const MGDoFHandler<dim>& mg_dof)
+  const DoFHandler<dim,spacedim>&,
+  const MGDoFHandler<dim,spacedim>& mg_dof)
 {
                                   // Fill target component with
                                   // standard values (identity) if it
@@ -114,7 +114,7 @@ void MGTransferComponentBase::build_matrices (
 
   component_start.resize(target_component.size());
   DoFTools::
-    count_dofs_per_component (static_cast<const DoFHandler<dim>&>(mg_dof),
+    count_dofs_per_component (static_cast<const DoFHandler<dim,spacedim>&>(mg_dof),
                               component_start, true, target_component);
 
   unsigned int k=0;
@@ -196,7 +196,7 @@ void MGTransferComponentBase::build_matrices (
 
       prolongation_sparsities[level]->collect_sizes();
       
-      for (typename MGDoFHandler<dim>::cell_iterator cell=mg_dof.begin(level);
+      for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
           cell != mg_dof.end(level); ++cell)
        if (cell->has_children())
          {
@@ -233,7 +233,7 @@ void MGTransferComponentBase::build_matrices (
 
       prolongation_matrices[level]->reinit (*prolongation_sparsities[level]);
                                       // now actually build the matrices
-      for (typename MGDoFHandler<dim>::cell_iterator cell=mg_dof.begin(level);
+      for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
           cell != mg_dof.end(level); ++cell)
        if (cell->has_children())
          {
@@ -269,10 +269,10 @@ void MGTransferComponentBase::build_matrices (
 
 
 template <typename number>
-template <int dim>
+template <int dim, int spacedim>
 void MGTransferSelect<number>::build_matrices (
-  const DoFHandler<dim> &dof,
-  const MGDoFHandler<dim> &mg_dof,
+  const DoFHandler<dim,spacedim> &dof,
+  const MGDoFHandler<dim,spacedim> &mg_dof,
   unsigned int select,
   unsigned int mg_select,
   const std::vector<unsigned int>& t_component,
@@ -317,16 +317,16 @@ void MGTransferSelect<number>::build_matrices (
   std::vector<unsigned int> level_dof_indices  (fe.dofs_per_cell);
   for (int level=dof.get_tria().n_levels()-1; level>=0; --level)
     {
-      typename MGDoFHandler<dim>::active_cell_iterator
+      typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_cell = mg_dof.begin_active(level);
-      const typename MGDoFHandler<dim>::active_cell_iterator
+      const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_end  = mg_dof.end_active(level);
       
                                       // Compute coarse level right hand side
                                       // by restricting from fine level.
       for (; level_cell!=level_end; ++level_cell)
        {
-         DoFObjectAccessor<dim, DoFHandler<dim> >& global_cell = *level_cell;
+         DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
                                           // get the dof numbers of
                                           // this cell for the global
                                           // and the level-wise
index 326add90f7cb4c29226f4dfd236b1eb61a2c58d8..b2fd0fd45fc9af0afcb668b44b999a39f5fd91ea 100644 (file)
@@ -31,9 +31,9 @@ DEAL_II_NAMESPACE_OPEN
 
 
 template <typename number>
-template <int dim>
+template <int dim, int spacedim>
 void MGTransferPrebuilt<number>::build_matrices (
-  const MGDoFHandler<dim> &mg_dof)
+  const MGDoFHandler<dim,spacedim> &mg_dof)
 {
   const unsigned int n_levels      = mg_dof.get_tria().n_levels();
   const unsigned int dofs_per_cell = mg_dof.get_fe().dofs_per_cell;
@@ -90,7 +90,7 @@ void MGTransferPrebuilt<number>::build_matrices (
                                              sizes[level],
                                              dofs_per_cell+1);
       
-      for (typename MGDoFHandler<dim>::cell_iterator cell=mg_dof.begin(level);
+      for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
           cell != mg_dof.end(level); ++cell)
        if (cell->has_children())
          {
@@ -127,7 +127,7 @@ void MGTransferPrebuilt<number>::build_matrices (
       prolongation_matrices[level]->reinit (*prolongation_sparsities[level]);
 
                                       // now actually build the matrices
-      for (typename MGDoFHandler<dim>::cell_iterator cell=mg_dof.begin(level);
+      for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
           cell != mg_dof.end(level); ++cell)
        if (cell->has_children())
          {
@@ -163,16 +163,16 @@ void MGTransferPrebuilt<number>::build_matrices (
   for (int level=mg_dof.get_tria().n_levels()-1; level>=0; --level)
     {
       copy_indices[level].clear();
-      typename MGDoFHandler<dim>::active_cell_iterator
+      typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_cell = mg_dof.begin_active(level);
-      const typename MGDoFHandler<dim>::active_cell_iterator
+      const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
        level_end  = mg_dof.end_active(level);
       
                                       // Compute coarse level right hand side
                                       // by restricting from fine level.
       for (; level_cell!=level_end; ++level_cell)
        {
-         DoFObjectAccessor<dim, DoFHandler<dim> >& global_cell = *level_cell;
+         DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
                                           // get the dof numbers of
                                           // this cell for the global
                                           // and the level-wise
index b5593136de049c388afef0abeeba0d661627d445..9e4dcf74d91df2fa35ca954b61a2221428414975 100644 (file)
@@ -66,7 +66,7 @@ DataEntryBase::DataEntryBase (const std::vector<std::string> &names_in,
 
 template <class DH, int patch_dim, int patch_space_dim>
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-DataEntryBase::DataEntryBase (const DataPostprocessor<DH::dimension> *data_postprocessor)
+DataEntryBase::DataEntryBase (const DataPostprocessor<DH::space_dimension> *data_postprocessor)
                :
                names(data_postprocessor->get_names()),
                data_component_interpretation (data_postprocessor->get_data_component_interpretation()),
@@ -127,7 +127,7 @@ template <typename VectorType>
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
 DataEntry<VectorType>::
 DataEntry (const VectorType                       *data,
-          const DataPostprocessor<DH::dimension> *data_postprocessor)
+          const DataPostprocessor<DH::space_dimension> *data_postprocessor)
                :
                 DataEntryBase (data_postprocessor),
                vector (data)
@@ -152,7 +152,7 @@ template <typename VectorType>
 void
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
 DataEntry<VectorType>::
-get_function_values (const FEValuesBase<DH::dimension> &fe_patch_values,
+get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
                      std::vector<Vector<double> >    &patch_values_system) const
 {
   fe_patch_values.get_function_values (*vector, patch_values_system);
@@ -166,7 +166,7 @@ template <typename VectorType>
 void
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
 DataEntry<VectorType>::
-get_function_values (const FEValuesBase<DH::dimension> &fe_patch_values,
+get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
                      std::vector<double>             &patch_values) const
 {
   fe_patch_values.get_function_values (*vector, patch_values);
@@ -179,8 +179,8 @@ template <typename VectorType>
 void
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
 DataEntry<VectorType>::
-get_function_gradients (const FEValuesBase<DH::dimension> &fe_patch_values,
-                       std::vector<std::vector<Tensor<1,DH::dimension> > >   &patch_gradients_system) const
+get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                       std::vector<std::vector<Tensor<1,DH::space_dimension> > >   &patch_gradients_system) const
 {
   fe_patch_values.get_function_grads (*vector, patch_gradients_system);
 }
@@ -193,8 +193,8 @@ template <typename VectorType>
 void
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
 DataEntry<VectorType>::
-get_function_gradients (const FEValuesBase<DH::dimension> &fe_patch_values,
-                       std::vector<Tensor<1,DH::dimension> >       &patch_gradients) const
+get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                       std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const
 {
   fe_patch_values.get_function_grads (*vector, patch_gradients);
 }
@@ -206,8 +206,8 @@ template <typename VectorType>
 void
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
 DataEntry<VectorType>::
-get_function_hessians (const FEValuesBase<DH::dimension> &fe_patch_values,
-                      std::vector<std::vector<Tensor<2,DH::dimension> > >   &patch_hessians_system) const
+get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                      std::vector<std::vector<Tensor<2,DH::space_dimension> > >   &patch_hessians_system) const
 {
   fe_patch_values.get_function_2nd_derivatives (*vector, patch_hessians_system);
 }
@@ -220,8 +220,8 @@ template <typename VectorType>
 void
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
 DataEntry<VectorType>::
-get_function_hessians (const FEValuesBase<DH::dimension> &fe_patch_values,
-                      std::vector<Tensor<2,DH::dimension> >       &patch_hessians) const
+get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                      std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const
 {
   fe_patch_values.get_function_2nd_derivatives (*vector, patch_hessians);
 }
@@ -398,7 +398,7 @@ template <class VECTOR>
 void
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
 add_data_vector (const VECTOR                           &vec,
-                const DataPostprocessor<DH::dimension> &data_postprocessor)
+                const DataPostprocessor<DH::space_dimension> &data_postprocessor)
 {
                                   // this is a specialized version of the
                                   // other function where we have a
@@ -620,7 +620,7 @@ DataOut_DoFData<DH,patch_dim,patch_space_dim>::memory_consumption () const
 
 
 template <int dim, class DH>
-void DataOut<dim,DH>::build_some_patches (internal::DataOut::ParallelData<DH::dimension, DH::dimension> &data)
+void DataOut<dim,DH>::build_some_patches (internal::DataOut::ParallelData<DH::dimension, DH::space_dimension> &data)
 {
                                   // Check consistency of redundant
                                   // template parameter
@@ -644,8 +644,8 @@ void DataOut<dim,DH>::build_some_patches (internal::DataOut::ParallelData<DH::di
                                   // collection of which we do a
                                   // shallow copy instead
   const hp::QCollection<DH::dimension>       q_collection (patch_points);
-  const hp::FECollection<DH::dimension>      fe_collection(this->dofs->get_fe());
-  const hp::MappingCollection<DH::dimension> mapping_collection(*(data.mapping));
+  const hp::FECollection<DH::dimension,DH::space_dimension>      fe_collection(this->dofs->get_fe());
+  const hp::MappingCollection<DH::dimension,DH::space_dimension> mapping_collection(*(data.mapping));
 
   UpdateFlags update_flags=update_values;
   if (curved_cell_region != no_curved_cells)
@@ -660,14 +660,14 @@ void DataOut<dim,DH>::build_some_patches (internal::DataOut::ParallelData<DH::di
   Assert (!(update_flags & update_normal_vectors),
          ExcMessage("The update of normal vectors may not be requested for evaluation of data on cells via DataPostprocessor."));
   
-  hp::FEValues<DH::dimension> x_fe_patch_values (mapping_collection,
+  hp::FEValues<DH::dimension,DH::space_dimension> x_fe_patch_values (mapping_collection,
                                                 fe_collection,
                                                 q_collection,
                                                 update_flags);
 
   const unsigned int n_q_points = patch_points.n_quadrature_points;
   
-  typename std::vector< dealii::DataOutBase::Patch<DH::dimension> >::iterator
+  typename std::vector< dealii::DataOutBase::Patch<DH::dimension,DH::space_dimension> >::iterator
     patch = this->patches.begin();
   cell_iterator cell=first_cell();
 
@@ -715,7 +715,7 @@ void DataOut<dim,DH>::build_some_patches (internal::DataOut::ParallelData<DH::di
       if (data.n_datasets > 0)
        {
           x_fe_patch_values.reinit (cell);
-          const FEValues<DH::dimension> &fe_patch_values
+          const FEValues<DH::dimension,DH::space_dimension> &fe_patch_values
             = x_fe_patch_values.get_present_fe_values ();
          
                                           // depending on the requested output
@@ -732,7 +732,7 @@ void DataOut<dim,DH>::build_some_patches (internal::DataOut::ParallelData<DH::di
              (curved_cell_region==curved_boundary && cell->at_boundary()))
            {
              Assert(patch->space_dim==dim, ExcInternalError());
-             const std::vector<Point<dim> > & q_points=fe_patch_values.get_quadrature_points();
+             const std::vector<Point<DH::space_dimension> > & q_points=fe_patch_values.get_quadrature_points();
                                               // resize the patch->data member
                                               // in order to have enough memory
                                               // for the quadrature points as
@@ -754,7 +754,7 @@ void DataOut<dim,DH>::build_some_patches (internal::DataOut::ParallelData<DH::di
                                           // first fill dof_data
          for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
            {
-             const DataPostprocessor<dim> *postprocessor=this->dof_data[dataset]->postprocessor;
+             const DataPostprocessor<DH::space_dimension> *postprocessor=this->dof_data[dataset]->postprocessor;
              
              if (postprocessor != 0)
                {
@@ -939,13 +939,13 @@ template <int dim, class DH>
 void DataOut<dim,DH>::build_patches (const unsigned int n_subdivisions,
                                     const unsigned int n_threads_) 
 {
-  build_patches (StaticMappingQ1<DH::dimension>::mapping,
+  build_patches (StaticMappingQ1<DH::dimension,DH::space_dimension>::mapping,
                 n_subdivisions, n_threads_, no_curved_cells);
 }
 
 
 template <int dim, class DH>
-void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
+void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension,DH::space_dimension> &mapping,
                                     const unsigned int nnnn_subdivisions,
                                     const unsigned int n_threads_,
                                     const CurvedCellRegion curved_region) 
@@ -964,7 +964,7 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
   Assert (n_subdivisions >= 1,
          ExcInvalidNumberOfSubdivisions(n_subdivisions));
 
-  typedef DataOut_DoFData<DH, DH::dimension> BaseClass;
+  typedef DataOut_DoFData<DH, DH::dimension, DH::space_dimension> BaseClass;
   Assert (this->dofs != 0, typename BaseClass::ExcNoDoFHandlerSelected());
 
   Assert (!DEAL_II_USE_MT || (n_threads_ >= 1),
@@ -988,7 +988,7 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
                                   // clear the patches array
   if (true)
     {
-      std::vector< dealii::DataOutBase::Patch<DH::dimension> > dummy;
+      std::vector< dealii::DataOutBase::Patch<DH::dimension, DH::space_dimension> > dummy;
       this->patches.swap (dummy);
     };
   
@@ -1011,7 +1011,7 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
                                 static_cast<unsigned int>(cell->index()));
       
       cell_to_patch_index_map[l].resize (max_index+1,
-                                         dealii::DataOutBase::Patch<DH::dimension>::no_neighbor);
+                                         dealii::DataOutBase::Patch<DH::dimension,DH::space_dimension>::no_neighbor);
     };
                                   
   unsigned int n_patches = 0;
@@ -1039,7 +1039,7 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
                                    //
                                    // then number the patches
                                    // consecutively
-  dealii::DataOutBase::Patch<DH::dimension>  default_patch;
+  dealii::DataOutBase::Patch<DH::dimension,DH::space_dimension>  default_patch;
   default_patch.n_subdivisions = n_subdivisions;
   default_patch.data.reinit (n_datasets, n_q_points);
   this->patches.insert (this->patches.end(), n_patches, default_patch);
@@ -1049,7 +1049,7 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
   
 
                                   // init data for the threads    
-  std::vector<internal::DataOut::ParallelData<DH::dimension, DH::dimension> > thread_data(n_threads);
+  std::vector<internal::DataOut::ParallelData<DH::dimension, DH::space_dimension> > thread_data(n_threads);
   for (unsigned int i=0;i<n_threads;++i)
     {
       thread_data[i].n_threads      = n_threads;
@@ -1113,52 +1113,52 @@ DataOut<dim,DH>::next_cell (const typename DataOut<dim,DH>::cell_iterator &cell)
 
 // explicit instantiations 
 
-#define INSTANTIATE(DH,D2,D3,V) \
+#define INSTANTIATE(DH,D0,D1,D2,D3,V)          \
 template void \
-DataOut_DoFData<DH,D2,D3>:: \
+DataOut_DoFData<DH<D0,D1>,D2,D3>::         \
 add_data_vector<V > (const V             &, \
                      const std::string   &, \
                      const DataVectorType,  \
                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &); \
 \
 template void \
-DataOut_DoFData<DH,D2,D3>:: \
+ DataOut_DoFData<DH<D0,D1>,D2,D3>::                   \
 add_data_vector<V > (const V                        &, \
                      const std::vector<std::string> &, \
                      const DataVectorType,  \
                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &); \
 \
 template void \
-DataOut_DoFData<DH,D2,D3>:: \
+ DataOut_DoFData<DH<D0,D1>,D2,D3>::             \
 add_data_vector<V > (const V                  &, \
-                    const DataPostprocessor<DH::dimension> &)
+                    const DataPostprocessor<DH<D0,D1>::space_dimension> &)
 
 #ifndef DEAL_II_USE_PETSC
-# define INSTANTIATE_VECTORS(DH,D2,D3) \
-    INSTANTIATE(DH,D2,D3,Vector<double>); \
-    INSTANTIATE(DH,D2,D3,Vector<float>); \
-    INSTANTIATE(DH,D2,D3,BlockVector<double>) ; \
-    INSTANTIATE(DH,D2,D3,BlockVector<float>)
+# define INSTANTIATE_VECTORS(DH,D0,D1,D2,D3)   \
+    INSTANTIATE(DH,D0,D1,D2,D3,Vector<double>); \
+    INSTANTIATE(DH,D0,D1,D2,D3,Vector<float>); \
+    INSTANTIATE(DH,D0,D1,D2,D3,BlockVector<double>) ; \
+    INSTANTIATE(DH,D0,D1,D2,D3,BlockVector<float>)
 #else
-# define INSTANTIATE_VECTORS(DH,D2,D3) \
-    INSTANTIATE(DH,D2,D3,Vector<double>); \
-    INSTANTIATE(DH,D2,D3,Vector<float>); \
-    INSTANTIATE(DH,D2,D3,BlockVector<double>) ; \
-    INSTANTIATE(DH,D2,D3,BlockVector<float>); \
-    INSTANTIATE(DH,D2,D3,PETScWrappers::Vector); \
-    INSTANTIATE(DH,D2,D3,PETScWrappers::BlockVector)
+# define INSTANTIATE_VECTORS(DH,D0,D1,D2,D3)    \
+    INSTANTIATE(DH,D0,D1,D2,D3,Vector<double>); \
+    INSTANTIATE(DH,D0,D1,D2,D3,Vector<float>); \
+    INSTANTIATE(DH,D0,D1,D2,D3,BlockVector<double>) ; \
+    INSTANTIATE(DH,D0,D1,D2,D3,BlockVector<float>); \
+    INSTANTIATE(DH,D0,D1,D2,D3,PETScWrappers::Vector);         \
+    INSTANTIATE(DH,D0,D1,D2,D3,PETScWrappers::BlockVector)
 #endif
 
 // now do actual instantiations, first for DoFHandler...
 template class DataOut_DoFData<DoFHandler<deal_II_dimension>,deal_II_dimension>;
 template class DataOut_DoFData<DoFHandler<deal_II_dimension>,deal_II_dimension+1>;
-INSTANTIATE_VECTORS(DoFHandler<deal_II_dimension>,deal_II_dimension,deal_II_dimension);
-INSTANTIATE_VECTORS(DoFHandler<deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1);
+INSTANTIATE_VECTORS(DoFHandler,deal_II_dimension,deal_II_dimension,deal_II_dimension,deal_II_dimension);
+INSTANTIATE_VECTORS(DoFHandler,deal_II_dimension,deal_II_dimension,deal_II_dimension+1,deal_II_dimension+1);
 
 // for 3d, also generate an extra class
 #if deal_II_dimension >= 2
 template class DataOut_DoFData<DoFHandler<deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>;
-INSTANTIATE_VECTORS(DoFHandler<deal_II_dimension>,deal_II_dimension-1,deal_II_dimension);
+INSTANTIATE_VECTORS(DoFHandler,deal_II_dimension,deal_II_dimension,deal_II_dimension-1,deal_II_dimension);
 #endif
 
 template class DataOut<deal_II_dimension, DoFHandler<deal_II_dimension> >;
@@ -1167,16 +1167,27 @@ template class DataOut<deal_II_dimension, DoFHandler<deal_II_dimension> >;
 // ...and now for hp::DoFHandler
 template class DataOut_DoFData<hp::DoFHandler<deal_II_dimension>,deal_II_dimension>;
 template class DataOut_DoFData<hp::DoFHandler<deal_II_dimension>,deal_II_dimension+1>;
-INSTANTIATE_VECTORS(hp::DoFHandler<deal_II_dimension>,deal_II_dimension,deal_II_dimension);
-INSTANTIATE_VECTORS(hp::DoFHandler<deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1);
+INSTANTIATE_VECTORS(hp::DoFHandler,deal_II_dimension,deal_II_dimension,deal_II_dimension,deal_II_dimension);
+INSTANTIATE_VECTORS(hp::DoFHandler,deal_II_dimension,deal_II_dimension,deal_II_dimension+1,deal_II_dimension+1);
 
 #if deal_II_dimension >= 2
 template class DataOut_DoFData<hp::DoFHandler<deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>;
-INSTANTIATE_VECTORS(hp::DoFHandler<deal_II_dimension>,deal_II_dimension-1,deal_II_dimension);
+INSTANTIATE_VECTORS(hp::DoFHandler,deal_II_dimension,deal_II_dimension,deal_II_dimension-1,deal_II_dimension);
 #endif
 
 template class DataOut<deal_II_dimension, hp::DoFHandler<deal_II_dimension> >;
 
+#if deal_II_dimension == 2 || deal_II_dimension ==1
+// now do actual instantiations, first for DoFHandler...
+template class DataOut_DoFData<DoFHandler<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension, deal_II_dimension+1>;
+template class DataOut_DoFData<DoFHandler<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension+1, deal_II_dimension+1>;
+
+INSTANTIATE_VECTORS(DoFHandler,deal_II_dimension,deal_II_dimension+1,deal_II_dimension,deal_II_dimension+1);
+INSTANTIATE_VECTORS(DoFHandler,deal_II_dimension,deal_II_dimension+1,deal_II_dimension+1,deal_II_dimension+1);
+
+template class DataOut<deal_II_dimension, DoFHandler<deal_II_dimension,deal_II_dimension+1> >;
+#endif
+
 
 #undef INSTANTIATE
 #undef INSTANTIATE_VECTORS
index 8530a5f9a5810b0474279437ed16d097764672bc..048e6ebda82d1a5b7cc7cbb642e6e360319219ea 100644 (file)
@@ -30,9 +30,9 @@
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int dim, class DH>
+template <int dim, int spacedim, class DH>
 unsigned int
-DataOutStack<dim,DH>::DataVector::memory_consumption () const
+DataOutStack<dim,spacedim,DH>::DataVector::memory_consumption () const
 {
   return (MemoryConsumption::memory_consumption (data) +
          MemoryConsumption::memory_consumption (names));
@@ -40,13 +40,13 @@ DataOutStack<dim,DH>::DataVector::memory_consumption () const
 
 
 
-template <int dim, class DH>
-DataOutStack<dim,DH>::~DataOutStack ()
+template <int dim, int spacedim, class DH>
+DataOutStack<dim,spacedim,DH>::~DataOutStack ()
 {}
 
 
-template <int dim, class DH>
-void DataOutStack<dim,DH>::new_parameter_value (const double p,
+template <int dim, int spacedim, class DH>
+void DataOutStack<dim,spacedim,DH>::new_parameter_value (const double p,
                                                const double dp)
 {
   parameter      = p;
@@ -69,8 +69,8 @@ void DataOutStack<dim,DH>::new_parameter_value (const double p,
 }
 
 
-template <int dim, class DH>
-void DataOutStack<dim,DH>::attach_dof_handler (const DH& dof) 
+template <int dim, int spacedim, class DH>
+void DataOutStack<dim,spacedim,DH>::attach_dof_handler (const DH& dof) 
 {
                                   // Check consistency of redundant
                                   // template parameter
@@ -80,8 +80,8 @@ void DataOutStack<dim,DH>::attach_dof_handler (const DH& dof)
 }
 
 
-template <int dim, class DH>
-void DataOutStack<dim,DH>::declare_data_vector (const std::string &name,
+template <int dim, int spacedim, class DH>
+void DataOutStack<dim,spacedim,DH>::declare_data_vector (const std::string &name,
                                                const VectorType   vector_type)
 {
   std::vector<std::string> names;
@@ -90,8 +90,8 @@ void DataOutStack<dim,DH>::declare_data_vector (const std::string &name,
 }
 
 
-template <int dim, class DH>
-void DataOutStack<dim,DH>::declare_data_vector (const std::vector<std::string> &names,
+template <int dim, int spacedim, class DH>
+void DataOutStack<dim,spacedim,DH>::declare_data_vector (const std::vector<std::string> &names,
                                                const VectorType    vector_type)
 {
                                   // make sure this function is
@@ -130,9 +130,9 @@ void DataOutStack<dim,DH>::declare_data_vector (const std::vector<std::string> &
 }
 
 
-template <int dim, class DH>
+template <int dim, int spacedim, class DH>
 template <typename number>
-void DataOutStack<dim,DH>::add_data_vector (const Vector<number> &vec,
+void DataOutStack<dim,spacedim,DH>::add_data_vector (const Vector<number> &vec,
                                            const std::string    &name)
 {
   const unsigned int n_components = dof_handler->get_fe().n_components ();
@@ -163,9 +163,9 @@ void DataOutStack<dim,DH>::add_data_vector (const Vector<number> &vec,
 }
 
 
-template <int dim, class DH>
+template <int dim, int spacedim, class DH>
 template <typename number>
-void DataOutStack<dim,DH>::add_data_vector (const Vector<number> &vec,
+void DataOutStack<dim,spacedim,DH>::add_data_vector (const Vector<number> &vec,
                                            const std::vector<std::string> &names)
 {
   Assert (dof_handler != 0, ExcNoDoFHandlerSelected ());
@@ -230,8 +230,8 @@ void DataOutStack<dim,DH>::add_data_vector (const Vector<number> &vec,
 }
 
 
-template <int dim, class DH>
-void DataOutStack<dim,DH>::build_patches (const unsigned int nnnn_subdivisions) 
+template <int dim, int spacedim, class DH>
+void DataOutStack<dim,spacedim,DH>::build_patches (const unsigned int nnnn_subdivisions) 
 {
                                   // this is mostly copied from the
                                   // DataOut class
@@ -409,8 +409,8 @@ void DataOutStack<dim,DH>::build_patches (const unsigned int nnnn_subdivisions)
 }
 
 
-template <int dim, class DH>
-void DataOutStack<dim,DH>::finish_parameter_value ()
+template <int dim, int spacedim, class DH>
+void DataOutStack<dim,spacedim,DH>::finish_parameter_value ()
 {
                                   // release lock on dof handler
   dof_handler = 0;
@@ -425,9 +425,9 @@ void DataOutStack<dim,DH>::finish_parameter_value ()
 
 
 
-template <int dim, class DH>
+template <int dim, int spacedim, class DH>
 unsigned int
-DataOutStack<dim,DH>::memory_consumption () const
+DataOutStack<dim,spacedim,DH>::memory_consumption () const
 {
   return (DataOutInterface<dim+1>::memory_consumption () +
          MemoryConsumption::memory_consumption (parameter) +
@@ -440,17 +440,17 @@ DataOutStack<dim,DH>::memory_consumption () const
 
 
 
-template <int dim, class DH>
+template <int dim, int spacedim, class DH>
 const std::vector< dealii::DataOutBase::Patch<dim+1,dim+1> > &
-DataOutStack<dim,DH>::get_patches () const
+DataOutStack<dim,spacedim,DH>::get_patches () const
 {
   return patches;
 }
 
 
 
-template <int dim, class DH>
-std::vector<std::string> DataOutStack<dim,DH>::get_dataset_names () const
+template <int dim, int spacedim, class DH>
+std::vector<std::string> DataOutStack<dim,spacedim,DH>::get_dataset_names () const
 {
   std::vector<std::string> names;
   for (typename std::vector<DataVector>::const_iterator dataset=dof_data.begin();
@@ -465,21 +465,21 @@ std::vector<std::string> DataOutStack<dim,DH>::get_dataset_names () const
 
 
 // explicit instantiations
-template class DataOutStack<deal_II_dimension,DoFHandler<deal_II_dimension> >;
+template class DataOutStack<deal_II_dimension,deal_II_dimension,DoFHandler<deal_II_dimension> >;
 
-template void DataOutStack<deal_II_dimension,DoFHandler<deal_II_dimension> >::
+template void DataOutStack<deal_II_dimension,deal_II_dimension,DoFHandler<deal_II_dimension> >::
 add_data_vector<double> (const Vector<double> &vec,
                         const std::string    &name);
 
-template void DataOutStack<deal_II_dimension,DoFHandler<deal_II_dimension> >::
+template void DataOutStack<deal_II_dimension,deal_II_dimension,DoFHandler<deal_II_dimension> >::
 add_data_vector<float> (const Vector<float>  &vec,
                        const std::string    &name);
 
-template class DataOutStack<deal_II_dimension,hp::DoFHandler<deal_II_dimension> >;
-template void DataOutStack<deal_II_dimension,hp::DoFHandler<deal_II_dimension> >::
+template class DataOutStack<deal_II_dimension,deal_II_dimension,hp::DoFHandler<deal_II_dimension> >;
+template void DataOutStack<deal_II_dimension,deal_II_dimension,hp::DoFHandler<deal_II_dimension> >::
 add_data_vector<double> (const Vector<double> &vec,
                         const std::string    &name);
-template void DataOutStack<deal_II_dimension,hp::DoFHandler<deal_II_dimension> >::
+template void DataOutStack<deal_II_dimension,deal_II_dimension,hp::DoFHandler<deal_II_dimension> >::
 add_data_vector<float> (const Vector<float>  &vec,
                        const std::string    &name);
 
index 0472fc83d8b2687834c6b64c420247ece0d606f3..3cae0d07052254cc046c9dd714f544cb330f61c4 100644 (file)
@@ -59,11 +59,11 @@ const UpdateFlags DerivativeApproximation::ThirdDerivative<dim>::update_flags =
 
 
 template <int dim>
-template <class InputVector>
+template <class InputVector, int spacedim>
 inline
 typename DerivativeApproximation::Gradient<dim>::ProjectedDerivative
 DerivativeApproximation::Gradient<dim>::
-get_projected_derivative (const FEValues<dim>  &fe_values,
+get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
                          const InputVector    &solution,
                          const unsigned int    component)
 {
@@ -108,11 +108,11 @@ DerivativeApproximation::Gradient<dim>::symmetrize (Derivative &)
 
 
 template <int dim>
-template <class InputVector>
+template <class InputVector, int spacedim>
 inline
 typename DerivativeApproximation::SecondDerivative<dim>::ProjectedDerivative
 DerivativeApproximation::SecondDerivative<dim>::
-get_projected_derivative (const FEValues<dim>  &fe_values,
+get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
                          const InputVector    &solution,
                          const unsigned int    component)
 {
@@ -396,11 +396,11 @@ DerivativeApproximation::SecondDerivative<dim>::symmetrize (Derivative &d)
 
 
 template <int dim>
-template <class InputVector>
+template <class InputVector, int spacedim>
 inline
 typename DerivativeApproximation::ThirdDerivative<dim>::ProjectedDerivative
 DerivativeApproximation::ThirdDerivative<dim>::
-get_projected_derivative (const FEValues<dim>  &fe_values,
+get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
                          const InputVector    &solution,
                          const unsigned int    component)
 {
@@ -504,11 +504,11 @@ DerivativeApproximation::ThirdDerivative<dim>::symmetrize (Derivative &d)
 
 
 
-template <int dim, template <int> class DH, class InputVector>
+template <int dim, template <int, int> class DH, class InputVector, int spacedim>
 void 
 DerivativeApproximation::
-approximate_gradient (const Mapping<dim>    &mapping,
-                     const DH<dim>         &dof_handler,
+approximate_gradient (const Mapping<dim,spacedim>    &mapping,
+                     const DH<dim,spacedim>         &dof_handler,
                      const InputVector     &solution,
                      Vector<float>         &derivative_norm,
                      const unsigned int     component)
@@ -521,10 +521,10 @@ approximate_gradient (const Mapping<dim>    &mapping,
 }
 
 
-template <int dim, template <int> class DH, class InputVector>
+template <int dim, template <int, int> class DH, class InputVector, int spacedim>
 void 
 DerivativeApproximation::
-approximate_gradient (const DH<dim>         &dof_handler,
+approximate_gradient (const DH<dim,spacedim>         &dof_handler,
                      const InputVector     &solution,
                      Vector<float>         &derivative_norm,
                      const unsigned int     component)
@@ -538,11 +538,11 @@ approximate_gradient (const DH<dim>         &dof_handler,
 }
 
 
-template <int dim, template <int> class DH, class InputVector>
+template <int dim, template <int, int> class DH, class InputVector, int spacedim>
 void 
 DerivativeApproximation::
-approximate_second_derivative (const Mapping<dim>    &mapping,
-                              const DH<dim>         &dof_handler,
+approximate_second_derivative (const Mapping<dim,spacedim>    &mapping,
+                              const DH<dim,spacedim>         &dof_handler,
                               const InputVector     &solution,
                               Vector<float>         &derivative_norm,
                               const unsigned int     component)
@@ -555,10 +555,10 @@ approximate_second_derivative (const Mapping<dim>    &mapping,
 }
 
 
-template <int dim, template <int> class DH, class InputVector>
+template <int dim, template <int, int> class DH, class InputVector, int spacedim>
 void 
 DerivativeApproximation::
-approximate_second_derivative (const DH<dim>         &dof_handler,
+approximate_second_derivative (const DH<dim,spacedim>         &dof_handler,
                               const InputVector     &solution,
                               Vector<float>         &derivative_norm,
                               const unsigned int     component)
@@ -572,13 +572,13 @@ approximate_second_derivative (const DH<dim>         &dof_handler,
 }
 
 
-template <int dim, template <int> class DH, class InputVector, int order>
+template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
 void
 DerivativeApproximation::
-approximate_derivative_tensor (const Mapping<dim>                           &mapping,
-                              const DH<dim>                                &dof,
+approximate_derivative_tensor (const Mapping<dim,spacedim>                           &mapping,
+                              const DH<dim,spacedim>                                &dof,
                               const InputVector                            &solution,
-                              const typename DH<dim>::active_cell_iterator &cell,
+                              const typename DH<dim,spacedim>::active_cell_iterator &cell,
                               Tensor<order,dim>                            &derivative,
                               const unsigned int                            component)
 {
@@ -593,12 +593,12 @@ approximate_derivative_tensor (const Mapping<dim>                           &map
 
 
 
-template <int dim, template <int> class DH, class InputVector, int order>
+template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
 void
 DerivativeApproximation::
-approximate_derivative_tensor (const DH<dim>                                &dof,
+approximate_derivative_tensor (const DH<dim,spacedim>                                &dof,
                               const InputVector                            &solution,
-                              const typename DH<dim>::active_cell_iterator &cell,
+                              const typename DH<dim,spacedim>::active_cell_iterator &cell,
                               Tensor<order,dim>                            &derivative,
                               const unsigned int                            component)
 {
@@ -616,11 +616,11 @@ approximate_derivative_tensor (const DH<dim>                                &dof
 
 
 template <class DerivativeDescription, int dim,
-          template <int> class DH, class InputVector>
+          template <int, int> class DH, class InputVector, int spacedim>
 void 
 DerivativeApproximation::
-approximate_derivative (const Mapping<dim>    &mapping,
-                       const DH<dim>         &dof_handler,
+approximate_derivative (const Mapping<dim,spacedim>    &mapping,
+                       const DH<dim,spacedim>         &dof_handler,
                        const InputVector     &solution,
                        const unsigned int     component,
                        Vector<float>         &derivative_norm)
@@ -638,8 +638,8 @@ approximate_derivative (const Mapping<dim>    &mapping,
 
   Threads::ThreadGroup<> threads;
   
-  typedef void (*FunPtr) (const Mapping<dim>    &,
-                          const DH<dim>         &,
+  typedef void (*FunPtr) (const Mapping<dim,spacedim>    &,
+                          const DH<dim,spacedim>         &,
                           const InputVector     &,
                           const unsigned int     ,
                           const IndexInterval   &,
@@ -659,10 +659,10 @@ approximate_derivative (const Mapping<dim>    &mapping,
 
 
 template <class DerivativeDescription, int dim,
-          template <int> class DH, class InputVector>
+          template <int, int> class DH, class InputVector, int spacedim>
 void 
-DerivativeApproximation::approximate (const Mapping<dim>    &mapping,
-                                     const DH<dim>         &dof_handler,
+DerivativeApproximation::approximate (const Mapping<dim,spacedim>    &mapping,
+                                     const DH<dim,spacedim>         &dof_handler,
                                      const InputVector     &solution,
                                      const unsigned int     component,
                                      const IndexInterval   &index_interval,
@@ -675,7 +675,7 @@ DerivativeApproximation::approximate (const Mapping<dim>    &mapping,
     derivative_norm_on_this_cell
     = derivative_norm.begin() + index_interval.first;
   
-  typename DH<dim>::active_cell_iterator cell, endc;
+  typename DH<dim,spacedim>::active_cell_iterator cell, endc;
   cell = endc = dof_handler.begin_active();
                                   // (static_cast to avoid warnings
                                   // about unsigned always >=0)
@@ -703,14 +703,14 @@ DerivativeApproximation::approximate (const Mapping<dim>    &mapping,
 
 
 template <class DerivativeDescription, int dim,
-          template <int> class DH, class InputVector>
+          template <int, int> class DH, class InputVector, int spacedim>
 void 
 DerivativeApproximation::
-approximate_cell (const Mapping<dim>                            &mapping,
-                 const DH<dim>                                 &dof_handler,
+approximate_cell (const Mapping<dim,spacedim>                            &mapping,
+                 const DH<dim,spacedim>                                 &dof_handler,
                  const InputVector                             &solution,
                  const unsigned int                             component,
-                 const typename DH<dim>::active_cell_iterator  &cell,
+                 const typename DH<dim,spacedim>::active_cell_iterator  &cell,
                  typename DerivativeDescription::Derivative    &derivative)    
 { 
   QMidpoint<dim> midpoint_rule;
@@ -739,7 +739,7 @@ approximate_cell (const Mapping<dim>                            &mapping,
                                   // active neighbors of a cell
                                   // reserve the maximal number of
                                   // active neighbors
-  std::vector<typename DH<dim>::active_cell_iterator> active_neighbors;
+  std::vector<typename DH<dim,spacedim>::active_cell_iterator> active_neighbors;
   active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
                            GeometryInfo<dim>::max_children_per_face);
 
@@ -777,16 +777,16 @@ approximate_cell (const Mapping<dim>                            &mapping,
                                       // first collect all neighbor
                                       // cells in a vector, and then
                                       // collect the data from them
-      GridTools::template get_active_neighbors<DH<dim> >(cell, active_neighbors);
+      GridTools::template get_active_neighbors<DH<dim,spacedim> >(cell, active_neighbors);
       
                                       // now loop over all active
                                       // neighbors and collect the
                                       // data we need
-      typename std::vector<typename DH<dim>::active_cell_iterator>::const_iterator
+      typename std::vector<typename DH<dim,spacedim>::active_cell_iterator>::const_iterator
        neighbor_ptr = active_neighbors.begin();
       for (; neighbor_ptr!=active_neighbors.end(); ++neighbor_ptr)
        {
-         const typename DH<dim>::active_cell_iterator
+         const typename DH<dim,spacedim>::active_cell_iterator
            neighbor = *neighbor_ptr;
            
                                           // reinit fe values object...
index 5e35be9482a52df29c0f1c8ea6299c40db9ea5c0..15a88199a669dc4ff50d80496a10c0038ac4a792 100644 (file)
@@ -72,10 +72,11 @@ void advance_by_n (CellIterator &cell,
 #if deal_II_dimension == 1
 
 
+template <int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<1>::
-estimate (const Mapping<1>      &mapping,
+KellyErrorEstimator<1,spacedim>::
+estimate (const Mapping<1,spacedim>      &mapping,
           const DH   &dof_handler,
           const Quadrature<0> &quadrature,
           const FunctionMap<1>::type &neumann_bc,
@@ -95,9 +96,11 @@ estimate (const Mapping<1>      &mapping,
 }
 
 
+
+template <int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<1>::
+KellyErrorEstimator<1,spacedim>::
 estimate (const DH   &dof_handler,
           const Quadrature<0> &quadrature,
           const FunctionMap<1>::type &neumann_bc,
@@ -110,15 +113,16 @@ estimate (const DH   &dof_handler,
           const unsigned int       material_id)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  estimate(StaticMappingQ1<1>::mapping, dof_handler, quadrature, neumann_bc, solution,
+  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
           error, component_mask, coefficients, n_threads, subdomain_id, material_id);
 }
 
 
 
+template <int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<1>::
+KellyErrorEstimator<1,spacedim>::
 estimate (const DH   &dof_handler,
           const Quadrature<0> &quadrature,
           const FunctionMap<1>::type &neumann_bc,
@@ -131,16 +135,17 @@ estimate (const DH   &dof_handler,
           const unsigned int       material_id)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  estimate(StaticMappingQ1<1>::mapping, dof_handler, quadrature, neumann_bc, solutions,
+  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
           errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
 }
 
 
 
+template <int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<1>::
-estimate (const Mapping<1>      &mapping,
+KellyErrorEstimator<1,spacedim>::
+estimate (const Mapping<1,spacedim>      &mapping,
           const DH   &dof_handler,
           const hp::QCollection<0> &quadrature,
           const FunctionMap<1>::type &neumann_bc,
@@ -160,9 +165,10 @@ estimate (const Mapping<1>      &mapping,
 }
 
 
+template <int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<1>::
+KellyErrorEstimator<1,spacedim>::
 estimate (const DH   &dof_handler,
           const hp::QCollection<0> &quadrature,
           const FunctionMap<1>::type &neumann_bc,
@@ -175,15 +181,16 @@ estimate (const DH   &dof_handler,
           const unsigned int       material_id)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  estimate(StaticMappingQ1<1>::mapping, dof_handler, quadrature, neumann_bc, solution,
+  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
           error, component_mask, coefficients, n_threads, subdomain_id, material_id);
 }
 
 
 
+template <int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<1>::
+KellyErrorEstimator<1,spacedim>::
 estimate (const DH   &dof_handler,
           const hp::QCollection<0> &quadrature,
           const FunctionMap<1>::type &neumann_bc,
@@ -196,16 +203,17 @@ estimate (const DH   &dof_handler,
           const unsigned int       material_id)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  estimate(StaticMappingQ1<1>::mapping, dof_handler, quadrature, neumann_bc, solutions,
+  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
           errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
 }
 
 
 
 
+template <int spacedim>
 template <typename InputVector, class DH>
-void KellyErrorEstimator<1>::
-estimate (const Mapping<1>                    &/*mapping*/,
+void KellyErrorEstimator<1,spacedim>::
+estimate (const Mapping<1,spacedim>                    &/*mapping*/,
           const DH                            &/*dof_handler*/,
           const hp::QCollection<0>            &,
           const FunctionMap<1>::type          &/*neumann_bc*/,
@@ -222,9 +230,10 @@ estimate (const Mapping<1>                    &/*mapping*/,
 
 
 
+template <int spacedim>
 template <typename InputVector, class DH>
-void KellyErrorEstimator<1>::
-estimate (const Mapping<1>                    &mapping,
+void KellyErrorEstimator<1,spacedim>::
+estimate (const Mapping<1,spacedim>                    &mapping,
           const DH                 &dof_handler,
           const Quadrature<0>                 &,
           const FunctionMap<1>::type          &neumann_bc,
@@ -318,12 +327,12 @@ estimate (const Mapping<1>                    &mapping,
   const QTrapez<1> quadrature;
   const hp::QCollection<1> q_collection(quadrature);
 
-  const hp::FECollection<1> fe (dof_handler.get_fe());
+  const hp::FECollection<1,spacedim> fe (dof_handler.get_fe());
 
-  hp::MappingCollection<1> mapping_collection;
+  hp::MappingCollection<1,spacedim> mapping_collection;
   mapping_collection.push_back (mapping);
   
-  hp::FEValues<1> fe_values (mapping_collection, fe, q_collection,
+  hp::FEValues<1,spacedim> fe_values (mapping_collection, fe, q_collection,
                             update_gradients);
   
                                   // loop over all cells and do something on
@@ -460,8 +469,8 @@ estimate (const Mapping<1>                    &mapping,
 #else // #if deal_II_dimension !=1
 
 
-template <int dim>
-KellyErrorEstimator<dim>::PerThreadData::
+template <int dim, int spacedim>
+KellyErrorEstimator<dim, spacedim>::PerThreadData::
 PerThreadData (const unsigned int n_solution_vectors,
               const unsigned int n_components,
               const unsigned int max_n_q_points,
@@ -506,9 +515,9 @@ PerThreadData (const unsigned int n_solution_vectors,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-KellyErrorEstimator<dim>::PerThreadData::
+KellyErrorEstimator<dim, spacedim>::PerThreadData::
 resize (const unsigned int n_components,
        const unsigned int n_q_points)
 {
@@ -542,11 +551,11 @@ resize (const unsigned int n_components,
 
 // the following function is still independent of dimension, but it
 // calls dimension dependent functions
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<dim>::
-estimate (const Mapping<dim>      &mapping,
+KellyErrorEstimator<dim, spacedim>::
+estimate (const Mapping<dim, spacedim>      &mapping,
           const DH                &dof_handler,
           const Quadrature<dim-1> &quadrature,
           const typename FunctionMap<dim>::type &neumann_bc,
@@ -566,10 +575,10 @@ estimate (const Mapping<dim>      &mapping,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<dim>::
+KellyErrorEstimator<dim,spacedim>::
 estimate (const DH                &dof_handler,
           const Quadrature<dim-1> &quadrature,
           const typename FunctionMap<dim>::type &neumann_bc,
@@ -588,11 +597,11 @@ estimate (const DH                &dof_handler,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<dim>::
-estimate (const Mapping<dim>      &mapping,
+KellyErrorEstimator<dim, spacedim>::
+estimate (const Mapping<dim, spacedim>      &mapping,
           const DH                &dof_handler,
           const hp::QCollection<dim-1> &quadrature,
           const typename FunctionMap<dim>::type &neumann_bc,
@@ -612,10 +621,10 @@ estimate (const Mapping<dim>      &mapping,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<dim>::
+KellyErrorEstimator<dim, spacedim>::
 estimate (const DH                &dof_handler,
           const hp::QCollection<dim-1> &quadrature,
           const typename FunctionMap<dim>::type &neumann_bc,
@@ -635,10 +644,10 @@ estimate (const DH                &dof_handler,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
-void KellyErrorEstimator<dim>::
-estimate_some (const hp::MappingCollection<dim>                  &mapping,
+void KellyErrorEstimator<dim, spacedim>::
+estimate_some (const hp::MappingCollection<dim, spacedim>      &mapping,
                const DH                                 &dof_handler,
                const hp::QCollection<dim-1>             &quadrature,
                const typename FunctionMap<dim>::type &neumann_bc,
@@ -904,11 +913,11 @@ estimate_some (const hp::MappingCollection<dim>                  &mapping,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<dim>::
-estimate (const Mapping<dim>                  &mapping,
+KellyErrorEstimator<dim, spacedim>::
+estimate (const Mapping<dim, spacedim>                  &mapping,
           const DH                            &dof_handler,
           const hp::QCollection<dim-1>        &face_quadratures,
           const typename FunctionMap<dim>::type &neumann_bc,
@@ -1017,7 +1026,7 @@ estimate (const Mapping<dim>                  &mapping,
                                   // work around another nasty bug in
                                   // icc7
   Threads::ThreadGroup<> threads;
-  void (*estimate_some_ptr) (const hp::MappingCollection<dim>                  &,
+  void (*estimate_some_ptr) (const hp::MappingCollection<dim,spacedim>                  &,
                             const DH               &,
                             const hp::QCollection<dim-1>             &,
                             const typename FunctionMap<dim>::type &,
@@ -1026,9 +1035,9 @@ estimate (const Mapping<dim>                  &mapping,
                             const std::pair<unsigned int, unsigned int>,
                             typename FaceIntegrals<DH>::type                       &,
                             PerThreadData                       &)
-    = &KellyErrorEstimator<dim>::template estimate_some<InputVector,DH>;
+    = &KellyErrorEstimator<dim, spacedim>::template estimate_some<InputVector,DH>;
 
-  hp::MappingCollection<dim> mapping_collection;
+  hp::MappingCollection<dim,spacedim> mapping_collection;
   mapping_collection.push_back (mapping);
   
   for (unsigned int i=0; i<n_threads; ++i)
@@ -1110,11 +1119,11 @@ estimate (const Mapping<dim>                  &mapping,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
 void
-KellyErrorEstimator<dim>::
-estimate (const Mapping<dim>                  &mapping,
+KellyErrorEstimator<dim, spacedim>::
+estimate (const Mapping<dim, spacedim>                  &mapping,
           const DH                            &dof_handler,
           const Quadrature<dim-1>             &quadrature,
           const typename FunctionMap<dim>::type &neumann_bc,
@@ -1135,9 +1144,9 @@ estimate (const Mapping<dim>                  &mapping,
 }
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
-void KellyErrorEstimator<dim>::estimate (const DH                            &dof_handler,
+void KellyErrorEstimator<dim, spacedim>::estimate (const DH                            &dof_handler,
                                         const Quadrature<dim-1>             &quadrature,
                                         const typename FunctionMap<dim>::type &neumann_bc,
                                         const std::vector<const InputVector *> &solutions,
@@ -1156,9 +1165,9 @@ void KellyErrorEstimator<dim>::estimate (const DH                            &do
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
-void KellyErrorEstimator<dim>::estimate (const DH                            &dof_handler,
+void KellyErrorEstimator<dim, spacedim>::estimate (const DH                            &dof_handler,
                                         const hp::QCollection<dim-1>             &quadrature,
                                         const typename FunctionMap<dim>::type &neumann_bc,
                                         const std::vector<const InputVector *> &solutions,
@@ -1177,9 +1186,9 @@ void KellyErrorEstimator<dim>::estimate (const DH                            &do
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
-void KellyErrorEstimator<dim>::
+void KellyErrorEstimator<dim, spacedim>::
 integrate_over_regular_face (const DH                                 &dof_handler,
                              const hp::QCollection<dim-1>             &quadrature,
                              const typename FunctionMap<dim>::type &neumann_bc,
@@ -1384,9 +1393,9 @@ integrate_over_regular_face (const DH                                 &dof_handl
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 template <typename InputVector, class DH>
-void KellyErrorEstimator<dim>::
+void KellyErrorEstimator<dim, spacedim>::
 integrate_over_irregular_face (const DH                                 &dof_handler,
                                const hp::QCollection<dim-1>             &quadrature,
                                const std::vector<const InputVector *> &solutions,
@@ -1582,7 +1591,7 @@ integrate_over_irregular_face (const DH                                 &dof_han
 
 // explicit instantiations
 #if deal_II_dimension != 1
-template class KellyErrorEstimator<deal_II_dimension>;
+template class KellyErrorEstimator<deal_II_dimension, deal_II_dimension>;
 #endif
 
 // instantiate the externally visible functions. define a list of functions
@@ -1591,8 +1600,8 @@ template class KellyErrorEstimator<deal_II_dimension>;
 #define INSTANTIATE_1(InputVector,DH,Q) \
 template    \
 void    \
-KellyErrorEstimator<deal_II_dimension>::    \
-estimate<InputVector,DH > (const Mapping<deal_II_dimension>      &,    \
+KellyErrorEstimator<deal_II_dimension, deal_II_dimension>::    \
+estimate<InputVector,DH > (const Mapping<deal_II_dimension, deal_II_dimension>      &,    \
           const DH   &,    \
           const Q<deal_II_dimension-1> &,    \
           const FunctionMap<deal_II_dimension>::type &,    \
@@ -1606,7 +1615,7 @@ estimate<InputVector,DH > (const Mapping<deal_II_dimension>      &,    \
     \
 template    \
 void    \
-KellyErrorEstimator<deal_II_dimension>::    \
+KellyErrorEstimator<deal_II_dimension, deal_II_dimension>::    \
 estimate<InputVector,DH > (const DH   &,    \
           const Q<deal_II_dimension-1> &,    \
           const FunctionMap<deal_II_dimension>::type &,    \
@@ -1620,8 +1629,8 @@ estimate<InputVector,DH > (const DH   &,    \
         \
 template    \
 void    \
-KellyErrorEstimator<deal_II_dimension>::    \
-estimate<InputVector,DH > (const Mapping<deal_II_dimension>          &,    \
+KellyErrorEstimator<deal_II_dimension, deal_II_dimension>::    \
+estimate<InputVector,DH > (const Mapping<deal_II_dimension, deal_II_dimension>          &,    \
           const DH       &,    \
           const Q<deal_II_dimension-1>     &,    \
           const FunctionMap<deal_II_dimension>::type &,    \
@@ -1635,7 +1644,7 @@ estimate<InputVector,DH > (const Mapping<deal_II_dimension>          &,    \
     \
 template    \
 void    \
-KellyErrorEstimator<deal_II_dimension>::    \
+KellyErrorEstimator<deal_II_dimension, deal_II_dimension>::    \
 estimate<InputVector,DH > (const DH       &,    \
           const Q<deal_II_dimension-1>     &,    \
           const FunctionMap<deal_II_dimension>::type &,    \
index d5053bbd670ed78cf8489b70eb4da2bbe7fa26fd..acab29d6af1de3571102057986b74fe7081c6c71 100644 (file)
@@ -65,12 +65,12 @@ MatrixCreator::IteratorRange<DH>::IteratorRange (const iterator_pair &ip)
 
 
 
-template <int dim, typename number>
-void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
-                                       const DoFHandler<dim>    &dof,
+template <int dim, typename number, int spacedim>
+void MatrixCreator::create_mass_matrix (const Mapping<dim, spacedim>       &mapping,
+                                       const DoFHandler<dim,spacedim>    &dof,
                                        const Quadrature<dim>    &q,
                                        SparseMatrix<number>     &matrix,
-                                       const Function<dim> * const coefficient)
+                                       const Function<spacedim> * const coefficient)
 {
   Assert (matrix.m() == dof.n_dofs(),
          ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
@@ -82,7 +82,7 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   const std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
     thread_ranges = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                                 dof.end(), n_threads);
@@ -92,14 +92,14 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
   Threads::ThreadMutex mutex;
   
                                   // then assemble in parallel
-  typedef void (*create_mass_matrix_1_t) (const Mapping<dim>       &mapping,
-                                         const DoFHandler<dim>    &dof,
+  typedef void (*create_mass_matrix_1_t) (const Mapping<dim, spacedim>       &mapping,
+                                         const DoFHandler<dim,spacedim>    &dof,
                                          const Quadrature<dim>    &q,
                                          SparseMatrix<number>     &matrix,
-                                         const Function<dim> * const coefficient,
-                                         const IteratorRange<DoFHandler<dim> >  range,
+                                         const Function<spacedim> * const coefficient,
+                                         const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                          Threads::ThreadMutex     &mutex);
-  create_mass_matrix_1_t p = &MatrixCreator::template create_mass_matrix_1<dim,number>;
+  create_mass_matrix_1_t p = &MatrixCreator::template create_mass_matrix_1<dim,number,spacedim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
     threads += Threads::spawn (p)(mapping, dof, q, matrix, coefficient,
                                   thread_ranges[thread], mutex);
@@ -108,24 +108,24 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
 
 
 
-template <int dim, typename number>
-void MatrixCreator::create_mass_matrix_1 (const Mapping<dim>       &mapping,
-                                         const DoFHandler<dim>    &dof,
+template <int dim, typename number, int spacedim>
+void MatrixCreator::create_mass_matrix_1 (const Mapping<dim, spacedim>       &mapping,
+                                         const DoFHandler<dim,spacedim>    &dof,
                                          const Quadrature<dim>    &q,
                                          SparseMatrix<number>     &matrix,
-                                         const Function<dim> * const coefficient,
-                                         const IteratorRange<DoFHandler<dim> >  range,
+                                         const Function<spacedim> * const coefficient,
+                                         const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                          Threads::ThreadMutex     &mutex)
 {
   UpdateFlags update_flags = UpdateFlags(update_values | update_JxW_values);
   if (coefficient != 0)
     update_flags = UpdateFlags (update_flags | update_quadrature_points);
   
-  FEValues<dim> fe_values (mapping, dof.get_fe(), q, update_flags);
+  FEValues<dim,spacedim> fe_values (mapping, dof.get_fe(), q, update_flags);
     
   const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                     n_q_points    = fe_values.n_quadrature_points;
-  const FiniteElement<dim>    &fe  = fe_values.get_fe();
+  const FiniteElement<dim,spacedim>    &fe  = fe_values.get_fe();
   const unsigned int n_components  = fe.n_components();
 
   Assert(coefficient == 0 ||
@@ -139,7 +139,7 @@ void MatrixCreator::create_mass_matrix_1 (const Mapping<dim>       &mapping,
   
   std::vector<unsigned int> dof_indices (dofs_per_cell);
   
-  typename DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     {
       fe_values.reinit (cell);
@@ -298,25 +298,25 @@ void MatrixCreator::create_mass_matrix_1 (const Mapping<dim>       &mapping,
 }
 
 
-template <int dim, typename number>
-void MatrixCreator::create_mass_matrix (const DoFHandler<dim>    &dof,
+template <int dim, typename number, int spacedim>
+void MatrixCreator::create_mass_matrix (const DoFHandler<dim,spacedim>    &dof,
                                        const Quadrature<dim>    &q,
                                        SparseMatrix<number>     &matrix,
-                                       const Function<dim> * const coefficient)
+                                       const Function<spacedim> * const coefficient)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  create_mass_matrix(StaticMappingQ1<dim>::mapping, dof, q, matrix, coefficient);
+  create_mass_matrix(StaticMappingQ1<dim,spacedim>::mapping, dof, q, matrix, coefficient);
 }
 
 
-template <int dim, typename number>
-void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
-                                       const DoFHandler<dim>    &dof,
+template <int dim, typename number, int spacedim>
+void MatrixCreator::create_mass_matrix (const Mapping<dim, spacedim>       &mapping,
+                                       const DoFHandler<dim,spacedim>    &dof,
                                        const Quadrature<dim>    &q,
                                        SparseMatrix<number>     &matrix,
-                                       const Function<dim>      &rhs,
+                                       const Function<spacedim>      &rhs,
                                        Vector<double>           &rhs_vector,
-                                       const Function<dim> * const coefficient)
+                                       const Function<spacedim> * const coefficient)
 {
   Assert (matrix.m() == dof.n_dofs(),
          ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
@@ -328,7 +328,7 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
     = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                  dof.end(), n_threads);
@@ -338,16 +338,16 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
   Threads::ThreadMutex mutex;
   
                                   // then assemble in parallel
-  typedef void (*create_mass_matrix_2_t) (const Mapping<dim>       &mapping,
-                                         const DoFHandler<dim>    &dof,
+  typedef void (*create_mass_matrix_2_t) (const Mapping<dim, spacedim>       &mapping,
+                                         const DoFHandler<dim,spacedim>    &dof,
                                          const Quadrature<dim>    &q,
                                          SparseMatrix<number>     &matrix,
-                                         const Function<dim>      &rhs,
+                                         const Function<spacedim>      &rhs,
                                          Vector<double>           &rhs_vector,
-                                         const Function<dim> * const coefficient,
-                                         const IteratorRange<DoFHandler<dim> >  range,
+                                         const Function<spacedim> * const coefficient,
+                                         const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                          Threads::ThreadMutex     &mutex);
-  create_mass_matrix_2_t p = &MatrixCreator::template create_mass_matrix_2<dim,number>;
+  create_mass_matrix_2_t p = &MatrixCreator::template create_mass_matrix_2<dim,number,spacedim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
     threads += Threads::spawn (p)(mapping, dof, q, matrix, rhs,
                                   rhs_vector, coefficient,
@@ -357,16 +357,16 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
 
 
 
-template <int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
-MatrixCreator::create_mass_matrix_2 (const Mapping<dim>       &mapping,
-                                    const DoFHandler<dim>    &dof,
+MatrixCreator::create_mass_matrix_2 (const Mapping<dim, spacedim>       &mapping,
+                                    const DoFHandler<dim,spacedim>    &dof,
                                     const Quadrature<dim>    &q,
                                     SparseMatrix<number>     &matrix,
-                                    const Function<dim>      &rhs,
+                                    const Function<spacedim>      &rhs,
                                     Vector<double>           &rhs_vector,
-                                    const Function<dim> * const coefficient,
-                                    const IteratorRange<DoFHandler<dim> >  range,
+                                    const Function<spacedim> * const coefficient,
+                                    const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                     Threads::ThreadMutex     &mutex)
 {
   UpdateFlags update_flags = UpdateFlags(update_values |
@@ -375,11 +375,11 @@ MatrixCreator::create_mass_matrix_2 (const Mapping<dim>       &mapping,
   if (coefficient != 0)
     update_flags = UpdateFlags (update_flags | update_quadrature_points);
 
-  FEValues<dim> fe_values (mapping, dof.get_fe(), q, update_flags);
+  FEValues<dim,spacedim> fe_values (mapping, dof.get_fe(), q, update_flags);
     
   const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                     n_q_points    = fe_values.n_quadrature_points;
-  const FiniteElement<dim>    &fe  = fe_values.get_fe();
+  const FiniteElement<dim,spacedim>    &fe  = fe_values.get_fe();
   const unsigned int n_components  = fe.n_components();
 
   Assert(coefficient == 0 ||
@@ -395,7 +395,7 @@ MatrixCreator::create_mass_matrix_2 (const Mapping<dim>       &mapping,
   
   std::vector<unsigned int> dof_indices (dofs_per_cell);
   
-  typename DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     {
       fe_values.reinit (cell);
@@ -493,27 +493,27 @@ MatrixCreator::create_mass_matrix_2 (const Mapping<dim>       &mapping,
 }
 
 
-template <int dim, typename number>
-void MatrixCreator::create_mass_matrix (const DoFHandler<dim>    &dof,
+template <int dim, typename number, int spacedim>
+void MatrixCreator::create_mass_matrix (const DoFHandler<dim,spacedim>    &dof,
                                        const Quadrature<dim>    &q,
                                        SparseMatrix<number>     &matrix,
-                                       const Function<dim>      &rhs,
+                                       const Function<spacedim>      &rhs,
                                        Vector<double>           &rhs_vector,
-                                       const Function<dim> * const coefficient)
+                                       const Function<spacedim> * const coefficient)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  create_mass_matrix(StaticMappingQ1<dim>::mapping,
+  create_mass_matrix(StaticMappingQ1<dim,spacedim>::mapping,
                     dof, q, matrix, rhs, rhs_vector, coefficient);
 }
 
 
 
-template <int dim, typename number>
-void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim>       &mapping,
-                                       const hp::DoFHandler<dim>    &dof,
+template <int dim, typename number, int spacedim>
+void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                       const hp::DoFHandler<dim,spacedim>    &dof,
                                        const hp::QCollection<dim>    &q,
                                        SparseMatrix<number>     &matrix,
-                                       const Function<dim> * const coefficient)
+                                       const Function<spacedim> * const coefficient)
 {
   Assert (matrix.m() == dof.n_dofs(),
          ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
@@ -525,7 +525,7 @@ void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim>       &
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename hp::DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename hp::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
     = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                  dof.end(), n_threads);
@@ -535,12 +535,12 @@ void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim>       &
   Threads::ThreadMutex mutex;
   
                                   // then assemble in parallel
-  typedef void (*create_mass_matrix_1_t) (const hp::MappingCollection<dim>       &mapping,
-                                         const hp::DoFHandler<dim>    &dof,
+  typedef void (*create_mass_matrix_1_t) (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                         const hp::DoFHandler<dim,spacedim>    &dof,
                                          const hp::QCollection<dim>    &q,
                                          SparseMatrix<number>     &matrix,
-                                         const Function<dim> * const coefficient,
-                                         const IteratorRange<hp::DoFHandler<dim> >  range,
+                                         const Function<spacedim> * const coefficient,
+                                         const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                          Threads::ThreadMutex     &mutex);
   create_mass_matrix_1_t p = &MatrixCreator::template create_mass_matrix_1<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
@@ -551,14 +551,14 @@ void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim>       &
 
 
 
-template <int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
-MatrixCreator::create_mass_matrix_1 (const hp::MappingCollection<dim>       &mapping,
-                                    const hp::DoFHandler<dim>    &dof,
+MatrixCreator::create_mass_matrix_1 (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                    const hp::DoFHandler<dim,spacedim>    &dof,
                                     const hp::QCollection<dim>    &q,
                                     SparseMatrix<number>     &matrix,
-                                    const Function<dim> * const coefficient,
-                                    const IteratorRange<hp::DoFHandler<dim> >  range,
+                                    const Function<spacedim> * const coefficient,
+                                    const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                     Threads::ThreadMutex     &mutex)
 {
   UpdateFlags update_flags = UpdateFlags(update_values |
@@ -566,7 +566,7 @@ MatrixCreator::create_mass_matrix_1 (const hp::MappingCollection<dim>       &map
   if (coefficient != 0)
     update_flags = UpdateFlags (update_flags | update_quadrature_points);
 
-  hp::FEValues<dim> x_fe_values (mapping, dof.get_fe(), q, update_flags);
+  hp::FEValues<dim,spacedim> x_fe_values (mapping, dof.get_fe(), q, update_flags);
     
   const unsigned int n_components  = dof.get_fe().n_components();
 
@@ -580,15 +580,15 @@ MatrixCreator::create_mass_matrix_1 (const hp::MappingCollection<dim>       &map
   
   std::vector<unsigned int> dof_indices;
   
-  typename hp::DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename hp::DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     {
       x_fe_values.reinit (cell);
-      const FEValues<dim> &fe_values = x_fe_values.get_present_fe_values ();
+      const FEValues<dim,spacedim> &fe_values = x_fe_values.get_present_fe_values ();
 
       const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                         n_q_points    = fe_values.n_quadrature_points;
-      const FiniteElement<dim>    &fe  = fe_values.get_fe();
+      const FiniteElement<dim,spacedim>    &fe  = fe_values.get_fe();
 
       cell_matrix.reinit (dofs_per_cell, dofs_per_cell);
       coefficient_values.resize (n_q_points);
@@ -682,11 +682,11 @@ MatrixCreator::create_mass_matrix_1 (const hp::MappingCollection<dim>       &map
 
 
 
-template <int dim, typename number>
-void MatrixCreator::create_mass_matrix (const hp::DoFHandler<dim>    &dof,
+template <int dim, typename number, int spacedim>
+void MatrixCreator::create_mass_matrix (const hp::DoFHandler<dim,spacedim>    &dof,
                                        const hp::QCollection<dim>    &q,
                                        SparseMatrix<number>     &matrix,
-                                       const Function<dim> * const coefficient)
+                                       const Function<spacedim> * const coefficient)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
   create_mass_matrix(hp::StaticMappingQ1<dim>::mapping_collection, dof, q, matrix, coefficient);
@@ -694,14 +694,14 @@ void MatrixCreator::create_mass_matrix (const hp::DoFHandler<dim>    &dof,
 
 
 
-template <int dim, typename number>
-void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim>       &mapping,
-                                       const hp::DoFHandler<dim>    &dof,
+template <int dim, typename number, int spacedim>
+void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                       const hp::DoFHandler<dim,spacedim>    &dof,
                                        const hp::QCollection<dim>    &q,
                                        SparseMatrix<number>     &matrix,
-                                       const Function<dim>      &rhs,
+                                       const Function<spacedim>      &rhs,
                                        Vector<double>           &rhs_vector,
-                                       const Function<dim> * const coefficient)
+                                       const Function<spacedim> * const coefficient)
 {
   Assert (matrix.m() == dof.n_dofs(),
          ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
@@ -713,7 +713,7 @@ void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim>       &
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename hp::DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename hp::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
     = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                  dof.end(), n_threads);
@@ -723,14 +723,14 @@ void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim>       &
   Threads::ThreadMutex mutex;
   
                                   // then assemble in parallel
-  typedef void (*create_mass_matrix_2_t) (const hp::MappingCollection<dim>       &mapping,
-                                         const hp::DoFHandler<dim>    &dof,
+  typedef void (*create_mass_matrix_2_t) (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                         const hp::DoFHandler<dim,spacedim>    &dof,
                                          const hp::QCollection<dim>    &q,
                                          SparseMatrix<number>     &matrix,
-                                         const Function<dim>      &rhs,
+                                         const Function<spacedim>      &rhs,
                                          Vector<double>           &rhs_vector,
-                                         const Function<dim> * const coefficient,
-                                         const IteratorRange<hp::DoFHandler<dim> >  range,
+                                         const Function<spacedim> * const coefficient,
+                                         const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                          Threads::ThreadMutex     &mutex);
   create_mass_matrix_2_t p = &MatrixCreator::template create_mass_matrix_2<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
@@ -742,16 +742,16 @@ void MatrixCreator::create_mass_matrix (const hp::MappingCollection<dim>       &
 
 
 
-template <int dim, typename number>
+template <int dim, typename number, int spacedim>
 void
-MatrixCreator::create_mass_matrix_2 (const hp::MappingCollection<dim>       &mapping,
-                                    const hp::DoFHandler<dim>    &dof,
+MatrixCreator::create_mass_matrix_2 (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                    const hp::DoFHandler<dim,spacedim>    &dof,
                                     const hp::QCollection<dim>    &q,
                                     SparseMatrix<number>     &matrix,
-                                    const Function<dim>      &rhs,
+                                    const Function<spacedim>      &rhs,
                                     Vector<double>           &rhs_vector,
-                                    const Function<dim> * const coefficient,
-                                    const IteratorRange<hp::DoFHandler<dim> >  range,
+                                    const Function<spacedim> * const coefficient,
+                                    const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                     Threads::ThreadMutex     &mutex)
 {
   UpdateFlags update_flags = UpdateFlags(update_values    |
@@ -760,7 +760,7 @@ MatrixCreator::create_mass_matrix_2 (const hp::MappingCollection<dim>       &map
   if (coefficient != 0)
     update_flags = UpdateFlags (update_flags | update_quadrature_points);
 
-  hp::FEValues<dim> x_fe_values (mapping, dof.get_fe(), q, update_flags);
+  hp::FEValues<dim,spacedim> x_fe_values (mapping, dof.get_fe(), q, update_flags);
     
   const unsigned int n_components  = dof.get_fe().n_components();
 
@@ -776,15 +776,15 @@ MatrixCreator::create_mass_matrix_2 (const hp::MappingCollection<dim>       &map
   
   std::vector<unsigned int> dof_indices;
   
-  typename hp::DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename hp::DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     {
       x_fe_values.reinit (cell);
-      const FEValues<dim> &fe_values = x_fe_values.get_present_fe_values ();
+      const FEValues<dim,spacedim> &fe_values = x_fe_values.get_present_fe_values ();
 
       const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                         n_q_points    = fe_values.n_quadrature_points;
-      const FiniteElement<dim>    &fe  = fe_values.get_fe();
+      const FiniteElement<dim,spacedim>    &fe  = fe_values.get_fe();
 
       cell_matrix.reinit (dofs_per_cell, dofs_per_cell);
       local_rhs.reinit (dofs_per_cell);
@@ -891,13 +891,13 @@ MatrixCreator::create_mass_matrix_2 (const hp::MappingCollection<dim>       &map
 
 
 
-template <int dim, typename number>
-void MatrixCreator::create_mass_matrix (const hp::DoFHandler<dim>    &dof,
+template <int dim, typename number, int spacedim>
+void MatrixCreator::create_mass_matrix (const hp::DoFHandler<dim,spacedim>    &dof,
                                        const hp::QCollection<dim>    &q,
                                        SparseMatrix<number>     &matrix,
-                                       const Function<dim>      &rhs,
+                                       const Function<spacedim>      &rhs,
                                        Vector<double>           &rhs_vector,
-                                       const Function<dim> * const coefficient)
+                                       const Function<spacedim> * const coefficient)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
   create_mass_matrix(hp::StaticMappingQ1<dim>::mapping_collection, dof, q,
@@ -909,15 +909,32 @@ void MatrixCreator::create_mass_matrix (const hp::DoFHandler<dim>    &dof,
 
 #if deal_II_dimension == 1
 
-template <int dim>
-void MatrixCreator::create_boundary_mass_matrix (const Mapping<dim>&,
-                                                const DoFHandler<dim>&,
-                                                const Quadrature<dim-1>&,
+template <>
+void MatrixCreator::create_boundary_mass_matrix (const Mapping<1,1>&,
+                                                const DoFHandler<1,1>&,
+                                                const Quadrature<0>&,
                                                 SparseMatrix<double>&,
-                                                const typename FunctionMap<dim>::type&,
+                                                const FunctionMap<1>::type&,
                                                 Vector<double>&,
                                                 std::vector<unsigned int>&,
-                                                const Function<dim>* const,
+                                                const Function<1>* const,
+                                                std::vector<unsigned int>)
+{
+                                  // what would that be in 1d? the
+                                  // identity matrix on the boundary
+                                  // dofs?
+  Assert (false, ExcNotImplemented());
+}
+
+template <>
+void MatrixCreator::create_boundary_mass_matrix (const Mapping<1,2>&,
+                                                const DoFHandler<1,2>&,
+                                                const Quadrature<0>&,
+                                                SparseMatrix<double>&,
+                                                const FunctionMap<2>::type&,
+                                                Vector<double>&,
+                                                std::vector<unsigned int>&,
+                                                const Function<2>* const,
                                                 std::vector<unsigned int>)
 {
                                   // what would that be in 1d? the
@@ -931,19 +948,19 @@ void MatrixCreator::create_boundary_mass_matrix (const Mapping<dim>&,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-MatrixCreator::create_boundary_mass_matrix (const Mapping<dim>        &mapping,
-                                           const DoFHandler<dim>     &dof,
-                                           const Quadrature<dim-1>   &q,
-                                           SparseMatrix<double>      &matrix,
-                                           const typename FunctionMap<dim>::type         &boundary_functions,
+MatrixCreator::create_boundary_mass_matrix (const Mapping<dim, spacedim>  &mapping,
+                                           const DoFHandler<dim,spacedim> &dof,
+                                           const Quadrature<dim-1>  &q,
+                                           SparseMatrix<double>  &matrix,
+                                           const typename FunctionMap<spacedim>::type  &boundary_functions,
                                            Vector<double>            &rhs_vector,
                                            std::vector<unsigned int> &dof_to_boundary_mapping,
-                                           const Function<dim> * const coefficient,
+                                           const Function<spacedim> * const coefficient,
                                            std::vector<unsigned int> component_mapping)
 {
-  const FiniteElement<dim> &fe = dof.get_fe();
+  const FiniteElement<dim,spacedim> &fe = dof.get_fe();
   const unsigned int n_components  = fe.n_components();
   
   Assert (matrix.n() == dof.n_boundary_dofs(boundary_functions),
@@ -971,7 +988,7 @@ MatrixCreator::create_boundary_mass_matrix (const Mapping<dim>        &mapping,
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
     = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                  dof.end(), n_threads);
@@ -980,22 +997,22 @@ MatrixCreator::create_boundary_mass_matrix (const Mapping<dim>        &mapping,
                                   // the matrix
   Threads::ThreadMutex mutex;
 
-  typedef boost::tuple<const Mapping<dim>&,
-    const DoFHandler<dim>&,
+  typedef boost::tuple<const Mapping<dim,spacedim>&,
+    const DoFHandler<dim,spacedim>&,
     const Quadrature<dim-1>&> Commons;
   
                                   // then assemble in parallel
   typedef void (*create_boundary_mass_matrix_1_t)
       (Commons,
        SparseMatrix<double>      &matrix,
-       const typename FunctionMap<dim>::type &boundary_functions,
+       const typename FunctionMap<spacedim>::type &boundary_functions,
        Vector<double>            &rhs_vector,
        std::vector<unsigned int> &dof_to_boundary_mapping,
-       const Function<dim> * const coefficient,
+       const Function<spacedim> * const coefficient,
        const std::vector<unsigned int>& component_mapping,
-       const IteratorRange<DoFHandler<dim> >   range,
+       const IteratorRange<DoFHandler<dim,spacedim> >   range,
        Threads::ThreadMutex      &mutex);
-  create_boundary_mass_matrix_1_t p = &MatrixCreator::template create_boundary_mass_matrix_1<dim>;
+  create_boundary_mass_matrix_1_t p = &MatrixCreator::template create_boundary_mass_matrix_1<dim,spacedim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
     threads += Threads::spawn (p)(Commons(mapping, dof, q), matrix,
                                   boundary_functions, rhs_vector,
@@ -1007,29 +1024,48 @@ MatrixCreator::create_boundary_mass_matrix (const Mapping<dim>        &mapping,
 
 
 
-template <int dim>
+template <>
 void
 MatrixCreator::
-create_boundary_mass_matrix_1 (boost::tuple<const Mapping<dim>&,
-                              const DoFHandler<dim>&,
-                              const Quadrature<dim-1>&> commons,
+create_boundary_mass_matrix_1<2,3> (boost::tuple<const Mapping<2,3> &,
+                                   const DoFHandler<2,3> &,
+                                   const Quadrature<1> & > ,
+                                   SparseMatrix<double>  &,
+                                   const FunctionMap<3>::type &,
+                                   Vector<double> &,
+                                   std::vector<unsigned int> &,
+                                   const Function<3> * const ,
+                                   const std::vector<unsigned int> &,
+                                   const IteratorRange<DoFHandler<2,3> > ,
+                                   Threads::ThreadMutex &)
+{
+  Assert(false,ExcNotImplemented());
+}
+
+
+template <int dim, int spacedim>
+void
+MatrixCreator::
+create_boundary_mass_matrix_1 (boost::tuple<const Mapping<dim, spacedim> &,
+                              const DoFHandler<dim,spacedim> &,
+                              const Quadrature<dim-1> & >  commons,
                               SparseMatrix<double>      &matrix,
-                              const typename FunctionMap<dim>::type &boundary_functions,
+                              const typename FunctionMap<spacedim>::type &boundary_functions,
                               Vector<double>            &rhs_vector,
                               std::vector<unsigned int> &dof_to_boundary_mapping,
-                              const Function<dim> * const coefficient,
+                              const Function<spacedim> * const coefficient,
                               const std::vector<unsigned int>& component_mapping,
-                              const IteratorRange<DoFHandler<dim> >   range,
+                              const IteratorRange<DoFHandler<dim,spacedim> >   range,
                               Threads::ThreadMutex      &mutex)
 {
                                   // All assertions for this function
                                   // are in the calling function
                                   // before creating threads.
-  const Mapping<dim>& mapping = boost::get<0>(commons);
-  const DoFHandler<dim>& dof = boost::get<1>(commons);
+  const Mapping<dim,spacedim>& mapping = boost::get<0>(commons);
+  const DoFHandler<dim,spacedim>& dof = boost::get<1>(commons);
   const Quadrature<dim-1>& q = boost::get<2>(commons);
   
-  const FiniteElement<dim> &fe = dof.get_fe();
+  const FiniteElement<dim,spacedim> &fe = dof.get_fe();
   const unsigned int n_components  = fe.n_components();
   const unsigned int n_function_components = boundary_functions.begin()->second->n_components;
   const bool         fe_is_system  = (n_components != 1);
@@ -1068,7 +1104,7 @@ create_boundary_mass_matrix_1 (boost::tuple<const Mapping<dim>&,
                                   // flag whether it is on the face
   std::vector<bool>         dof_is_on_face(dofs_per_cell);
   
-  typename DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
                                       // check if this face is on that part of
@@ -1124,7 +1160,7 @@ create_boundary_mass_matrix_1 (boost::tuple<const Mapping<dim>&,
              
              for (unsigned int comp = 0;comp<n_components;++comp)
                {
-                 const FiniteElement<dim>& base = fe.base_element(fe.component_to_base_index(comp).first);
+                 const FiniteElement<dim,spacedim>& base = fe.base_element(fe.component_to_base_index(comp).first);
                  const unsigned int bcomp = fe.component_to_base_index(comp).second;
                  
                  if (!base.conforms(FiniteElementData<dim>::H1) &&
@@ -1274,18 +1310,18 @@ create_boundary_mass_matrix_1 (boost::tuple<const Mapping<dim>&,
 
 #endif
 
-template <int dim>
-void MatrixCreator::create_boundary_mass_matrix (const DoFHandler<dim>     &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_boundary_mass_matrix (const DoFHandler<dim,spacedim>     &dof,
                                                 const Quadrature<dim-1>   &q,
                                                 SparseMatrix<double>      &matrix,
-                                                const typename FunctionMap<dim>::type &rhs,
+                                                const typename FunctionMap<spacedim>::type &rhs,
                                                 Vector<double>            &rhs_vector,
                                                 std::vector<unsigned int> &dof_to_boundary_mapping,
-                                                const Function<dim> * const a,
+                                                const Function<spacedim> * const a,
                                                 std::vector<unsigned int> component_mapping)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  create_boundary_mass_matrix(StaticMappingQ1<dim>::mapping, dof, q,
+  create_boundary_mass_matrix(StaticMappingQ1<dim,spacedim>::mapping, dof, q,
                              matrix,rhs, rhs_vector, dof_to_boundary_mapping, a, component_mapping);
 }
 
@@ -1293,16 +1329,16 @@ void MatrixCreator::create_boundary_mass_matrix (const DoFHandler<dim>     &dof,
 
 #if deal_II_dimension == 1
 
-template <int dim>
+template <int dim, int spacedim>
 void
-MatrixCreator::create_boundary_mass_matrix (const hp::MappingCollection<dim>&,
-                                           const hp::DoFHandler<dim>&,
+MatrixCreator::create_boundary_mass_matrix (const hp::MappingCollection<dim,spacedim>&,
+                                           const hp::DoFHandler<dim,spacedim>&,
                                            const hp::QCollection<dim-1>&,
                                            SparseMatrix<double>&,
-                                           const typename FunctionMap<dim>::type&,
+                                           const typename FunctionMap<spacedim>::type&,
                                            Vector<double>&,
                                            std::vector<unsigned int>&,
-                                           const Function<dim>* const,
+                                           const Function<spacedim>* const,
                                            std::vector<unsigned int>)
 {
                                   // what would that be in 1d? the
@@ -1315,16 +1351,16 @@ MatrixCreator::create_boundary_mass_matrix (const hp::MappingCollection<dim>&,
 #else
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-MatrixCreator::create_boundary_mass_matrix (const hp::MappingCollection<dim>        &mapping,
-                                           const hp::DoFHandler<dim>     &dof,
+MatrixCreator::create_boundary_mass_matrix (const hp::MappingCollection<dim,spacedim>        &mapping,
+                                           const hp::DoFHandler<dim,spacedim>     &dof,
                                            const hp::QCollection<dim-1>   &q,
                                            SparseMatrix<double>      &matrix,
-                                           const typename FunctionMap<dim>::type         &boundary_functions,
+                                           const typename FunctionMap<spacedim>::type         &boundary_functions,
                                            Vector<double>            &rhs_vector,
                                            std::vector<unsigned int> &dof_to_boundary_mapping,
-                                           const Function<dim> * const coefficient,
+                                           const Function<spacedim> * const coefficient,
                                            std::vector<unsigned int> component_mapping)
 {
   const hp::FECollection<dim> &fe_collection = dof.get_fe();
@@ -1355,7 +1391,7 @@ MatrixCreator::create_boundary_mass_matrix (const hp::MappingCollection<dim>
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename hp::DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename hp::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
     = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                  dof.end(), n_threads);
@@ -1372,14 +1408,14 @@ MatrixCreator::create_boundary_mass_matrix (const hp::MappingCollection<dim>
   typedef void (*create_boundary_mass_matrix_1_t)
       (Commons,
        SparseMatrix<double>      &matrix,
-       const typename FunctionMap<dim>::type &boundary_functions,
+       const typename FunctionMap<spacedim>::type &boundary_functions,
        Vector<double>            &rhs_vector,
        std::vector<unsigned int> &dof_to_boundary_mapping,
-       const Function<dim> * const coefficient,
+       const Function<spacedim> * const coefficient,
        const std::vector<unsigned int>& component_mapping,
-       const IteratorRange<hp::DoFHandler<dim> >   range,
+       const IteratorRange<hp::DoFHandler<dim,spacedim> >   range,
        Threads::ThreadMutex      &mutex);
-  create_boundary_mass_matrix_1_t p = &MatrixCreator::template create_boundary_mass_matrix_1<dim>;
+  create_boundary_mass_matrix_1_t p = &MatrixCreator::template create_boundary_mass_matrix_1<dim,spacedim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
     threads += Threads::spawn (p)(Commons(mapping, dof, q), matrix,
                                   boundary_functions, rhs_vector,
@@ -1391,25 +1427,25 @@ MatrixCreator::create_boundary_mass_matrix (const hp::MappingCollection<dim>
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
 MatrixCreator::
-create_boundary_mass_matrix_1 (boost::tuple<const hp::MappingCollection<dim>&,
-                              const hp::DoFHandler<dim>&,
-                              const hp::QCollection<dim-1>&> commons,
+create_boundary_mass_matrix_1 (boost::tuple<const hp::MappingCollection<dim,spacedim> &,
+                              const hp::DoFHandler<dim,spacedim> &,
+                              const hp::QCollection<dim-1> &> commons,
                               SparseMatrix<double>      &matrix,
-                              const typename FunctionMap<dim>::type &boundary_functions,
+                              const typename FunctionMap<spacedim>::type &boundary_functions,
                               Vector<double>            &rhs_vector,
                               std::vector<unsigned int> &dof_to_boundary_mapping,
-                              const Function<dim> * const coefficient,
+                              const Function<spacedim> * const coefficient,
                               const std::vector<unsigned int>& component_mapping,
-                              const IteratorRange<hp::DoFHandler<dim> >   range,
+                              const IteratorRange<hp::DoFHandler<dim,spacedim> >   range,
                               Threads::ThreadMutex      &mutex)
 {
   const hp::MappingCollection<dim>& mapping = boost::get<0>(commons);
   const hp::DoFHandler<dim>& dof = boost::get<1>(commons);
   const hp::QCollection<dim-1>& q = boost::get<2>(commons);
-  const hp::FECollection<dim> &fe_collection = dof.get_fe();
+  const hp::FECollection<dim,spacedim> &fe_collection = dof.get_fe();
   const unsigned int n_components  = fe_collection.n_components();
   const unsigned int n_function_components = boundary_functions.begin()->second->n_components;
   const bool         fe_is_system  = (n_components != 1);
@@ -1419,7 +1455,7 @@ create_boundary_mass_matrix_1 (boost::tuple<const hp::MappingCollection<dim>&,
       unsigned int max_element = 0;
       for (std::vector<unsigned int>::const_iterator i=dof_to_boundary_mapping.begin();
           i!=dof_to_boundary_mapping.end(); ++i)
-       if ((*i != hp::DoFHandler<dim>::invalid_dof_index) &&
+       if ((*i != hp::DoFHandler<dim,spacedim>::invalid_dof_index) &&
            (*i > max_element))
          max_element = *i;
       Assert (max_element  == matrix.n()-1, ExcInternalError());
@@ -1455,7 +1491,7 @@ create_boundary_mass_matrix_1 (boost::tuple<const hp::MappingCollection<dim>&,
   std::vector<bool>         dof_is_on_face(max_dofs_per_cell);
 
 
-  typename hp::DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename hp::DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
                                       // check if this face is on that part of
@@ -1467,7 +1503,7 @@ create_boundary_mass_matrix_1 (boost::tuple<const hp::MappingCollection<dim>&,
 
          const FEFaceValues<dim> &fe_values = x_fe_values.get_present_fe_values ();
 
-         const FiniteElement<dim> &fe = cell->get_fe();
+         const FiniteElement<dim,spacedim> &fe = cell->get_fe();
          const unsigned int dofs_per_cell = fe.dofs_per_cell;
          const unsigned int dofs_per_face = fe.dofs_per_face;
          
@@ -1763,29 +1799,29 @@ create_boundary_mass_matrix_1 (boost::tuple<const hp::MappingCollection<dim>&,
 
 #endif
 
-template <int dim>
-void MatrixCreator::create_boundary_mass_matrix (const hp::DoFHandler<dim>     &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_boundary_mass_matrix (const hp::DoFHandler<dim,spacedim>     &dof,
                                                 const hp::QCollection<dim-1>   &q,
                                                 SparseMatrix<double>      &matrix,
-                                                const typename FunctionMap<dim>::type &rhs,
+                                                const typename FunctionMap<spacedim>::type &rhs,
                                                 Vector<double>            &rhs_vector,
                                                 std::vector<unsigned int> &dof_to_boundary_mapping,
-                                                const Function<dim> * const a,
+                                                const Function<spacedim> * const a,
                                                 std::vector<unsigned int> component_mapping)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
-  create_boundary_mass_matrix(hp::StaticMappingQ1<dim>::mapping_collection, dof, q,
+  create_boundary_mass_matrix(hp::StaticMappingQ1<dim,spacedim>::mapping_collection, dof, q,
                              matrix,rhs, rhs_vector, dof_to_boundary_mapping, a, component_mapping);
 }
 
 
 
-template <int dim>
-void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
-                                          const DoFHandler<dim>    &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_laplace_matrix (const Mapping<dim, spacedim>       &mapping,
+                                          const DoFHandler<dim,spacedim>    &dof,
                                           const Quadrature<dim>    &q,
                                           SparseMatrix<double>     &matrix,
-                                          const Function<dim> * const coefficient)
+                                          const Function<spacedim> * const coefficient)
 {
   Assert (matrix.m() == dof.n_dofs(),
          ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
@@ -1797,7 +1833,7 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
     = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                  dof.end(), n_threads);
@@ -1807,12 +1843,12 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
   Threads::ThreadMutex mutex;
   
                                   // then assemble in parallel
-  typedef void (*create_laplace_matrix_1_t) (const Mapping<dim>       &mapping,
-                                            const DoFHandler<dim>    &dof,
+  typedef void (*create_laplace_matrix_1_t) (const Mapping<dim, spacedim>       &mapping,
+                                            const DoFHandler<dim,spacedim>    &dof,
                                             const Quadrature<dim>    &q,
                                             SparseMatrix<double>     &matrix,
-                                            const Function<dim> * const coefficient,
-                                            const IteratorRange<DoFHandler<dim> >  range,
+                                            const Function<spacedim> * const coefficient,
+                                            const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                             Threads::ThreadMutex     &mutex);
   create_laplace_matrix_1_t p = &MatrixCreator::template create_laplace_matrix_1<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
@@ -1823,13 +1859,13 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
 
 
 
-template <int dim>
-void MatrixCreator::create_laplace_matrix_1 (const Mapping<dim>       &mapping,
-                                            const DoFHandler<dim>    &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_laplace_matrix_1 (const Mapping<dim, spacedim>       &mapping,
+                                            const DoFHandler<dim,spacedim>    &dof,
                                             const Quadrature<dim>    &q,
                                             SparseMatrix<double>     &matrix,
-                                            const Function<dim> * const coefficient,
-                                            const IteratorRange<DoFHandler<dim> >  range,
+                                            const Function<spacedim> * const coefficient,
+                                            const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                             Threads::ThreadMutex     &mutex)
 {
   UpdateFlags update_flags = UpdateFlags(update_JxW_values |
@@ -1837,11 +1873,11 @@ void MatrixCreator::create_laplace_matrix_1 (const Mapping<dim>       &mapping,
   if (coefficient != 0)
     update_flags = UpdateFlags (update_flags | update_quadrature_points);
 
-  FEValues<dim> fe_values (mapping, dof.get_fe(), q, update_flags);
+  FEValues<dim,spacedim> fe_values (mapping, dof.get_fe(), q, update_flags);
     
   const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                     n_q_points    = fe_values.n_quadrature_points;
-  const FiniteElement<dim>    &fe  = fe_values.get_fe();
+  const FiniteElement<dim,spacedim>    &fe  = fe_values.get_fe();
   const unsigned int n_components  = fe.n_components();
 
   Assert(coefficient == 0 ||
@@ -1855,7 +1891,7 @@ void MatrixCreator::create_laplace_matrix_1 (const Mapping<dim>       &mapping,
   
   std::vector<unsigned int> dof_indices (dofs_per_cell);
   
-  typename DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     {
       fe_values.reinit (cell);
@@ -1946,11 +1982,11 @@ void MatrixCreator::create_laplace_matrix_1 (const Mapping<dim>       &mapping,
 
 
 
-template <int dim>
-void MatrixCreator::create_laplace_matrix (const DoFHandler<dim>    &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_laplace_matrix (const DoFHandler<dim,spacedim>    &dof,
                                           const Quadrature<dim>    &q,
                                           SparseMatrix<double>     &matrix,
-                                          const Function<dim> * const coefficient)
+                                          const Function<spacedim> * const coefficient)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
   create_laplace_matrix(StaticMappingQ1<dim>::mapping, dof, q, matrix, coefficient);
@@ -1958,14 +1994,14 @@ void MatrixCreator::create_laplace_matrix (const DoFHandler<dim>    &dof,
 
 
 
-template <int dim>
-void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
-                                          const DoFHandler<dim>    &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_laplace_matrix (const Mapping<dim, spacedim>       &mapping,
+                                          const DoFHandler<dim,spacedim>    &dof,
                                           const Quadrature<dim>    &q,
                                           SparseMatrix<double>     &matrix,
-                                          const Function<dim>      &rhs,
+                                          const Function<spacedim>      &rhs,
                                           Vector<double>           &rhs_vector,
-                                          const Function<dim> * const coefficient)
+                                          const Function<spacedim> * const coefficient)
 {
   Assert (matrix.m() == dof.n_dofs(),
          ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
@@ -1977,7 +2013,7 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
     = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                  dof.end(), n_threads);
@@ -1987,14 +2023,14 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
   Threads::ThreadMutex mutex;
   
                                   // then assemble in parallel
-  typedef void (*create_laplace_matrix_2_t) (const Mapping<dim>       &mapping,
-                                            const DoFHandler<dim>    &dof,
+  typedef void (*create_laplace_matrix_2_t) (const Mapping<dim, spacedim>       &mapping,
+                                            const DoFHandler<dim,spacedim>    &dof,
                                             const Quadrature<dim>    &q,
                                             SparseMatrix<double>     &matrix,
-                                            const Function<dim>      &rhs,
+                                            const Function<spacedim>      &rhs,
                                             Vector<double>           &rhs_vector,
-                                            const Function<dim> * const coefficient,
-                                            const IteratorRange<DoFHandler<dim> >  range,
+                                            const Function<spacedim> * const coefficient,
+                                            const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                             Threads::ThreadMutex     &mutex);
   create_laplace_matrix_2_t p = &MatrixCreator::template create_laplace_matrix_2<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
@@ -2006,16 +2042,16 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-MatrixCreator::create_laplace_matrix_2 (const Mapping<dim>       &mapping,
-                                       const DoFHandler<dim>    &dof,
+MatrixCreator::create_laplace_matrix_2 (const Mapping<dim, spacedim>       &mapping,
+                                       const DoFHandler<dim,spacedim>    &dof,
                                        const Quadrature<dim>    &q,
                                        SparseMatrix<double>     &matrix,
-                                       const Function<dim>      &rhs,
+                                       const Function<spacedim>      &rhs,
                                        Vector<double>           &rhs_vector,
-                                       const Function<dim> * const coefficient,
-                                       const IteratorRange<DoFHandler<dim> >  range,
+                                       const Function<spacedim> * const coefficient,
+                                       const IteratorRange<DoFHandler<dim,spacedim> >  range,
                                        Threads::ThreadMutex     &mutex)
 {
   UpdateFlags update_flags = UpdateFlags(update_values    |
@@ -2025,11 +2061,11 @@ MatrixCreator::create_laplace_matrix_2 (const Mapping<dim>       &mapping,
   if (coefficient != 0)
     update_flags = UpdateFlags (update_flags | update_quadrature_points);
 
-  FEValues<dim> fe_values (mapping, dof.get_fe(), q, update_flags);
+  FEValues<dim,spacedim> fe_values (mapping, dof.get_fe(), q, update_flags);
     
   const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                     n_q_points    = fe_values.n_quadrature_points;
-  const FiniteElement<dim>    &fe  = fe_values.get_fe();
+  const FiniteElement<dim,spacedim>    &fe  = fe_values.get_fe();
   const unsigned int n_components  = fe.n_components();
 
   Assert(coefficient == 0 ||
@@ -2045,7 +2081,7 @@ MatrixCreator::create_laplace_matrix_2 (const Mapping<dim>       &mapping,
   
   std::vector<unsigned int> dof_indices (dofs_per_cell);
   
-  typename DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     {
       fe_values.reinit (cell);
@@ -2146,13 +2182,13 @@ MatrixCreator::create_laplace_matrix_2 (const Mapping<dim>       &mapping,
 
 
 
-template <int dim>
-void MatrixCreator::create_laplace_matrix (const DoFHandler<dim>    &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_laplace_matrix (const DoFHandler<dim,spacedim>    &dof,
                                           const Quadrature<dim>    &q,
                                           SparseMatrix<double>     &matrix,
-                                          const Function<dim>      &rhs,
+                                          const Function<spacedim>      &rhs,
                                           Vector<double>           &rhs_vector,
-                                          const Function<dim> * const coefficient)
+                                          const Function<spacedim> * const coefficient)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
   create_laplace_matrix(StaticMappingQ1<dim>::mapping, dof, q,
@@ -2161,12 +2197,12 @@ void MatrixCreator::create_laplace_matrix (const DoFHandler<dim>    &dof,
 
 
 
-template <int dim>
-void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim>       &mapping,
-                                          const hp::DoFHandler<dim>    &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                          const hp::DoFHandler<dim,spacedim>    &dof,
                                           const hp::QCollection<dim>    &q,
                                           SparseMatrix<double>     &matrix,
-                                          const Function<dim> * const coefficient)
+                                          const Function<spacedim> * const coefficient)
 {
   Assert (matrix.m() == dof.n_dofs(),
          ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
@@ -2178,7 +2214,7 @@ void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim>
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename hp::DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename hp::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
     = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                  dof.end(), n_threads);
@@ -2188,12 +2224,12 @@ void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim>
   Threads::ThreadMutex mutex;
   
                                   // then assemble in parallel
-  typedef void (*create_laplace_matrix_1_t) (const hp::MappingCollection<dim>       &mapping,
-                                            const hp::DoFHandler<dim>    &dof,
+  typedef void (*create_laplace_matrix_1_t) (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                            const hp::DoFHandler<dim,spacedim>    &dof,
                                             const hp::QCollection<dim>    &q,
                                             SparseMatrix<double>     &matrix,
-                                            const Function<dim> * const coefficient,
-                                            const IteratorRange<hp::DoFHandler<dim> >  range,
+                                            const Function<spacedim> * const coefficient,
+                                            const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                             Threads::ThreadMutex     &mutex);
   create_laplace_matrix_1_t p = &MatrixCreator::template create_laplace_matrix_1<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
@@ -2204,14 +2240,14 @@ void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim>
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-MatrixCreator::create_laplace_matrix_1 (const hp::MappingCollection<dim>       &mapping,
-                                       const hp::DoFHandler<dim>    &dof,
+MatrixCreator::create_laplace_matrix_1 (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                       const hp::DoFHandler<dim,spacedim>    &dof,
                                        const hp::QCollection<dim>    &q,
                                        SparseMatrix<double>     &matrix,
-                                       const Function<dim> * const coefficient,
-                                       const IteratorRange<hp::DoFHandler<dim> >  range,
+                                       const Function<spacedim> * const coefficient,
+                                       const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                        Threads::ThreadMutex     &mutex)
 {
   UpdateFlags update_flags = UpdateFlags(update_gradients |
@@ -2219,7 +2255,7 @@ MatrixCreator::create_laplace_matrix_1 (const hp::MappingCollection<dim>       &
   if (coefficient != 0)
     update_flags = UpdateFlags (update_flags | update_quadrature_points);
 
-  hp::FEValues<dim> x_fe_values (mapping, dof.get_fe(), q, update_flags);
+  hp::FEValues<dim,spacedim> x_fe_values (mapping, dof.get_fe(), q, update_flags);
     
   const unsigned int n_components  = dof.get_fe().n_components();
 
@@ -2233,15 +2269,15 @@ MatrixCreator::create_laplace_matrix_1 (const hp::MappingCollection<dim>       &
   
   std::vector<unsigned int> dof_indices;
   
-  typename hp::DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename hp::DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     {
       x_fe_values.reinit (cell);
-      const FEValues<dim> &fe_values = x_fe_values.get_present_fe_values ();
+      const FEValues<dim,spacedim> &fe_values = x_fe_values.get_present_fe_values ();
 
       const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                         n_q_points    = fe_values.n_quadrature_points;
-      const FiniteElement<dim>    &fe  = fe_values.get_fe();
+      const FiniteElement<dim,spacedim>    &fe  = fe_values.get_fe();
 
       cell_matrix.reinit (dofs_per_cell, dofs_per_cell);
       coefficient_values.resize (n_q_points);
@@ -2335,11 +2371,11 @@ MatrixCreator::create_laplace_matrix_1 (const hp::MappingCollection<dim>       &
 
 
 
-template <int dim>
-void MatrixCreator::create_laplace_matrix (const hp::DoFHandler<dim>    &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_laplace_matrix (const hp::DoFHandler<dim,spacedim>    &dof,
                                           const hp::QCollection<dim>    &q,
                                           SparseMatrix<double>     &matrix,
-                                          const Function<dim> * const coefficient)
+                                          const Function<spacedim> * const coefficient)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
   create_laplace_matrix(hp::StaticMappingQ1<dim>::mapping_collection, dof, q, matrix, coefficient);
@@ -2347,14 +2383,14 @@ void MatrixCreator::create_laplace_matrix (const hp::DoFHandler<dim>    &dof,
 
 
 
-template <int dim>
-void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim>       &mapping,
-                                          const hp::DoFHandler<dim>    &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                          const hp::DoFHandler<dim,spacedim>    &dof,
                                           const hp::QCollection<dim>    &q,
                                           SparseMatrix<double>     &matrix,
-                                          const Function<dim>      &rhs,
+                                          const Function<spacedim>      &rhs,
                                           Vector<double>           &rhs_vector,
-                                          const Function<dim> * const coefficient)
+                                          const Function<spacedim> * const coefficient)
 {
   Assert (matrix.m() == dof.n_dofs(),
          ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
@@ -2366,7 +2402,7 @@ void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim>
 
                                   // define starting and end point
                                   // for each thread
-  typedef typename hp::DoFHandler<dim>::active_cell_iterator active_cell_iterator;  
+  typedef typename hp::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;  
   std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
     = Threads::split_range<active_cell_iterator> (dof.begin_active(),
                                                  dof.end(), n_threads);
@@ -2376,14 +2412,14 @@ void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim>
   Threads::ThreadMutex mutex;
   
                                   // then assemble in parallel
-  typedef void (*create_laplace_matrix_2_t) (const hp::MappingCollection<dim>       &mapping,
-                                            const hp::DoFHandler<dim>    &dof,
+  typedef void (*create_laplace_matrix_2_t) (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                            const hp::DoFHandler<dim,spacedim>    &dof,
                                             const hp::QCollection<dim>    &q,
                                             SparseMatrix<double>     &matrix,
-                                            const Function<dim>      &rhs,
+                                            const Function<spacedim>      &rhs,
                                             Vector<double>           &rhs_vector,
-                                            const Function<dim> * const coefficient,
-                                            const IteratorRange<hp::DoFHandler<dim> >  range,
+                                            const Function<spacedim> * const coefficient,
+                                            const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                             Threads::ThreadMutex     &mutex);
   create_laplace_matrix_2_t p = &MatrixCreator::template create_laplace_matrix_2<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
@@ -2395,16 +2431,16 @@ void MatrixCreator::create_laplace_matrix (const hp::MappingCollection<dim>
 
 
 
-template <int dim>
+template <int dim, int spacedim>
 void
-MatrixCreator::create_laplace_matrix_2 (const hp::MappingCollection<dim>       &mapping,
-                                       const hp::DoFHandler<dim>    &dof,
+MatrixCreator::create_laplace_matrix_2 (const hp::MappingCollection<dim,spacedim>       &mapping,
+                                       const hp::DoFHandler<dim,spacedim>    &dof,
                                        const hp::QCollection<dim>    &q,
                                        SparseMatrix<double>     &matrix,
-                                       const Function<dim>      &rhs,
+                                       const Function<spacedim>      &rhs,
                                        Vector<double>           &rhs_vector,
-                                       const Function<dim> * const coefficient,
-                                       const IteratorRange<hp::DoFHandler<dim> >  range,
+                                       const Function<spacedim> * const coefficient,
+                                       const IteratorRange<hp::DoFHandler<dim,spacedim> >  range,
                                        Threads::ThreadMutex     &mutex)
 {
   UpdateFlags update_flags = UpdateFlags(update_values    |
@@ -2414,7 +2450,7 @@ MatrixCreator::create_laplace_matrix_2 (const hp::MappingCollection<dim>       &
   if (coefficient != 0)
     update_flags = UpdateFlags (update_flags | update_quadrature_points);
 
-  hp::FEValues<dim> x_fe_values (mapping, dof.get_fe(), q, update_flags);
+  hp::FEValues<dim,spacedim> x_fe_values (mapping, dof.get_fe(), q, update_flags);
     
   const unsigned int n_components  = dof.get_fe().n_components();
 
@@ -2430,15 +2466,15 @@ MatrixCreator::create_laplace_matrix_2 (const hp::MappingCollection<dim>       &
   
   std::vector<unsigned int> dof_indices;
   
-  typename hp::DoFHandler<dim>::active_cell_iterator cell = range.first;
+  typename hp::DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
   for (; cell!=range.second; ++cell)
     {
       x_fe_values.reinit (cell);
-      const FEValues<dim> &fe_values = x_fe_values.get_present_fe_values ();
+      const FEValues<dim,spacedim> &fe_values = x_fe_values.get_present_fe_values ();
 
       const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
                         n_q_points    = fe_values.n_quadrature_points;
-      const FiniteElement<dim>    &fe  = fe_values.get_fe();
+      const FiniteElement<dim,spacedim>    &fe  = fe_values.get_fe();
 
       cell_matrix.reinit (dofs_per_cell, dofs_per_cell);
       local_rhs.reinit (dofs_per_cell);
@@ -2545,13 +2581,13 @@ MatrixCreator::create_laplace_matrix_2 (const hp::MappingCollection<dim>       &
 
 
 
-template <int dim>
-void MatrixCreator::create_laplace_matrix (const hp::DoFHandler<dim>    &dof,
+template <int dim, int spacedim>
+void MatrixCreator::create_laplace_matrix (const hp::DoFHandler<dim,spacedim>    &dof,
                                           const hp::QCollection<dim>    &q,
                                           SparseMatrix<double>     &matrix,
-                                          const Function<dim>      &rhs,
+                                          const Function<spacedim>      &rhs,
                                           Vector<double>           &rhs_vector,
-                                          const Function<dim> * const coefficient)
+                                          const Function<spacedim> * const coefficient)
 {
   Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
   create_laplace_matrix(hp::StaticMappingQ1<dim>::mapping_collection, dof, q,
@@ -2812,4 +2848,192 @@ void MatrixCreator::create_laplace_matrix<deal_II_dimension>
  Vector<double>           &rhs_vector,
  const Function<deal_II_dimension> * const coefficient);
 
+
+
+#if deal_II_dimension != 3
+
+// non-hp version of create_mass_matrix
+template
+void MatrixCreator::create_mass_matrix<deal_II_dimension,double,deal_II_dimension+1>
+(const Mapping<deal_II_dimension,deal_II_dimension+1>       &mapping,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+ const Quadrature<deal_II_dimension>    &q,
+ SparseMatrix<double>     &matrix,
+ const Function<deal_II_dimension+1> * const coefficient);
+template
+void MatrixCreator::create_mass_matrix<deal_II_dimension,double,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+ const Quadrature<deal_II_dimension>    &q,
+ SparseMatrix<double>     &matrix,
+ const Function<deal_II_dimension+1> * const coefficient);
+template
+void MatrixCreator::create_mass_matrix<deal_II_dimension,double,deal_II_dimension+1>
+(const Mapping<deal_II_dimension,deal_II_dimension+1>       &mapping,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+ const Quadrature<deal_II_dimension>    &q,
+ SparseMatrix<double>     &matrix,
+ const Function<deal_II_dimension+1>      &rhs,
+ Vector<double>           &rhs_vector,
+ const Function<deal_II_dimension+1> * const coefficient);
+template
+void MatrixCreator::create_mass_matrix<deal_II_dimension,double,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+ const Quadrature<deal_II_dimension>    &q,
+ SparseMatrix<double>     &matrix,
+ const Function<deal_II_dimension+1>      &rhs,
+ Vector<double>           &rhs_vector,
+ const Function<deal_II_dimension+1> * const coefficient);
+
+
+template
+void MatrixCreator::create_mass_matrix<deal_II_dimension,float,deal_II_dimension+1>
+(const Mapping<deal_II_dimension,deal_II_dimension+1>       &mapping,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+ const Quadrature<deal_II_dimension>    &q,
+ SparseMatrix<float>     &matrix,
+ const Function<deal_II_dimension+1> * const coefficient);
+template
+void MatrixCreator::create_mass_matrix<deal_II_dimension,float,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+ const Quadrature<deal_II_dimension>    &q,
+ SparseMatrix<float>     &matrix,
+ const Function<deal_II_dimension+1> * const coefficient);
+template
+void MatrixCreator::create_mass_matrix<deal_II_dimension,float,deal_II_dimension+1>
+(const Mapping<deal_II_dimension,deal_II_dimension+1>       &mapping,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+ const Quadrature<deal_II_dimension>    &q,
+ SparseMatrix<float>     &matrix,
+ const Function<deal_II_dimension+1>      &rhs,
+ Vector<double>           &rhs_vector,
+ const Function<deal_II_dimension+1> * const coefficient);
+template
+void MatrixCreator::create_mass_matrix<deal_II_dimension,float,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+ const Quadrature<deal_II_dimension>    &q,
+ SparseMatrix<float>     &matrix,
+ const Function<deal_II_dimension+1>      &rhs,
+ Vector<double>           &rhs_vector,
+ const Function<deal_II_dimension+1> * const coefficient);
+
+template
+void
+MatrixCreator::create_boundary_mass_matrix<deal_II_dimension,deal_II_dimension+1>
+(const Mapping<deal_II_dimension,deal_II_dimension+1>        &mapping,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1>     &dof,
+ const Quadrature<deal_II_dimension-1>   &q,
+ SparseMatrix<double>      &matrix,
+ const FunctionMap<deal_II_dimension+1>::type         &boundary_functions,
+ Vector<double>            &rhs_vector,
+ std::vector<unsigned int> &dof_to_boundary_mapping,
+ const Function<deal_II_dimension+1> * const a,
+ std::vector<unsigned int>);
+
+template
+void MatrixCreator::create_boundary_mass_matrix<deal_II_dimension,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1>     &dof,
+ const Quadrature<deal_II_dimension-1>   &q,
+ SparseMatrix<double>      &matrix,
+ const FunctionMap<deal_II_dimension+1>::type &rhs,
+ Vector<double>            &rhs_vector,
+ std::vector<unsigned int> &dof_to_boundary_mapping,
+ const Function<deal_II_dimension+1> * const a,
+ std::vector<unsigned int>);
+
+
+// #if deal_II_dimension != 1
+// template
+// void
+// MatrixCreator::create_boundary_mass_matrix<deal_II_dimension,deal_II_dimension+1>
+// (const Mapping<deal_II_dimension,deal_II_dimension+1>        &mapping,
+//  const DoFHandler<deal_II_dimension,deal_II_dimension+1>     &dof,
+//  const Quadrature<deal_II_dimension-1>   &q,
+//  SparseMatrix<double>      &matrix,
+//  const FunctionMap<deal_II_dimension+1>::type         &boundary_functions,
+//  Vector<double>            &rhs_vector,
+//  std::vector<unsigned int> &dof_to_boundary_mapping,
+//  const Function<deal_II_dimension+1> * const a,
+//  std::vector<unsigned int> &component_mapping);
+// #endif
+
+// template
+// void MatrixCreator::create_boundary_mass_matrix<deal_II_dimension,deal_II_dimension+1>
+// (const DoFHandler<deal_II_dimension,deal_II_dimension+1>     &dof,
+//  const Quadrature<deal_II_dimension-1>   &q,
+//  SparseMatrix<double>      &matrix,
+//  const FunctionMap<deal_II_dimension+1>::type &rhs,
+//  Vector<double>            &rhs_vector,
+//  std::vector<unsigned int> &dof_to_boundary_mapping,
+//  const Function<deal_II_dimension+1> * const a,
+//  std::vector<unsigned int> &component_mapping);
+
+
+// // non-hp version of create_mass_matrix
+// template
+// void MatrixCreator::create_mass_matrix
+// (const Mapping<deal_II_dimension,deal_II_dimension+1>       &mapping,
+//  const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+//  const Quadrature<deal_II_dimension>    &q,
+//  SparseMatrix<double>     &matrix,
+//  const Function<deal_II_dimension+1> * const coefficient);
+// template
+// void MatrixCreator::create_mass_matrix
+// (const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+//  const Quadrature<deal_II_dimension>    &q,
+//  SparseMatrix<double>     &matrix,
+//  const Function<deal_II_dimension+1> * const coefficient);
+// template
+// void MatrixCreator::create_mass_matrix
+// (const Mapping<deal_II_dimension,deal_II_dimension+1>       &mapping,
+//  const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+//  const Quadrature<deal_II_dimension>    &q,
+//  SparseMatrix<double>     &matrix,
+//  const Function<deal_II_dimension+1>      &rhs,
+//  Vector<double>           &rhs_vector,
+//  const Function<deal_II_dimension+1> * const coefficient);
+// template
+// void MatrixCreator::create_mass_matrix
+// (const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+//  const Quadrature<deal_II_dimension>    &q,
+//  SparseMatrix<double>     &matrix,
+//  const Function<deal_II_dimension+1>      &rhs,
+//  Vector<double>           &rhs_vector,
+//  const Function<deal_II_dimension+1> * const coefficient);
+
+
+// template
+// void MatrixCreator::create_mass_matrix
+// (const Mapping<deal_II_dimension,deal_II_dimension+1>       &mapping,
+//  const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+//  const Quadrature<deal_II_dimension>    &q,
+//  SparseMatrix<float>     &matrix,
+//  const Function<deal_II_dimension+1> * const coefficient);
+// template
+// void MatrixCreator::create_mass_matrix
+// (const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+//  const Quadrature<deal_II_dimension>    &q,
+//  SparseMatrix<float>     &matrix,
+//  const Function<deal_II_dimension+1> * const coefficient);
+// template
+// void MatrixCreator::create_mass_matrix
+// (const Mapping<deal_II_dimension,deal_II_dimension+1>       &mapping,
+//  const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+//  const Quadrature<deal_II_dimension>    &q,
+//  SparseMatrix<float>     &matrix,
+//  const Function<deal_II_dimension+1>      &rhs,
+//  Vector<double>           &rhs_vector,
+//  const Function<deal_II_dimension+1> * const coefficient);
+// template
+// void MatrixCreator::create_mass_matrix
+// (const DoFHandler<deal_II_dimension,deal_II_dimension+1>    &dof,
+//  const Quadrature<deal_II_dimension>    &q,
+//  SparseMatrix<float>     &matrix,
+//  const Function<deal_II_dimension+1>      &rhs,
+//  Vector<double>           &rhs_vector,
+//  const Function<deal_II_dimension+1> * const coefficient);
+
+
+#endif
+
 DEAL_II_NAMESPACE_CLOSE
index 7c7957309859094ce9bb78439bee9943e3107a3b..542ffbc45d1b109a5e43116dc3449ad7f0cdf9a8 100644 (file)
@@ -114,7 +114,7 @@ VectorTools::create_boundary_right_hand_side<deal_II_dimension>
  const std::set<unsigned char> &);
 
 template
-void VectorTools::interpolate_boundary_values<deal_II_dimension> (
+void VectorTools::interpolate_boundary_values ( 
   const DoFHandler<deal_II_dimension> &,
   const unsigned char,
   const Function<deal_II_dimension>   &,
@@ -122,7 +122,7 @@ void VectorTools::interpolate_boundary_values<deal_II_dimension> (
   const std::vector<bool>    &);
 
 template
-void VectorTools::interpolate_boundary_values<deal_II_dimension> (
+void VectorTools::interpolate_boundary_values (
   const hp::DoFHandler<deal_II_dimension> &,
   const unsigned char,
   const Function<deal_II_dimension>   &,
@@ -130,7 +130,7 @@ void VectorTools::interpolate_boundary_values<deal_II_dimension> (
   const std::vector<bool>    &);
 
 template
-void VectorTools::interpolate_boundary_values<deal_II_dimension> (
+void VectorTools::interpolate_boundary_values (
   const MGDoFHandler<deal_II_dimension> &,
   const unsigned char,
   const Function<deal_II_dimension>   &,
@@ -181,7 +181,7 @@ VectorTools::compute_no_normal_flux_constraints (const DoFHandler<deal_II_dimens
 // and thus need no explicit instantiation
 //#if deal_II_dimension > 1
 template
-void VectorTools::interpolate_boundary_values<deal_II_dimension>
+void VectorTools::interpolate_boundary_values
 (const Mapping<deal_II_dimension>    &,
  const DoFHandler<deal_II_dimension> &,
  const FunctionMap<deal_II_dimension>::type &,
@@ -189,7 +189,7 @@ void VectorTools::interpolate_boundary_values<deal_II_dimension>
  const std::vector<bool>    &);
 
 template
-void VectorTools::interpolate_boundary_values<deal_II_dimension>
+void VectorTools::interpolate_boundary_values
 (const Mapping<deal_II_dimension>    &,
  const DoFHandler<deal_II_dimension> &,
  const unsigned char,
@@ -202,11 +202,44 @@ void VectorTools::interpolate_boundary_values<deal_II_dimension>
 
 template
 void
-VectorTools::interpolate_boundary_values<deal_II_dimension>
+VectorTools::interpolate_boundary_values
 (const DoFHandler<deal_II_dimension>         &,
  const FunctionMap<deal_II_dimension>::type &,
  std::map<unsigned int,double> &,
  const std::vector<bool>       &);
 
 
+#if deal_II_dimension != 3
+
+template
+void VectorTools::create_right_hand_side<deal_II_dimension,deal_II_dimension+1>
+(const Mapping<deal_II_dimension,deal_II_dimension+1>    &,
+ const DoFHandler<deal_II_dimension,deal_II_dimension+1> &,
+ const Quadrature<deal_II_dimension> &,
+ const Function<deal_II_dimension+1>   &,
+ Vector<double>                      &);
+template
+void VectorTools::create_right_hand_side<deal_II_dimension,deal_II_dimension+1>
+(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &,
+ const Quadrature<deal_II_dimension> &,
+ const Function<deal_II_dimension+1>   &,
+ Vector<double>                      &);
+
+// template
+// void VectorTools::create_right_hand_side<deal_II_dimension,deal_II_dimension+1>
+// (const hp::MappingCollection<deal_II_dimension,deal_II_dimension+1>    &,
+//  const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &,
+//  const hp::QCollection<deal_II_dimension> &,
+//  const Function<deal_II_dimension+1>   &,
+//  Vector<double>                      &);
+// template
+// void VectorTools::create_right_hand_side<deal_II_dimension,deal_II_dimension+1>
+// (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &,
+//  const hp::QCollection<deal_II_dimension> &,
+//  const Function<deal_II_dimension+1>   &,
+//  Vector<double>                      &);
+
+#endif
+
+
 DEAL_II_NAMESPACE_CLOSE
index 9eac481971f20c4cc17d36552f4b94855b84ec5c..13600d579752d0e6f8e19aa47bf3e294635155eb 100644 (file)
 for (VEC : SERIAL_VECTORS)
 {  
   template
-    void VectorTools::interpolate<deal_II_dimension>
+    void VectorTools::interpolate
     (const Mapping<deal_II_dimension>&,
      const DoFHandler<deal_II_dimension>&,
      const Function<deal_II_dimension>&,
      VEC&);
-  template
-    void VectorTools::interpolate<deal_II_dimension>
-    (const DoFHandler<deal_II_dimension>&,
-     const Function<deal_II_dimension>&,
-     VEC&);
-
-  template
-    void VectorTools::interpolate<deal_II_dimension>
+   template 
+     void VectorTools::interpolate
+      (const DoFHandler<deal_II_dimension>&,
+      const Function<deal_II_dimension>&,
+      VEC&);
+      
+  template 
+    void VectorTools::interpolate
     (const Mapping<deal_II_dimension>&,
      const hp::DoFHandler<deal_II_dimension>&,
      const Function<deal_II_dimension>&,
      VEC&);
   template
-    void VectorTools::interpolate<deal_II_dimension>
+    void VectorTools::interpolate
     (const hp::DoFHandler<deal_II_dimension>&,
      const Function<deal_II_dimension>&,
      VEC&);
 
   template
-    void VectorTools::interpolate<deal_II_dimension>
+    void VectorTools::interpolate
     (const Mapping<deal_II_dimension>&,
      const MGDoFHandler<deal_II_dimension>&,
      const Function<deal_II_dimension>&,
      VEC&);
   template
-    void VectorTools::interpolate<deal_II_dimension>
+    void VectorTools::interpolate
     (const MGDoFHandler<deal_II_dimension>&,
      const Function<deal_II_dimension>&,
      VEC&);
 
   template
-    void VectorTools::interpolate<deal_II_dimension>
+    void VectorTools::interpolate
     (const DoFHandler<deal_II_dimension>&,
      const DoFHandler<deal_II_dimension>&,
      const FullMatrix<double>&,
@@ -224,4 +224,43 @@ for (VEC : SERIAL_VECTORS)
      const bool,
      const Quadrature<deal_II_dimension-1> &,
      const bool);
+
+
+#if deal_II_dimension != 3
+  template
+    void VectorTools::interpolate
+    (const Mapping<deal_II_dimension,deal_II_dimension+1>&,
+     const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+     const Function<deal_II_dimension+1>&,
+     VEC&);
+  template
+    void VectorTools::interpolate
+    (const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+     const Function<deal_II_dimension+1>&,
+     VEC&);
+
+  template
+    void VectorTools::project
+    (const Mapping<deal_II_dimension,deal_II_dimension+1>      &,
+     const DoFHandler<deal_II_dimension,deal_II_dimension+1>   &,
+     const ConstraintMatrix                &,
+     const Quadrature<deal_II_dimension>   &,
+     const Function<deal_II_dimension+1>     &,
+     VEC                                   &,
+     const bool,
+     const Quadrature<deal_II_dimension-1> &,
+     const bool);
+
+  template
+    void VectorTools::project
+    (const DoFHandler<deal_II_dimension,deal_II_dimension+1>   &,
+     const ConstraintMatrix                &,
+     const Quadrature<deal_II_dimension>   &,
+     const Function<deal_II_dimension+1>     &,
+     VEC                                   &,
+     const bool,
+     const Quadrature<deal_II_dimension-1> &,
+     const bool);
+#endif
+
 }
index 0d7b378d5ea1815af2c6efb68287c401df0e73e3..1563e4cbaeaa5baf822f4d1c05dff61e72b1033f 100644 (file)
@@ -11,14 +11,18 @@ somethings in common. In fact, these iterators are instantiations or
 subclasses of the same class TriaIterator (we do not include TriaRawIterator
 here, since it is only for %internal use).
 
-The template signature of TriaIterator is
+Basically, the template signature of TriaIterator is
 @code
-  TriaIterator<dim, Accessor>
-@endcode 
+  TriaIterator<Accessor>
+@endcode
 
-Usually, you will not use this definition directly, but employ one of the
-typedefs below. Before going into this, let us first discuss the concept of
-iterators, before delving into what the accessors do.
+Conceptually, this type represents something like a pointer to an object
+represented by the <code>Accessor</code> class.  Usually, you will not use the
+actual class names spelled out directly, but employ one of the typedefs
+provided by the container classes, such as <code>typename
+Triangulation@<dim@>::cell_iterator</code>. Before going into this, let us
+first discuss the concept of iterators, before delving into what the accessors
+do.
 
 As usual in C++, iterators, just as pointers, are incremented to the next
 element using <tt>operator ++</tt>, and decremented to the previous element
@@ -33,7 +37,7 @@ as <tt>begin_active()</tt>, <tt>begin_face()</tt>, etc.
 
 In terms of the concepts for iterators defined in the C++ standard, the
 deal.II mesh iterators are bi-directional iterators: they can be incremented
-and decremented, but an operation like <tt>it=it+n</tt> takes a computing time
+and decremented, but an operation like <tt>it=it+n</tt> takes a compute time
 proportional to <tt>n</tt>, since it is implemented as a sequence of
 <tt>n</tt> individual unit increments. Note that this is in contrast to the
 next more specialized iterator concept, random access iterators, for which
@@ -44,9 +48,7 @@ access to an arbitrary object requires only constant time, rather than linear.
 
 As mentioned above, iterators in deal.II can be considered as iterating over
 all the objects that constitute a mesh. (These objects are lines, quads, and
-hexes, and are each represented by a different kind of Accessor class; this
-accessor is the second template argument in the code example above, and are
-discussed in more detail below.) This suggests to view a triangulation as a
+hexes, and are represented by the type of Accessor class given as template argument to the iterator.) This suggests to view a triangulation as a
 collection of cells and other objects that are held together by a certain data
 structure that links all these objects, in the same was as a linked list is
 the data structure that connects objects in a linear fashion.
@@ -57,7 +59,7 @@ data. This can be understood as follows: Consider the cells of the coarse mesh
 as roots; then, if one of these coarse mesh cells is refined, it will have
 2<sup>dim</sup> children, which in turn can, but do not have to have
 2<sup>dim</sup> children of their own, and so on. This means, that each cell
-of the coarse mesh can be considered the root of a binary tree (in qd), a
+of the coarse mesh can be considered the root of a binary tree (in 1d), a
 quadtree (in 2d), or an octree (in 3d). The collection of these trees
 emanating from the cells of the coarse mesh then constitutes the forest that
 completely describes the triangulation, including all of its active and
@@ -72,7 +74,7 @@ or 8 children). Depending on the dimension, these objects are also termed
 cells or faces.
 
 Iterators loop over the elements of such forests. While the usual iterators
-loop over all nodes of a forest, active iterators skip iterate over the
+loop over all nodes of a forest, active iterators iterate over the
 elements in the same order, but skip all non-active entries and therefore only
 visit terminal nodes (i.e. active cells, faces, etc). There are many ways to
 traverse the elements of a forest, for example breadth first or depth
@@ -95,21 +97,21 @@ Iterators have two properties: what they point to (i.e. the type of the
 Accessor template argument), and the exact definition of the set they iterate
 over. In general, iterators are always declared as
 @code
-  KindIterator<dim,Accessor>
+  KindIterator<Accessor>
 @endcode
 
 Here, <tt>Kind</tt> determines what property an accessor needs to have to be
 reached by this iterator (or omitted, for that matter). For example,
 @code
-  Iterator<dim,Accessor>
+  Iterator<Accessor>
 @endcode
 iterates over all objects of kind Accessor that make up the mesh (for example
 all cells, whether they are further refined and have children, or not), whereas
 @code
-  ActiveIterator<dim,Accessor>
+  ActiveIterator<Accessor>
 @endcode
 skips all objects that have children, i.e. objects that are not active.
-Active iterators therefore operate on a strict subset of the objects
+Active iterators therefore operate on a subset of the objects
 that normal iterators act on, namely those that possess the property that
 they are active. Note that this is independent of the kind of object we
 are operating on: all valid accessor classes have to provide the iterator
@@ -118,7 +120,7 @@ classes a method to find out whether they are active or not.
 (For completeness, let us mention that there is a third kind of iterators: "raw
 iterators" also traverse objects that are unused in the triangulation, but
 allocated anyway for efficiency reasons. User code should never use raw
-iterators, they are only for internal purposes of the library.)
+iterators, they are only for %internal purposes of the library.)
 
 Whether an object is active can be considered a "predicate": a property that
 is either true or false. Filtered iterators can be used to restrict the scope
@@ -147,9 +149,9 @@ order. Take this code example:
   DoFHandler<dim>    dof1(tria);
   DoFHandler<dim>    dof2(tria);
   ...
-  typename Trianguation<dim>::cell_iterator ti  = tria.active();
-  typename DoFHandler<dim>::cell_iterator   di1 = dof1.active();
-  typename DoFHandler<dim>::cell_iterator   di2 = dof2.active();
+  typename Trianguation<dim>::cell_iterator ti  = tria.begin();
+  typename DoFHandler<dim>::cell_iterator   di1 = dof1.begin();
+  typename DoFHandler<dim>::cell_iterator   di2 = dof2.begin();
   ...
   while (ti != tria.end())
   {
@@ -170,7 +172,7 @@ assume any such order, but rather consider this an implementation detail
 of the library.
 
 Corresponding to above example, the order in which iterators traverse active
-objects is the same for all iterators in the following snippet:
+objects is the same for all iterators in the following snippet, the difference to the previous example being that here we only consider active cells:
 @code
   typename Trianguation<dim>::active_cell_iterator ti  = tria.begin_active();
   typename DoFHandler<dim>::active_cell_iterator   di1 = dof1.begin_active();
@@ -201,8 +203,9 @@ arrays and tables and lists that the Triangulation class sets up to describe a
 mesh.
 
 Accessing data that characterizes a cell is always done through the Accessor,
-i.e. the expression <tt>i-&gt;</tt> grants access to <b>all</b> attributes of
-this Accessor. Examples of properties you can query from an iterator are
+i.e. the expression <code>i-&gt;xxx()</code> grants access to <b>all</b>
+attributes of this Accessor. Examples of properties you can query from an
+iterator are
 @code
   cell->vertex(1);
   line->child(0);
@@ -211,17 +214,52 @@ this Accessor. Examples of properties you can query from an iterator are
   face->boundary_indicator();
 @endcode
 
-Since dereferencing iterators yields accessor objects, these member functions
-are declared in documented in the hierarchy of <code>TriaObjectAccessor</code>,
-<code>CellAccessor</code>, <code>DoFObjectAccessor</code>,
-<code>DoFCellAccessor</code>, <code>MGDoFObjectAccessor</code>, and
-<code>MGDoFCellAccessor</code> classes. 
+Since dereferencing iterators yields accessor objects, these calls are to
+member functions <code>Accesor::vertex()</code>,
+<code>Accessor::child()</code> etc. These in turn figure out the relevant data
+from the various data structures that store this data. How this is actually
+done and what data structures are used is not really of concern to authors of
+applications in deal.II. In particular, by hiding the actual data structures
+we are able to store data in an efficient way, not necessarily in a way that
+makes it easily accessible or understandable to application writers.
+
+
+
+@section IteratorsTypedefs Kinds of accessors
+
+Depending on what sort of data you want to access, there are different kinds
+of accessor classes:
 
+- The TriaAccessor class provides you with data that identifies the geometric
+  properties of cells, faces, lines, quads, and hexes that make up a
+  triangulation, as well as mother-child relationships.
 
-@section IteratorsTypedefs Iterators defined in the deal.II containers
+- The CellAccessor class is derived from the TriaAccessor class for cases
+  where an object has full dimension, i.e. is a cell rather than for example a
+  line bounding a cell. In that case, additional information about the
+  topological connection of a mesh is available from an accessor such as to
+  request iterators pointing to neighbors of a cell.
 
-Several classes in deal.II typedef iterators inside their class declarations.
-The normal iterator types and calls to get them for cells and faces are:
+- The DoFAccessor class lets you access information related to degrees of
+  freedom associated with cells, faces, etc; it does so for both DoFHandler
+  and hp::DoFHandler objects. Note that the DoFAccessor class is derived from
+  either TriaAccessor or CellAccessor (depending on whether the DoFAccessor
+  points to an object of full dimension or not) and so is able to provide a
+  superset of information over its base classes.
+
+- The DoFCellAccessor class has the same purpose and relation to
+  DoFCellAccessor as the CellAccessor has to TriaAccessor.
+
+- The MGDoFAccessor and MFCellDoFAccessor give access to the multilevel degree
+  of freedom information associated with MGDoFHandler objects. As before,
+  since the MGDoFHandler extends the data structures of regular DoFHandler
+  objects, the MGDoFAccessor is also derived from the DoFAccessor (or
+  DoFCellAccessor) class to provide a superset of information.
+
+Except to look up member documentation, you will not usually have to deal with
+the actual class names listed above. Rather, one uses the typedefs provided by
+the container classes Triangulation, DoFHandler, hp::DoFHandler and
+MGDoFHandler, as well as the function that generate such objects:
 
 <table border=1>
   <tr>
@@ -232,25 +270,25 @@ The normal iterator types and calls to get them for cells and faces are:
   
   <tr>
     <th>Triangulation</th>
-    <td>TriaIterator&lt;dim, CellAccessor&lt;dim&gt; &gt;</td>
+    <td>typename Triangulation@<dim,spacedim@>::cell_iterator</td>
     <td>triangulation.begin()</td>
   </tr>
 
   <tr>
     <th>DoFHandler</th>
-    <td>TriaIterator&lt;dim, DoFCellAccessor&lt; ::DoFHandler&lt;dim&gt; &gt; &gt;</td>
+    <td>typename DoFHandler@<dim,spacedim@>::cell_iterator</td>
     <td>dof_handler.begin()</td>
   </tr>
 
   <tr>
     <th>hp::DoFHandler</th>
-    <td>TriaIterator&lt;dim, DoFCellAccessor&lt;hp::DoFHandler&lt;dim&gt; &gt; &gt;</td>
+    <td>typename hp::DoFHandler@<dim,spacedim@>::cell_iterator</td>
     <td>hp_dof_handler.begin()</td>
   </tr>
 
   <tr>
     <th>MGDoFHandler</th>
-    <td>TriaIterator&lt;dim, MGDoFCellAccessor&lt;dim&gt; &gt;</td>
+    <td>typename MGDoFHandler@<dim,spacedim@>::cell_iterator</td>
     <td>mg_dof_handler.begin()</td>
   </tr>
 </table>
@@ -265,59 +303,60 @@ The normal iterator types and calls to get them for cells and faces are:
   
   <tr>
     <th>Triangulation</th>
-    <td>TriaIterator&lt;dim, TriaObjectAccessor&lt;dim-1, dim&gt; &gt;</td>
+    <td>typename Triangulation@<dim,spacedim@>::face_iterator</td>
     <td>triangulation.begin_face()</td>
   </tr>
 
   <tr>
     <th>DoFHandler</th>
-    <td>TriaIterator&lt;dim, DoFObjectAccessor&lt;dim-1, ::DoFHandler&lt;dim&gt; &gt; &gt;</td>
+    <td>typename DoFHandler@<dim,spacedim@>::face_iterator</td>
     <td>dof_handler.begin_face()</td>
   </tr>
 
   <tr>
     <th>hp::DoFHandler</th>
-    <td>TriaIterator&lt;dim, DoFObjectAccessor&lt;dim-1, hp::DoFHandler&lt;dim&gt; &gt; &gt;</td>
+    <td>typename hp::DoFHandler@<dim,spacedim@>::face_iterator</td>
     <td>hp_dof_handler.begin_face()</td>
   </tr>
 
   <tr>
     <th>MGDoFHandler</th>
-    <td>TriaIterator&lt;dim, MGDoFObjectAccessor&lt;dim-1, dim&gt; &gt;</td>
+    <td>typename MGDoFHandler@<dim,spacedim@>::face_iterator</td>
     <td>mg_dof_handler.begin_face()</td>
   </tr>
 </table>
 
 
-Likewise, active iterators are as follows:
+Likewise, active iterators have the following properties:
+
 <table border=1>
   <tr>
     <th>Container</th>
-    <th>active_cell_iterator type</th>
+    <th>cell_iterator type</th>
     <th>function call</th>
   </tr>
   
   <tr>
     <th>Triangulation</th>
-    <td>TriaActiveIterator&lt;dim, TriaCellAccessor&lt;dim&gt; &gt;</td>
+    <td>typename Triangulation@<dim,spacedim@>::active_cell_iterator</td>
     <td>triangulation.begin_active()</td>
   </tr>
 
   <tr>
     <th>DoFHandler</th>
-    <td>TriaActiveIterator&lt;dim, DoFCellAccessor&lt; ::DoFHandler&lt;dim&gt; &gt; &gt;</td>
+    <td>typename DoFHandler@<dim,spacedim@>::active_cell_iterator</td>
     <td>dof_handler.begin_active()</td>
   </tr>
 
   <tr>
     <th>hp::DoFHandler</th>
-    <td>TriaActiveIterator&lt;dim, DoFCellAccessor&lt;hp::DoFHandler&lt;dim&gt; &gt; &gt;</td>
+    <td>typename hp::DoFHandler@<dim,spacedim@>::active_cell_iterator</td>
     <td>hp_dof_handler.begin_active()</td>
   </tr>
 
   <tr>
     <th>MGDoFHandler</th>
-    <td>TriaActiveIterator&lt;dim, MGDoFCellAccessor&lt;dim&gt; &gt;</td>
+    <td>typename MGDoFHandler@<dim,spacedim@>::active_cell_iterator</td>
     <td>mg_dof_handler.begin_active()</td>
   </tr>
 </table>
@@ -326,46 +365,65 @@ Likewise, active iterators are as follows:
 <table border=1>
   <tr>
     <th>Container</th>
-    <th>active_face_iterator type</th>
+    <th>face_iterator type</th>
     <th>function call</th>
   </tr>
   
   <tr>
     <th>Triangulation</th>
-    <td>TriaActiveIterator&lt;dim, TriaObjectAccessor&lt;dim-1, dim&gt; &gt;</td>
+    <td>typename Triangulation@<dim,spacedim@>::active_face_iterator</td>
     <td>triangulation.begin_active_face()</td>
   </tr>
 
   <tr>
     <th>DoFHandler</th>
-    <td>TriaActiveIterator&lt;dim, DoFObjectAccessor&lt;dim-1, ::DoFHandler&lt;dim&gt; &gt; &gt;</td>
+    <td>typename DoFHandler@<dim,spacedim@>::active_face_iterator</td>
     <td>dof_handler.begin_active_face()</td>
   </tr>
 
   <tr>
     <th>hp::DoFHandler</th>
-    <td>TriaActiveIterator&lt;dim, DoFObjectAccessor&lt;dim-1, hp::DoFHandler&lt;dim&gt; &gt; &gt;</td>
+    <td>typename hp::DoFHandler@<dim,spacedim@>::active_face_iterator</td>
     <td>hp_dof_handler.begin_active_face()</td>
   </tr>
 
   <tr>
     <th>MGDoFHandler</th>
-    <td>TriaActiveIterator&lt;dim, MGDoFObjectAccessor&lt;dim-1, dim&gt; &gt;</td>
+    <td>typename MGDoFHandler@<dim,spacedim@>::active_face_iterator</td>
     <td>mg_dof_handler.begin_active_face()</td>
   </tr>
 </table>
 
+
 In addition to these types and calls that act on cells and faces (logical
 concepts that depend on the dimension: a cell is a quadrilateral in 2d, but
-a hexehedron in 3d), there are corresponding types and calls like
+a hexahedron in 3d), there are corresponding types and calls like
 <code>begin_active_quad()</code> or <code>end_quad()</code> that act on the
 dimension independent geometric objects line, quad, and hex. These calls,
 just as the ones above, exist in active and non-active forms.
 
+The actual definition of all the typedefs local to the container classes are
+stated in the
+
+- internal::Triangulation::Iterators<1,spacedim>,
+  internal::Triangulation::Iterators<2,spacedim>, and
+  internal::Triangulation::Iterators<3,spacedim> classes for Triangulation
+  iterators,
 
+- internal::DoFHandler::Iterators<DH<1,spacedim> >,
+  internal::DoFHandler::Iterators<DH<2,spacedim> >, and
+  internal::DoFHandler::Iterators<DH<3,spacedim> > classes for DoFHandler
+  and hp::DoFHandler iterators,
+
+- internal::MGDoFHandler::Iterators<1,spacedim>,
+  internal::MGDoFHandler::Iterators<2,spacedim>, and
+  internal::MGDoFHandler::Iterators<3,spacedim> classes for MGDoFHandler
+  iterators.
+  
+  
 @section IteratorAccessorInternals Iterator and accessor internals
 
-Iterators, being like pointer, act as if they pointed to an actual
+Iterators, being like pointers, act as if they pointed to an actual
 object, but in reality all they do is to return an accessor when
 dereferenced. The accessor object contains the state, i.e. it knows
 which object it represents, by storing for example which Triangulation
@@ -376,49 +434,20 @@ face, or edge) it represents
 There is a representation of past-the-end-pointers, denoted by special
 values of the member variables <code>present_level</code> and <code>present_index</code> in
 the TriaAccessor class: If <code>present_level</code> @> =0 and <code>present_index</code> @> =0,
-then the object is valid (there is no check whether the triangulation
-really has that many levels or that many cells on the present level
-when we investigate the state of an iterator; however, in many places
-where an iterator is dereferenced we make this check); if
+then the object is valid; if
 <code>present_level</code>==-1 and <code>present_index</code>==-1, then the iterator points
 past the end; in all other cases, the iterator is considered invalid.
-You can check this by calling the state() function.
-
-An iterator is also invalid, if the pointer pointing to the
-Triangulation object is invalid or zero.
-
-Finally, an iterator is invalid, if the element pointed to by
-<code>present_level</code> and <code>present_index</code> is not used, i.e. if the
-<tt>used</tt> flag is set to false.
-
-The last two checks are not made in state() since both cases should
-only occur upon unitialized construction through <tt>memcpy</tt>
-and the like (the parent triangulation can only be set upon
-construction). If an iterator is constructed empty through the
-empty constructor, it sets <code>present_level</code>==-2 and
-<code>present_index</code>==-2. Thus, the iterator is invalid anyway,
-regardless of the state of the triangulation pointer and the state
-of the element pointed to.
+You can check this by calling the TriaAccessorBase::state() function.
 
 Past-the-end iterators may also be used to compare an iterator with
 the before-the-start value, when running backwards. There is no
 distiction between the iterators pointing past the two ends of a
 vector.
 
-Defining only one value to be past-the-end and making all other
-values invalid provides a second track of security: if we should
-have forgotten a check in the library when an iterator is
-incremented or decremented, we automatically convert the iterator
-from the allowed state "past-the-end" to the disallowed state
-"invalid" which increases the chance that somehwen earlier than for
-past-the-end iterators an exception is raised.
-
-Cells are stored based on a hierachical structure of levels, therefore
-the above mentioned structure is useful. Faces however are not organized
-in levels, therefore the <code>present_level</code> 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.
+Cells are stored based on a hierachical structure of levels, therefore the
+above mentioned structure is useful. Faces however are not organized in
+levels, and accessors for objects of lower dimensionality do not have a
+<code>present_level</code> member variable.
 
 
 @ingroup grid
index 3202ab105fdeabf52ede3e544946b8fbc4544dca..3ec4087b257c45b75a81dee451597b1037cedafb 100644 (file)
@@ -366,6 +366,15 @@ inconvenience this causes.
   <br> 
   (RH 2008/07/08 as of branch_anisotropic at 2005/03/03)
   </p>
+
+  <li>
+  <p>
+  New: The class QGaussLog allows the quadrature of integrals with logarithmic
+  kernels.
+  <br> 
+  (Cataldo Manigrasso 2008/05/28)
+  </p>
+
 </ol>
 
 
@@ -374,7 +383,6 @@ inconvenience this causes.
 <h3>lac</h3>
 
 <ol>
-  <li>
   <p>
   New: All SparseMatrix classes (SparseMatrix<number>, PETSc sparse
   matrices, Trilinos sparse matrices, block sparse matrices) can now
@@ -495,6 +503,21 @@ inconvenience this causes.
   <br>
   (WB 2008/07/30)
   </p>
+
+
+  <li> New: Added two new functions to calculate the left or the right inverse of a given 
+  rectangular matrix (FullMatrix::left_invert, FullMatrix::right_invert).
+  They throw an exception if the matrices are not invertible.
+  <br>
+  (Cataldo Manigrasso 2008/6/12)
+  </li>
+
+  <li> Fixed: FullMatrix::Tadd can now transpose correctly rectangular
+  matrices, there was a mismatch about the indexes in the code.
+  <br>
+  (Cataldo Manigrasso 2008/6/12)
+</li>
+
 </ol>
 
 
index bf4aaa34df7d98878b7d84fd966fb29bbac27f6a..c73046ef6c37fc14d5b16f4103441a8a1c00f2ed 100644 (file)
@@ -21,6 +21,7 @@
 #include <lac/identity_matrix.h>
 #include <lac/lapack_full_matrix.h>
 
+
 #include <vector>
 #include <iomanip>
 
@@ -28,7 +29,9 @@ DEAL_II_NAMESPACE_OPEN
 
 
 // forward declarations
-template<typename number> class Vector;
+template <typename number> class Vector;
+
+template <int rank, int dim> class Tensor;
 
 
 /*! @addtogroup Matrix1
@@ -291,6 +294,7 @@ class FullMatrix : public Table<2,number>
                                      */
     explicit FullMatrix (const IdentityMatrix &id);
     
+
                                     /**
                                      * Assignment operator.
                                      */
@@ -899,7 +903,8 @@ class FullMatrix : public Table<2,number>
     void symmetrize ();
 
                                     /**
-                                     * A=Inverse(A). Inversion of
+                                     * A=Inverse(A). A must be a square matrix. 
+                                      * Inversion of 
                                      * this matrix by Gauss-Jordan
                                      * algorithm with partial
                                      * pivoting.  This process is
@@ -935,6 +940,70 @@ class FullMatrix : public Table<2,number>
     template <typename number2>
     void invert (const FullMatrix<number2> &M);
 
+                                    /**
+                                     * Assign the left_inverse of the given matrix
+                                     * to <tt>*this</tt>. The calculation being 
+                                     * performed is <i>(A<sup>T</sup>*A)<sup>-1</sup>
+                                     * *A<sup>T</sup></i>.
+                                     */   
+    template <typename number2>
+    void left_invert (const FullMatrix<number2> &M);
+
+                                    /**
+                                     * Assign the right_inverse of the given matrix
+                                     * to <tt>*this</tt>. The calculation being 
+                                     * performed is <i>A<sup>T</sup>*(A*A<sup>T</sup>)
+                                     * <sup>-1</sup></i>.
+                                     */
+    template <typename number2>
+    void right_invert (const FullMatrix<number2> &M);
+
+                                     /** 
+                                     * Fill matrix with elements
+                                     * extracted from a tensor,
+                                     * taking rows included between
+                                     * <tt>r_i</tt> and <tt>r_j</tt>
+                                     * and columns between
+                                     * <tt>c_i</tt> and
+                                     * <tt>c_j</tt>. The resulting
+                                     * matrix is then inserted in the
+                                     * destination matrix at position
+                                     * <tt>(dst_r, dst_c)</tt> Checks
+                                     * on the indices are made.
+                                     */
+    template <int dim>
+    void
+    copy_from (Tensor<2,dim> &T,
+              const unsigned int src_r_i=0,
+              const unsigned int src_r_j=dim-1,
+              const unsigned int src_c_i=0,
+              const unsigned int src_c_j=dim-1,
+              const unsigned int dst_r=0,
+              const unsigned int dst_c=0);
+
+                                     /**
+                                     * Insert a submatrix (also
+                                     * rectangular) into a tensor,
+                                     * putting its upper left element
+                                     * at the specified position
+                                     * <tt>(dst_r, dst_c)</tt> and
+                                     * the other elements
+                                     * consequently. Default values
+                                     * are chosen so that no
+                                     * parameter needs to be specified
+                                     * if the size of the tensor and
+                                     * that of the matrix coincide.
+                                      */
+    template <int dim>
+    void 
+    copy_to(Tensor<2,dim> &T,
+           const unsigned int src_r_i=0,
+           const unsigned int src_r_j=dim-1,
+           const unsigned int src_c_i=0,
+           const unsigned int src_c_j=dim-1,
+           const unsigned int dst_r=0,
+           const unsigned int dst_c=0);
+
 
 //@}
 ///@name Multiplications
@@ -1433,7 +1502,6 @@ FullMatrix<number>::print (STREAM             &s,
 }
 
 
-
 #endif // DOXYGEN
 
 DEAL_II_NAMESPACE_CLOSE
index a6282b63f42830160b44259483422d09a88de2dc..f76231908626978b7882be864f60d9ee0d2277f8 100644 (file)
@@ -40,7 +40,8 @@ FullMatrix<number>::FullMatrix (const unsigned int n)
 
 template <typename number>
 FullMatrix<number>::FullMatrix (const unsigned int m,
-                               const unsigned int n) :
+                               const unsigned int n) 
+                :
                Table<2,number> (m, n)
 {}
 
@@ -74,8 +75,6 @@ FullMatrix<number>::FullMatrix (const IdentityMatrix &id)
 }
 
 
-
-
 template <typename number>
 FullMatrix<number>&
 FullMatrix<number>::operator = (const FullMatrix<number>& M)
@@ -857,9 +856,10 @@ void FullMatrix<number>::Tadd (const FullMatrix<number2> &src,
   
                                   // Compute maximal size of copied block
   const unsigned int rows = std::min (m() - dst_offset_i,
-                                     src.m() - src_offset_j);
+                                     src.n() - src_offset_j);
   const unsigned int cols = std::min (n() - dst_offset_j,
-                                     src.n() - src_offset_i);
+                                     src.m() - src_offset_i);
+
   
   for (unsigned int i=0; i<rows ; ++i)
     for (unsigned int j=0; j<cols ; ++j)
@@ -1163,6 +1163,120 @@ FullMatrix<number>::invert (const FullMatrix<number2> &M)
     };    
 }
 
+template <typename number>
+template <typename number2>
+void
+FullMatrix<number>::left_invert (const FullMatrix<number2> &A)
+{
+  Assert (!A.empty(), ExcEmptyMatrix());
+  Assert(A.m()>A.n(), ExcDimensionMismatch(A.m(), A.n()));
+  Assert(this->m()==A.n(), ExcDimensionMismatch(this->m(), A.n()));
+  Assert(this->n()==A.m(), ExcDimensionMismatch(this->n(), A.m()));
+  
+  FullMatrix<number2> A_t(A.n(),A.m());
+  FullMatrix<number2> A_t_times_A(A.n(),A.n());
+  FullMatrix<number2> A_t_times_A_inv(A.n(),A.n());
+  FullMatrix<number2> left_inv(A.n(),A.m());
+
+  A_t.Tadd(A,1);
+  A_t.mmult(A_t_times_A,A);
+  if (number(A_t_times_A.determinant())==number(0))
+    Assert(false, ExcSingular())
+  else
+    {
+      A_t_times_A_inv.invert(A_t_times_A);
+      A_t_times_A_inv.mmult(left_inv,A_t);                               
+  
+      *this=left_inv;
+    }
+}
+
+template <typename number>
+template <typename number2>
+void
+FullMatrix<number>::right_invert (const FullMatrix<number2> &A)
+{
+  Assert (!A.empty(), ExcEmptyMatrix());
+  Assert(A.n()>A.m(), ExcDimensionMismatch(A.n(), A.m()));
+  Assert(this->m()==A.n(), ExcDimensionMismatch(this->m(), A.n()));
+  Assert(this->n()==A.m(), ExcDimensionMismatch(this->n(), A.m()));
+  
+  FullMatrix<number> A_t(A.n(),A.m());
+  FullMatrix<number> A_times_A_t(A.m(),A.m());
+  FullMatrix<number> A_times_A_t_inv(A.m(),A.m());
+  FullMatrix<number> right_inv(A.n(),A.m());
+
+  A_t.Tadd(A,1);
+  A.mmult(A_times_A_t,A_t);
+  if (number(A_times_A_t.determinant())==number(0))
+    Assert(false, ExcSingular())
+  else
+    {
+      A_times_A_t_inv.invert(A_times_A_t);
+      A_t.mmult(right_inv,A_times_A_t_inv);                              
+  
+      *this=right_inv;
+    }
+}
+
+
+template <typename number>
+template <int dim>
+void
+FullMatrix<number>::copy_from (Tensor<2,dim> &T, 
+                              const unsigned int src_r_i,
+                              const unsigned int src_r_j,
+                              const unsigned int src_c_i,
+                              const unsigned int src_c_j,
+                              const unsigned int dst_r,
+                              const unsigned int dst_c) 
+{
+
+  Assert (!this->empty(), ExcEmptyMatrix());  
+  Assert(this->m()-dst_r>src_r_j-src_r_i, 
+        ExcIndexRange(this->m()-dst_r,0,src_r_j-src_r_i));
+  Assert(this->n()-dst_c>src_c_j-src_c_i, 
+        ExcIndexRange(this->n()-dst_c,0,src_c_j-src_c_i));
+  Assert(dim>src_r_j, ExcIndexRange(dim,0,src_r_j));
+  Assert(dim>src_c_j, ExcIndexRange(dim,0,src_r_j));
+  Assert(src_r_j>=src_r_i, ExcIndexRange(src_r_j,0,src_r_i));
+  Assert(src_c_j>=src_c_i, ExcIndexRange(src_r_j,0,src_r_i));
+  
+  for (unsigned int i=0; i<src_r_j-src_r_i+1; i++)
+    for (unsigned int j=0; j<src_c_j-src_c_i+1; j++)
+      (*this)(i+dst_r,j+dst_c)=number(T[i+src_r_i][j+src_c_i]);        
+
+}
+
+
+template <typename number>
+template <int dim>
+void
+FullMatrix<number>::copy_to (Tensor<2,dim> &T,
+                            const unsigned int src_r_i,
+                            const unsigned int src_r_j,
+                            const unsigned int src_c_i,
+                            const unsigned int src_c_j,
+                            const unsigned int dst_r,
+                            const unsigned int dst_c)
+{
+  Assert (!this->empty(), ExcEmptyMatrix());  
+  Assert(dim-dst_r>src_r_j-src_r_i, 
+        ExcIndexRange(dim-dst_r,0,src_r_j-src_r_i));
+  Assert(dim-dst_c>src_c_j-src_c_i, 
+        ExcIndexRange(dim-dst_c,0,src_c_j-src_c_i));
+  Assert(this->m()>src_r_j, ExcIndexRange(dim,0,src_r_j));
+  Assert(this->n()>src_c_j, ExcIndexRange(dim,0,src_r_j));
+  Assert(src_r_j>=src_r_i, ExcIndexRange(src_r_j,0,src_r_i));
+  Assert(src_c_j>=src_c_i, ExcIndexRange(src_r_j,0,src_r_i));
+
+
+  for (unsigned int i=0; i<src_r_j-src_r_i+1; i++)
+    for (unsigned int j=0; j<src_c_j-src_c_i+1; j++)
+      T[i+dst_r][j+dst_c] = double ((*this)(i+src_r_i,j+src_c_i));
+}
+
+
 
 template <typename number>
 template <typename somenumber>
index 0fa3339cdb1bc44d3e2a91da107bff519a3aee2d..9af29628ec7e70d9045ea213e8cb2828bc1ce22b 100644 (file)
 
 #include <lac/full_matrix.templates.h>
 #include <base/logstream.h>
+#include <base/tensor.h>
+#include <base/tensor_base.h>
 
 DEAL_II_NAMESPACE_OPEN
 
 #include "full_matrix.inst"
 
-
 // do a few functions that currently don't fit the scheme because they have
 // two template arguments that need to be different (the case of same
 // arguments is covered by the default copy constructor and copy operator that
index 4b527ba37d29be702b28d3958b9af1d49832c2a7..4d42c761416977841d9c40d803ed80285d3fe4a8 100644 (file)
@@ -19,7 +19,28 @@ for (S : REAL_SCALARS)
     template void FullMatrix<S>::print(
       LogStream&, const unsigned int, const unsigned int) const;
     template void FullMatrix<S>::print(
-      std::ostream&, const unsigned int, const unsigned int) const;
+      std::ostream&, const unsigned int, const unsigned int) const;    
+
+    template void FullMatrix<S>::copy_from<1>(
+      Tensor<2,1>&, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned);
+                                               
+    template void FullMatrix<S>::copy_from<2>(
+      Tensor<2,2>&, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned);
+                                               
+    template void FullMatrix<S>::copy_from<3>(
+      Tensor<2,3>&, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned);
+                                               
+    template void FullMatrix<S>::copy_to<1>(
+      Tensor<2,1>&, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned);
+
+    template void FullMatrix<S>::copy_to<2>(
+      Tensor<2,2>&, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned);
+
+    template void FullMatrix<S>::copy_to<3>(
+      Tensor<2,3>&, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned, const unsigned);
+
+
+
   }
 
 for (S1, S2 : REAL_SCALARS)
@@ -62,6 +83,11 @@ for (S1, S2 : REAL_SCALARS)
       void FullMatrix<S1>::Tmmult<S2> (FullMatrix<S2>&, const FullMatrix<S2>&, const bool) const;
     template
       void FullMatrix<S1>::invert<S2> (const FullMatrix<S2>&);
+    template 
+      void FullMatrix<S1>::left_invert<S2> (const FullMatrix<S2> &);
+    template 
+      void FullMatrix<S1>::right_invert<S2> (const FullMatrix<S2> &);
 
     template
       void FullMatrix<S1>::fill_permutation<S2> (
@@ -155,6 +181,11 @@ for (S1, S2 : COMPLEX_SCALARS)
     template
       void FullMatrix<S1>::invert<S2> (const FullMatrix<S2>&);
 
+    template 
+      void FullMatrix<S1>::left_invert<S2> (const FullMatrix<S2> &);
+    template 
+      void FullMatrix<S1>::right_invert<S2> (const FullMatrix<S2> &);
+
     template
       void FullMatrix<S1>::fill_permutation<S2> (
        const FullMatrix<S2>&,

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.